Commit e55f61d6 authored by Ted Choc's avatar Ted Choc Committed by Commit Bot

Initial plumbing to support "move to other window" on multi-display devices. (i.e. the ZTE Axon M)

BUG=824954

Change-Id: I473641d51907cdab567df7110b6c4415876c03f8
Reviewed-on: https://chromium-review.googlesource.com/1011583Reviewed-by: default avatarTheresa <twellington@chromium.org>
Commit-Queue: Ted Choc <tedchoc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#550652}
parent dea26b73
...@@ -1761,7 +1761,8 @@ public class ChromeTabbedActivity ...@@ -1761,7 +1761,8 @@ public class ChromeTabbedActivity
MultiWindowUtils.setOpenInOtherWindowIntentExtras(intent, this, targetActivity); MultiWindowUtils.setOpenInOtherWindowIntentExtras(intent, this, targetActivity);
MultiWindowUtils.onMultiInstanceModeStarted(); MultiWindowUtils.onMultiInstanceModeStarted();
tab.detachAndStartReparenting(intent, null, null); tab.detachAndStartReparenting(
intent, MultiWindowUtils.getOpenInOtherWindowActivityOptions(this), null);
} }
@Override @Override
......
...@@ -8,12 +8,16 @@ import android.annotation.TargetApi; ...@@ -8,12 +8,16 @@ import android.annotation.TargetApi;
import android.app.Activity; import android.app.Activity;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.ActivityManager.AppTask; import android.app.ActivityManager.AppTask;
import android.app.ActivityOptions;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.hardware.display.DisplayManager;
import android.os.Build; import android.os.Build;
import android.os.Bundle;
import android.provider.Browser; import android.provider.Browser;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.Display;
import org.chromium.base.ActivityState; import org.chromium.base.ActivityState;
import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.ApiCompatibilityUtils;
...@@ -25,6 +29,7 @@ import org.chromium.chrome.browser.ChromeTabbedActivity; ...@@ -25,6 +29,7 @@ import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.ChromeTabbedActivity2; import org.chromium.chrome.browser.ChromeTabbedActivity2;
import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.IntentHandler;
import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.chrome.browser.util.IntentUtils;
import org.chromium.ui.display.DisplayAndroidManager;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.lang.reflect.Field; import java.lang.reflect.Field;
...@@ -43,6 +48,8 @@ public class MultiWindowUtils implements ActivityStateListener { ...@@ -43,6 +48,8 @@ public class MultiWindowUtils implements ActivityStateListener {
// getInstance() is called early in start-up, so there is not point in lazily initializing it. // getInstance() is called early in start-up, so there is not point in lazily initializing it.
private static final MultiWindowUtils sInstance = AppHooks.get().createMultiWindowUtils(); private static final MultiWindowUtils sInstance = AppHooks.get().createMultiWindowUtils();
private static final boolean SUPPORTS_MULTI_DISPLAY = false;
// Used to keep track of whether ChromeTabbedActivity2 is running. A tri-state Boolean is // Used to keep track of whether ChromeTabbedActivity2 is running. A tri-state Boolean is
// used in case both activities die in the background and MultiWindowUtils is recreated. // used in case both activities die in the background and MultiWindowUtils is recreated.
private Boolean mTabbedActivity2TaskRunning; private Boolean mTabbedActivity2TaskRunning;
...@@ -67,6 +74,21 @@ public class MultiWindowUtils implements ActivityStateListener { ...@@ -67,6 +74,21 @@ public class MultiWindowUtils implements ActivityStateListener {
return ApiCompatibilityUtils.isInMultiWindowMode(activity); return ApiCompatibilityUtils.isInMultiWindowMode(activity);
} }
/**
* @param activity The {@link Activity} to check.
* @return Whether the system currently supports multiple displays.
*/
public boolean isInMultiDisplayMode(Activity activity) {
if (!SUPPORTS_MULTI_DISPLAY) return false;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
return false;
}
DisplayManager displayManager =
(DisplayManager) activity.getSystemService(Context.DISPLAY_SERVICE);
Display[] displays = displayManager.getDisplays();
return displays != null && displays.length == 2;
}
@VisibleForTesting @VisibleForTesting
public void setIsInMultiWindowModeForTesting(boolean isInMultiWindowMode) { public void setIsInMultiWindowModeForTesting(boolean isInMultiWindowMode) {
mIsInMultiWindowModeForTesting = isInMultiWindowMode; mIsInMultiWindowModeForTesting = isInMultiWindowMode;
...@@ -77,8 +99,9 @@ public class MultiWindowUtils implements ActivityStateListener { ...@@ -77,8 +99,9 @@ public class MultiWindowUtils implements ActivityStateListener {
* other window. * other window.
*/ */
public boolean isOpenInOtherWindowSupported(Activity activity) { public boolean isOpenInOtherWindowSupported(Activity activity) {
if (!isInMultiWindowMode(activity) && !isInMultiDisplayMode(activity)) return false;
// Supported only in multi-window mode and if activity supports side-by-side instances. // Supported only in multi-window mode and if activity supports side-by-side instances.
return isInMultiWindowMode(activity) && getOpenInOtherWindowActivity(activity) != null; return getOpenInOtherWindowActivity(activity) != null;
} }
/** /**
...@@ -86,7 +109,6 @@ public class MultiWindowUtils implements ActivityStateListener { ...@@ -86,7 +109,6 @@ public class MultiWindowUtils implements ActivityStateListener {
* Returns null if the current activity doesn't support opening/moving tabs to another activity. * Returns null if the current activity doesn't support opening/moving tabs to another activity.
*/ */
public Class<? extends Activity> getOpenInOtherWindowActivity(Activity current) { public Class<? extends Activity> getOpenInOtherWindowActivity(Activity current) {
if (current instanceof ChromeTabbedActivity2) { if (current instanceof ChromeTabbedActivity2) {
// If a second ChromeTabbedActivity is created, MultiWindowUtils needs to listen for // If a second ChromeTabbedActivity is created, MultiWindowUtils needs to listen for
// activity state changes to facilitate determining which ChromeTabbedActivity should // activity state changes to facilitate determining which ChromeTabbedActivity should
...@@ -131,6 +153,38 @@ public class MultiWindowUtils implements ActivityStateListener { ...@@ -131,6 +153,38 @@ public class MultiWindowUtils implements ActivityStateListener {
intent.putExtra(Browser.EXTRA_CREATE_NEW_TAB, true); intent.putExtra(Browser.EXTRA_CREATE_NEW_TAB, true);
} }
/**
* Generate the activity options used when handling "open in other window" or "move to other
* window" on a multi-display capable device.
*
* This should be used in combination with
* {@link #setOpenInOtherWindowIntentExtras(Intent, Activity, Class)}.
*
* @param activity The activity firing the intent.
* @return The ActivityOptions needed to open the content in another display.
* @see Context#startActivity(Intent, Bundle)
*/
public static Bundle getOpenInOtherWindowActivityOptions(Activity activity) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return null;
if (!getInstance().isInMultiDisplayMode(activity)) return null;
Display defaultDisplay = DisplayAndroidManager.getDefaultDisplayForContext(activity);
DisplayManager displayManager =
(DisplayManager) activity.getSystemService(Context.DISPLAY_SERVICE);
Display launchDisplay = null;
for (Display display : displayManager.getDisplays()) {
if (display.getDisplayId() == defaultDisplay.getDisplayId()) continue;
launchDisplay = display;
break;
}
if (launchDisplay == null) {
throw new IllegalStateException(
"Attempting to open window in other display, but one is not found");
}
return ActivityOptions.makeBasic()
.setLaunchDisplayId(launchDisplay.getDisplayId())
.toBundle();
}
@Override @Override
public void onActivityStateChange(Activity activity, int newState) { public void onActivityStateChange(Activity activity, int newState) {
if (newState == ActivityState.RESUMED && activity instanceof ChromeTabbedActivity) { if (newState == ActivityState.RESUMED && activity instanceof ChromeTabbedActivity) {
......
...@@ -91,7 +91,8 @@ public class TabDelegate extends TabCreator { ...@@ -91,7 +91,8 @@ public class TabDelegate extends TabCreator {
MultiWindowUtils.setOpenInOtherWindowIntentExtras(intent, activity, targetActivity); MultiWindowUtils.setOpenInOtherWindowIntentExtras(intent, activity, targetActivity);
IntentHandler.addTrustedIntentExtras(intent); IntentHandler.addTrustedIntentExtras(intent);
MultiWindowUtils.onMultiInstanceModeStarted(); MultiWindowUtils.onMultiInstanceModeStarted();
activity.startActivity(intent); activity.startActivity(
intent, MultiWindowUtils.getOpenInOtherWindowActivityOptions(activity));
} }
@Override @Override
......
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