Move some display logic into hierarchy [1/2]
Starting to decouple WM-side computation logic from specific
hierarchy levels in WM hierarchy. This means trying to make
helper functions in pinned/docked controllers and in TaskStack
more "static" by using parameters instead of mDisplayContent
references. The short-term purpose of this is to make it
easier to use this logic from the ATM hierarchy. Longer-term
the purpose is to make it possible to use the controller
logic at any level of the hierarchy.
Bug: 113900640
Test: go/wm-smoke + relevant am/wm servicestests
Change-Id: I7054a0d4d75862bb152bae9bc179a418a2dadffc
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 348b2af..4b34297 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -157,8 +157,8 @@
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.SurfaceSession;
-import android.view.WindowManagerPolicyConstants.PointerEventListener;
import android.view.WindowManager;
+import android.view.WindowManagerPolicyConstants.PointerEventListener;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ToBooleanFunction;
@@ -1525,7 +1525,7 @@
config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, config.uiMode, dw,
- dh, mDisplayId);
+ dh, displayInfo.displayCutout, mDisplayId);
config.densityDpi = displayInfo.logicalDensityDpi;
config.colorMode =
@@ -1602,7 +1602,7 @@
}
private int computeCompatSmallestWidth(boolean rotated, int uiMode, int dw, int dh,
- int displayId) {
+ DisplayCutout displayCutout, int displayId) {
mTmpDisplayMetrics.setTo(mDisplayMetrics);
final DisplayMetrics tmpDm = mTmpDisplayMetrics;
final int unrotDw, unrotDh;
@@ -1614,22 +1614,22 @@
unrotDh = dh;
}
int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, uiMode, tmpDm, unrotDw, unrotDh,
- displayId);
+ displayCutout, displayId);
sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, uiMode, tmpDm, unrotDh, unrotDw,
- displayId);
+ displayCutout, displayId);
sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, uiMode, tmpDm, unrotDw, unrotDh,
- displayId);
+ displayCutout, displayId);
sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, uiMode, tmpDm, unrotDh, unrotDw,
- displayId);
+ displayCutout, displayId);
return sw;
}
private int reduceCompatConfigWidthSize(int curSize, int rotation, int uiMode,
- DisplayMetrics dm, int dw, int dh, int displayId) {
+ DisplayMetrics dm, int dw, int dh, DisplayCutout displayCutout, int displayId) {
dm.noncompatWidthPixels = mService.mPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode,
- displayId, mDisplayInfo.displayCutout);
+ displayId, displayCutout);
dm.noncompatHeightPixels = mService.mPolicy.getNonDecorDisplayHeight(dw, dh, rotation,
- uiMode, displayId, mDisplayInfo.displayCutout);
+ uiMode, displayId, displayCutout);
float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
if (curSize == 0 || size < curSize) {
@@ -1667,24 +1667,24 @@
unrotDw);
int sl = Configuration.resetScreenLayout(outConfig.screenLayout);
sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh, uiMode,
- displayId);
+ displayInfo.displayCutout, displayId);
sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw, uiMode,
- displayId);
+ displayInfo.displayCutout, displayId);
sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh, uiMode,
- displayId);
+ displayInfo.displayCutout, displayId);
sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw, uiMode,
- displayId);
+ displayInfo.displayCutout, displayId);
outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
outConfig.screenLayout = sl;
}
private int reduceConfigLayout(int curLayout, int rotation, float density, int dw, int dh,
- int uiMode, int displayId) {
+ int uiMode, DisplayCutout displayCutout, int displayId) {
// Get the app screen size at this rotation.
int w = mService.mPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode, displayId,
- mDisplayInfo.displayCutout);
+ displayCutout);
int h = mService.mPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode, displayId,
- mDisplayInfo.displayCutout);
+ displayCutout);
// Compute the screen layout size class for this rotation.
int longSize = w;
@@ -1892,7 +1892,7 @@
// 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 (!hasPinnedStack()) {
- mPinnedStackControllerLocked.onDisplayInfoChanged();
+ mPinnedStackControllerLocked.onDisplayInfoChanged(getDisplayInfo());
}
}
@@ -2494,11 +2494,15 @@
void rotateBounds(int oldRotation, int newRotation, Rect bounds) {
getBounds(mTmpRect, newRotation);
+ rotateBounds(mTmpRect, oldRotation, newRotation, bounds);
+ }
+ void rotateBounds(Rect parentBounds, int oldRotation, int newRotation, Rect bounds) {
// Compute a transform matrix to undo the coordinate space transformation,
// and present the window at the same physical position it previously occupied.
final int deltaRotation = deltaRotation(newRotation, oldRotation);
- createRotationMatrix(deltaRotation, mTmpRect.width(), mTmpRect.height(), mTmpMatrix);
+ createRotationMatrix(
+ deltaRotation, parentBounds.width(), parentBounds.height(), mTmpMatrix);
mTmpRectF.set(bounds);
mTmpMatrix.mapRect(mTmpRectF);
@@ -3426,27 +3430,27 @@
}
private void updateBounds() {
- calculateBounds(mTmpBounds);
+ calculateBounds(mDisplayInfo, mTmpBounds);
setBounds(mTmpBounds);
}
// Determines the current display bounds based on the current state
- private void calculateBounds(Rect out) {
+ private void calculateBounds(DisplayInfo displayInfo, Rect out) {
// Uses same calculation as in LogicalDisplay#configureDisplayInTransactionLocked.
- final int orientation = mDisplayInfo.rotation;
- boolean rotated = (orientation == ROTATION_90 || orientation == ROTATION_270);
+ final int rotation = displayInfo.rotation;
+ boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
final int physWidth = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
final int physHeight = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
- int width = mDisplayInfo.logicalWidth;
+ int width = displayInfo.logicalWidth;
int left = (physWidth - width) / 2;
- int height = mDisplayInfo.logicalHeight;
+ int height = displayInfo.logicalHeight;
int top = (physHeight - height) / 2;
out.set(left, top, left + width, top + height);
}
@Override
public void getBounds(Rect out) {
- calculateBounds(out);
+ calculateBounds(mDisplayInfo, out);
}
private void getBounds(Rect out, int orientation) {
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 985ce06..6daf2f5 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -171,7 +171,7 @@
final int orientation = mTmpRect2.width() <= mTmpRect2.height()
? ORIENTATION_PORTRAIT
: ORIENTATION_LANDSCAPE;
- final int dockSide = getDockSide(mTmpRect, mTmpRect2, orientation);
+ final int dockSide = getDockSide(mTmpRect, mTmpRect2, orientation, rotation);
final int position = DockedDividerUtils.calculatePositionForBounds(mTmpRect, dockSide,
getContentWidth());
@@ -202,7 +202,7 @@
* @param orientation the origination of device
* @return current docked side
*/
- int getDockSide(Rect bounds, Rect displayRect, int orientation) {
+ int getDockSide(Rect bounds, Rect displayRect, int orientation, int rotation) {
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
// Portrait mode, docked either at the top or the bottom.
final int diff = (displayRect.bottom - bounds.bottom) - (bounds.top - displayRect.top);
@@ -211,7 +211,8 @@
} else if (diff < 0) {
return DOCKED_BOTTOM;
}
- return canPrimaryStackDockTo(DOCKED_TOP) ? DOCKED_TOP : DOCKED_BOTTOM;
+ return canPrimaryStackDockTo(DOCKED_TOP, displayRect, rotation)
+ ? DOCKED_TOP : DOCKED_BOTTOM;
} else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
// Landscape mode, docked either on the left or on the right.
final int diff = (displayRect.right - bounds.right) - (bounds.left - displayRect.left);
@@ -220,7 +221,8 @@
} else if (diff < 0) {
return DOCKED_RIGHT;
}
- return canPrimaryStackDockTo(DOCKED_LEFT) ? DOCKED_LEFT : DOCKED_RIGHT;
+ return canPrimaryStackDockTo(DOCKED_LEFT, displayRect, rotation)
+ ? DOCKED_LEFT : DOCKED_RIGHT;
}
return DOCKED_INVALID;
}
@@ -463,10 +465,9 @@
* @param dockSide the side to see if it is valid
* @return true if the side provided is valid
*/
- boolean canPrimaryStackDockTo(int dockSide) {
- final DisplayInfo di = mDisplayContent.getDisplayInfo();
- return mService.mPolicy.isDockSideAllowed(dockSide, mOriginalDockedSide, di.logicalWidth,
- di.logicalHeight, di.rotation);
+ boolean canPrimaryStackDockTo(int dockSide, Rect parentRect, int rotation) {
+ return mService.mPolicy.isDockSideAllowed(dockSide, mOriginalDockedSide,
+ parentRect.width(), parentRect.height(), rotation);
}
void notifyDockedStackExistsChanged(boolean exists) {
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index 405aaab..d21f67d 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -314,8 +314,8 @@
* onTaskStackBoundsChanged() to be called. But we still should update our known display info
* with the new state so that we can update SystemUI.
*/
- synchronized void onDisplayInfoChanged() {
- mDisplayInfo.copyFrom(mDisplayContent.getDisplayInfo());
+ synchronized void onDisplayInfoChanged(DisplayInfo displayInfo) {
+ mDisplayInfo.copyFrom(displayInfo);
notifyMovementBoundsChanged(false /* fromImeAdjustment */, false /* fromShelfAdjustment */);
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 0d98b20..70a275b 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -61,6 +61,7 @@
import android.util.Slog;
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
+import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.Surface;
import android.view.SurfaceControl;
@@ -486,9 +487,11 @@
mTmpRect2.set(getRawBounds());
mDisplayContent.rotateBounds(mRotation, newRotation, mTmpRect2);
if (inSplitScreenPrimaryWindowingMode()) {
- repositionPrimarySplitScreenStackAfterRotation(mTmpRect2);
- snapDockedStackAfterRotation(mTmpRect2);
- final int newDockSide = getDockSide(mTmpRect2);
+ final Configuration parentConfig = getParent().getConfiguration();
+ repositionSplitScreenStackAfterRotation(parentConfig, true /* primary */, mTmpRect2);
+ final DisplayCutout cutout = mDisplayContent.getDisplayInfo().displayCutout;
+ snapDockedStackAfterRotation(parentConfig, cutout, mTmpRect2);
+ final int newDockSide = getDockSide(mDisplayContent, parentConfig, mTmpRect2);
// Update the dock create mode and clear the dock create bounds, these
// might change after a rotation and the original values will be invalid.
@@ -513,23 +516,30 @@
* Some primary split screen sides are not allowed by the policy. This method queries the policy
* and moves the primary stack around if needed.
*
- * @param inOutBounds the bounds of the primary stack to adjust
+ * @param parentConfig the configuration of the stack's parent.
+ * @param primary true if adjusting the primary docked stack, false for secondary.
+ * @param inOutBounds the bounds of the stack to adjust.
*/
- private void repositionPrimarySplitScreenStackAfterRotation(Rect inOutBounds) {
- int dockSide = getDockSide(inOutBounds);
- if (mDisplayContent.getDockedDividerController().canPrimaryStackDockTo(dockSide)) {
+ void repositionSplitScreenStackAfterRotation(Configuration parentConfig, boolean primary,
+ Rect inOutBounds) {
+ final int dockSide = getDockSide(mDisplayContent, parentConfig, inOutBounds);
+ final int otherDockSide = DockedDividerUtils.invertDockSide(dockSide);
+ final int primaryDockSide = primary ? dockSide : otherDockSide;
+ if (mDisplayContent.getDockedDividerController()
+ .canPrimaryStackDockTo(primaryDockSide,
+ parentConfig.windowConfiguration.getBounds(),
+ mDisplayContent.getDisplayInfo().rotation)) {
return;
}
- mDisplayContent.getBounds(mTmpRect);
- dockSide = DockedDividerUtils.invertDockSide(dockSide);
- switch (dockSide) {
+ final Rect parentBounds = parentConfig.windowConfiguration.getBounds();
+ switch (otherDockSide) {
case DOCKED_LEFT:
int movement = inOutBounds.left;
inOutBounds.left -= movement;
inOutBounds.right -= movement;
break;
case DOCKED_RIGHT:
- movement = mTmpRect.right - inOutBounds.right;
+ movement = parentBounds.right - inOutBounds.right;
inOutBounds.left += movement;
inOutBounds.right += movement;
break;
@@ -539,7 +549,7 @@
inOutBounds.bottom -= movement;
break;
case DOCKED_BOTTOM:
- movement = mTmpRect.bottom - inOutBounds.bottom;
+ movement = parentBounds.bottom - inOutBounds.bottom;
inOutBounds.top += movement;
inOutBounds.bottom += movement;
break;
@@ -549,22 +559,22 @@
/**
* Snaps the bounds after rotation to the closest snap target for the docked stack.
*/
- private void snapDockedStackAfterRotation(Rect outBounds) {
+ void snapDockedStackAfterRotation(Configuration parentConfig, DisplayCutout displayCutout,
+ Rect outBounds) {
// Calculate the current position.
- final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
final int dividerSize = mDisplayContent.getDockedDividerController().getContentWidth();
- final int dockSide = getDockSide(outBounds);
+ final int dockSide = getDockSide(parentConfig, outBounds);
final int dividerPosition = DockedDividerUtils.calculatePositionForBounds(outBounds,
dockSide, dividerSize);
- final int displayWidth = displayInfo.logicalWidth;
- final int displayHeight = displayInfo.logicalHeight;
+ final int displayWidth = parentConfig.windowConfiguration.getBounds().width();
+ final int displayHeight = parentConfig.windowConfiguration.getBounds().height();
// Snap the position to a target.
- final int rotation = displayInfo.rotation;
- final int orientation = mDisplayContent.getConfiguration().orientation;
+ final int rotation = mDisplayContent.getDisplayInfo().rotation;
+ final int orientation = parentConfig.orientation;
mService.mPolicy.getStableInsetsLw(rotation, displayWidth, displayHeight,
- displayInfo.displayCutout, outBounds);
+ displayCutout, outBounds);
final DividerSnapAlgorithm algorithm = new DividerSnapAlgorithm(
mService.mContext.getResources(), displayWidth, displayHeight,
dividerSize, orientation == Configuration.ORIENTATION_PORTRAIT, outBounds,
@@ -573,7 +583,7 @@
// Recalculate the bounds based on the position of the target.
DockedDividerUtils.calculateBoundsForPosition(target.position, dockSide,
- outBounds, displayInfo.logicalWidth, displayInfo.logicalHeight,
+ outBounds, displayWidth, displayHeight,
dividerSize);
}
@@ -1473,27 +1483,27 @@
* information which side of the screen was the dock anchored.
*/
int getDockSide() {
- return getDockSide(getRawBounds());
+ return getDockSide(mDisplayContent.getConfiguration(), getRawBounds());
}
int getDockSideForDisplay(DisplayContent dc) {
- return getDockSide(dc, getRawBounds());
+ return getDockSide(dc, dc.getConfiguration(), getRawBounds());
}
- private int getDockSide(Rect bounds) {
+ int getDockSide(Configuration parentConfig, Rect bounds) {
if (mDisplayContent == null) {
return DOCKED_INVALID;
}
- return getDockSide(mDisplayContent, bounds);
+ return getDockSide(mDisplayContent, parentConfig, bounds);
}
- private int getDockSide(DisplayContent dc, Rect bounds) {
+ private int getDockSide(DisplayContent dc, Configuration parentConfig, Rect bounds) {
if (!inSplitScreenWindowingMode()) {
return DOCKED_INVALID;
}
- dc.getBounds(mTmpRect);
- final int orientation = dc.getConfiguration().orientation;
- return dc.getDockedDividerController().getDockSide(bounds, mTmpRect, orientation);
+ return dc.getDockedDividerController().getDockSide(bounds,
+ parentConfig.windowConfiguration.getBounds(),
+ parentConfig.orientation, dc.getDisplayInfo().rotation);
}
boolean hasTaskForUser(int userId) {