Ability to getStack by windowingMode/activityType in WM.
Another step away from using static stack ids for things.
Test: Existing tests pass.
Test: go/wm-smoke
Bug: 64146578
Change-Id: I419eca4968ea97bfa6ff71f6e1deaa247abd0328
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 2d1fc91..78f8157 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -16,8 +16,7 @@
package com.android.server.wm;
-import static android.app.ActivityManager.StackId;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
@@ -1312,7 +1311,8 @@
// Notify the pinned stack upon all windows drawn. If there was an animation in
// progress then this signal will resume that animation.
- final TaskStack pinnedStack = mDisplayContent.getStackById(PINNED_STACK_ID);
+ final TaskStack pinnedStack =
+ mDisplayContent.getStack(WINDOWING_MODE_PINNED);
if (pinnedStack != null) {
pinnedStack.onAllWindowsDrawn();
}
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index b7b1f7c..dc5a814 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -236,6 +236,28 @@
return thisType == ACTIVITY_TYPE_UNDEFINED || otherType == ACTIVITY_TYPE_UNDEFINED;
}
+ /**
+ * Returns true if this container is compatible with the input windowing mode and activity type.
+ */
+ public boolean isCompatible(int windowingMode, int activityType) {
+ final int thisActivityType = getActivityType();
+ final int thisWindowingMode = getWindowingMode();
+ final boolean sameActivityType = thisActivityType == activityType;
+ final boolean sameWindowingMode = thisWindowingMode == windowingMode;
+
+ if (sameActivityType && sameWindowingMode) {
+ return true;
+ }
+
+ if (activityType != ACTIVITY_TYPE_UNDEFINED && activityType != ACTIVITY_TYPE_STANDARD) {
+ // Only activity type need to match for non-standard activity types that are defined.
+ return sameActivityType;
+ }
+
+ // Otherwise we are compatible if the windowing mode is the same.
+ return sameWindowingMode;
+ }
+
public void registerConfigurationChangeListener(ConfigurationContainerListener listener) {
if (mChangeListeners.contains(listener)) {
return;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 98a1bd3..7ae5d1a 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -19,8 +19,10 @@
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -117,7 +119,6 @@
import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.app.ActivityManager.StackId;
-import android.app.WindowConfiguration;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
@@ -1457,6 +1458,28 @@
return null;
}
+ /**
+ * Returns the topmost stack on the display that is compatible with the input windowing mode.
+ * Null is no compatible stack on the display.
+ */
+ TaskStack getStack(int windowingMode) {
+ return getStack(windowingMode, ACTIVITY_TYPE_UNDEFINED);
+ }
+
+ /**
+ * Returns the topmost stack on the display that is compatible with the input windowing mode and
+ * activity type. Null is no compatible stack on the display.
+ */
+ private TaskStack getStack(int windowingMode, int activityType) {
+ for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
+ final TaskStack stack = mTaskStackContainers.get(i);
+ if (stack.isCompatible(windowingMode, activityType)) {
+ return stack;
+ }
+ }
+ return null;
+ }
+
@VisibleForTesting
int getStackCount() {
return mTaskStackContainers.size();
@@ -1501,7 +1524,7 @@
// If there was no pinned stack, we still need to notify the controller of the display info
// update as a result of the config change. We do this here to consolidate the flow between
// changes when there is and is not a stack.
- if (getStackById(PINNED_STACK_ID) == null) {
+ if (getStack(WINDOWING_MODE_PINNED) == null) {
mPinnedStackControllerLocked.onDisplayInfoChanged();
}
}
@@ -2238,7 +2261,7 @@
* @return The docked stack, but only if it is visible, and {@code null} otherwise.
*/
TaskStack getDockedStackLocked() {
- final TaskStack stack = getStackById(DOCKED_STACK_ID);
+ final TaskStack stack = getStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
return (stack != null && stack.isVisible()) ? stack : null;
}
@@ -2247,7 +2270,7 @@
* visible.
*/
TaskStack getDockedStackIgnoringVisibility() {
- return getStackById(DOCKED_STACK_ID);
+ return getStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
}
/** Find the visible, touch-deliverable window under the given point */
@@ -3421,11 +3444,11 @@
: requestedPosition >= topChildPosition;
int targetPosition = requestedPosition;
- if (toTop && stack.mStackId != PINNED_STACK_ID
- && getStackById(PINNED_STACK_ID) != null) {
+ if (toTop && stack.getWindowingMode() != WINDOWING_MODE_PINNED
+ && getStack(WINDOWING_MODE_PINNED) != null) {
// The pinned stack is always the top most stack (always-on-top) when it is present.
TaskStack topStack = mChildren.get(topChildPosition);
- if (topStack.mStackId != PINNED_STACK_ID) {
+ if (topStack.getWindowingMode() != WINDOWING_MODE_PINNED) {
throw new IllegalStateException("Pinned stack isn't top stack??? " + mChildren);
}
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 030b986..e0a4666 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -17,8 +17,9 @@
package com.android.server.wm;
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
-import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.Surface.ROTATION_270;
@@ -456,7 +457,8 @@
boolean isHomeStackResizable) {
long animDuration = 0;
if (animate) {
- final TaskStack stack = mDisplayContent.getStackById(DOCKED_STACK_ID);
+ final TaskStack stack =
+ mDisplayContent.getStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
final long transitionDuration = isAnimationMaximizing()
? mService.mAppTransition.getLastClipRevealTransitionDuration()
: DEFAULT_APP_TRANSITION_DURATION;
@@ -605,8 +607,8 @@
if (mMinimizedDock && mService.mPolicy.isKeyguardShowingAndNotOccluded()) {
return;
}
- final TaskStack fullscreenStack =
- mDisplayContent.getStackById(FULLSCREEN_WORKSPACE_STACK_ID);
+ final TaskStack fullscreenStack = mDisplayContent.getStack(
+ WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
final boolean homeVisible = homeTask.getTopVisibleAppToken() != null;
final boolean homeBehind = fullscreenStack != null && fullscreenStack.isVisible();
setMinimizedDockedStack(homeVisible && !homeBehind, animate);
@@ -801,7 +803,8 @@
}
private boolean animateForMinimizedDockedStack(long now) {
- final TaskStack stack = mDisplayContent.getStackById(DOCKED_STACK_ID);
+ final TaskStack stack =
+ mDisplayContent.getStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
if (!mAnimationStarted) {
mAnimationStarted = true;
mAnimationStartTime = now;
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index 1e7140a..4c9326db 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -404,27 +405,29 @@
*/
private void notifyMovementBoundsChanged(boolean fromImeAdjustement) {
synchronized (mService.mWindowMap) {
- if (mPinnedStackListener != null) {
- try {
- final Rect insetBounds = new Rect();
- getInsetBounds(insetBounds);
- final Rect normalBounds = getDefaultBounds();
- if (isValidPictureInPictureAspectRatio(mAspectRatio)) {
- transformBoundsToAspectRatio(normalBounds, mAspectRatio,
- false /* useCurrentMinEdgeSize */);
- }
- final Rect animatingBounds = mTmpAnimatingBoundsRect;
- final TaskStack pinnedStack = mDisplayContent.getStackById(PINNED_STACK_ID);
- if (pinnedStack != null) {
- pinnedStack.getAnimationOrCurrentBounds(animatingBounds);
- } else {
- animatingBounds.set(normalBounds);
- }
- mPinnedStackListener.onMovementBoundsChanged(insetBounds, normalBounds,
- animatingBounds, fromImeAdjustement, mDisplayInfo.rotation);
- } catch (RemoteException e) {
- Slog.e(TAG_WM, "Error delivering actions changed event.", e);
+ if (mPinnedStackListener == null) {
+ return;
+ }
+ try {
+ final Rect insetBounds = new Rect();
+ getInsetBounds(insetBounds);
+ final Rect normalBounds = getDefaultBounds();
+ if (isValidPictureInPictureAspectRatio(mAspectRatio)) {
+ transformBoundsToAspectRatio(normalBounds, mAspectRatio,
+ false /* useCurrentMinEdgeSize */);
}
+ final Rect animatingBounds = mTmpAnimatingBoundsRect;
+ final TaskStack pinnedStack =
+ mDisplayContent.getStack(WINDOWING_MODE_PINNED);
+ if (pinnedStack != null) {
+ pinnedStack.getAnimationOrCurrentBounds(animatingBounds);
+ } else {
+ animatingBounds.set(normalBounds);
+ }
+ mPinnedStackListener.onMovementBoundsChanged(insetBounds, normalBounds,
+ animatingBounds, fromImeAdjustement, mDisplayInfo.rotation);
+ } catch (RemoteException e) {
+ Slog.e(TAG_WM, "Error delivering actions changed event.", e);
}
}
}