// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package org.chromium.chrome.browser.media.remote; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; import android.os.Handler; import android.support.v7.app.MediaRouteChooserDialog; import android.support.v7.app.MediaRouteChooserDialogFragment; import android.support.v7.app.MediaRouteDialogFactory; import android.support.v7.media.MediaRouter; import android.view.View; import android.widget.FrameLayout; import org.chromium.chrome.browser.media.remote.MediaRouteController.MediaStateListener; /** * The Chrome implementation of the dialog factory so custom behavior can * be injected for the disconnect button. */ public class MediaRouteChooserDialogFactory extends MediaRouteDialogFactory { private final MediaRouteController mController; private final Context mContext; private final MediaStateListener mPlayer; MediaRouteChooserDialogFactory(MediaStateListener player, MediaRouteController controller, Context context) { mPlayer = player; mController = controller; mContext = context; } private static class SystemVisibilitySaver { private int mSystemVisibility; private boolean mRestoreSystemVisibility; void saveSystemVisibility(Activity activity) { // If we are in fullscreen we may have also have hidden the system UI. This // is overridden when we display the dialog. Save the system UI visibility // state so we can restore it. FrameLayout decor = (FrameLayout) activity.getWindow().getDecorView(); mSystemVisibility = decor.getSystemUiVisibility(); mRestoreSystemVisibility = ( (mSystemVisibility & View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) != 0); } void restoreSystemVisibility(Activity activity) { if (mRestoreSystemVisibility) { FrameLayout decor = (FrameLayout) activity.getWindow().getDecorView(); // In some cases we come out of fullscreen before closing this dialog. In these // cases we don't want to restore the system UI visibility state. int systemVisibility = decor.getSystemUiVisibility(); if ((systemVisibility & View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) != 0) { decor.setSystemUiVisibility(mSystemVisibility); } } } } /** * A dialog fragment for choosing a media route that saves system visibility for handling * fullscreen state of Chrome correctly. Needs to be a named public static class, see * https://crbug.com/618993. */ public static final class Fragment extends MediaRouteChooserDialogFragment { final Handler mHandler = new Handler(); final MediaRouteController mController; final MediaStateListener mPlayer; final SystemVisibilitySaver mVisibilitySaver = new SystemVisibilitySaver(); boolean mCancelled = false; Context mContext = null; // The class has to be a public static class with a zero-argument constructor. // Since we can't pass any callbacks to the fragment easily, just close the dialog. // See https://crbug.com/618993. public Fragment() { mHandler.post(new Runnable() { @Override public void run() { Fragment.this.dismiss(); } }); mController = null; mPlayer = null; } @SuppressLint("ValidFragment") Fragment(MediaRouteController controller, MediaStateListener player) { mController = controller; mPlayer = player; } @Override public MediaRouteChooserDialog onCreateChooserDialog( Context context, Bundle savedInstanceState) { mVisibilitySaver.saveSystemVisibility(getActivity()); mContext = context; return new MediaRouteChooserDialog(context); } @Override public void onStop() { super.onStop(); mVisibilitySaver.restoreSystemVisibility(getActivity()); } @Override public void onCancel(DialogInterface dialog) { mCancelled = true; super.onCancel(dialog); } @Override public void onDismiss(DialogInterface dialog) { super.onDismiss(dialog); if (mCancelled) { if (mPlayer != null) mPlayer.onRouteDialogCancelled(); return; } if (mController != null) { MediaRouter router = MediaRouter.getInstance(mContext); mController.onRouteSelected(mPlayer, router, router.getSelectedRoute()); } } } @Override public MediaRouteChooserDialogFragment onCreateChooserDialogFragment() { return new Fragment(mController, mPlayer); } }