summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java4
-rw-r--r--services/core/java/com/android/server/wm/DisplayWindowSettings.java37
-rw-r--r--services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java7
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java10
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java62
7 files changed, 123 insertions, 6 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index d8720aba3f55..ee1e64f46421 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -685,6 +685,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
*/
private boolean mInEnsureActivitiesVisible = false;
+ // Used to indicate that the movement of child tasks to top will not move the display to top as
+ // well and thus won't change the top resumed / focused record
+ boolean mDontMoveToTop;
+
private final Consumer<WindowState> mUpdateWindowsForAnimator = w -> {
WindowStateAnimator winAnimator = w.mWinAnimator;
final ActivityRecord activity = w.mActivityRecord;
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
index b82fdd237f2b..6d5abe1e2f31 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
@@ -16,11 +16,11 @@
package com.android.server.wm;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
import static android.view.WindowManager.REMOVE_CONTENT_MODE_DESTROY;
import static android.view.WindowManager.REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY;
import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED;
-import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
-import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
import static com.android.server.wm.DisplayContent.FORCE_SCALING_MODE_AUTO;
import static com.android.server.wm.DisplayContent.FORCE_SCALING_MODE_DISABLED;
@@ -196,6 +196,14 @@ class DisplayWindowSettings {
mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
}
+ void setDontMoveToTop(DisplayContent dc, boolean dontMoveToTop) {
+ DisplayInfo displayInfo = dc.getDisplayInfo();
+ SettingsProvider.SettingsEntry overrideSettings =
+ mSettingsProvider.getSettings(displayInfo);
+ overrideSettings.mDontMoveToTop = dontMoveToTop;
+ mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
+ }
+
boolean shouldShowSystemDecorsLocked(DisplayContent dc) {
if (dc.getDisplayId() == Display.DEFAULT_DISPLAY) {
// Default display should show system decors.
@@ -274,6 +282,10 @@ class DisplayWindowSettings {
final int forcedScalingMode = settings.mForcedScalingMode != null
? settings.mForcedScalingMode : FORCE_SCALING_MODE_AUTO;
dc.mDisplayScalingDisabled = forcedScalingMode == FORCE_SCALING_MODE_DISABLED;
+
+ boolean dontMoveToTop = settings.mDontMoveToTop != null
+ ? settings.mDontMoveToTop : false;
+ dc.mDontMoveToTop = dontMoveToTop;
}
/**
@@ -358,6 +370,8 @@ class DisplayWindowSettings {
Boolean mIgnoreOrientationRequest;
@Nullable
Boolean mIgnoreDisplayCutout;
+ @Nullable
+ Boolean mDontMoveToTop;
SettingsEntry() {}
@@ -432,6 +446,10 @@ class DisplayWindowSettings {
mIgnoreDisplayCutout = other.mIgnoreDisplayCutout;
changed = true;
}
+ if (other.mDontMoveToTop != mDontMoveToTop) {
+ mDontMoveToTop = other.mDontMoveToTop;
+ changed = true;
+ }
return changed;
}
@@ -515,6 +533,11 @@ class DisplayWindowSettings {
mIgnoreDisplayCutout = delta.mIgnoreDisplayCutout;
changed = true;
}
+ if (delta.mDontMoveToTop != null
+ && delta.mDontMoveToTop != mDontMoveToTop) {
+ mDontMoveToTop = delta.mDontMoveToTop;
+ changed = true;
+ }
return changed;
}
@@ -531,7 +554,8 @@ class DisplayWindowSettings {
&& mImePolicy == null
&& mFixedToUserRotation == null
&& mIgnoreOrientationRequest == null
- && mIgnoreDisplayCutout == null;
+ && mIgnoreDisplayCutout == null
+ && mDontMoveToTop == null;
}
@Override
@@ -553,7 +577,8 @@ class DisplayWindowSettings {
&& Objects.equals(mImePolicy, that.mImePolicy)
&& Objects.equals(mFixedToUserRotation, that.mFixedToUserRotation)
&& Objects.equals(mIgnoreOrientationRequest, that.mIgnoreOrientationRequest)
- && Objects.equals(mIgnoreDisplayCutout, that.mIgnoreDisplayCutout);
+ && Objects.equals(mIgnoreDisplayCutout, that.mIgnoreDisplayCutout)
+ && Objects.equals(mDontMoveToTop, that.mDontMoveToTop);
}
@Override
@@ -561,7 +586,8 @@ class DisplayWindowSettings {
return Objects.hash(mWindowingMode, mUserRotationMode, mUserRotation, mForcedWidth,
mForcedHeight, mForcedDensity, mForcedScalingMode, mRemoveContentMode,
mShouldShowWithInsecureKeyguard, mShouldShowSystemDecors, mImePolicy,
- mFixedToUserRotation, mIgnoreOrientationRequest, mIgnoreDisplayCutout);
+ mFixedToUserRotation, mIgnoreOrientationRequest, mIgnoreDisplayCutout,
+ mDontMoveToTop);
}
@Override
@@ -581,6 +607,7 @@ class DisplayWindowSettings {
+ ", mFixedToUserRotation=" + mFixedToUserRotation
+ ", mIgnoreOrientationRequest=" + mIgnoreOrientationRequest
+ ", mIgnoreDisplayCutout=" + mIgnoreDisplayCutout
+ + ", mDontMoveToTop=" + mDontMoveToTop
+ '}';
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java b/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java
index 5f3ab43eca7c..737f8107f83f 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java
@@ -405,6 +405,9 @@ class DisplayWindowSettingsProvider implements SettingsProvider {
"ignoreOrientationRequest", null /* defaultValue */);
settingsEntry.mIgnoreDisplayCutout = getBooleanAttribute(parser,
"ignoreDisplayCutout", null /* defaultValue */);
+ settingsEntry.mDontMoveToTop = getBooleanAttribute(parser,
+ "dontMoveToTop", null /* defaultValue */);
+
fileData.mSettings.put(name, settingsEntry);
}
XmlUtils.skipCurrentTag(parser);
@@ -496,6 +499,10 @@ class DisplayWindowSettingsProvider implements SettingsProvider {
out.attributeBoolean(null, "ignoreDisplayCutout",
settingsEntry.mIgnoreDisplayCutout);
}
+ if (settingsEntry.mDontMoveToTop != null) {
+ out.attributeBoolean(null, "dontMoveToTop",
+ settingsEntry.mDontMoveToTop);
+ }
out.endTag(null, "display");
}
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 63732d8d4bdc..40248c43fe5d 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -404,7 +404,11 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
}
// We don't allow untrusted display to top when root task moves to top,
// until user tapping this display to change display position as top intentionally.
- if (!mDisplayContent.isTrusted() && !getParent().isOnTop()) {
+ //
+ // Displays with {@code mDontMoveToTop} property set to {@code true} won't be
+ // allowed to top neither.
+ if ((!mDisplayContent.isTrusted() || mDisplayContent.mDontMoveToTop)
+ && !getParent().isOnTop()) {
includingParents = false;
}
final int targetPosition = findPositionForRootTask(position, child, false /* adding */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 4bea9a2eea45..4c2d12436858 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -1608,6 +1608,16 @@ public class DisplayContentTests extends WindowTestsBase {
}
@Test
+ public void testGetOrCreateRootHomeTask_dontMoveToTop() {
+ DisplayContent display = createNewDisplay();
+ display.mDontMoveToTop = true;
+ TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea();
+
+ assertNull(taskDisplayArea.getRootHomeTask());
+ assertNull(taskDisplayArea.getOrCreateRootHomeTask());
+ }
+
+ @Test
public void testValidWindowingLayer() {
final SurfaceControl windowingLayer = mDisplayContent.getWindowingLayer();
assertNotNull(windowingLayer);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
index 33e8fc0bd94b..3e05c86898e2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
@@ -217,6 +217,7 @@ public class DisplayWindowSettingsProviderTests extends WindowTestsBase {
SettingsEntry overrideSettings = provider.getOverrideSettings(secondaryDisplayInfo);
overrideSettings.mShouldShowSystemDecors = true;
overrideSettings.mImePolicy = DISPLAY_IME_POLICY_LOCAL;
+ overrideSettings.mDontMoveToTop = true;
provider.updateOverrideSettings(secondaryDisplayInfo, overrideSettings);
assertTrue(mOverrideSettingsStorage.wasWriteSuccessful());
@@ -227,6 +228,8 @@ public class DisplayWindowSettingsProviderTests extends WindowTestsBase {
getStoredDisplayAttributeValue(mOverrideSettingsStorage, "shouldShowSystemDecors"));
assertEquals("Attribute value must be stored", "0",
getStoredDisplayAttributeValue(mOverrideSettingsStorage, "imePolicy"));
+ assertEquals("Attribute value must be stored", "true",
+ getStoredDisplayAttributeValue(mOverrideSettingsStorage, "dontMoveToTop"));
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
index d83e9c21fae7..a3ade51970fc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
@@ -156,6 +156,9 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
spyOn(mDisplayContent);
doReturn(true).when(mDisplayContent).isTrusted();
+ // Allow child stack to move to top.
+ mDisplayContent.mDontMoveToTop = false;
+
// The display contains pinned stack that was added in {@link #setUp}.
final Task stack = createTaskStackOnDisplay(mDisplayContent);
final Task task = createTaskInStack(stack, 0 /* userId */);
@@ -173,6 +176,65 @@ public class TaskDisplayAreaTests extends WindowTestsBase {
}
@Test
+ public void testMovingChildTaskOnTop() {
+ // Make sure the display is trusted display which capable to move the stack to top.
+ spyOn(mDisplayContent);
+ doReturn(true).when(mDisplayContent).isTrusted();
+
+ // Allow child stack to move to top.
+ mDisplayContent.mDontMoveToTop = false;
+
+ // The display contains pinned stack that was added in {@link #setUp}.
+ Task stack = createTaskStackOnDisplay(mDisplayContent);
+ Task task = createTaskInStack(stack, 0 /* userId */);
+
+ // Add another display at top.
+ mWm.mRoot.positionChildAt(WindowContainer.POSITION_TOP, createNewDisplay(),
+ false /* includingParents */);
+
+ // Ensure that original display ({@code mDisplayContent}) is not on top.
+ assertEquals("Testing DisplayContent should not be on the top",
+ mWm.mRoot.getChildCount() - 2, mWm.mRoot.mChildren.indexOf(mDisplayContent));
+
+ // Move the task of {@code mDisplayContent} to top.
+ stack.positionChildAt(WindowContainer.POSITION_TOP, task, true /* includingParents */);
+
+ // Ensure that original display ({@code mDisplayContent}) is now on the top.
+ assertEquals("The testing DisplayContent should be moved to top with task",
+ mWm.mRoot.getChildCount() - 1, mWm.mRoot.mChildren.indexOf(mDisplayContent));
+ }
+
+ @Test
+ public void testDontMovingChildTaskOnTop() {
+ // Make sure the display is trusted display which capable to move the stack to top.
+ spyOn(mDisplayContent);
+ doReturn(true).when(mDisplayContent).isTrusted();
+
+ // Allow child stack to move to top.
+ mDisplayContent.mDontMoveToTop = true;
+
+ // The display contains pinned stack that was added in {@link #setUp}.
+ Task stack = createTaskStackOnDisplay(mDisplayContent);
+ Task task = createTaskInStack(stack, 0 /* userId */);
+
+ // Add another display at top.
+ mWm.mRoot.positionChildAt(WindowContainer.POSITION_TOP, createNewDisplay(),
+ false /* includingParents */);
+
+ // Ensure that original display ({@code mDisplayContent}) is not on top.
+ assertEquals("Testing DisplayContent should not be on the top",
+ mWm.mRoot.getChildCount() - 2, mWm.mRoot.mChildren.indexOf(mDisplayContent));
+
+ // Try moving the task of {@code mDisplayContent} to top.
+ stack.positionChildAt(WindowContainer.POSITION_TOP, task, true /* includingParents */);
+
+ // Ensure that original display ({@code mDisplayContent}) hasn't moved and is not
+ // on the top.
+ assertEquals("The testing DisplayContent should not be moved to top with task",
+ mWm.mRoot.getChildCount() - 2, mWm.mRoot.mChildren.indexOf(mDisplayContent));
+ }
+
+ @Test
public void testReuseTaskAsRootTask() {
final Task candidateTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, mDisplayContent);