Merge "Handle rotation while recents animation is running" into sc-dev
This commit is contained in:
@@ -5492,6 +5492,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean updateDisplayOverrideConfigurationLocked() {
|
boolean updateDisplayOverrideConfigurationLocked() {
|
||||||
|
// Preemptively cancel the running recents animation -- SysUI can't currently handle this
|
||||||
|
// case properly since the signals it receives all happen post-change
|
||||||
|
final RecentsAnimationController recentsAnimationController =
|
||||||
|
mWmService.getRecentsAnimationController();
|
||||||
|
if (recentsAnimationController != null) {
|
||||||
|
recentsAnimationController.cancelAnimationForDisplayChange();
|
||||||
|
}
|
||||||
|
|
||||||
Configuration values = new Configuration();
|
Configuration values = new Configuration();
|
||||||
computeScreenConfiguration(values);
|
computeScreenConfiguration(values);
|
||||||
|
|
||||||
|
|||||||
@@ -480,6 +480,16 @@ public class DisplayRotation {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Preemptively cancel the running recents animation -- SysUI can't currently handle this
|
||||||
|
// case properly since the signals it receives all happen post-change. We do this earlier
|
||||||
|
// in the rotation flow, since DisplayContent.updateDisplayOverrideConfigurationLocked seems
|
||||||
|
// to happen too late.
|
||||||
|
final RecentsAnimationController recentsAnimationController =
|
||||||
|
mService.getRecentsAnimationController();
|
||||||
|
if (recentsAnimationController != null) {
|
||||||
|
recentsAnimationController.cancelAnimationForDisplayChange();
|
||||||
|
}
|
||||||
|
|
||||||
final Transition t = (useShellTransitions
|
final Transition t = (useShellTransitions
|
||||||
&& !mService.mAtmService.getTransitionController().isCollecting())
|
&& !mService.mAtmService.getTransitionController().isCollecting())
|
||||||
? mService.mAtmService.getTransitionController().createTransition(TRANSIT_CHANGE)
|
? mService.mAtmService.getTransitionController().createTransition(TRANSIT_CHANGE)
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ public class RecentsAnimationController implements DeathRecipient {
|
|||||||
final ArraySet<Task> tasks = Sets.newArraySet(task);
|
final ArraySet<Task> tasks = Sets.newArraySet(task);
|
||||||
snapshotController.snapshotTasks(tasks);
|
snapshotController.snapshotTasks(tasks);
|
||||||
snapshotController.addSkipClosingAppSnapshotTasks(tasks);
|
snapshotController.addSkipClosingAppSnapshotTasks(tasks);
|
||||||
return snapshotController.getSnapshot(taskId, 0 /* userId */,
|
return snapshotController.getSnapshot(taskId, task.mUserId,
|
||||||
false /* restoreFromDisk */, false /* isLowResolution */);
|
false /* restoreFromDisk */, false /* isLowResolution */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -353,18 +353,23 @@ public class RecentsAnimationController implements DeathRecipient {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cleanupScreenshot() {
|
public void cleanupScreenshot() {
|
||||||
|
final long token = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
synchronized (mService.mGlobalLock) {
|
synchronized (mService.mGlobalLock) {
|
||||||
if (mRecentScreenshotAnimator != null) {
|
if (mRecentScreenshotAnimator != null) {
|
||||||
mRecentScreenshotAnimator.cancelAnimation();
|
mRecentScreenshotAnimator.cancelAnimation();
|
||||||
mRecentScreenshotAnimator = null;
|
mRecentScreenshotAnimator = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setWillFinishToHome(boolean willFinishToHome) {
|
public void setWillFinishToHome(boolean willFinishToHome) {
|
||||||
synchronized (mService.getWindowManagerLock()) {
|
synchronized (mService.getWindowManagerLock()) {
|
||||||
mWillFinishToHome = willFinishToHome;
|
RecentsAnimationController.this.setWillFinishToHome(willFinishToHome);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -513,7 +518,6 @@ public class RecentsAnimationController implements DeathRecipient {
|
|||||||
|| config.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
|| config.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
AnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible) {
|
AnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible) {
|
||||||
return addAnimation(task, isRecentTaskInvisible, false /* hidden */,
|
return addAnimation(task, isRecentTaskInvisible, false /* hidden */,
|
||||||
@@ -816,6 +820,18 @@ public class RecentsAnimationController implements DeathRecipient {
|
|||||||
cancelAnimation(REORDER_KEEP_IN_PLACE, screenshot, "rootTaskOrderChanged");
|
cancelAnimation(REORDER_KEEP_IN_PLACE, screenshot, "rootTaskOrderChanged");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If there is a recents animation running, we need to cancel the animation and snapshot the
|
||||||
|
* tasks before the change (to ensure they are captured at the right configuration)
|
||||||
|
*/
|
||||||
|
public void cancelAnimationForDisplayChange() {
|
||||||
|
if (mCanceled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cancelAnimation(mWillFinishToHome ? REORDER_MOVE_TO_TOP : REORDER_MOVE_TO_ORIGINAL_POSITION,
|
||||||
|
true /* screenshot */, "cancelAnimationForDisplayChange");
|
||||||
|
}
|
||||||
|
|
||||||
private void cancelAnimation(@ReorderMode int reorderMode, boolean screenshot, String reason) {
|
private void cancelAnimation(@ReorderMode int reorderMode, boolean screenshot, String reason) {
|
||||||
ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "cancelAnimation(): reason=%s", reason);
|
ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "cancelAnimation(): reason=%s", reason);
|
||||||
synchronized (mService.getWindowManagerLock()) {
|
synchronized (mService.getWindowManagerLock()) {
|
||||||
@@ -826,7 +842,7 @@ public class RecentsAnimationController implements DeathRecipient {
|
|||||||
mService.mH.removeCallbacks(mFailsafeRunnable);
|
mService.mH.removeCallbacks(mFailsafeRunnable);
|
||||||
mCanceled = true;
|
mCanceled = true;
|
||||||
|
|
||||||
if (screenshot) {
|
if (screenshot && !mPendingAnimations.isEmpty()) {
|
||||||
// Screen shot previous task when next task starts transition and notify the runner.
|
// Screen shot previous task when next task starts transition and notify the runner.
|
||||||
// We will actually finish the animation once the runner calls cleanUpScreenshot().
|
// We will actually finish the animation once the runner calls cleanUpScreenshot().
|
||||||
final Task task = mPendingAnimations.get(0).mTask;
|
final Task task = mPendingAnimations.get(0).mTask;
|
||||||
@@ -853,6 +869,11 @@ public class RecentsAnimationController implements DeathRecipient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
void setWillFinishToHome(boolean willFinishToHome) {
|
||||||
|
mWillFinishToHome = willFinishToHome;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel recents animation when the next app transition starts.
|
* Cancel recents animation when the next app transition starts.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -905,7 +926,8 @@ public class RecentsAnimationController implements DeathRecipient {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final TaskScreenshotAnimatable animatable = new TaskScreenshotAnimatable(mService.mSurfaceControlFactory, task,
|
final TaskScreenshotAnimatable animatable = new TaskScreenshotAnimatable(
|
||||||
|
mService.mSurfaceControlFactory, task,
|
||||||
new SurfaceControl.ScreenshotHardwareBuffer(taskSnapshot.getHardwareBuffer(),
|
new SurfaceControl.ScreenshotHardwareBuffer(taskSnapshot.getHardwareBuffer(),
|
||||||
taskSnapshot.getColorSpace(), false /* containsSecureLayers */));
|
taskSnapshot.getColorSpace(), false /* containsSecureLayers */));
|
||||||
mRecentScreenshotAnimator = new SurfaceAnimator(
|
mRecentScreenshotAnimator = new SurfaceAnimator(
|
||||||
@@ -1006,7 +1028,16 @@ public class RecentsAnimationController implements DeathRecipient {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void binderDied() {
|
public void binderDied() {
|
||||||
|
if (!mCanceled) {
|
||||||
cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "binderDied");
|
cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "binderDied");
|
||||||
|
} else {
|
||||||
|
synchronized (mService.getWindowManagerLock()) {
|
||||||
|
if (mRecentScreenshotAnimator != null) {
|
||||||
|
mRecentScreenshotAnimator.cancelAnimation();
|
||||||
|
mRecentScreenshotAnimator = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
synchronized (mService.getWindowManagerLock()) {
|
synchronized (mService.getWindowManagerLock()) {
|
||||||
// Clear associated input consumers on runner death
|
// Clear associated input consumers on runner death
|
||||||
|
|||||||
@@ -655,6 +655,36 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
|
|||||||
assertFalse(win1.mHasSurface);
|
assertFalse(win1.mHasSurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCancelForRotation_ReorderToTop() throws Exception {
|
||||||
|
mWm.setRecentsAnimationController(mController);
|
||||||
|
final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
|
||||||
|
final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, activity, "win1");
|
||||||
|
activity.addWindow(win1);
|
||||||
|
|
||||||
|
mController.addAnimation(activity.getTask(), false /* isRecentTaskInvisible */);
|
||||||
|
mController.setWillFinishToHome(true);
|
||||||
|
mController.cancelAnimationForDisplayChange();
|
||||||
|
|
||||||
|
verify(mMockRunner).onAnimationCanceled(any());
|
||||||
|
verify(mAnimationCallbacks).onAnimationFinished(REORDER_MOVE_TO_TOP, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCancelForRotation_ReorderToOriginalPosition() throws Exception {
|
||||||
|
mWm.setRecentsAnimationController(mController);
|
||||||
|
final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
|
||||||
|
final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, activity, "win1");
|
||||||
|
activity.addWindow(win1);
|
||||||
|
|
||||||
|
mController.addAnimation(activity.getTask(), false /* isRecentTaskInvisible */);
|
||||||
|
mController.setWillFinishToHome(false);
|
||||||
|
mController.cancelAnimationForDisplayChange();
|
||||||
|
|
||||||
|
verify(mMockRunner).onAnimationCanceled(any());
|
||||||
|
verify(mAnimationCallbacks).onAnimationFinished(REORDER_MOVE_TO_ORIGINAL_POSITION, false);
|
||||||
|
}
|
||||||
|
|
||||||
private ActivityRecord createHomeActivity() {
|
private ActivityRecord createHomeActivity() {
|
||||||
final ActivityRecord homeActivity = new ActivityBuilder(mWm.mAtmService)
|
final ActivityRecord homeActivity = new ActivityBuilder(mWm.mAtmService)
|
||||||
.setParentTask(mRootHomeTask)
|
.setParentTask(mRootHomeTask)
|
||||||
|
|||||||
Reference in New Issue
Block a user