summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java4
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java26
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java122
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());