Fix defer-display-removal logic
WindowAnimator.animate repeatedly calls into handleCompleteDeferredRemoval() which wasn't checking the same conditions as removeIfPossible() (which is the function that actually sets mDeferredRemoval). This meant that removeImmediately() would be called early at times and break CTS tests. Similarly, moved the onDisplayRemoved call in keyguard controller to removeImmediately() so that it wouldn't get called prematurely. Also fix a NPE in DefaultTransitionHandler Bug: 183993924 Test: atest MultiDisplayPolicyTests (with shell-transitions) Change-Id: I73b10a290a3b2be6ea4d978190863cc6ce62ef8f
This commit is contained in:
@@ -419,8 +419,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
|
||||
// hasRoundedCorners is currently only enabled for tasks
|
||||
final Context displayContext =
|
||||
mDisplayController.getDisplayContext(change.getTaskInfo().displayId);
|
||||
cornerRadius =
|
||||
ScreenDecorationsUtils.getWindowCornerRadius(displayContext);
|
||||
cornerRadius = displayContext == null ? 0
|
||||
: ScreenDecorationsUtils.getWindowCornerRadius(displayContext);
|
||||
} else {
|
||||
cornerRadius = 0;
|
||||
}
|
||||
|
||||
@@ -3127,12 +3127,16 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
mDisplayPolicy.switchUser();
|
||||
}
|
||||
|
||||
@Override
|
||||
void removeIfPossible() {
|
||||
if (isAnimating(TRANSITION | PARENTS)
|
||||
private boolean shouldDeferRemoval() {
|
||||
return isAnimating(TRANSITION | PARENTS)
|
||||
// isAnimating is a legacy transition query and will be removed, so also add a
|
||||
// check for whether this is in a shell-transition when not using legacy.
|
||||
|| mTransitionController.inTransition()) {
|
||||
|| mTransitionController.isTransitionOnDisplay(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
void removeIfPossible() {
|
||||
if (shouldDeferRemoval()) {
|
||||
mDeferredRemoval = true;
|
||||
return;
|
||||
}
|
||||
@@ -3161,6 +3165,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
mInputMonitor.onDisplayRemoved();
|
||||
mWmService.mDisplayNotificationController.dispatchDisplayRemoved(this);
|
||||
mWmService.mAccessibilityController.onDisplayRemoved(mDisplayId);
|
||||
mRootWindowContainer.mTaskSupervisor
|
||||
.getKeyguardController().onDisplayRemoved(mDisplayId);
|
||||
} finally {
|
||||
mDisplayReady = false;
|
||||
}
|
||||
@@ -3174,7 +3180,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
/** Returns true if a removal action is still being deferred. */
|
||||
@Override
|
||||
boolean handleCompleteDeferredRemoval() {
|
||||
final boolean stillDeferringRemoval = super.handleCompleteDeferredRemoval();
|
||||
final boolean stillDeferringRemoval =
|
||||
super.handleCompleteDeferredRemoval() || shouldDeferRemoval();
|
||||
|
||||
if (!stillDeferringRemoval && mDeferredRemoval) {
|
||||
removeImmediately();
|
||||
@@ -5915,8 +5922,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
forAllRootTasks(t -> {t.removeIfPossible("releaseSelfIfNeeded");});
|
||||
} else if (getTopRootTask() == null) {
|
||||
removeIfPossible();
|
||||
mRootWindowContainer.mTaskSupervisor
|
||||
.getKeyguardController().onDisplayRemoved(mDisplayId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -158,8 +158,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
||||
/** The final animation targets derived from participants after promotion. */
|
||||
private ArrayList<WindowContainer> mTargets;
|
||||
|
||||
/** The main display running this transition. */
|
||||
private DisplayContent mTargetDisplay;
|
||||
/** The displays that this transition is running on. */
|
||||
private final ArrayList<DisplayContent> mTargetDisplays = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Set of participating windowtokens (activity/wallpaper) which are visible at the end of
|
||||
@@ -209,6 +209,10 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
||||
return mTransientLaunches != null && mTransientLaunches.contains(activity);
|
||||
}
|
||||
|
||||
boolean isOnDisplay(@NonNull DisplayContent dc) {
|
||||
return mTargetDisplays.contains(dc);
|
||||
}
|
||||
|
||||
void setSeamlessRotation(@NonNull WindowContainer wc) {
|
||||
final ChangeInfo info = mChanges.get(wc);
|
||||
if (info == null) return;
|
||||
@@ -280,6 +284,9 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
||||
mChanges.put(wc, info);
|
||||
}
|
||||
mParticipants.add(wc);
|
||||
if (wc.getDisplayContent() != null && !mTargetDisplays.contains(wc.getDisplayContent())) {
|
||||
mTargetDisplays.add(wc.getDisplayContent());
|
||||
}
|
||||
if (info.mShowWallpaper) {
|
||||
// Collect the wallpaper token (for isWallpaper(wc)) so it is part of the sync set.
|
||||
final WindowState wallpaper =
|
||||
@@ -516,15 +523,23 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
||||
dc.getInputMonitor().setActiveRecents(null /* activity */, null /* layer */);
|
||||
}
|
||||
|
||||
final AsyncRotationController asyncRotationController =
|
||||
mTargetDisplay.getAsyncRotationController();
|
||||
if (asyncRotationController != null) {
|
||||
asyncRotationController.onTransitionFinished();
|
||||
}
|
||||
// Transient-launch activities cannot be IME target (WindowState#canBeImeTarget),
|
||||
// so re-compute in case the IME target is changed after transition.
|
||||
if (mTransientLaunches != null) {
|
||||
mTargetDisplay.computeImeTarget(true /* updateImeTarget */);
|
||||
for (int i = 0; i < mTargetDisplays.size(); ++i) {
|
||||
final DisplayContent dc = mTargetDisplays.get(i);
|
||||
final AsyncRotationController asyncRotationController = dc.getAsyncRotationController();
|
||||
if (asyncRotationController != null) {
|
||||
asyncRotationController.onTransitionFinished();
|
||||
}
|
||||
if (mTransientLaunches != null) {
|
||||
// Transient-launch activities cannot be IME target (WindowState#canBeImeTarget),
|
||||
// so re-compute in case the IME target is changed after transition.
|
||||
for (int t = 0; t < mTransientLaunches.size(); ++t) {
|
||||
if (mTransientLaunches.valueAt(t).getDisplayContent() == dc) {
|
||||
dc.computeImeTarget(true /* updateImeTarget */);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dc.handleCompleteDeferredRemoval();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -555,19 +570,13 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
||||
Slog.e(TAG, "Unexpected Sync ID " + syncId + ". Expected " + mSyncId);
|
||||
return;
|
||||
}
|
||||
boolean hasWallpaper = false;
|
||||
DisplayContent dc = null;
|
||||
for (int i = mParticipants.size() - 1; i >= 0; --i) {
|
||||
final WindowContainer<?> wc = mParticipants.valueAt(i);
|
||||
if (dc == null && wc.mDisplayContent != null) {
|
||||
dc = wc.mDisplayContent;
|
||||
}
|
||||
if (!hasWallpaper && isWallpaper(wc)) {
|
||||
hasWallpaper = true;
|
||||
}
|
||||
if (mTargetDisplays.isEmpty()) {
|
||||
mTargetDisplays.add(mController.mAtm.mRootWindowContainer.getDefaultDisplay());
|
||||
}
|
||||
if (dc == null) dc = mController.mAtm.mRootWindowContainer.getDefaultDisplay();
|
||||
mTargetDisplay = dc;
|
||||
// While there can be multiple DC's involved. For now, we just use the first one as
|
||||
// the "primary" one for most things. Eventually, this will need to change, but, for the
|
||||
// time being, we don't have full cross-display transitions so it isn't a problem.
|
||||
final DisplayContent dc = mTargetDisplays.get(0);
|
||||
|
||||
if (mState == STATE_ABORT) {
|
||||
mController.abort(this);
|
||||
@@ -577,8 +586,11 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
||||
return;
|
||||
}
|
||||
// Ensure that wallpaper visibility is updated with the latest wallpaper target.
|
||||
if (hasWallpaper) {
|
||||
dc.mWallpaperController.adjustWallpaperWindows();
|
||||
for (int i = mParticipants.size() - 1; i >= 0; --i) {
|
||||
final WindowContainer<?> wc = mParticipants.valueAt(i);
|
||||
if (isWallpaper(wc) && wc.getDisplayContent() != null) {
|
||||
wc.getDisplayContent().mWallpaperController.adjustWallpaperWindows();
|
||||
}
|
||||
}
|
||||
|
||||
mState = STATE_PLAYING;
|
||||
|
||||
@@ -256,6 +256,17 @@ class TransitionController {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @return {@code true} if wc is in a participant subtree */
|
||||
boolean isTransitionOnDisplay(@NonNull DisplayContent dc) {
|
||||
if (mCollectingTransition != null && mCollectingTransition.isOnDisplay(dc)) {
|
||||
return true;
|
||||
}
|
||||
for (int i = mPlayingTransitions.size() - 1; i >= 0; --i) {
|
||||
if (mPlayingTransitions.get(i).isOnDisplay(dc)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if {@param ar} is part of a transient-launch activity in an active
|
||||
* transition.
|
||||
|
||||
Reference in New Issue
Block a user