summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java7
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java7
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java31
-rw-r--r--services/core/java/com/android/server/wm/DisplayRotation.java16
-rw-r--r--services/core/java/com/android/server/wm/Transition.java15
-rw-r--r--services/core/java/com/android/server/wm/TransitionController.java21
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java2
9 files changed, 82 insertions, 32 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index 4ba6acaba025..b673d48f3d15 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -141,8 +141,9 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
static boolean isRotationSeamless(@NonNull TransitionInfo info,
DisplayController displayController) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
- "Display is rotating, check if it should be seamless.");
+ "Display is changing, check if it should be seamless.");
boolean checkedDisplayLayout = false;
+ boolean hasTask = false;
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
@@ -166,6 +167,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
return false;
}
} else if (change.getTaskInfo() != null) {
+ hasTask = true;
// We only enable seamless rotation if all the visible task windows requested it.
if (change.getRotationAnimation() != ROTATION_ANIMATION_SEAMLESS) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
@@ -209,8 +211,12 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
}
}
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Rotation IS seamless.");
- return true;
+ // ROTATION_ANIMATION_SEAMLESS can only be requested by task.
+ if (hasTask) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Rotation IS seamless.");
+ return true;
+ }
+ return false;
}
/**
@@ -280,7 +286,6 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
final TransitionInfo.Change change = info.getChanges().get(i);
if (info.getType() == TRANSIT_CHANGE && change.getMode() == TRANSIT_CHANGE
- && (change.getEndRotation() != change.getStartRotation())
&& (change.getFlags() & FLAG_IS_DISPLAY) != 0) {
boolean isSeamless = isRotationSeamless(info, mDisplayController);
final int anim = getRotationAnimation(info);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java
index ada2ed27c114..13c670a1ab1e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java
@@ -186,11 +186,11 @@ class ScreenRotationAnimation {
t.setAlpha(mBackColorSurface, 1);
t.show(mBackColorSurface);
+ t.setLayer(mAnimLeash, SCREEN_FREEZE_LAYER_BASE);
t.setPosition(mAnimLeash, 0, 0);
t.setAlpha(mAnimLeash, 1);
t.show(mAnimLeash);
- t.setLayer(mScreenshotLayer, SCREEN_FREEZE_LAYER_BASE);
t.setBuffer(mScreenshotLayer, buffer);
t.setColorSpace(mScreenshotLayer, screenshotBuffer.getColorSpace());
t.show(mScreenshotLayer);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
index b0f0d71c2638..e39171343bb9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
@@ -583,6 +583,13 @@ public class ShellTransitionTests {
.setRotate(ROTATION_ANIMATION_SEAMLESS).build())
.build();
assertFalse(DefaultTransitionHandler.isRotationSeamless(seamlessButAlert, displays));
+
+ // Not seamless if there is no changed task.
+ final TransitionInfo noTask = new TransitionInfoBuilder(TRANSIT_CHANGE)
+ .addChange(new ChangeBuilder(TRANSIT_CHANGE).setFlags(FLAG_IS_DISPLAY)
+ .setRotate().build())
+ .build();
+ assertFalse(DefaultTransitionHandler.isRotationSeamless(noTask, displays));
}
class TransitionInfoBuilder {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index c45b661f06fb..b107ff8a6b7b 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -5943,6 +5943,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
void startFreezingScreen(int overrideOriginalDisplayRotation) {
+ if (mAtmService.getTransitionController().isShellTransitionsEnabled()) {
+ return;
+ }
ProtoLog.i(WM_DEBUG_ORIENTATION,
"Set freezing of %s: visible=%b freezing=%b visibleRequested=%b. %s",
appToken, isVisible(), mFreezingScreen, mVisibleRequested,
@@ -8443,9 +8446,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (shouldRelaunchLocked(changes, mTmpConfig) || forceNewConfig) {
// Aha, the activity isn't handling the change, so DIE DIE DIE.
configChangeFlags |= changes;
- if (!mAtmService.getTransitionController().isShellTransitionsEnabled()) {
- startFreezingScreenLocked(globalChanges);
- }
+ startFreezingScreenLocked(globalChanges);
forceNewConfig = false;
// Do not preserve window if it is freezing screen because the original window won't be
// able to update drawn state that causes freeze timeout.
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 63f6387c87ae..f800f0e395de 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -76,6 +76,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.window.DisplayAreaOrganizer.FEATURE_ROOT;
@@ -1389,11 +1390,16 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
final Configuration currentDisplayConfig = getConfiguration();
mTmpConfiguration.setTo(currentDisplayConfig);
computeScreenConfiguration(mTmpConfiguration);
- configChanged |= currentDisplayConfig.diff(mTmpConfiguration) != 0;
+ final int changes = currentDisplayConfig.diff(mTmpConfiguration);
+ configChanged |= changes != 0;
if (configChanged) {
mWaitingForConfig = true;
- mWmService.startFreezingDisplay(0 /* exitAnim */, 0 /* enterAnim */, this);
+ if (mAtmService.getTransitionController().isShellTransitionsEnabled()) {
+ requestChangeTransitionIfNeeded(changes);
+ } else {
+ mWmService.startFreezingDisplay(0 /* exitAnim */, 0 /* enterAnim */, this);
+ }
sendNewConfiguration();
}
@@ -3165,6 +3171,24 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
return mScreenRotationAnimation;
}
+ /**
+ * Requests to start a transition for the display configuration change. The given changes must
+ * be non-zero. This method is no-op if the display has been collected.
+ */
+ void requestChangeTransitionIfNeeded(@ActivityInfo.Config int changes) {
+ final TransitionController controller = mAtmService.getTransitionController();
+ if (controller.isCollecting()) {
+ if (!controller.isCollecting(this)) {
+ controller.collect(this);
+ }
+ return;
+ }
+ final Transition t = controller.requestTransitionIfNeeded(TRANSIT_CHANGE, this);
+ if (t != null) {
+ t.setKnownConfigChanges(this, changes);
+ }
+ }
+
/** If the display is in transition, there should be a screenshot covering it. */
@Override
boolean inTransition() {
@@ -5724,6 +5748,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
mWmService.mDisplayNotificationController.dispatchDisplayChanged(
this, getConfiguration());
+ if (isReady() && mAtmService.getTransitionController().isShellTransitionsEnabled()) {
+ requestChangeTransitionIfNeeded(changes);
+ }
}
return changes;
}
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index c9db14de507c..971bebd8c486 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -22,7 +22,6 @@ import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFA
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
-import static android.view.WindowManager.TRANSIT_CHANGE;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN;
@@ -492,12 +491,6 @@ public class DisplayRotation {
recentsAnimationController.cancelAnimationForDisplayChange();
}
- final Transition t = (useShellTransitions
- && !mService.mAtmService.getTransitionController().isCollecting())
- ? mService.mAtmService.getTransitionController().createTransition(TRANSIT_CHANGE)
- : null;
- mService.mAtmService.getTransitionController().collect(mDisplayContent);
-
ProtoLog.v(WM_DEBUG_ORIENTATION,
"Display id=%d rotation changed to %d from %d, lastOrientation=%d",
displayId, rotation, oldRotation, lastOrientation);
@@ -511,11 +504,10 @@ public class DisplayRotation {
mDisplayContent.setLayoutNeeded();
if (useShellTransitions) {
- if (t != null) {
- // This created its own transition, so send a start request.
- mService.mAtmService.getTransitionController().requestStartTransition(
- t, null /* trigger */, null /* remote */);
- } else {
+ final boolean wasInTransition = mDisplayContent.inTransition();
+ mDisplayContent.requestChangeTransitionIfNeeded(
+ ActivityInfo.CONFIG_WINDOW_CONFIGURATION);
+ if (wasInTransition) {
// Use remote-rotation infra since the transition has already been requested
// TODO(shell-transitions): Remove this once lifecycle management can cover all
// rotation cases.
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 1a46d0f9a877..1909875565f6 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -58,6 +58,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
+import android.content.pm.ActivityInfo;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Binder;
@@ -269,6 +270,18 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
mChanges.get(wc).mExistenceChanged = true;
}
+ /**
+ * Specifies configuration change explicitly for the window container, so it can be chosen as
+ * transition target. This is usually used with transition mode
+ * {@link android.view.WindowManager#TRANSIT_CHANGE}.
+ */
+ void setKnownConfigChanges(WindowContainer<?> wc, @ActivityInfo.Config int changes) {
+ final ChangeInfo changeInfo = mChanges.get(wc);
+ if (changeInfo != null) {
+ changeInfo.mKnownConfigChanges = changes;
+ }
+ }
+
private void sendRemoteCallback(@Nullable IRemoteCallback callback) {
if (callback == null) return;
mController.mAtm.mH.sendMessage(PooledLambda.obtainMessage(cb -> {
@@ -1218,6 +1231,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
final Rect mAbsoluteBounds = new Rect();
boolean mShowWallpaper;
int mRotation = ROTATION_UNDEFINED;
+ @ActivityInfo.Config int mKnownConfigChanges;
ChangeInfo(@NonNull WindowContainer origState) {
mVisible = origState.isVisibleRequested();
@@ -1240,6 +1254,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
final boolean currVisible = newState.isVisibleRequested();
if (currVisible == mVisible && !mVisible) return false;
return currVisible != mVisible
+ || mKnownConfigChanges != 0
// if mWindowingMode is 0, this container wasn't attached at collect time, so
// assume no change in windowing-mode.
|| (mWindowingMode != 0 && newState.getWindowingMode() != mWindowingMode)
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index c1d0f80adbb7..fc5423942dc3 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -71,15 +71,7 @@ class TransitionController {
final Lock mRunningLock = new Lock();
- private final IBinder.DeathRecipient mTransitionPlayerDeath = () -> {
- // clean-up/finish any playing transitions.
- for (int i = 0; i < mPlayingTransitions.size(); ++i) {
- mPlayingTransitions.get(i).cleanUpOnFailure();
- }
- mPlayingTransitions.clear();
- mTransitionPlayer = null;
- mRunningLock.doNotifyLocked();
- };
+ private final IBinder.DeathRecipient mTransitionPlayerDeath;
/** The transition currently being constructed (collecting participants). */
private Transition mCollectingTransition = null;
@@ -90,6 +82,17 @@ class TransitionController {
TransitionController(ActivityTaskManagerService atm) {
mAtm = atm;
mStatusBar = LocalServices.getService(StatusBarManagerInternal.class);
+ mTransitionPlayerDeath = () -> {
+ synchronized (mAtm.mGlobalLock) {
+ // Clean-up/finish any playing transitions.
+ for (int i = 0; i < mPlayingTransitions.size(); ++i) {
+ mPlayingTransitions.get(i).cleanUpOnFailure();
+ }
+ mPlayingTransitions.clear();
+ mTransitionPlayer = null;
+ mRunningLock.doNotifyLocked();
+ }
+ };
}
/** @see #createTransition(int, int) */
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 0b2b05054e60..4cc764ac33ca 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -327,7 +327,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
if (transition != null) {
// First check if we have a display rotation transition and if so, update it.
final DisplayContent dc = DisplayRotation.getDisplayFromTransition(transition);
- if (dc != null && transition.mChanges.get(dc).mRotation != dc.getRotation()) {
+ if (dc != null && transition.mChanges.get(dc).hasChanged(dc)) {
// Go through all tasks and collect them before the rotation
// TODO(shell-transitions): move collect() to onConfigurationChange once
// wallpaper handling is synchronized.