From 1dbc5c87bbec913db5fd6d73dd3c83494caf720c Mon Sep 17 00:00:00 2001 From: Wale Ogunwale Date: Fri, 8 Dec 2017 08:12:20 -0800 Subject: [PATCH] Move home stack behind top fullscreen stack when split-screen is dismissed Further improvement on ag/3245389 where we were moving the home stack behind the top stack, however we don't want to move the home stack behind a top stack that isn't fullscreen like Pip. Also: - Fixed issue where we are creating a non-resizeable stack in split-screen first because we were resolving the windowing mode again in setWindowingMode which doesn't take into account the activity we will be placing into the stack. - Don't ensure visible activities if a stack windowing mode is changing as a side effect of us entering split-screen mode. - Make sure recents activity is moved to the front if it already exists when we are entering split-screen mode. Change-Id: I07a681c74713abb3eef01c298ee15c5752212cb2 Fixes: 69980806 Fixes: 69662547 Fixes: 69898573 Test: go/wm-smoke Test: Steps from bug. --- .../android/server/am/ActivityDisplay.java | 11 +++-- .../server/am/ActivityManagerService.java | 2 +- .../com/android/server/am/ActivityStack.java | 49 ++++++++++++------- 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java index 9bfdd0c5009c6..5f2f3af7a2cda 100644 --- a/services/core/java/com/android/server/am/ActivityDisplay.java +++ b/services/core/java/com/android/server/am/ActivityDisplay.java @@ -409,15 +409,16 @@ class ActivityDisplay extends ConfigurationContainer { otherStack.setWindowingMode(WINDOWING_MODE_FULLSCREEN); } } finally { - if (mHomeStack != null && !isTopStack(mHomeStack)) { + final ActivityStack topFullscreenStack = + getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); + if (topFullscreenStack != null && 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(); + // current top fullscreen stack so it shows up when the top stack is finished. // 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"); + topFullscreenStack.moveToFront("onSplitScreenModeDismissed"); } mSupervisor.mWindowManager.continueSurfaceLayout(); } @@ -435,7 +436,7 @@ class ActivityDisplay extends ConfigurationContainer { } otherStack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, false /* animate */, false /* showRecents */, - false /* sendNonResizeableNotification */); + true /* enteringSplitScreenMode */); } } finally { 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 6760c862dbb68..81ebd11d43d3b 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -10586,7 +10586,7 @@ public class ActivityManagerService extends IActivityManager.Stub stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task); } stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents, - true /* sendNonResizeableNotification */); + false /* enteringSplitScreenMode */); return windowingMode != task.getWindowingMode(); } finally { Binder.restoreCallingIdentity(ident); diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index cf40be53e70d3..27bd9b7335745 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -484,20 +484,24 @@ class ActivityStack extends ConfigurationContai @Override public void setWindowingMode(int windowingMode) { setWindowingMode(windowingMode, false /* animate */, true /* showRecents */, - true /* sendNonResizeableNotification */); + false /* enteringSplitScreenMode */); } void setWindowingMode(int preferredWindowingMode, boolean animate, boolean showRecents, - boolean sendNonResizeableNotification) { + boolean enteringSplitScreenMode) { + final boolean creating = mWindowContainerController == null; final int currentMode = getWindowingMode(); final ActivityDisplay display = getDisplay(); final TaskRecord topTask = topTask(); final ActivityStack splitScreenStack = display.getSplitScreenPrimaryStack(); mTmpOptions.setLaunchWindowingMode(preferredWindowingMode); - // Need to make sure windowing mode is supported. - int windowingMode = display.resolveWindowingMode( - null /* ActivityRecord */, mTmpOptions, topTask, getActivityType()); + // Need to make sure windowing mode is supported. If we in the process of creating the stack + // no need to resolve the windowing mode again as it is already resolved to the right mode. + int windowingMode = creating + ? preferredWindowingMode + : display.resolveWindowingMode( + 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. @@ -506,14 +510,19 @@ class ActivityStack extends ConfigurationContai final boolean alreadyInSplitScreenMode = display.hasSplitScreenPrimaryStack(); + // Don't send non-resizeable notifications if the windowing mode changed was a side effect + // of us entering split-screen mode. + final boolean sendNonResizeableNotification = !enteringSplitScreenMode; // Take any required action due to us not supporting the preferred windowing mode. - if (sendNonResizeableNotification - && windowingMode != preferredWindowingMode && isActivityTypeStandardOrUndefined()) { - if (alreadyInSplitScreenMode - && (preferredWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY - || preferredWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY)) { - // Looks like we can't launch in split screen mode, go ahead an dismiss split-screen - // and display a warning toast about it. + if (alreadyInSplitScreenMode && windowingMode == WINDOWING_MODE_FULLSCREEN + && sendNonResizeableNotification && isActivityTypeStandardOrUndefined()) { + final boolean preferredSplitScreen = + preferredWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY + || preferredWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; + if (preferredSplitScreen || creating) { + // Looks like we can't launch in split screen mode or the stack we are launching + // doesn't support split-screen mode, go ahead an dismiss split-screen and display a + // warning toast about it. mService.mTaskChangeNotificationController.notifyActivityDismissingDockedStack(); display.getSplitScreenPrimaryStack().setWindowingMode(WINDOWING_MODE_FULLSCREEN); } @@ -544,7 +553,7 @@ class ActivityStack extends ConfigurationContai } super.setWindowingMode(windowingMode); - if (mWindowContainerController == null) { + if (creating) { // Nothing else to do if we don't have a window container yet. E.g. call from ctor. return; } @@ -594,16 +603,22 @@ class ActivityStack extends ConfigurationContai // the one where the home stack is visible since recents isn't visible yet, but the // divider will be off. I think we should just make the initial bounds that of home // so that the divider matches and remove this logic. - display.getOrCreateStack(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, - ACTIVITY_TYPE_RECENTS, true /* onTop */); + final ActivityStack recentStack = display.getOrCreateStack( + WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_RECENTS, + true /* onTop */); + recentStack.moveToFront("setWindowingMode"); // If task moved to docked stack - show recents if needed. mService.mWindowManager.showRecentApps(false /* fromHome */); } wm.continueSurfaceLayout(); } - mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS); - mStackSupervisor.resumeFocusedStackTopActivityLocked(); + // Don't ensure visible activities if the windowing mode change was a side effect of us + // entering split-screen mode. + if (!enteringSplitScreenMode) { + mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); + } } @Override