Loading services/core/java/com/android/server/am/ActivityManagerService.java +1 −1 Original line number Diff line number Diff line Loading @@ -5292,7 +5292,7 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized (this) { mWindowManager.cancelRecentsAnimation(restoreHomeStackPosition ? REORDER_MOVE_TO_ORIGINAL_POSITION : REORDER_KEEP_IN_PLACE); : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation"); } } finally { Binder.restoreCallingIdentity(origId); services/core/java/com/android/server/am/RecentsAnimation.java +55 −1 Original line number Diff line number Diff line Loading @@ -46,6 +46,8 @@ import com.android.server.wm.WindowManagerService; */ class RecentsAnimation implements RecentsAnimationCallbacks { private static final String TAG = RecentsAnimation.class.getSimpleName(); // TODO (b/73188263): Reset debugging flags private static final boolean DEBUG = true; private final ActivityManagerService mService; private final ActivityStackSupervisor mStackSupervisor; Loading Loading @@ -74,10 +76,13 @@ class RecentsAnimation implements RecentsAnimationCallbacks { void startRecentsActivity(Intent intent, IRecentsAnimationRunner recentsAnimationRunner, ComponentName recentsComponent, int recentsUid) { if (DEBUG) Slog.d(TAG, "startRecentsActivity(): intent=" + intent); Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "RecentsAnimation#startRecentsActivity"); if (!mWindowManager.canStartRecentsAnimation()) { notifyAnimationCancelBeforeStart(recentsAnimationRunner); if (DEBUG) Slog.d(TAG, "Can't start recents animation, nextAppTransition=" + mWindowManager.getPendingAppTransition()); return; } Loading @@ -97,6 +102,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks { mRestoreTargetBehindStack = display.getStackAbove(targetStack); if (mRestoreTargetBehindStack == null) { notifyAnimationCancelBeforeStart(recentsAnimationRunner); if (DEBUG) Slog.d(TAG, "No stack above target stack=" + targetStack); return; } } Loading @@ -119,6 +125,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks { // Move the recents activity into place for the animation if it is not top most display = targetActivity.getDisplay(); display.moveStackBehindBottomMostVisibleStack(targetStack); if (DEBUG) Slog.d(TAG, "Moved stack=" + targetStack + " behind stack=" + display.getStackAbove(targetStack)); } else { // No recents activity ActivityOptions options = ActivityOptions.makeBasic(); Loading @@ -140,6 +148,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks { display = targetActivity.getDisplay(); // TODO: Maybe wait for app to draw in this particular case? if (DEBUG) Slog.d(TAG, "Started intent=" + intent); } // Mark the target activity as launch-behind to bump its visibility for the Loading @@ -148,7 +158,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks { // Fetch all the surface controls and pass them to the client to get the animation // started mWindowManager.cancelRecentsAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); mWindowManager.cancelRecentsAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "startRecentsActivity"); mWindowManager.initializeRecentsAnimation(mTargetActivityType, recentsAnimationRunner, this, display.mDisplayId, mStackSupervisor.mRecentTasks.getRecentTaskIds()); Loading @@ -158,6 +169,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks { mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunched(START_TASK_TO_FRONT, targetActivity); } catch (Exception e) { Slog.e(TAG, "Failed to start recents activity", e); throw e; } finally { mWindowManager.continueSurfaceLayout(); Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); Loading @@ -167,6 +181,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks { @Override public void onAnimationFinished(@RecentsAnimationController.ReorderMode int reorderMode) { synchronized (mService) { if (DEBUG) Slog.d(TAG, "onAnimationFinished(): controller=" + mWindowManager.getRecentsAnimationController() + " reorderMode=" + reorderMode); if (mWindowManager.getRecentsAnimationController() == null) return; // Just to be sure end the launch hint in case the target activity was never launched. Loading @@ -187,6 +204,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks { final ActivityStack targetStack = mDefaultDisplay.getStack( WINDOWING_MODE_UNDEFINED, mTargetActivityType); final ActivityRecord targetActivity = targetStack.getTopActivity(); if (DEBUG) Slog.d(TAG, "onAnimationFinished(): targetStack=" + targetStack + " targetActivity=" + targetActivity + " mRestoreTargetBehindStack=" + mRestoreTargetBehindStack); if (targetActivity == null) { return; } Loading @@ -198,10 +218,27 @@ class RecentsAnimation implements RecentsAnimationCallbacks { // Bring the target stack to the front mStackSupervisor.mNoAnimActivities.add(targetActivity); targetStack.moveToFront("RecentsAnimation.onAnimationFinished()"); if (DEBUG) { final ActivityStack topStack = getTopNonAlwaysOnTopStack(); if (topStack != targetStack) { Slog.w(TAG, "Expected target stack=" + targetStack + " to be top most but found stack=" + topStack); } } } else if (reorderMode == REORDER_MOVE_TO_ORIGINAL_POSITION){ // Restore the target stack to its previous position final ActivityDisplay display = targetActivity.getDisplay(); display.moveStackBehindStack(targetStack, mRestoreTargetBehindStack); if (DEBUG) { final ActivityStack aboveTargetStack = mDefaultDisplay.getStackAbove(targetStack); if (mRestoreTargetBehindStack != null && aboveTargetStack != mRestoreTargetBehindStack) { Slog.w(TAG, "Expected target stack=" + targetStack + " to restored behind stack=" + mRestoreTargetBehindStack + " but it is behind stack=" + aboveTargetStack); } } } else { // Keep target stack in place, nothing changes, so ignore the transition // logic below Loading @@ -221,6 +258,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks { // split-screen), or we will have returned to the app, and the minimized state // should be reset mWindowManager.checkSplitScreenMinimizedChanged(true /* animate */); } catch (Exception e) { Slog.e(TAG, "Failed to clean up recents activity", e); throw e; } finally { mWindowManager.continueSurfaceLayout(); Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); Loading @@ -239,4 +279,18 @@ class RecentsAnimation implements RecentsAnimationCallbacks { Slog.e(TAG, "Failed to cancel recents animation before start", e); } } /** * @return The top stack that is not always-on-top. */ private ActivityStack getTopNonAlwaysOnTopStack() { for (int i = mDefaultDisplay.getChildCount() - 1; i >= 0; i--) { final ActivityStack s = mDefaultDisplay.getChildAt(i); if (s.getWindowConfiguration().isAlwaysOnTop()) { continue; } return s; } return null; } } services/core/java/com/android/server/wm/RecentsAnimationController.java +46 −32 Original line number Diff line number Diff line Loading @@ -17,19 +17,16 @@ package com.android.server.wm; import static android.app.ActivityManagerInternal.APP_TRANSITION_RECENTS_ANIM; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.RemoteAnimationTarget.MODE_CLOSING; import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.H.NOTIFY_APP_TRANSITION_STARTING; import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET; import static com.android.server.wm.AnimationAdapterProto.REMOTE; import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RECENTS_ANIMATIONS; import static com.android.server.wm.WindowManagerService.H.NOTIFY_APP_TRANSITION_STARTING; import android.annotation.IntDef; import android.app.ActivityManager.TaskSnapshot; Loading @@ -41,24 +38,22 @@ import android.os.IBinder.DeathRecipient; import android.os.RemoteException; import android.os.SystemClock; import android.util.ArraySet; import android.util.Log; import android.util.Slog;import android.util.proto.ProtoOutputStream; import android.util.Slog; import android.util.SparseBooleanArray; import android.util.SparseIntArray; import android.util.proto.ProtoOutputStream; import android.view.IRecentsAnimationController; import android.view.IRecentsAnimationRunner; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; import com.android.internal.annotations.VisibleForTesting; import com.google.android.collect.Sets; import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; import com.android.server.wm.utils.InsetUtils; import com.google.android.collect.Sets; import java.io.PrintWriter; import java.util.ArrayList; /** * Controls a single instance of the remote driven recents animation. In particular, this allows * the calling SystemUI to animate the visible task windows as a part of the transition. The remote Loading @@ -67,8 +62,7 @@ import java.util.ArrayList; * app if it requires the animation to be canceled at any time (ie. due to timeout, etc.) */ public class RecentsAnimationController implements DeathRecipient { private static final String TAG = TAG_WITH_CLASS_NAME ? "RecentsAnimationController" : TAG_WM; private static final boolean DEBUG = false; private static final String TAG = RecentsAnimationController.class.getSimpleName(); private static final long FAILSAFE_DELAY = 1000; public static final int REORDER_KEEP_IN_PLACE = 0; Loading @@ -88,7 +82,7 @@ public class RecentsAnimationController implements DeathRecipient { private final ArrayList<TaskAnimationAdapter> mPendingAnimations = new ArrayList<>(); private final int mDisplayId; private final Runnable mFailsafeRunnable = () -> { cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "failSafeRunnable"); }; // The recents component app token that is shown behind the visibile tasks Loading Loading @@ -124,7 +118,8 @@ public class RecentsAnimationController implements DeathRecipient { @Override public TaskSnapshot screenshotTask(int taskId) { if (DEBUG) Log.d(TAG, "screenshotTask(" + taskId + "): mCanceled=" + mCanceled); if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "screenshotTask(" + taskId + "):" + " mCanceled=" + mCanceled); final long token = Binder.clearCallingIdentity(); try { synchronized (mService.getWindowManagerLock()) { Loading Loading @@ -153,7 +148,8 @@ public class RecentsAnimationController implements DeathRecipient { @Override public void finish(boolean moveHomeToTop) { if (DEBUG) Log.d(TAG, "finish(" + moveHomeToTop + "): mCanceled=" + mCanceled); if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "finish(" + moveHomeToTop + "):" + " mCanceled=" + mCanceled); final long token = Binder.clearCallingIdentity(); try { synchronized (mService.getWindowManagerLock()) { Loading Loading @@ -190,8 +186,8 @@ public class RecentsAnimationController implements DeathRecipient { @Override public void setInputConsumerEnabled(boolean enabled) { if (DEBUG) Log.d(TAG, "setInputConsumerEnabled(" + enabled + "): mCanceled=" + mCanceled); if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "setInputConsumerEnabled(" + enabled + "):" + " mCanceled=" + mCanceled); final long token = Binder.clearCallingIdentity(); try { synchronized (mService.getWindowManagerLock()) { Loading Loading @@ -264,14 +260,14 @@ public class RecentsAnimationController implements DeathRecipient { // Skip the animation if there is nothing to animate if (mPendingAnimations.isEmpty()) { cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "initialize-noVisibleTasks"); return; } try { linkToDeathOfRunner(); } catch (RemoteException e) { cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "initialize-failedToLinkToDeath"); return; } Loading @@ -279,7 +275,8 @@ public class RecentsAnimationController implements DeathRecipient { final AppWindowToken recentsComponentAppToken = dc.getStack(WINDOWING_MODE_UNDEFINED, targetActivityType).getTopChild().getTopFullscreenAppToken(); if (recentsComponentAppToken != null) { if (DEBUG) Log.d(TAG, "setHomeApp(" + recentsComponentAppToken.getName() + ")"); if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "setHomeApp(" + recentsComponentAppToken.getName() + ")"); mTargetAppToken = recentsComponentAppToken; if (recentsComponentAppToken.windowsCanBeWallpaperTarget()) { dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; Loading @@ -295,7 +292,7 @@ public class RecentsAnimationController implements DeathRecipient { @VisibleForTesting AnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible) { if (DEBUG) Log.d(TAG, "addAnimation(" + task.getName() + ")"); if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "addAnimation(" + task.getName() + ")"); // TODO: Refactor this to use the task's animator final SurfaceAnimator anim = new SurfaceAnimator(task, null /* animationFinishedCallback */, mService); Loading @@ -309,14 +306,15 @@ public class RecentsAnimationController implements DeathRecipient { @VisibleForTesting void removeAnimation(TaskAnimationAdapter taskAdapter) { if (DEBUG) Log.d(TAG, "removeAnimation(" + taskAdapter.mTask.getName() + ")"); if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "removeAnimation(" + taskAdapter.mTask.mTaskId + ")"); taskAdapter.mTask.setCanAffectSystemUiFlags(true); taskAdapter.mCapturedFinishCallback.onAnimationFinished(taskAdapter); mPendingAnimations.remove(taskAdapter); } void startAnimation() { if (DEBUG) Log.d(TAG, "startAnimation(): mPendingStart=" + mPendingStart if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "startAnimation(): mPendingStart=" + mPendingStart + " mCanceled=" + mCanceled); if (!mPendingStart || mCanceled) { // Skip starting if we've already started or canceled the animation Loading @@ -336,7 +334,7 @@ public class RecentsAnimationController implements DeathRecipient { // Skip the animation if there is nothing to animate if (appAnimations.isEmpty()) { cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "startAnimation-noAppWindows"); return; } Loading @@ -354,6 +352,13 @@ public class RecentsAnimationController implements DeathRecipient { : null; mRunner.onAnimationStart_New(mController, appTargets, contentInsets, minimizedHomeBounds); if (DEBUG_RECENTS_ANIMATIONS) { Slog.d(TAG, "startAnimation(): Notify animation start:"); for (int i = 0; i < mPendingAnimations.size(); i++) { final Task task = mPendingAnimations.get(i).mTask; Slog.d(TAG, "\t" + task.mTaskId); } } } catch (RemoteException e) { Slog.e(TAG, "Failed to start recents animation", e); } Loading @@ -363,8 +368,8 @@ public class RecentsAnimationController implements DeathRecipient { reasons).sendToTarget(); } void cancelAnimation(@ReorderMode int reorderMode) { if (DEBUG) Log.d(TAG, "cancelAnimation()"); void cancelAnimation(@ReorderMode int reorderMode, String reason) { if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "cancelAnimation()"); synchronized (mService.getWindowManagerLock()) { if (mCanceled) { // We've already canceled the animation Loading @@ -385,8 +390,9 @@ public class RecentsAnimationController implements DeathRecipient { } void cleanupAnimation(@ReorderMode int reorderMode) { if (DEBUG) Log.d(TAG, "cleanupAnimation(): mPendingAnimations=" + mPendingAnimations.size()); if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "cleanupAnimation(): Notify animation finished mPendingAnimations=" + mPendingAnimations.size() + " reorderMode=" + reorderMode); for (int i = mPendingAnimations.size() - 1; i >= 0; i--) { final TaskAnimationAdapter taskAdapter = mPendingAnimations.get(i); if (reorderMode == REORDER_MOVE_TO_TOP || reorderMode == REORDER_KEEP_IN_PLACE) { Loading Loading @@ -421,7 +427,7 @@ public class RecentsAnimationController implements DeathRecipient { @Override public void binderDied() { cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "binderDied"); } void checkAnimationReady(WallpaperController wallpaperController) { Loading Loading @@ -550,7 +556,7 @@ public class RecentsAnimationController implements DeathRecipient { @Override public void onAnimationCancelled(SurfaceControl animationLeash) { cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "taskAnimationAdapterCanceled"); } @Override Loading @@ -572,6 +578,10 @@ public class RecentsAnimationController implements DeathRecipient { } else { pw.print(prefix); pw.println("Target: null"); } pw.println("mIsRecentTaskInvisible=" + mIsRecentTaskInvisible); pw.println("mPosition=" + mPosition); pw.println("mBounds=" + mBounds); pw.println("mIsRecentTaskInvisible=" + mIsRecentTaskInvisible); } @Override Loading @@ -588,6 +598,10 @@ public class RecentsAnimationController implements DeathRecipient { final String innerPrefix = prefix + " "; pw.print(prefix); pw.println(RecentsAnimationController.class.getSimpleName() + ":"); pw.print(innerPrefix); pw.println("mPendingStart=" + mPendingStart); pw.print(innerPrefix); pw.println("mCanceled=" + mCanceled); pw.print(innerPrefix); pw.println("mInputConsumerEnabled=" + mInputConsumerEnabled); pw.print(innerPrefix); pw.println("mSplitScreenMinimized=" + mSplitScreenMinimized); pw.print(innerPrefix); pw.println("mTargetAppToken=" + mTargetAppToken); pw.print(innerPrefix); pw.println("isTargetOverWallpaper=" + isTargetOverWallpaper()); } } services/core/java/com/android/server/wm/RemoteAnimationController.java +36 −10 File changed.Preview size limit exceeded, changes collapsed. Show changes services/core/java/com/android/server/wm/WallpaperController.java +1 −1 Original line number Diff line number Diff line Loading @@ -620,7 +620,7 @@ class WallpaperController { // If there was a recents animation in progress, cancel that animation if (mService.getRecentsAnimationController() != null) { mService.getRecentsAnimationController().cancelAnimation( REORDER_MOVE_TO_ORIGINAL_POSITION); REORDER_MOVE_TO_ORIGINAL_POSITION, "wallpaperDrawPendingTimeout"); } return true; } Loading Loading
services/core/java/com/android/server/am/ActivityManagerService.java +1 −1 Original line number Diff line number Diff line Loading @@ -5292,7 +5292,7 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized (this) { mWindowManager.cancelRecentsAnimation(restoreHomeStackPosition ? REORDER_MOVE_TO_ORIGINAL_POSITION : REORDER_KEEP_IN_PLACE); : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation"); } } finally { Binder.restoreCallingIdentity(origId);
services/core/java/com/android/server/am/RecentsAnimation.java +55 −1 Original line number Diff line number Diff line Loading @@ -46,6 +46,8 @@ import com.android.server.wm.WindowManagerService; */ class RecentsAnimation implements RecentsAnimationCallbacks { private static final String TAG = RecentsAnimation.class.getSimpleName(); // TODO (b/73188263): Reset debugging flags private static final boolean DEBUG = true; private final ActivityManagerService mService; private final ActivityStackSupervisor mStackSupervisor; Loading Loading @@ -74,10 +76,13 @@ class RecentsAnimation implements RecentsAnimationCallbacks { void startRecentsActivity(Intent intent, IRecentsAnimationRunner recentsAnimationRunner, ComponentName recentsComponent, int recentsUid) { if (DEBUG) Slog.d(TAG, "startRecentsActivity(): intent=" + intent); Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "RecentsAnimation#startRecentsActivity"); if (!mWindowManager.canStartRecentsAnimation()) { notifyAnimationCancelBeforeStart(recentsAnimationRunner); if (DEBUG) Slog.d(TAG, "Can't start recents animation, nextAppTransition=" + mWindowManager.getPendingAppTransition()); return; } Loading @@ -97,6 +102,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks { mRestoreTargetBehindStack = display.getStackAbove(targetStack); if (mRestoreTargetBehindStack == null) { notifyAnimationCancelBeforeStart(recentsAnimationRunner); if (DEBUG) Slog.d(TAG, "No stack above target stack=" + targetStack); return; } } Loading @@ -119,6 +125,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks { // Move the recents activity into place for the animation if it is not top most display = targetActivity.getDisplay(); display.moveStackBehindBottomMostVisibleStack(targetStack); if (DEBUG) Slog.d(TAG, "Moved stack=" + targetStack + " behind stack=" + display.getStackAbove(targetStack)); } else { // No recents activity ActivityOptions options = ActivityOptions.makeBasic(); Loading @@ -140,6 +148,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks { display = targetActivity.getDisplay(); // TODO: Maybe wait for app to draw in this particular case? if (DEBUG) Slog.d(TAG, "Started intent=" + intent); } // Mark the target activity as launch-behind to bump its visibility for the Loading @@ -148,7 +158,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks { // Fetch all the surface controls and pass them to the client to get the animation // started mWindowManager.cancelRecentsAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); mWindowManager.cancelRecentsAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "startRecentsActivity"); mWindowManager.initializeRecentsAnimation(mTargetActivityType, recentsAnimationRunner, this, display.mDisplayId, mStackSupervisor.mRecentTasks.getRecentTaskIds()); Loading @@ -158,6 +169,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks { mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunched(START_TASK_TO_FRONT, targetActivity); } catch (Exception e) { Slog.e(TAG, "Failed to start recents activity", e); throw e; } finally { mWindowManager.continueSurfaceLayout(); Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); Loading @@ -167,6 +181,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks { @Override public void onAnimationFinished(@RecentsAnimationController.ReorderMode int reorderMode) { synchronized (mService) { if (DEBUG) Slog.d(TAG, "onAnimationFinished(): controller=" + mWindowManager.getRecentsAnimationController() + " reorderMode=" + reorderMode); if (mWindowManager.getRecentsAnimationController() == null) return; // Just to be sure end the launch hint in case the target activity was never launched. Loading @@ -187,6 +204,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks { final ActivityStack targetStack = mDefaultDisplay.getStack( WINDOWING_MODE_UNDEFINED, mTargetActivityType); final ActivityRecord targetActivity = targetStack.getTopActivity(); if (DEBUG) Slog.d(TAG, "onAnimationFinished(): targetStack=" + targetStack + " targetActivity=" + targetActivity + " mRestoreTargetBehindStack=" + mRestoreTargetBehindStack); if (targetActivity == null) { return; } Loading @@ -198,10 +218,27 @@ class RecentsAnimation implements RecentsAnimationCallbacks { // Bring the target stack to the front mStackSupervisor.mNoAnimActivities.add(targetActivity); targetStack.moveToFront("RecentsAnimation.onAnimationFinished()"); if (DEBUG) { final ActivityStack topStack = getTopNonAlwaysOnTopStack(); if (topStack != targetStack) { Slog.w(TAG, "Expected target stack=" + targetStack + " to be top most but found stack=" + topStack); } } } else if (reorderMode == REORDER_MOVE_TO_ORIGINAL_POSITION){ // Restore the target stack to its previous position final ActivityDisplay display = targetActivity.getDisplay(); display.moveStackBehindStack(targetStack, mRestoreTargetBehindStack); if (DEBUG) { final ActivityStack aboveTargetStack = mDefaultDisplay.getStackAbove(targetStack); if (mRestoreTargetBehindStack != null && aboveTargetStack != mRestoreTargetBehindStack) { Slog.w(TAG, "Expected target stack=" + targetStack + " to restored behind stack=" + mRestoreTargetBehindStack + " but it is behind stack=" + aboveTargetStack); } } } else { // Keep target stack in place, nothing changes, so ignore the transition // logic below Loading @@ -221,6 +258,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks { // split-screen), or we will have returned to the app, and the minimized state // should be reset mWindowManager.checkSplitScreenMinimizedChanged(true /* animate */); } catch (Exception e) { Slog.e(TAG, "Failed to clean up recents activity", e); throw e; } finally { mWindowManager.continueSurfaceLayout(); Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); Loading @@ -239,4 +279,18 @@ class RecentsAnimation implements RecentsAnimationCallbacks { Slog.e(TAG, "Failed to cancel recents animation before start", e); } } /** * @return The top stack that is not always-on-top. */ private ActivityStack getTopNonAlwaysOnTopStack() { for (int i = mDefaultDisplay.getChildCount() - 1; i >= 0; i--) { final ActivityStack s = mDefaultDisplay.getChildAt(i); if (s.getWindowConfiguration().isAlwaysOnTop()) { continue; } return s; } return null; } }
services/core/java/com/android/server/wm/RecentsAnimationController.java +46 −32 Original line number Diff line number Diff line Loading @@ -17,19 +17,16 @@ package com.android.server.wm; import static android.app.ActivityManagerInternal.APP_TRANSITION_RECENTS_ANIM; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.RemoteAnimationTarget.MODE_CLOSING; import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.H.NOTIFY_APP_TRANSITION_STARTING; import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET; import static com.android.server.wm.AnimationAdapterProto.REMOTE; import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RECENTS_ANIMATIONS; import static com.android.server.wm.WindowManagerService.H.NOTIFY_APP_TRANSITION_STARTING; import android.annotation.IntDef; import android.app.ActivityManager.TaskSnapshot; Loading @@ -41,24 +38,22 @@ import android.os.IBinder.DeathRecipient; import android.os.RemoteException; import android.os.SystemClock; import android.util.ArraySet; import android.util.Log; import android.util.Slog;import android.util.proto.ProtoOutputStream; import android.util.Slog; import android.util.SparseBooleanArray; import android.util.SparseIntArray; import android.util.proto.ProtoOutputStream; import android.view.IRecentsAnimationController; import android.view.IRecentsAnimationRunner; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; import com.android.internal.annotations.VisibleForTesting; import com.google.android.collect.Sets; import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; import com.android.server.wm.utils.InsetUtils; import com.google.android.collect.Sets; import java.io.PrintWriter; import java.util.ArrayList; /** * Controls a single instance of the remote driven recents animation. In particular, this allows * the calling SystemUI to animate the visible task windows as a part of the transition. The remote Loading @@ -67,8 +62,7 @@ import java.util.ArrayList; * app if it requires the animation to be canceled at any time (ie. due to timeout, etc.) */ public class RecentsAnimationController implements DeathRecipient { private static final String TAG = TAG_WITH_CLASS_NAME ? "RecentsAnimationController" : TAG_WM; private static final boolean DEBUG = false; private static final String TAG = RecentsAnimationController.class.getSimpleName(); private static final long FAILSAFE_DELAY = 1000; public static final int REORDER_KEEP_IN_PLACE = 0; Loading @@ -88,7 +82,7 @@ public class RecentsAnimationController implements DeathRecipient { private final ArrayList<TaskAnimationAdapter> mPendingAnimations = new ArrayList<>(); private final int mDisplayId; private final Runnable mFailsafeRunnable = () -> { cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "failSafeRunnable"); }; // The recents component app token that is shown behind the visibile tasks Loading Loading @@ -124,7 +118,8 @@ public class RecentsAnimationController implements DeathRecipient { @Override public TaskSnapshot screenshotTask(int taskId) { if (DEBUG) Log.d(TAG, "screenshotTask(" + taskId + "): mCanceled=" + mCanceled); if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "screenshotTask(" + taskId + "):" + " mCanceled=" + mCanceled); final long token = Binder.clearCallingIdentity(); try { synchronized (mService.getWindowManagerLock()) { Loading Loading @@ -153,7 +148,8 @@ public class RecentsAnimationController implements DeathRecipient { @Override public void finish(boolean moveHomeToTop) { if (DEBUG) Log.d(TAG, "finish(" + moveHomeToTop + "): mCanceled=" + mCanceled); if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "finish(" + moveHomeToTop + "):" + " mCanceled=" + mCanceled); final long token = Binder.clearCallingIdentity(); try { synchronized (mService.getWindowManagerLock()) { Loading Loading @@ -190,8 +186,8 @@ public class RecentsAnimationController implements DeathRecipient { @Override public void setInputConsumerEnabled(boolean enabled) { if (DEBUG) Log.d(TAG, "setInputConsumerEnabled(" + enabled + "): mCanceled=" + mCanceled); if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "setInputConsumerEnabled(" + enabled + "):" + " mCanceled=" + mCanceled); final long token = Binder.clearCallingIdentity(); try { synchronized (mService.getWindowManagerLock()) { Loading Loading @@ -264,14 +260,14 @@ public class RecentsAnimationController implements DeathRecipient { // Skip the animation if there is nothing to animate if (mPendingAnimations.isEmpty()) { cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "initialize-noVisibleTasks"); return; } try { linkToDeathOfRunner(); } catch (RemoteException e) { cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "initialize-failedToLinkToDeath"); return; } Loading @@ -279,7 +275,8 @@ public class RecentsAnimationController implements DeathRecipient { final AppWindowToken recentsComponentAppToken = dc.getStack(WINDOWING_MODE_UNDEFINED, targetActivityType).getTopChild().getTopFullscreenAppToken(); if (recentsComponentAppToken != null) { if (DEBUG) Log.d(TAG, "setHomeApp(" + recentsComponentAppToken.getName() + ")"); if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "setHomeApp(" + recentsComponentAppToken.getName() + ")"); mTargetAppToken = recentsComponentAppToken; if (recentsComponentAppToken.windowsCanBeWallpaperTarget()) { dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; Loading @@ -295,7 +292,7 @@ public class RecentsAnimationController implements DeathRecipient { @VisibleForTesting AnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible) { if (DEBUG) Log.d(TAG, "addAnimation(" + task.getName() + ")"); if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "addAnimation(" + task.getName() + ")"); // TODO: Refactor this to use the task's animator final SurfaceAnimator anim = new SurfaceAnimator(task, null /* animationFinishedCallback */, mService); Loading @@ -309,14 +306,15 @@ public class RecentsAnimationController implements DeathRecipient { @VisibleForTesting void removeAnimation(TaskAnimationAdapter taskAdapter) { if (DEBUG) Log.d(TAG, "removeAnimation(" + taskAdapter.mTask.getName() + ")"); if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "removeAnimation(" + taskAdapter.mTask.mTaskId + ")"); taskAdapter.mTask.setCanAffectSystemUiFlags(true); taskAdapter.mCapturedFinishCallback.onAnimationFinished(taskAdapter); mPendingAnimations.remove(taskAdapter); } void startAnimation() { if (DEBUG) Log.d(TAG, "startAnimation(): mPendingStart=" + mPendingStart if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "startAnimation(): mPendingStart=" + mPendingStart + " mCanceled=" + mCanceled); if (!mPendingStart || mCanceled) { // Skip starting if we've already started or canceled the animation Loading @@ -336,7 +334,7 @@ public class RecentsAnimationController implements DeathRecipient { // Skip the animation if there is nothing to animate if (appAnimations.isEmpty()) { cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "startAnimation-noAppWindows"); return; } Loading @@ -354,6 +352,13 @@ public class RecentsAnimationController implements DeathRecipient { : null; mRunner.onAnimationStart_New(mController, appTargets, contentInsets, minimizedHomeBounds); if (DEBUG_RECENTS_ANIMATIONS) { Slog.d(TAG, "startAnimation(): Notify animation start:"); for (int i = 0; i < mPendingAnimations.size(); i++) { final Task task = mPendingAnimations.get(i).mTask; Slog.d(TAG, "\t" + task.mTaskId); } } } catch (RemoteException e) { Slog.e(TAG, "Failed to start recents animation", e); } Loading @@ -363,8 +368,8 @@ public class RecentsAnimationController implements DeathRecipient { reasons).sendToTarget(); } void cancelAnimation(@ReorderMode int reorderMode) { if (DEBUG) Log.d(TAG, "cancelAnimation()"); void cancelAnimation(@ReorderMode int reorderMode, String reason) { if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "cancelAnimation()"); synchronized (mService.getWindowManagerLock()) { if (mCanceled) { // We've already canceled the animation Loading @@ -385,8 +390,9 @@ public class RecentsAnimationController implements DeathRecipient { } void cleanupAnimation(@ReorderMode int reorderMode) { if (DEBUG) Log.d(TAG, "cleanupAnimation(): mPendingAnimations=" + mPendingAnimations.size()); if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "cleanupAnimation(): Notify animation finished mPendingAnimations=" + mPendingAnimations.size() + " reorderMode=" + reorderMode); for (int i = mPendingAnimations.size() - 1; i >= 0; i--) { final TaskAnimationAdapter taskAdapter = mPendingAnimations.get(i); if (reorderMode == REORDER_MOVE_TO_TOP || reorderMode == REORDER_KEEP_IN_PLACE) { Loading Loading @@ -421,7 +427,7 @@ public class RecentsAnimationController implements DeathRecipient { @Override public void binderDied() { cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "binderDied"); } void checkAnimationReady(WallpaperController wallpaperController) { Loading Loading @@ -550,7 +556,7 @@ public class RecentsAnimationController implements DeathRecipient { @Override public void onAnimationCancelled(SurfaceControl animationLeash) { cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "taskAnimationAdapterCanceled"); } @Override Loading @@ -572,6 +578,10 @@ public class RecentsAnimationController implements DeathRecipient { } else { pw.print(prefix); pw.println("Target: null"); } pw.println("mIsRecentTaskInvisible=" + mIsRecentTaskInvisible); pw.println("mPosition=" + mPosition); pw.println("mBounds=" + mBounds); pw.println("mIsRecentTaskInvisible=" + mIsRecentTaskInvisible); } @Override Loading @@ -588,6 +598,10 @@ public class RecentsAnimationController implements DeathRecipient { final String innerPrefix = prefix + " "; pw.print(prefix); pw.println(RecentsAnimationController.class.getSimpleName() + ":"); pw.print(innerPrefix); pw.println("mPendingStart=" + mPendingStart); pw.print(innerPrefix); pw.println("mCanceled=" + mCanceled); pw.print(innerPrefix); pw.println("mInputConsumerEnabled=" + mInputConsumerEnabled); pw.print(innerPrefix); pw.println("mSplitScreenMinimized=" + mSplitScreenMinimized); pw.print(innerPrefix); pw.println("mTargetAppToken=" + mTargetAppToken); pw.print(innerPrefix); pw.println("isTargetOverWallpaper=" + isTargetOverWallpaper()); } }
services/core/java/com/android/server/wm/RemoteAnimationController.java +36 −10 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/core/java/com/android/server/wm/WallpaperController.java +1 −1 Original line number Diff line number Diff line Loading @@ -620,7 +620,7 @@ class WallpaperController { // If there was a recents animation in progress, cancel that animation if (mService.getRecentsAnimationController() != null) { mService.getRecentsAnimationController().cancelAnimation( REORDER_MOVE_TO_ORIGINAL_POSITION); REORDER_MOVE_TO_ORIGINAL_POSITION, "wallpaperDrawPendingTimeout"); } return true; } Loading