From b1e75f7b2a5444bccae00ec803a6bad81789ba19 Mon Sep 17 00:00:00 2001 From: Evan Rosky Date: Fri, 26 Apr 2019 20:23:26 -0700 Subject: [PATCH] Fix display-level windowingMode change This includes the following fixes: It updates the ATM hierarchy and executes accumulated transitions when display windowingMode changes. This was being skipped because the mode change was being set on DC before reconfigureDisplayLocked. Don't freeze the display when only window-effecting configs change Don't cancel change transition on display change if the window hasn't moved to a different display Cancel change transition when app loses visibility. Bug: 130755818 Test: Added test to AppChangeTransitionTests, manual test on chromeos for display windowing-mode change. Change-Id: Ic1a0427f3e5ba940dc4c12765395e8ca050b0baf --- .../com/android/server/wm/ActivityRecord.java | 4 +++- .../com/android/server/wm/AppWindowToken.java | 8 ++++++-- .../server/wm/WindowManagerService.java | 17 +++++++++++++++++ .../server/wm/AppChangeTransitionTests.java | 18 ++++++++++++++++++ 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 4278860a0d773..5d3739bfdfea8 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -2318,7 +2318,9 @@ final class ActivityRecord extends ConfigurationContainer { return; } - if (configChanges == 0 && mAppWindowToken.okToDisplay()) { + // Window configuration changes only effect windows, so don't require a screen freeze. + int freezableConfigChanges = configChanges & ~(CONFIG_WINDOW_CONFIGURATION); + if (freezableConfigChanges == 0 && mAppWindowToken.okToDisplay()) { if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Skipping set freeze of " + appToken); return; } diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 2321898b91cc6..a9903ddb75222 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -508,6 +508,10 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree final DisplayContent displayContent = getDisplayContent(); displayContent.mOpeningApps.remove(this); displayContent.mClosingApps.remove(this); + if (isInChangeTransition()) { + clearChangeLeash(getPendingTransaction(), true /* cancel */); + } + displayContent.mChangingApps.remove(this); waitingToShow = false; hiddenRequested = !visible; mDeferHidingClient = deferHidingClient; @@ -1309,7 +1313,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree void onDisplayChanged(DisplayContent dc) { DisplayContent prevDc = mDisplayContent; super.onDisplayChanged(dc); - if (prevDc == null) { + if (prevDc == null || prevDc == mDisplayContent) { return; } if (prevDc.mChangingApps.contains(this)) { @@ -1332,7 +1336,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } } - if (prevDc != mDisplayContent && mLetterbox != null) { + if (mLetterbox != null) { mLetterbox.onMovedToDisplay(mDisplayContent.getDisplayId()); } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index dae29b2cf1803..c986c448fb741 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -6776,9 +6776,26 @@ public class WindowManagerService extends IWindowManager.Stub return; } + int lastWindowingMode = displayContent.getWindowingMode(); mDisplayWindowSettings.setWindowingModeLocked(displayContent, mode); reconfigureDisplayLocked(displayContent); + + if (lastWindowingMode != displayContent.getWindowingMode()) { + // reconfigure won't detect this change in isolation because the windowing mode is + // already set on the display, so fire off a new config now. + mH.removeMessages(H.SEND_NEW_CONFIGURATION); + + final long origId = Binder.clearCallingIdentity(); + try { + // direct call since lock is shared. + sendNewConfiguration(displayId); + } finally { + Binder.restoreCallingIdentity(origId); + } + // Now that all configurations are updated, execute pending transitions + displayContent.executeAppTransition(); + } } } diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java index 83c0af92a6ee6..b930354390dfe 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java @@ -154,4 +154,22 @@ public class AppChangeTransitionTests extends WindowTestsBase { waitUntilHandlersIdle(); mToken.removeImmediately(); } + + @Test + public void testCancelPendingChangeOnHide() { + // setup currently defaults to no snapshot. + setUpOnDisplay(mDisplayContent); + + mTask.setWindowingMode(WINDOWING_MODE_FREEFORM); + assertEquals(1, mDisplayContent.mChangingApps.size()); + assertTrue(mToken.isInChangeTransition()); + + // Changing visibility should cancel the change transition and become closing + mToken.setVisibility(false, false); + assertEquals(0, mDisplayContent.mChangingApps.size()); + assertFalse(mToken.isInChangeTransition()); + + waitUntilHandlersIdle(); + mToken.removeImmediately(); + } }