Commit 68cf0b83 authored by avayvod's avatar avayvod Committed by Commit bot

[Cast,Android] Subscribe to onCancel and onDismiss correctly

Subclass DialogFragment classes to get notified about the dialog being cancelled and dismissed.
Don't call dismiss() from the onDismiss() handler.

BaseMediaRouteDialogManager:
- expose mDialogFragment to avoid calling closeDialog() from onDismiss()
- add SystemVisibilitySaver to handle the dialogs showing when in FS mode
  (before was handled by ChromeMediaRouteDialogFactory).

MediaRouteChooserDialogManager:
- use subclassed MediaRouteChooserDialogFragment
- use SystemVisibilitySaver and handle onCancel() and onDismiss()

MediaRouteControllerDialogManager:
- use subclassed MediaRouteControllerDialogFragment
- use SystemVisibilitySaver and handle onDismiss() as onCancel() isn't called.

ChromeMediaRouteDialogController:
- exit onDialogCancelled() early if onRouteClosed() was called before (see the comment).

BUG=551184

Review URL: https://codereview.chromium.org/1463693002

Cr-Commit-Position: refs/heads/master@{#361406}
parent 05373dc0
......@@ -4,15 +4,16 @@
package org.chromium.chrome.browser.media.router;
import android.app.Activity;
import android.content.Context;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.MediaRouteDialogFactory;
import android.support.v7.media.MediaRouter;
import android.view.View;
import android.widget.FrameLayout;
import org.chromium.base.ApplicationStatus;
import org.chromium.chrome.browser.media.remote.ChromeMediaRouteDialogFactory;
import org.chromium.chrome.browser.media.router.cast.MediaSource;
import javax.annotation.Nullable;
......@@ -22,11 +23,45 @@ import javax.annotation.Nullable;
*/
public abstract class BaseMediaRouteDialogManager implements MediaRouteDialogManager {
/**
* A helper class to handle the system visibility change caused by the dialog showing up.
* Call saveSystemVisibility() in onCreateDialog() of the DialogFragment and later
* restoreSystemVisibility() in onStop().
* TODO(avayvod): refactor this to avoid a redundant copy in ChromeMediaRouteDialogFactory.
*/
protected static class SystemVisibilitySaver {
private int mSystemVisibilityToRestore;
private boolean mWasFullscreenBeforeShowing;
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();
mSystemVisibilityToRestore = decor.getSystemUiVisibility();
mWasFullscreenBeforeShowing = (
(mSystemVisibilityToRestore & View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) != 0);
}
void restoreSystemVisibility(Activity activity) {
if (!mWasFullscreenBeforeShowing) return;
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.
boolean isStillFullscreen =
(decor.getSystemUiVisibility() & View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) == 0;
if (!isStillFullscreen) return;
decor.setSystemUiVisibility(mSystemVisibilityToRestore);
}
}
private final MediaSource mMediaSource;
private final MediaRouter mAndroidMediaRouter;
private final MediaRouteDialogDelegate mDelegate;
private DialogFragment mDialogFragment;
protected DialogFragment mDialogFragment;
@Override
public void openDialog() {
......@@ -39,8 +74,7 @@ public abstract class BaseMediaRouteDialogManager implements MediaRouteDialogMan
FragmentManager fm = currentActivity.getSupportFragmentManager();
if (fm == null) return;
MediaRouteDialogFactory factory = new ChromeMediaRouteDialogFactory();
mDialogFragment = openDialogInternal(fm, factory);
mDialogFragment = openDialogInternal(fm);
}
@Override
......@@ -68,12 +102,10 @@ public abstract class BaseMediaRouteDialogManager implements MediaRouteDialogMan
* needed.
*
* @param fm {@link FragmentManager} to use to show the dialog.
* @param factory {@link MediaRouteDialogFactory} to use to create the dialog.
* @return null if the initialization fails, otherwise the initialized dialog fragment.
*/
@Nullable
protected abstract DialogFragment openDialogInternal(
FragmentManager fm, MediaRouteDialogFactory factory);
protected abstract DialogFragment openDialogInternal(FragmentManager fm);
protected MediaRouteDialogDelegate delegate() {
return mDelegate;
......
......@@ -104,6 +104,12 @@ public class ChromeMediaRouterDialogController implements MediaRouteDialogDelega
@Override
public void onDialogCancelled() {
// For MediaRouteControllerDialog this method will be called in case the route is closed
// since it only call onDismiss() and there's no way to distinguish between the two.
// Here we can figure it out: if mDialogManager is null, onRouteClosed() was called and
// there's no need to tell the native controller the dialog has been cancelled.
if (mDialogManager == null) return;
mDialogManager = null;
nativeOnDialogCancelled(mNativeDialogController);
}
......
......@@ -4,15 +4,11 @@
package org.chromium.chrome.browser.media.router;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnDismissListener;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.MediaRouteChooserDialogFragment;
import android.support.v7.app.MediaRouteDialogFactory;
import org.chromium.chrome.browser.media.router.cast.MediaSink;
import org.chromium.chrome.browser.media.router.cast.MediaSource;
......@@ -20,8 +16,7 @@ import org.chromium.chrome.browser.media.router.cast.MediaSource;
/**
* Manages the dialog responsible for selecting a {@link MediaSink}.
*/
public class MediaRouteChooserDialogManager extends BaseMediaRouteDialogManager implements
OnCancelListener, OnDismissListener {
public class MediaRouteChooserDialogManager extends BaseMediaRouteDialogManager {
private static final String DIALOG_FRAGMENT_TAG =
"android.support.v7.mediarouter:MediaRouteChooserDialogFragment";
......@@ -34,22 +29,22 @@ public class MediaRouteChooserDialogManager extends BaseMediaRouteDialogManager
}
@Override
protected DialogFragment openDialogInternal(FragmentManager fm,
MediaRouteDialogFactory factory) {
protected DialogFragment openDialogInternal(FragmentManager fm) {
if (fm.findFragmentByTag(DIALOG_FRAGMENT_TAG) != null) return null;
MediaRouteChooserDialogFragment fragment = factory.onCreateChooserDialogFragment();
fragment.setRouteSelector(mediaSource().buildRouteSelector());
fragment.show(fm, DIALOG_FRAGMENT_TAG);
fm.executePendingTransactions();
Dialog dialog = fragment.getDialog();
if (dialog == null) return null;
MediaRouteChooserDialogFragment fragment = new MediaRouteChooserDialogFragment() {
final SystemVisibilitySaver mVisibilitySaver = new SystemVisibilitySaver();
dialog.setOnCancelListener(this);
dialog.setOnDismissListener(this);
@Override
public void onStart() {
mVisibilitySaver.saveSystemVisibility(getActivity());
super.onStart();
}
return fragment;
@Override
public void onStop() {
super.onStop();
mVisibilitySaver.restoreSystemVisibility(getActivity());
}
@Override
......@@ -57,16 +52,27 @@ public class MediaRouteChooserDialogManager extends BaseMediaRouteDialogManager
mCancelled = true;
delegate().onDialogCancelled();
super.onCancel(dialog);
}
@Override
public void onDismiss(DialogInterface dialog) {
closeDialog();
super.onDismiss(dialog);
mDialogFragment = null;
if (mCancelled) return;
MediaSink newSink = MediaSink.fromRoute(androidMediaRouter().getSelectedRoute());
delegate().onSinkSelected(newSink);
}
};
fragment.setRouteSelector(mediaSource().buildRouteSelector());
fragment.show(fm, DIALOG_FRAGMENT_TAG);
fm.executePendingTransactions();
return fragment;
}
}
......@@ -4,15 +4,11 @@
package org.chromium.chrome.browser.media.router;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnDismissListener;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.MediaRouteControllerDialogFragment;
import android.support.v7.app.MediaRouteDialogFactory;
import android.support.v7.media.MediaRouter;
import org.chromium.chrome.browser.media.router.cast.MediaSource;
......@@ -20,13 +16,13 @@ import org.chromium.chrome.browser.media.router.cast.MediaSource;
/**
* Manages the dialog responsible for controlling an existing media route.
*/
public class MediaRouteControllerDialogManager extends BaseMediaRouteDialogManager implements
OnCancelListener, OnDismissListener {
public class MediaRouteControllerDialogManager extends BaseMediaRouteDialogManager {
private static final String DIALOG_FRAGMENT_TAG =
"android.support.v7.mediarouter:MediaRouteControllerDialogFragment";
private final String mMediaRouteId;
private final MediaRouter.Callback mCallback = new MediaRouter.Callback() {
@Override
public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo route) {
......@@ -42,32 +38,38 @@ public class MediaRouteControllerDialogManager extends BaseMediaRouteDialogManag
}
@Override
protected DialogFragment openDialogInternal(FragmentManager fm,
MediaRouteDialogFactory factory) {
protected DialogFragment openDialogInternal(FragmentManager fm) {
if (fm.findFragmentByTag(DIALOG_FRAGMENT_TAG) != null) return null;
MediaRouteControllerDialogFragment fragment = factory.onCreateControllerDialogFragment();
fragment.show(fm, DIALOG_FRAGMENT_TAG);
fm.executePendingTransactions();
Dialog dialog = fragment.getDialog();
if (dialog == null) return null;
dialog.setOnCancelListener(this);
dialog.setOnDismissListener(this);
androidMediaRouter().addCallback(mediaSource().buildRouteSelector(), mCallback);
MediaRouteControllerDialogFragment fragment = new MediaRouteControllerDialogFragment() {
final SystemVisibilitySaver mVisibilitySaver = new SystemVisibilitySaver();
return fragment;
@Override
public void onStart() {
mVisibilitySaver.saveSystemVisibility(getActivity());
super.onStart();
}
@Override
public void onCancel(DialogInterface dialog) {
delegate().onDialogCancelled();
public void onStop() {
super.onStop();
mVisibilitySaver.restoreSystemVisibility(getActivity());
}
@Override
public void onDismiss(DialogInterface dialog) {
delegate().onDialogCancelled();
androidMediaRouter().removeCallback(mCallback);
closeDialog();
mDialogFragment = null;
super.onDismiss(dialog);
}
};
fragment.show(fm, DIALOG_FRAGMENT_TAG);
fm.executePendingTransactions();
androidMediaRouter().addCallback(mediaSource().buildRouteSelector(), mCallback);
return fragment;
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment