From eb76b762e2c2e6e02a4d7456e16fb5cf9881f342 Mon Sep 17 00:00:00 2001 From: Wale Ogunwale Date: Fri, 17 Nov 2017 10:08:04 -0800 Subject: [PATCH] Move home stack behind top stack when split-screen is dismissed Whenever split-screen is dismissed we were returning to whatever stack was on the other side since that is the next thing in terms of z-order. However, visually to the user we should be returning home. This CL makes it so. Also, - Fixed issue were FLAG_ACTIVITY_LAUNCH_ADJACENT might not work due to early return in ActivityStarter.getLaunchStack since the stack return by mSupervisor.getLaunchStack() is never null. - Just set windowing mode when AMS.setTaskWindowingMode is called vs. creating a stack to re-parent to. - Fixed issue with reporting multi-window mode changed to be based on onConfigurationChanged() for the activity record. - Corrected a few issues with order of sending pip mode changed and multi-window mode changed due to now sending multi-window mode changed in onConfigurationChanged(). Change-Id: I4893937853968bfd0b437dc646a82ead8f127f2e Fixes: 69378933 Fixes: 68953884 Test: ActivityManagerSplitScreenTests.onSplitScreenModeDismissed --- .../java/com/android/server/am/ActivityDisplay.java | 10 ++++++++++ .../com/android/server/am/ActivityManagerService.java | 12 ++++++------ .../core/java/com/android/server/am/ActivityRecord.java | 9 +++++++-- .../core/java/com/android/server/am/ActivityStack.java | 2 +- .../com/android/server/am/ActivityStackSupervisor.java | 4 ++++ .../java/com/android/server/am/ActivityStarter.java | 17 ++++++----------- .../core/java/com/android/server/am/TaskRecord.java | 12 ++++++++---- 7 files changed, 42 insertions(+), 24 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java index 3dbee42f2e79..b11b16e12c3a 100644 --- a/services/core/java/com/android/server/am/ActivityDisplay.java +++ b/services/core/java/com/android/server/am/ActivityDisplay.java @@ -399,6 +399,16 @@ class ActivityDisplay extends ConfigurationContainer { otherStack.setWindowingMode(WINDOWING_MODE_FULLSCREEN); } } finally { + if (mHomeStack != null && !isTopStack(mHomeStack)) { + // Whenever split-screen is dismissed we want the home stack directly behind the + // currently top stack so it shows up when the top stack is finished. + final ActivityStack topStack = getTopStack(); + // TODO: Would be better to use ActivityDisplay.positionChildAt() for this, however + // ActivityDisplay doesn't have a direct controller to WM side yet. We can switch + // once we have that. + mHomeStack.moveToFront("onSplitScreenModeDismissed"); + topStack.moveToFront("onSplitScreenModeDismissed"); + } mSupervisor.mWindowManager.continueSurfaceLayout(); } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index b2681935798a..fe992daf7d04 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -10522,12 +10522,12 @@ public class ActivityManagerService extends IActivityManager.Stub + " non-standard task " + taskId + " to windowing mode=" + windowingMode); } - final ActivityDisplay display = task.getStack().getDisplay(); - final ActivityStack stack = display.getOrCreateStack(windowingMode, - task.getStack().getActivityType(), toTop); - // TODO: Use ActivityStack.setWindowingMode instead of re-parenting. - task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, - "moveTaskToStack"); + + final ActivityStack stack = task.getStack(); + if (toTop) { + stack.moveToFront("setTaskWindowingMode", task); + } + stack.setWindowingMode(windowingMode); } finally { Binder.restoreCallingIdentity(ident); } diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 883019ea7b10..a089e6ceef78 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -647,8 +647,13 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo return; } + if (task.getStack().deferScheduleMultiWindowModeChanged()) { + // Don't do anything if we are currently deferring multi-window mode change. + return; + } + // An activity is considered to be in multi-window mode if its task isn't fullscreen. - final boolean inMultiWindowMode = task.inMultiWindowMode(); + final boolean inMultiWindowMode = inMultiWindowMode(); if (inMultiWindowMode != mLastReportedMultiWindowMode) { mLastReportedMultiWindowMode = inMultiWindowMode; scheduleMultiWindowModeChanged(getConfiguration()); @@ -675,7 +680,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo // Picture-in-picture mode changes also trigger a multi-window mode change as well, so // update that here in order mLastReportedPictureInPictureMode = inPictureInPictureMode; - mLastReportedMultiWindowMode = inPictureInPictureMode; + mLastReportedMultiWindowMode = inMultiWindowMode(); final Configuration newConfig = task.computeNewOverrideConfigurationForBounds( targetStackBounds, null); schedulePictureInPictureModeChanged(newConfig); diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 3cf22833c101..ced8621d7beb 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -494,7 +494,7 @@ class ActivityStack extends ConfigurationContai // Need to make sure windowing mode is supported. int windowingMode = display.resolveWindowingMode( - null /* ActivityRecord */, mTmpOptions, topTask, getActivityType());; + null /* ActivityRecord */, mTmpOptions, topTask, getActivityType()); if (splitScreenStack == this && windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) { // Resolution to split-screen secondary for the primary split-screen stack means we want // to go fullscreen. diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 52ee67e628e3..445bf679455e 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -4308,6 +4308,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D final ActivityRecord r = task.mActivities.get(i); if (r.app != null && r.app.thread != null) { mPipModeChangedActivities.add(r); + // If we are scheduling pip change, then remove this activity from multi-window + // change list as the processing of pip change will make sure multi-window changed + // message is processed in the right order relative to pip changed. + mMultiWindowModeChangedActivities.remove(r); } } mPipModeChangedTargetStackBounds = targetStackBounds; diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index 6010422bf8b8..27eb98586e7f 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -2123,18 +2123,13 @@ class ActivityStarter { return mReuseTask.getStack(); } - final int vrDisplayId = mPreferredDisplayId == mService.mVr2dDisplayId - ? mPreferredDisplayId : INVALID_DISPLAY; - final ActivityStack launchStack = mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP, - vrDisplayId); - - if (launchStack != null) { - return launchStack; - } - if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0) || mPreferredDisplayId != DEFAULT_DISPLAY) { - return null; + // We don't pass in the default display id into the get launch stack call so it can do a + // full resolution. + final int candidateDisplay = + mPreferredDisplayId != DEFAULT_DISPLAY ? mPreferredDisplayId : INVALID_DISPLAY; + return mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP, candidateDisplay); } // Otherwise handle adjacent launch. @@ -2166,7 +2161,7 @@ class ActivityStarter { mSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack(); if (dockedStack != null && !dockedStack.shouldBeVisible(r)) { // There is a docked stack, but it isn't visible, so we can't launch into that. - return null; + return mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP); } else { return dockedStack; } diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index fd6d618bc62d..83965ee497c8 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -1991,7 +1991,6 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi final Rect currentBounds = getOverrideBounds(); mTmpConfig.setTo(getOverrideConfiguration()); - final boolean oldMatchParentBounds = matchParentBounds(); final Configuration newConfig = getOverrideConfiguration(); final boolean matchParentBounds = bounds == null || bounds.isEmpty(); @@ -2014,12 +2013,17 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom); } onOverrideConfigurationChanged(newConfig); + return !mTmpConfig.equals(newConfig); + } - if (matchParentBounds != oldMatchParentBounds) { + @Override + public void onConfigurationChanged(Configuration newParentConfig) { + final boolean wasInMultiWindowMode = inMultiWindowMode(); + super.onConfigurationChanged(newParentConfig); + if (wasInMultiWindowMode != inMultiWindowMode()) { mService.mStackSupervisor.scheduleUpdateMultiWindowMode(this); } - - return !mTmpConfig.equals(newConfig); + // TODO: Should also take care of Pip mode changes here. } /** Clears passed config and fills it with new override values. */ -- 2.11.0