Loading services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java +0 −5 Original line number Diff line number Diff line Loading @@ -279,11 +279,6 @@ public abstract class ActivityTaskManagerInternal { */ public abstract boolean isRecentsComponentHomeActivity(int userId); /** * Cancels any currently running recents animation. */ public abstract void cancelRecentsAnimation(boolean restoreHomeRootTaskPosition); /** * Returns true if the app can close system dialogs. Otherwise it either throws a {@link * SecurityException} or returns false with a logcat message depending on whether the app Loading services/core/java/com/android/server/wm/ActivityTaskManagerService.java +0 −5 Original line number Diff line number Diff line Loading @@ -5255,11 +5255,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return getRecentTasks().isRecentsComponentHomeActivity(userId); } @Override public void cancelRecentsAnimation(boolean restoreHomeRootTaskPosition) { ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeRootTaskPosition); } @Override public boolean checkCanCloseSystemDialogs(int pid, int uid, @Nullable String packageName) { return ActivityTaskManagerService.this.checkCanCloseSystemDialogs(pid, uid, Loading services/core/java/com/android/server/wm/RecentsAnimationController.java +93 −60 Original line number Diff line number Diff line Loading @@ -36,8 +36,10 @@ import static com.android.server.wm.WindowManagerInternal.AppTransitionListener; import android.annotation.IntDef; import android.annotation.NonNull; import android.app.WindowConfiguration; import android.graphics.GraphicBuffer; import android.graphics.Point; import android.graphics.Rect; import android.hardware.HardwareBuffer; import android.os.Binder; import android.os.IBinder.DeathRecipient; import android.os.RemoteException; Loading @@ -54,6 +56,7 @@ import android.view.InputWindowHandle; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; import android.view.SurfaceSession; import android.view.WindowInsets.Type; import android.window.PictureInPictureSurfaceTransaction; import android.window.TaskSnapshot; Loading Loading @@ -150,6 +153,8 @@ public class RecentsAnimationController implements DeathRecipient { private boolean mCancelOnNextTransitionStart; // Whether to take a screenshot when handling a deferred cancel private boolean mCancelDeferredWithScreenshot; // The reorder mode to apply after the cleanupScreenshot() callback private int mPendingCancelWithScreenshotReorderMode = REORDER_MOVE_TO_ORIGINAL_POSITION; @VisibleForTesting boolean mIsAddingTaskToTargets; Loading @@ -158,12 +163,6 @@ public class RecentsAnimationController implements DeathRecipient { private boolean mNavigationBarAttachedToApp; private ActivityRecord mNavBarAttachedApp; /** * Animates the screenshot of task that used to be controlled by RecentsAnimation. * @see {@link #setCancelOnNextTransitionStart} */ SurfaceAnimator mRecentScreenshotAnimator; /** * An app transition listener to cancel the recents animation only after the app transition * starts or is canceled. Loading Loading @@ -355,12 +354,9 @@ public class RecentsAnimationController implements DeathRecipient { public void cleanupScreenshot() { final long token = Binder.clearCallingIdentity(); try { synchronized (mService.mGlobalLock) { if (mRecentScreenshotAnimator != null) { mRecentScreenshotAnimator.cancelAnimation(); mRecentScreenshotAnimator = null; } } // Note, the callback will handle its own synchronization, do not lock on WM lock // prior to calling the callback continueDeferredCancelAnimation(); } finally { Binder.restoreCallingIdentity(token); } Loading Loading @@ -519,13 +515,13 @@ public class RecentsAnimationController implements DeathRecipient { } @VisibleForTesting AnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible) { TaskAnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible) { return addAnimation(task, isRecentTaskInvisible, false /* hidden */, null /* finishedCallback */); } @VisibleForTesting AnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible, boolean hidden, TaskAnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible, boolean hidden, OnAnimationFinishedCallback finishedCallback) { ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "addAnimation(%s)", task.getName()); final TaskAnimationAdapter taskAdapter = new TaskAnimationAdapter(task, Loading @@ -541,9 +537,7 @@ public class RecentsAnimationController implements DeathRecipient { void removeAnimation(TaskAnimationAdapter taskAdapter) { ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "removeAnimation(%d)", taskAdapter.mTask.mTaskId); taskAdapter.mTask.setCanAffectSystemUiFlags(true); taskAdapter.mCapturedFinishCallback.onAnimationFinished(taskAdapter.mLastAnimationType, taskAdapter); taskAdapter.onRemove(); mPendingAnimations.remove(taskAdapter); } Loading Loading @@ -821,8 +815,22 @@ public class RecentsAnimationController implements DeathRecipient { } /** * 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) * Cancels the running animation when starting home, providing a snapshot for the runner to * properly handle the cancellation. This call uses the provided hint to determine how to * finish the animation. */ public void cancelAnimationForHomeStart() { if (mCanceled) { return; } cancelAnimation(mWillFinishToHome ? REORDER_MOVE_TO_TOP : REORDER_KEEP_IN_PLACE, true /* screenshot */, "cancelAnimationForHomeStart"); } /** * Cancels the running animation when there is a display change, providing a snapshot for the * runner to properly handle the cancellation. This call uses the provided hint to determine * how to finish the animation. */ public void cancelAnimationForDisplayChange() { if (mCanceled) { Loading @@ -843,16 +851,22 @@ public class RecentsAnimationController implements DeathRecipient { mCanceled = true; if (screenshot && !mPendingAnimations.isEmpty()) { final TaskAnimationAdapter adapter = mPendingAnimations.get(0); final Task task = adapter.mTask; // Screen shot previous task when next task starts transition and notify the runner. // We will actually finish the animation once the runner calls cleanUpScreenshot(). final Task task = mPendingAnimations.get(0).mTask; final TaskSnapshot taskSnapshot = screenshotRecentTask(task, reorderMode); final TaskSnapshot taskSnapshot = screenshotRecentTask(task); mPendingCancelWithScreenshotReorderMode = reorderMode; try { mRunner.onAnimationCanceled(taskSnapshot); } catch (RemoteException e) { Slog.e(TAG, "Failed to cancel recents animation", e); } if (taskSnapshot == null) { if (taskSnapshot != null) { // Defer until the runner calls back to cleanupScreenshot() adapter.setSnapshotOverlay(taskSnapshot); } else { // Do a normal cancel since we couldn't screenshot mCallbacks.onAnimationFinished(reorderMode, false /* sendUserLeaveHint */); } } else { Loading @@ -869,6 +883,12 @@ public class RecentsAnimationController implements DeathRecipient { } } @VisibleForTesting void continueDeferredCancelAnimation() { mCallbacks.onAnimationFinished(mPendingCancelWithScreenshotReorderMode, false /* sendUserLeaveHint */); } @VisibleForTesting void setWillFinishToHome(boolean willFinishToHome) { mWillFinishToHome = willFinishToHome; Loading Loading @@ -915,29 +935,13 @@ public class RecentsAnimationController implements DeathRecipient { return mRequestDeferCancelUntilNextTransition && mCancelDeferredWithScreenshot; } TaskSnapshot screenshotRecentTask(Task task, @ReorderMode int reorderMode) { TaskSnapshot screenshotRecentTask(Task task) { final TaskSnapshotController snapshotController = mService.mTaskSnapshotController; final ArraySet<Task> tasks = Sets.newArraySet(task); snapshotController.snapshotTasks(tasks); snapshotController.addSkipClosingAppSnapshotTasks(tasks); final TaskSnapshot taskSnapshot = snapshotController.getSnapshot(task.mTaskId, task.mUserId, false /* restoreFromDisk */, false /* isLowResolution */); if (taskSnapshot == null) { return null; } final TaskScreenshotAnimatable animatable = new TaskScreenshotAnimatable( mService.mSurfaceControlFactory, task, new SurfaceControl.ScreenshotHardwareBuffer(taskSnapshot.getHardwareBuffer(), taskSnapshot.getColorSpace(), false /* containsSecureLayers */)); mRecentScreenshotAnimator = new SurfaceAnimator( animatable, (type, anim) -> { ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "mRecentScreenshotAnimator finish"); mCallbacks.onAnimationFinished(reorderMode, false /* sendUserLeaveHint */); }, mService); mRecentScreenshotAnimator.transferAnimation(task.mSurfaceAnimator); return taskSnapshot; return snapshotController.getSnapshot(task.mTaskId, task.mUserId, false /* restoreFromDisk */, false /* isLowResolution */); } void cleanupAnimation(@ReorderMode int reorderMode) { Loading Loading @@ -976,12 +980,6 @@ public class RecentsAnimationController implements DeathRecipient { mRunner = null; mCanceled = true; // Make sure previous animator has cleaned-up. if (mRecentScreenshotAnimator != null) { mRecentScreenshotAnimator.cancelAnimation(); mRecentScreenshotAnimator = null; } // Restore IME icon only when moving the original app task to front from recents, in case // IME icon may missing if the moving task has already been the current focused task. if (reorderMode == REORDER_MOVE_TO_ORIGINAL_POSITION && !mIsAddingTaskToTargets) { Loading Loading @@ -1028,16 +1026,7 @@ public class RecentsAnimationController implements DeathRecipient { @Override public void binderDied() { if (!mCanceled) { cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "binderDied"); } else { synchronized (mService.getWindowManagerLock()) { if (mRecentScreenshotAnimator != null) { mRecentScreenshotAnimator.cancelAnimation(); mRecentScreenshotAnimator = null; } } } synchronized (mService.getWindowManagerLock()) { // Clear associated input consumers on runner death Loading Loading @@ -1171,6 +1160,8 @@ public class RecentsAnimationController implements DeathRecipient { private PictureInPictureSurfaceTransaction mFinishTransaction; // An overlay used to mask the content as an app goes into PIP private SurfaceControl mFinishOverlay; // An overlay used for canceling the animation with a screenshot private SurfaceControl mSnapshotOverlay; TaskAnimationAdapter(Task task, boolean isRecentTaskInvisible) { mTask = task; Loading Loading @@ -1205,10 +1196,47 @@ public class RecentsAnimationController implements DeathRecipient { return mTarget; } void setSnapshotOverlay(TaskSnapshot snapshot) { // Create a surface control for the snapshot and reparent it to the leash final HardwareBuffer buffer = snapshot.getHardwareBuffer(); if (buffer == null) { return; } final SurfaceSession session = new SurfaceSession(); mSnapshotOverlay = mService.mSurfaceControlFactory.apply(session) .setName("RecentTaskScreenshotSurface") .setCallsite("TaskAnimationAdapter.setSnapshotOverlay") .setFormat(buffer.getFormat()) .setParent(mCapturedLeash) .setBLASTLayer() .build(); final float scale = 1.0f * mTask.getBounds().width() / buffer.getWidth(); mTask.getPendingTransaction() .setBuffer(mSnapshotOverlay, GraphicBuffer.createFromHardwareBuffer(buffer)) .setColorSpace(mSnapshotOverlay, snapshot.getColorSpace()) .setLayer(mSnapshotOverlay, Integer.MAX_VALUE) .setMatrix(mSnapshotOverlay, scale, 0, 0, scale) .show(mSnapshotOverlay) .apply(); } void onRemove() { if (mSnapshotOverlay != null) { // Clean up the snapshot overlay if necessary mTask.getPendingTransaction() .remove(mSnapshotOverlay) .apply(); mSnapshotOverlay = null; } mTask.setCanAffectSystemUiFlags(true); mCapturedFinishCallback.onAnimationFinished(mLastAnimationType, this); } void onCleanup() { if (mFinishTransaction != null) { final Transaction pendingTransaction = mTask.getPendingTransaction(); if (mFinishTransaction != null) { // Reparent the overlay if (mFinishOverlay != null) { pendingTransaction.reparent(mFinishOverlay, mTask.mSurfaceControl); Loading Loading @@ -1236,10 +1264,15 @@ public class RecentsAnimationController implements DeathRecipient { } else if (!mTask.isAttached()) { // Apply the task's pending transaction in case it is detached and its transaction // is not reachable. mTask.getPendingTransaction().apply(); pendingTransaction.apply(); } } @VisibleForTesting public SurfaceControl getSnapshotOverlay() { return mSnapshotOverlay; } @Override public boolean getShowWallpaper() { return false; Loading services/core/java/com/android/server/wm/RootWindowContainer.java +3 −1 Original line number Diff line number Diff line Loading @@ -1529,7 +1529,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // Updates the extra information of the intent. if (fromHomeKey) { homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true); mWindowManager.cancelRecentsAnimation(REORDER_KEEP_IN_PLACE, "startHomeActivity"); if (mWindowManager.getRecentsAnimationController() != null) { mWindowManager.getRecentsAnimationController().cancelAnimationForHomeStart(); } } homeIntent.putExtra(WindowManagerPolicy.EXTRA_START_REASON, reason); Loading services/core/java/com/android/server/wm/TaskScreenshotAnimatable.javadeleted 100644 → 0 +0 −120 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.wm; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_RECENTS_ANIMATIONS; import android.graphics.GraphicBuffer; import android.hardware.HardwareBuffer; import android.view.SurfaceControl; import android.view.SurfaceSession; import com.android.internal.protolog.common.ProtoLog; import java.util.function.Function; /** * Class used by {@link RecentsAnimationController} to create a surface control with taking * screenshot of task when canceling recents animation. * * @see {@link RecentsAnimationController#setCancelOnNextTransitionStart} */ class TaskScreenshotAnimatable implements SurfaceAnimator.Animatable { private static final String TAG = "TaskScreenshotAnim"; private Task mTask; private SurfaceControl mSurfaceControl; private int mWidth; private int mHeight; TaskScreenshotAnimatable(Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory, Task task, SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer) { HardwareBuffer buffer = screenshotBuffer == null ? null : screenshotBuffer.getHardwareBuffer(); mTask = task; mWidth = (buffer != null) ? buffer.getWidth() : 1; mHeight = (buffer != null) ? buffer.getHeight() : 1; ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "Creating TaskScreenshotAnimatable: task: %s width: %d height: %d", task, mWidth, mHeight); mSurfaceControl = surfaceControlFactory.apply(new SurfaceSession()) .setName("RecentTaskScreenshotSurface") .setBLASTLayer() .setCallsite("TaskScreenshotAnimatable") .build(); if (buffer != null) { GraphicBuffer graphicBuffer = GraphicBuffer.createFromHardwareBuffer(buffer); getPendingTransaction().setBuffer(mSurfaceControl, graphicBuffer); getPendingTransaction().setColorSpace(mSurfaceControl, screenshotBuffer.getColorSpace()); final float scale = 1.0f * mTask.getBounds().width() / mWidth; getPendingTransaction().setMatrix(mSurfaceControl, scale, 0, 0, scale); } getPendingTransaction().show(mSurfaceControl); } @Override public SurfaceControl.Transaction getPendingTransaction() { return mTask.getPendingTransaction(); } @Override public void commitPendingTransaction() { mTask.commitPendingTransaction(); } @Override public void onAnimationLeashCreated(SurfaceControl.Transaction t, SurfaceControl leash) { t.setLayer(leash, 1); } @Override public void onAnimationLeashLost(SurfaceControl.Transaction t) { if (mSurfaceControl != null) { t.remove(mSurfaceControl); mSurfaceControl = null; } } @Override public SurfaceControl.Builder makeAnimationLeash() { return mTask.makeAnimationLeash(); } @Override public SurfaceControl getAnimationLeashParent() { return mTask.getAnimationLeashParent(); } @Override public SurfaceControl getSurfaceControl() { return mSurfaceControl; } @Override public SurfaceControl getParentSurfaceControl() { return mTask.mSurfaceControl; } @Override public int getSurfaceWidth() { return mWidth; } @Override public int getSurfaceHeight() { return mHeight; } } Loading
services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java +0 −5 Original line number Diff line number Diff line Loading @@ -279,11 +279,6 @@ public abstract class ActivityTaskManagerInternal { */ public abstract boolean isRecentsComponentHomeActivity(int userId); /** * Cancels any currently running recents animation. */ public abstract void cancelRecentsAnimation(boolean restoreHomeRootTaskPosition); /** * Returns true if the app can close system dialogs. Otherwise it either throws a {@link * SecurityException} or returns false with a logcat message depending on whether the app Loading
services/core/java/com/android/server/wm/ActivityTaskManagerService.java +0 −5 Original line number Diff line number Diff line Loading @@ -5255,11 +5255,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return getRecentTasks().isRecentsComponentHomeActivity(userId); } @Override public void cancelRecentsAnimation(boolean restoreHomeRootTaskPosition) { ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeRootTaskPosition); } @Override public boolean checkCanCloseSystemDialogs(int pid, int uid, @Nullable String packageName) { return ActivityTaskManagerService.this.checkCanCloseSystemDialogs(pid, uid, Loading
services/core/java/com/android/server/wm/RecentsAnimationController.java +93 −60 Original line number Diff line number Diff line Loading @@ -36,8 +36,10 @@ import static com.android.server.wm.WindowManagerInternal.AppTransitionListener; import android.annotation.IntDef; import android.annotation.NonNull; import android.app.WindowConfiguration; import android.graphics.GraphicBuffer; import android.graphics.Point; import android.graphics.Rect; import android.hardware.HardwareBuffer; import android.os.Binder; import android.os.IBinder.DeathRecipient; import android.os.RemoteException; Loading @@ -54,6 +56,7 @@ import android.view.InputWindowHandle; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; import android.view.SurfaceSession; import android.view.WindowInsets.Type; import android.window.PictureInPictureSurfaceTransaction; import android.window.TaskSnapshot; Loading Loading @@ -150,6 +153,8 @@ public class RecentsAnimationController implements DeathRecipient { private boolean mCancelOnNextTransitionStart; // Whether to take a screenshot when handling a deferred cancel private boolean mCancelDeferredWithScreenshot; // The reorder mode to apply after the cleanupScreenshot() callback private int mPendingCancelWithScreenshotReorderMode = REORDER_MOVE_TO_ORIGINAL_POSITION; @VisibleForTesting boolean mIsAddingTaskToTargets; Loading @@ -158,12 +163,6 @@ public class RecentsAnimationController implements DeathRecipient { private boolean mNavigationBarAttachedToApp; private ActivityRecord mNavBarAttachedApp; /** * Animates the screenshot of task that used to be controlled by RecentsAnimation. * @see {@link #setCancelOnNextTransitionStart} */ SurfaceAnimator mRecentScreenshotAnimator; /** * An app transition listener to cancel the recents animation only after the app transition * starts or is canceled. Loading Loading @@ -355,12 +354,9 @@ public class RecentsAnimationController implements DeathRecipient { public void cleanupScreenshot() { final long token = Binder.clearCallingIdentity(); try { synchronized (mService.mGlobalLock) { if (mRecentScreenshotAnimator != null) { mRecentScreenshotAnimator.cancelAnimation(); mRecentScreenshotAnimator = null; } } // Note, the callback will handle its own synchronization, do not lock on WM lock // prior to calling the callback continueDeferredCancelAnimation(); } finally { Binder.restoreCallingIdentity(token); } Loading Loading @@ -519,13 +515,13 @@ public class RecentsAnimationController implements DeathRecipient { } @VisibleForTesting AnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible) { TaskAnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible) { return addAnimation(task, isRecentTaskInvisible, false /* hidden */, null /* finishedCallback */); } @VisibleForTesting AnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible, boolean hidden, TaskAnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible, boolean hidden, OnAnimationFinishedCallback finishedCallback) { ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "addAnimation(%s)", task.getName()); final TaskAnimationAdapter taskAdapter = new TaskAnimationAdapter(task, Loading @@ -541,9 +537,7 @@ public class RecentsAnimationController implements DeathRecipient { void removeAnimation(TaskAnimationAdapter taskAdapter) { ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "removeAnimation(%d)", taskAdapter.mTask.mTaskId); taskAdapter.mTask.setCanAffectSystemUiFlags(true); taskAdapter.mCapturedFinishCallback.onAnimationFinished(taskAdapter.mLastAnimationType, taskAdapter); taskAdapter.onRemove(); mPendingAnimations.remove(taskAdapter); } Loading Loading @@ -821,8 +815,22 @@ public class RecentsAnimationController implements DeathRecipient { } /** * 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) * Cancels the running animation when starting home, providing a snapshot for the runner to * properly handle the cancellation. This call uses the provided hint to determine how to * finish the animation. */ public void cancelAnimationForHomeStart() { if (mCanceled) { return; } cancelAnimation(mWillFinishToHome ? REORDER_MOVE_TO_TOP : REORDER_KEEP_IN_PLACE, true /* screenshot */, "cancelAnimationForHomeStart"); } /** * Cancels the running animation when there is a display change, providing a snapshot for the * runner to properly handle the cancellation. This call uses the provided hint to determine * how to finish the animation. */ public void cancelAnimationForDisplayChange() { if (mCanceled) { Loading @@ -843,16 +851,22 @@ public class RecentsAnimationController implements DeathRecipient { mCanceled = true; if (screenshot && !mPendingAnimations.isEmpty()) { final TaskAnimationAdapter adapter = mPendingAnimations.get(0); final Task task = adapter.mTask; // Screen shot previous task when next task starts transition and notify the runner. // We will actually finish the animation once the runner calls cleanUpScreenshot(). final Task task = mPendingAnimations.get(0).mTask; final TaskSnapshot taskSnapshot = screenshotRecentTask(task, reorderMode); final TaskSnapshot taskSnapshot = screenshotRecentTask(task); mPendingCancelWithScreenshotReorderMode = reorderMode; try { mRunner.onAnimationCanceled(taskSnapshot); } catch (RemoteException e) { Slog.e(TAG, "Failed to cancel recents animation", e); } if (taskSnapshot == null) { if (taskSnapshot != null) { // Defer until the runner calls back to cleanupScreenshot() adapter.setSnapshotOverlay(taskSnapshot); } else { // Do a normal cancel since we couldn't screenshot mCallbacks.onAnimationFinished(reorderMode, false /* sendUserLeaveHint */); } } else { Loading @@ -869,6 +883,12 @@ public class RecentsAnimationController implements DeathRecipient { } } @VisibleForTesting void continueDeferredCancelAnimation() { mCallbacks.onAnimationFinished(mPendingCancelWithScreenshotReorderMode, false /* sendUserLeaveHint */); } @VisibleForTesting void setWillFinishToHome(boolean willFinishToHome) { mWillFinishToHome = willFinishToHome; Loading Loading @@ -915,29 +935,13 @@ public class RecentsAnimationController implements DeathRecipient { return mRequestDeferCancelUntilNextTransition && mCancelDeferredWithScreenshot; } TaskSnapshot screenshotRecentTask(Task task, @ReorderMode int reorderMode) { TaskSnapshot screenshotRecentTask(Task task) { final TaskSnapshotController snapshotController = mService.mTaskSnapshotController; final ArraySet<Task> tasks = Sets.newArraySet(task); snapshotController.snapshotTasks(tasks); snapshotController.addSkipClosingAppSnapshotTasks(tasks); final TaskSnapshot taskSnapshot = snapshotController.getSnapshot(task.mTaskId, task.mUserId, false /* restoreFromDisk */, false /* isLowResolution */); if (taskSnapshot == null) { return null; } final TaskScreenshotAnimatable animatable = new TaskScreenshotAnimatable( mService.mSurfaceControlFactory, task, new SurfaceControl.ScreenshotHardwareBuffer(taskSnapshot.getHardwareBuffer(), taskSnapshot.getColorSpace(), false /* containsSecureLayers */)); mRecentScreenshotAnimator = new SurfaceAnimator( animatable, (type, anim) -> { ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "mRecentScreenshotAnimator finish"); mCallbacks.onAnimationFinished(reorderMode, false /* sendUserLeaveHint */); }, mService); mRecentScreenshotAnimator.transferAnimation(task.mSurfaceAnimator); return taskSnapshot; return snapshotController.getSnapshot(task.mTaskId, task.mUserId, false /* restoreFromDisk */, false /* isLowResolution */); } void cleanupAnimation(@ReorderMode int reorderMode) { Loading Loading @@ -976,12 +980,6 @@ public class RecentsAnimationController implements DeathRecipient { mRunner = null; mCanceled = true; // Make sure previous animator has cleaned-up. if (mRecentScreenshotAnimator != null) { mRecentScreenshotAnimator.cancelAnimation(); mRecentScreenshotAnimator = null; } // Restore IME icon only when moving the original app task to front from recents, in case // IME icon may missing if the moving task has already been the current focused task. if (reorderMode == REORDER_MOVE_TO_ORIGINAL_POSITION && !mIsAddingTaskToTargets) { Loading Loading @@ -1028,16 +1026,7 @@ public class RecentsAnimationController implements DeathRecipient { @Override public void binderDied() { if (!mCanceled) { cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "binderDied"); } else { synchronized (mService.getWindowManagerLock()) { if (mRecentScreenshotAnimator != null) { mRecentScreenshotAnimator.cancelAnimation(); mRecentScreenshotAnimator = null; } } } synchronized (mService.getWindowManagerLock()) { // Clear associated input consumers on runner death Loading Loading @@ -1171,6 +1160,8 @@ public class RecentsAnimationController implements DeathRecipient { private PictureInPictureSurfaceTransaction mFinishTransaction; // An overlay used to mask the content as an app goes into PIP private SurfaceControl mFinishOverlay; // An overlay used for canceling the animation with a screenshot private SurfaceControl mSnapshotOverlay; TaskAnimationAdapter(Task task, boolean isRecentTaskInvisible) { mTask = task; Loading Loading @@ -1205,10 +1196,47 @@ public class RecentsAnimationController implements DeathRecipient { return mTarget; } void setSnapshotOverlay(TaskSnapshot snapshot) { // Create a surface control for the snapshot and reparent it to the leash final HardwareBuffer buffer = snapshot.getHardwareBuffer(); if (buffer == null) { return; } final SurfaceSession session = new SurfaceSession(); mSnapshotOverlay = mService.mSurfaceControlFactory.apply(session) .setName("RecentTaskScreenshotSurface") .setCallsite("TaskAnimationAdapter.setSnapshotOverlay") .setFormat(buffer.getFormat()) .setParent(mCapturedLeash) .setBLASTLayer() .build(); final float scale = 1.0f * mTask.getBounds().width() / buffer.getWidth(); mTask.getPendingTransaction() .setBuffer(mSnapshotOverlay, GraphicBuffer.createFromHardwareBuffer(buffer)) .setColorSpace(mSnapshotOverlay, snapshot.getColorSpace()) .setLayer(mSnapshotOverlay, Integer.MAX_VALUE) .setMatrix(mSnapshotOverlay, scale, 0, 0, scale) .show(mSnapshotOverlay) .apply(); } void onRemove() { if (mSnapshotOverlay != null) { // Clean up the snapshot overlay if necessary mTask.getPendingTransaction() .remove(mSnapshotOverlay) .apply(); mSnapshotOverlay = null; } mTask.setCanAffectSystemUiFlags(true); mCapturedFinishCallback.onAnimationFinished(mLastAnimationType, this); } void onCleanup() { if (mFinishTransaction != null) { final Transaction pendingTransaction = mTask.getPendingTransaction(); if (mFinishTransaction != null) { // Reparent the overlay if (mFinishOverlay != null) { pendingTransaction.reparent(mFinishOverlay, mTask.mSurfaceControl); Loading Loading @@ -1236,10 +1264,15 @@ public class RecentsAnimationController implements DeathRecipient { } else if (!mTask.isAttached()) { // Apply the task's pending transaction in case it is detached and its transaction // is not reachable. mTask.getPendingTransaction().apply(); pendingTransaction.apply(); } } @VisibleForTesting public SurfaceControl getSnapshotOverlay() { return mSnapshotOverlay; } @Override public boolean getShowWallpaper() { return false; Loading
services/core/java/com/android/server/wm/RootWindowContainer.java +3 −1 Original line number Diff line number Diff line Loading @@ -1529,7 +1529,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // Updates the extra information of the intent. if (fromHomeKey) { homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true); mWindowManager.cancelRecentsAnimation(REORDER_KEEP_IN_PLACE, "startHomeActivity"); if (mWindowManager.getRecentsAnimationController() != null) { mWindowManager.getRecentsAnimationController().cancelAnimationForHomeStart(); } } homeIntent.putExtra(WindowManagerPolicy.EXTRA_START_REASON, reason); Loading
services/core/java/com/android/server/wm/TaskScreenshotAnimatable.javadeleted 100644 → 0 +0 −120 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.wm; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_RECENTS_ANIMATIONS; import android.graphics.GraphicBuffer; import android.hardware.HardwareBuffer; import android.view.SurfaceControl; import android.view.SurfaceSession; import com.android.internal.protolog.common.ProtoLog; import java.util.function.Function; /** * Class used by {@link RecentsAnimationController} to create a surface control with taking * screenshot of task when canceling recents animation. * * @see {@link RecentsAnimationController#setCancelOnNextTransitionStart} */ class TaskScreenshotAnimatable implements SurfaceAnimator.Animatable { private static final String TAG = "TaskScreenshotAnim"; private Task mTask; private SurfaceControl mSurfaceControl; private int mWidth; private int mHeight; TaskScreenshotAnimatable(Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory, Task task, SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer) { HardwareBuffer buffer = screenshotBuffer == null ? null : screenshotBuffer.getHardwareBuffer(); mTask = task; mWidth = (buffer != null) ? buffer.getWidth() : 1; mHeight = (buffer != null) ? buffer.getHeight() : 1; ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "Creating TaskScreenshotAnimatable: task: %s width: %d height: %d", task, mWidth, mHeight); mSurfaceControl = surfaceControlFactory.apply(new SurfaceSession()) .setName("RecentTaskScreenshotSurface") .setBLASTLayer() .setCallsite("TaskScreenshotAnimatable") .build(); if (buffer != null) { GraphicBuffer graphicBuffer = GraphicBuffer.createFromHardwareBuffer(buffer); getPendingTransaction().setBuffer(mSurfaceControl, graphicBuffer); getPendingTransaction().setColorSpace(mSurfaceControl, screenshotBuffer.getColorSpace()); final float scale = 1.0f * mTask.getBounds().width() / mWidth; getPendingTransaction().setMatrix(mSurfaceControl, scale, 0, 0, scale); } getPendingTransaction().show(mSurfaceControl); } @Override public SurfaceControl.Transaction getPendingTransaction() { return mTask.getPendingTransaction(); } @Override public void commitPendingTransaction() { mTask.commitPendingTransaction(); } @Override public void onAnimationLeashCreated(SurfaceControl.Transaction t, SurfaceControl leash) { t.setLayer(leash, 1); } @Override public void onAnimationLeashLost(SurfaceControl.Transaction t) { if (mSurfaceControl != null) { t.remove(mSurfaceControl); mSurfaceControl = null; } } @Override public SurfaceControl.Builder makeAnimationLeash() { return mTask.makeAnimationLeash(); } @Override public SurfaceControl getAnimationLeashParent() { return mTask.getAnimationLeashParent(); } @Override public SurfaceControl getSurfaceControl() { return mSurfaceControl; } @Override public SurfaceControl getParentSurfaceControl() { return mTask.mSurfaceControl; } @Override public int getSurfaceWidth() { return mWidth; } @Override public int getSurfaceHeight() { return mHeight; } }