Merge "Use rotation transition to handle display config change" into sc-v2-dev
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) */
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user