diff options
3 files changed, 142 insertions, 10 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java index 1fb97f97f421..2fb98690f661 100644 --- a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java +++ b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java @@ -114,7 +114,7 @@ class DisplayWindowPolicyControllerHelper { * @see DisplayWindowPolicyController#keepActivityOnWindowFlagsChanged(ActivityInfo, int, int) */ boolean keepActivityOnWindowFlagsChanged(ActivityInfo aInfo, int flagChanges, - int privateFlagChanges) { + int privateFlagChanges, int flagValues, int privateFlagValues) { if (mDisplayWindowPolicyController == null) { return true; } @@ -125,7 +125,7 @@ class DisplayWindowPolicyControllerHelper { } return mDisplayWindowPolicyController.keepActivityOnWindowFlagsChanged( - aInfo, flagChanges, privateFlagChanges); + aInfo, flagValues, privateFlagValues); } /** Update the top activity and the uids of non-finishing activity */ diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 40b8274d4e51..6edf871d6d8d 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2290,14 +2290,24 @@ public class WindowManagerService extends IWindowManager.Stub winAnimator.setColorSpaceAgnosticLocked((win.mAttrs.privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC) != 0); } - if (win.mActivityRecord != null - && !displayContent.mDwpcHelper.keepActivityOnWindowFlagsChanged( - win.mActivityRecord.info, flagChanges, privateFlagChanges)) { - mH.sendMessage(mH.obtainMessage(H.REPARENT_TASK_TO_DEFAULT_DISPLAY, - win.mActivityRecord.getTask())); - Slog.w(TAG_WM, "Activity " + win.mActivityRecord + " window flag changed," - + " can't remain on display " + displayContent.getDisplayId()); - return 0; + // See if the DisplayWindowPolicyController wants to keep the activity on the window + if (displayContent.mDwpcHelper.hasController() + && win.mActivityRecord != null && (!win.mRelayoutCalled || flagChanges != 0 + || privateFlagChanges != 0)) { + int newOrChangedFlags = !win.mRelayoutCalled ? win.mAttrs.flags : flagChanges; + int newOrChangedPrivateFlags = + !win.mRelayoutCalled ? win.mAttrs.privateFlags : privateFlagChanges; + + if (!displayContent.mDwpcHelper.keepActivityOnWindowFlagsChanged( + win.mActivityRecord.info, newOrChangedFlags, newOrChangedPrivateFlags, + win.mAttrs.flags, + win.mAttrs.privateFlags)) { + mH.sendMessage(mH.obtainMessage(H.REPARENT_TASK_TO_DEFAULT_DISPLAY, + win.mActivityRecord.getTask())); + Slog.w(TAG_WM, "Activity " + win.mActivityRecord + " window flag changed," + + " can't remain on display " + displayContent.getDisplayId()); + return 0; + } } } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java index ba6b3b6c9378..58bf184994e4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java @@ -27,6 +27,7 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUST import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.FLAG_OWN_FOCUS; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; +import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_SPY; import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY; @@ -65,6 +66,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.content.pm.ActivityInfo; import android.content.res.Resources; import android.graphics.Point; import android.graphics.Rect; @@ -89,6 +91,7 @@ import android.view.SurfaceControl; import android.view.View; import android.view.WindowInsets; import android.view.WindowManager; +import android.view.WindowManager.LayoutParams; import android.window.ClientWindowFrames; import android.window.ScreenCapture; import android.window.WindowContainerToken; @@ -101,6 +104,7 @@ import com.android.compatibility.common.util.AdoptShellPermissionsRule; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; /** * Build/Install/Run: @@ -272,6 +276,124 @@ public class WindowManagerServiceTests extends WindowTestsBase { } @Test + public void testRelayout_firstLayout_dwpcHelperCalledWithCorrectFlags() { + // When doing the first layout, the initial flags should be reported as changed to + // keepActivityOnWindowFlagsChanged. + testRelayoutFlagChanges( + /*firstRelayout=*/ true, + /*startFlags=*/ FLAG_SECURE, + /*startPrivateFlags=*/ PRIVATE_FLAG_TRUSTED_OVERLAY, + /*newFlags=*/ FLAG_SECURE, + /*newPrivateFlags=*/ PRIVATE_FLAG_TRUSTED_OVERLAY, + /*expectedChangedFlags=*/ FLAG_SECURE, + /*expectedChangedPrivateFlags=*/ PRIVATE_FLAG_TRUSTED_OVERLAY, + /*expectedFlagsValue=*/ FLAG_SECURE, + /*expectedPrivateFlagsValue=*/ PRIVATE_FLAG_TRUSTED_OVERLAY); + } + + @Test + public void testRelayout_secondLayoutFlagAdded_dwpcHelperCalledWithCorrectFlags() { + testRelayoutFlagChanges( + /*firstRelayout=*/ false, + /*startFlags=*/ 0, + /*startPrivateFlags=*/ 0, + /*newFlags=*/ FLAG_SECURE, + /*newPrivateFlags=*/ 0, + /*expectedChangedFlags=*/ FLAG_SECURE, + /*expectedChangedPrivateFlags=*/ 0, + /*expectedFlagsValue=*/ FLAG_SECURE, + /*expectedPrivateFlagsValue=*/ 0); + } + + @Test + public void testRelayout_secondLayoutMultipleFlagsAddOne_dwpcHelperCalledWithCorrectFlags() { + testRelayoutFlagChanges( + /*firstRelayout=*/ false, + /*startFlags=*/ FLAG_NOT_FOCUSABLE, + /*startPrivateFlags=*/ 0, + /*newFlags=*/ FLAG_SECURE | FLAG_NOT_FOCUSABLE, + /*newPrivateFlags=*/ 0, + /*expectedChangedFlags=*/ FLAG_SECURE, + /*expectedChangedPrivateFlags=*/ 0, + /*expectedFlagsValue=*/ FLAG_SECURE | FLAG_NOT_FOCUSABLE, + /*expectedPrivateFlagsValue=*/ 0); + } + + @Test + public void testRelayout_secondLayoutPrivateFlagAdded_dwpcHelperCalledWithCorrectFlags() { + testRelayoutFlagChanges( + /*firstRelayout=*/ false, + /*startFlags=*/ 0, + /*startPrivateFlags=*/ 0, + /*newFlags=*/ 0, + /*newPrivateFlags=*/ PRIVATE_FLAG_TRUSTED_OVERLAY, + /*expectedChangedFlags=*/ 0, + /*expectedChangedPrivateFlags=*/ PRIVATE_FLAG_TRUSTED_OVERLAY, + /*expectedFlagsValue=*/ 0, + /*expectedPrivateFlagsValue=*/ PRIVATE_FLAG_TRUSTED_OVERLAY); + } + + @Test + public void testRelayout_secondLayoutFlagsRemoved_dwpcHelperCalledWithCorrectFlags() { + testRelayoutFlagChanges( + /*firstRelayout=*/ false, + /*startFlags=*/ FLAG_SECURE, + /*startPrivateFlags=*/ PRIVATE_FLAG_TRUSTED_OVERLAY, + /*newFlags=*/ 0, + /*newPrivateFlags=*/ 0, + /*expectedChangedFlags=*/ FLAG_SECURE, + /*expectedChangedPrivateFlags=*/ PRIVATE_FLAG_TRUSTED_OVERLAY, + /*expectedFlagsValue=*/ 0, + /*expectedPrivateFlagsValue=*/ 0); + } + + // Helper method to test relayout of a window, either for the initial layout, or a subsequent + // one, and makes sure that the flags and private flags changes and final values are properly + // reported to mDwpcHelper.keepActivityOnWindowFlagsChanged. + private void testRelayoutFlagChanges(boolean firstRelayout, int startFlags, + int startPrivateFlags, int newFlags, int newPrivateFlags, int expectedChangedFlags, + int expectedChangedPrivateFlags, int expectedFlagsValue, + int expectedPrivateFlagsValue) { + final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, "appWin"); + win.mRelayoutCalled = !firstRelayout; + mWm.mWindowMap.put(win.mClient.asBinder(), win); + spyOn(mDisplayContent.mDwpcHelper); + when(mDisplayContent.mDwpcHelper.hasController()).thenReturn(true); + + win.mAttrs.flags = startFlags; + win.mAttrs.privateFlags = startPrivateFlags; + + LayoutParams newParams = new LayoutParams(); + newParams.copyFrom(win.mAttrs); + newParams.flags = newFlags; + newParams.privateFlags = newPrivateFlags; + + int seq = 1; + if (!firstRelayout) { + win.mRelayoutSeq = 1; + seq = 2; + } + mWm.relayoutWindow(win.mSession, win.mClient, newParams, 100, 200, View.VISIBLE, 0, seq, + 0, new ClientWindowFrames(), new MergedConfiguration(), + new SurfaceControl(), new InsetsState(), new InsetsSourceControl.Array(), + new Bundle()); + + ArgumentCaptor<Integer> changedFlags = ArgumentCaptor.forClass(Integer.class); + ArgumentCaptor<Integer> changedPrivateFlags = ArgumentCaptor.forClass(Integer.class); + ArgumentCaptor<Integer> flagsValue = ArgumentCaptor.forClass(Integer.class); + ArgumentCaptor<Integer> privateFlagsValue = ArgumentCaptor.forClass(Integer.class); + + verify(mDisplayContent.mDwpcHelper).keepActivityOnWindowFlagsChanged( + any(ActivityInfo.class), changedFlags.capture(), changedPrivateFlags.capture(), + flagsValue.capture(), privateFlagsValue.capture()); + + assertThat(changedFlags.getValue()).isEqualTo(expectedChangedFlags); + assertThat(changedPrivateFlags.getValue()).isEqualTo(expectedChangedPrivateFlags); + assertThat(flagsValue.getValue()).isEqualTo(expectedFlagsValue); + assertThat(privateFlagsValue.getValue()).isEqualTo(expectedPrivateFlagsValue); + } + + @Test public void testMoveWindowTokenToDisplay_NullToken_DoNothing() { mWm.moveWindowTokenToDisplay(null, mDisplayContent.getDisplayId()); |