Merge "Don't return half folded state when display in transition" into 24D1-dev
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/IPip.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/IPip.aidl
index b5f25433f..e779879 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/IPip.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/IPip.aidl
@@ -53,9 +53,11 @@
* @param destinationBounds the destination bounds the PiP window lands into
* @param overlay an optional overlay to fade out after entering PiP
* @param appBounds the bounds used to set the buffer size of the optional content overlay
+ * @param sourceRectHint the bounds to show in the transition to PiP
*/
oneway void stopSwipePipToHome(int taskId, in ComponentName componentName,
- in Rect destinationBounds, in SurfaceControl overlay, in Rect appBounds) = 2;
+ in Rect destinationBounds, in SurfaceControl overlay, in Rect appBounds,
+ in Rect sourceRectHint) = 2;
/**
* Notifies the swiping Activity to PiP onto home transition is aborted
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index 6751f6f..e9a9b17 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -373,6 +373,10 @@
@NonNull
final Rect mAppBounds = new Rect();
+ /** The source rect hint from stopSwipePipToHome(). */
+ @Nullable
+ private Rect mSwipeSourceRectHint;
+
public PipTaskOrganizer(Context context,
@NonNull SyncTransactionQueue syncTransactionQueue,
@NonNull PipTransitionState pipTransitionState,
@@ -504,7 +508,7 @@
* Expect {@link #onTaskAppeared(ActivityManager.RunningTaskInfo, SurfaceControl)} afterwards.
*/
public void stopSwipePipToHome(int taskId, ComponentName componentName, Rect destinationBounds,
- SurfaceControl overlay, Rect appBounds) {
+ SurfaceControl overlay, Rect appBounds, Rect sourceRectHint) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"stopSwipePipToHome: %s, stat=%s", componentName, mPipTransitionState);
// do nothing if there is no startSwipePipToHome being called before
@@ -513,6 +517,7 @@
}
mPipBoundsState.setBounds(destinationBounds);
setContentOverlay(overlay, appBounds);
+ mSwipeSourceRectHint = sourceRectHint;
if (ENABLE_SHELL_TRANSITIONS && overlay != null) {
// With Shell transition, the overlay was attached to the remote transition leash, which
// will be removed when the current transition is finished, so we need to reparent it
@@ -529,6 +534,20 @@
}
}
+ /**
+ * Returns non-null Rect if the pip is entering from swipe-to-home with a specified source hint.
+ * This also consumes the rect hint.
+ */
+ @Nullable
+ Rect takeSwipeSourceRectHint() {
+ final Rect sourceRectHint = mSwipeSourceRectHint;
+ if (sourceRectHint == null || sourceRectHint.isEmpty()) {
+ return null;
+ }
+ mSwipeSourceRectHint = null;
+ return mPipTransitionState.getInSwipePipToHomeTransition() ? sourceRectHint : null;
+ }
+
private void mayRemoveContentOverlay(SurfaceControl overlay) {
final WeakReference<SurfaceControl> overlayRef = new WeakReference<>(overlay);
final long timeoutDuration = (mEnterAnimationDuration
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index 14550a3..d4d1caf 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -989,8 +989,11 @@
final Rect currentBounds = pipChange.getStartAbsBounds();
int rotationDelta = deltaRotation(startRotation, endRotation);
- Rect sourceHintRect = PipBoundsAlgorithm.getValidSourceHintRect(
- taskInfo.pictureInPictureParams, currentBounds, destinationBounds);
+ Rect sourceHintRect = mPipOrganizer.takeSwipeSourceRectHint();
+ if (sourceHintRect == null) {
+ sourceHintRect = PipBoundsAlgorithm.getValidSourceHintRect(
+ taskInfo.pictureInPictureParams, currentBounds, destinationBounds);
+ }
if (rotationDelta != Surface.ROTATION_0
&& endRotation != mPipDisplayLayoutState.getRotation()) {
// Computes the destination bounds in new rotation.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index 84afed1..abee915 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -998,9 +998,9 @@
}
private void stopSwipePipToHome(int taskId, ComponentName componentName, Rect destinationBounds,
- SurfaceControl overlay, Rect appBounds) {
+ SurfaceControl overlay, Rect appBounds, Rect sourceRectHint) {
mPipTaskOrganizer.stopSwipePipToHome(taskId, componentName, destinationBounds, overlay,
- appBounds);
+ appBounds, sourceRectHint);
}
private void abortSwipePipToHome(int taskId, ComponentName componentName) {
@@ -1287,13 +1287,15 @@
@Override
public void stopSwipePipToHome(int taskId, ComponentName componentName,
- Rect destinationBounds, SurfaceControl overlay, Rect appBounds) {
+ Rect destinationBounds, SurfaceControl overlay, Rect appBounds,
+ Rect sourceRectHint) {
if (overlay != null) {
overlay.setUnreleasedWarningCallSite("PipController.stopSwipePipToHome");
}
executeRemoteCallWithTaskPermission(mController, "stopSwipePipToHome",
(controller) -> controller.stopSwipePipToHome(
- taskId, componentName, destinationBounds, overlay, appBounds));
+ taskId, componentName, destinationBounds, overlay, appBounds,
+ sourceRectHint));
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
index e73a850..e714b6d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
@@ -193,7 +193,8 @@
}
private void onSwipePipToHomeAnimationStart(int taskId, ComponentName componentName,
- Rect destinationBounds, SurfaceControl overlay, Rect appBounds) {
+ Rect destinationBounds, SurfaceControl overlay, Rect appBounds,
+ Rect sourceRectHint) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"onSwipePipToHomeAnimationStart: %s", componentName);
mPipScheduler.setInSwipePipToHomeTransition(true);
@@ -234,13 +235,15 @@
@Override
public void stopSwipePipToHome(int taskId, ComponentName componentName,
- Rect destinationBounds, SurfaceControl overlay, Rect appBounds) {
+ Rect destinationBounds, SurfaceControl overlay, Rect appBounds,
+ Rect sourceRectHint) {
if (overlay != null) {
overlay.setUnreleasedWarningCallSite("PipController.stopSwipePipToHome");
}
executeRemoteCallWithTaskPermission(mController, "stopSwipePipToHome",
(controller) -> controller.onSwipePipToHomeAnimationStart(
- taskId, componentName, destinationBounds, overlay, appBounds));
+ taskId, componentName, destinationBounds, overlay, appBounds,
+ sourceRectHint));
}
@Override
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index c939ed58..1e7f8a5 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -610,7 +610,13 @@
final DisplayContent displayContent = mActivityRecord.mDisplayContent;
final boolean isIgnoreOrientationRequestEnabled = displayContent != null
&& displayContent.getIgnoreOrientationRequest();
- if (shouldApplyUserFullscreenOverride() && isIgnoreOrientationRequestEnabled) {
+ if (shouldApplyUserFullscreenOverride() && isIgnoreOrientationRequestEnabled
+ // Do not override orientation to fullscreen for camera activities.
+ // Fixed-orientation activities are rarely tested in other orientations, and it
+ // often results in sideways or stretched previews. As the camera compat treatment
+ // targets fixed-orientation activities, overriding the orientation disables the
+ // treatment.
+ && !mActivityRecord.isCameraActive()) {
Slog.v(TAG, "Requested orientation " + screenOrientationToString(candidate) + " for "
+ mActivityRecord + " is overridden to "
+ screenOrientationToString(SCREEN_ORIENTATION_USER)
@@ -645,7 +651,13 @@
// mUserAspectRatio is always initialized first in shouldApplyUserFullscreenOverride(),
// which will always come first before this check as user override > device
// manufacturer override.
- if (isSystemOverrideToFullscreenEnabled() && isIgnoreOrientationRequestEnabled) {
+ if (isSystemOverrideToFullscreenEnabled() && isIgnoreOrientationRequestEnabled
+ // Do not override orientation to fullscreen for camera activities.
+ // Fixed-orientation activities are rarely tested in other orientations, and it
+ // often results in sideways or stretched previews. As the camera compat treatment
+ // targets fixed-orientation activities, overriding the orientation disables the
+ // treatment.
+ && !mActivityRecord.isCameraActive()) {
Slog.v(TAG, "Requested orientation " + screenOrientationToString(candidate) + " for "
+ mActivityRecord + " is overridden to "
+ screenOrientationToString(SCREEN_ORIENTATION_USER));
@@ -1133,17 +1145,6 @@
}
boolean shouldApplyUserFullscreenOverride() {
- // Do not override orientation to fullscreen for camera activities.
- // Fixed-orientation activities are rarely tested in other orientations, and it often
- // results in sideways or stretched previews. As the camera compat treatment targets
- // fixed-orientation activities, overriding the orientation disables the treatment.
- final DisplayContent displayContent = mActivityRecord.mDisplayContent;
- if (displayContent != null && displayContent.mDisplayRotationCompatPolicy != null
- && displayContent.mDisplayRotationCompatPolicy
- .isCameraActive(mActivityRecord, /* mustBeFullscreen= */ true)) {
- return false;
- }
-
if (isUserFullscreenOverrideEnabled()) {
mUserAspectRatio = getUserMinAspectRatioOverrideCode();
@@ -1161,7 +1162,8 @@
}
boolean hasFullscreenOverride() {
- return isSystemOverrideToFullscreenEnabled() || shouldApplyUserFullscreenOverride();
+ // `mUserAspectRatio` is always initialized first in `shouldApplyUserFullscreenOverride()`.
+ return shouldApplyUserFullscreenOverride() || isSystemOverrideToFullscreenEnabled();
}
float getUserMinAspectRatio() {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 944b821..7805e29 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -4623,7 +4623,10 @@
}
final WindowState w = getTopVisibleAppMainWindow();
if (w != null) {
+ w.mIsSurfacePositionPaused = true;
w.applyWithNextDraw((d) -> {
+ w.mIsSurfacePositionPaused = false;
+ w.updateSurfacePosition(d);
d.merge(t);
});
} else {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 06bfbac..f76bd43 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2529,9 +2529,6 @@
if (displayPolicy.areSystemBarsForcedConsumedLw()) {
result |= WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS;
}
- if (!win.isGoneForLayout()) {
- win.mResizedWhileGone = false;
- }
if (outFrames != null && outMergedConfiguration != null) {
win.fillClientWindowFramesAndConfiguration(outFrames, outMergedConfiguration,
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index e0b959d..927c483 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -826,9 +826,14 @@
}
private int applyTaskChanges(Task tr, WindowContainerTransaction.Change c) {
- int effects = applyChanges(tr, c);
final SurfaceControl.Transaction t = c.getBoundsChangeTransaction();
+ // Check bounds change transaction at the beginning because it may pause updating window
+ // surface position. Then the following changes won't apply intermediate position.
+ if (t != null) {
+ tr.setMainWindowSizeChangeTransaction(t);
+ }
+ int effects = applyChanges(tr, c);
if ((c.getChangeMask() & WindowContainerTransaction.Change.CHANGE_HIDDEN) != 0) {
if (tr.setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, c.getHidden())) {
effects = TRANSACT_EFFECTS_LIFECYCLE;
@@ -849,10 +854,6 @@
tr.forAllActivities(a -> { a.setWindowingMode(childWindowingMode); });
}
- if (t != null) {
- tr.setMainWindowSizeChangeTransaction(t);
- }
-
Rect enterPipBounds = c.getEnterPipBounds();
if (enterPipBounds != null) {
tr.mDisplayContent.mPinnedTaskController.setEnterPipBounds(enterPipBounds);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 8bdcff7..6730694 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -653,9 +653,10 @@
private final Transaction mTmpTransaction;
/**
- * Whether the window was resized by us while it was gone for layout.
+ * Whether the surface position of window is paused to update. Currently it is only used for
+ * {@link Task#setMainWindowSizeChangeTransaction(Transaction)} to synchronize position.
*/
- boolean mResizedWhileGone = false;
+ boolean mIsSurfacePositionPaused;
/**
* During seamless rotation we have two phases, first the old window contents
@@ -2156,9 +2157,6 @@
ProtoLog.d(WM_DEBUG_RESIZE, "onResize: Resizing %s", this);
resizingWindows.add(this);
}
- if (isGoneForLayout()) {
- mResizedWhileGone = true;
- }
super.onResize();
}
@@ -4112,6 +4110,9 @@
pw.println(prefix + "mHasSurface=" + mHasSurface
+ " isReadyForDisplay()=" + isReadyForDisplay()
+ " mWindowRemovalAllowed=" + mWindowRemovalAllowed);
+ if (mIsSurfacePositionPaused) {
+ pw.println(prefix + "mIsSurfacePositionPaused=true");
+ }
if (mInvGlobalScale != 1f) {
pw.println(prefix + "mCompatFrame=" + mWindowFrames.mCompatFrame.toShortString(sTmpSB));
}
@@ -5197,7 +5198,7 @@
@Override
@VisibleForTesting
void updateSurfacePosition(Transaction t) {
- if (mSurfaceControl == null) {
+ if (mSurfaceControl == null || mIsSurfacePositionPaused) {
return;
}
if (mActivityRecord != null && mActivityRecord.isConfigurationDispatchPaused()) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
index 80f2ada..0810258 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
@@ -867,7 +867,7 @@
/* candidate */ SCREEN_ORIENTATION_UNSPECIFIED));
}
@Test
- public void testOverrideOrientationIfNeeded_fullscreenOverride_cameraActivity_unchanged() {
+ public void testOverrideOrientationIfNeeded_userFullscreenOverride_cameraActivity_noChange() {
doReturn(true).when(mLetterboxConfiguration).isCameraCompatTreatmentEnabled();
doReturn(true).when(mLetterboxConfiguration)
.isCameraCompatTreatmentEnabledAtBuildTime();
@@ -875,9 +875,31 @@
// Recreate DisplayContent with DisplayRotationCompatPolicy
mActivity = setUpActivityWithComponent();
mController = new LetterboxUiController(mWm, mActivity);
- spyOn(mDisplayContent.mDisplayRotationCompatPolicy);
+ spyOn(mController);
+ doReturn(true).when(mController).shouldApplyUserFullscreenOverride();
- doReturn(false).when(mDisplayContent.mDisplayRotationCompatPolicy)
+ spyOn(mDisplayContent.mDisplayRotationCompatPolicy);
+ doReturn(true).when(mDisplayContent.mDisplayRotationCompatPolicy)
+ .isCameraActive(mActivity, /* mustBeFullscreen= */ true);
+
+ assertEquals(SCREEN_ORIENTATION_PORTRAIT, mController.overrideOrientationIfNeeded(
+ /* candidate */ SCREEN_ORIENTATION_PORTRAIT));
+ }
+
+ @Test
+ public void testOverrideOrientationIfNeeded_systemFullscreenOverride_cameraActivity_noChange() {
+ doReturn(true).when(mLetterboxConfiguration).isCameraCompatTreatmentEnabled();
+ doReturn(true).when(mLetterboxConfiguration)
+ .isCameraCompatTreatmentEnabledAtBuildTime();
+
+ // Recreate DisplayContent with DisplayRotationCompatPolicy
+ mActivity = setUpActivityWithComponent();
+ mController = new LetterboxUiController(mWm, mActivity);
+ spyOn(mController);
+ doReturn(true).when(mController).isSystemOverrideToFullscreenEnabled();
+
+ spyOn(mDisplayContent.mDisplayRotationCompatPolicy);
+ doReturn(true).when(mDisplayContent.mDisplayRotationCompatPolicy)
.isCameraActive(mActivity, /* mustBeFullscreen= */ true);
assertEquals(SCREEN_ORIENTATION_PORTRAIT, mController.overrideOrientationIfNeeded(
@@ -1015,7 +1037,7 @@
}
@Test
- public void testShouldEnableUserAspectRatioSettings_noIgnoreOrientaion_returnsFalse()
+ public void testShouldEnableUserAspectRatioSettings_noIgnoreOrientation_returnsFalse()
throws Exception {
prepareActivityForShouldApplyUserMinAspectRatioOverride(/* orientationRequest */ false);
mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE, /* value */ true);
@@ -1063,7 +1085,7 @@
}
@Test
- public void testShouldApplyUserMinAspectRatioOverride_noIgnoreOrientationreturnsFalse() {
+ public void testShouldApplyUserMinAspectRatioOverride_noIgnoreOrientation_returnsFalse() {
prepareActivityForShouldApplyUserMinAspectRatioOverride(/* orientationRequest */ false);
assertFalse(mController.shouldApplyUserMinAspectRatioOverride());