// 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);
}
}