Merge "Enable additional logging for recents/remote animations" into pi-dev

This commit is contained in:
TreeHugger Robot
2018-04-11 02:10:29 +00:00
committed by Android (Google) Code Review
7 changed files with 150 additions and 47 deletions

View File

@@ -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);

View File

@@ -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;
@@ -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;
}
@@ -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;
}
}
@@ -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();
@@ -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
@@ -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());
@@ -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);
@@ -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.
@@ -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;
}
@@ -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
@@ -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);
@@ -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;
}
}

View File

@@ -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;
@@ -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
@@ -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;
@@ -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
@@ -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()) {
@@ -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()) {
@@ -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()) {
@@ -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;
}
@@ -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;
@@ -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);
@@ -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
@@ -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;
}
@@ -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);
}
@@ -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
@@ -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) {
@@ -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) {
@@ -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
@@ -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
@@ -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());
}
}

View File

@@ -19,6 +19,7 @@ package com.android.server.wm;
import static com.android.server.wm.AnimationAdapterProto.REMOTE;
import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_REMOTE_ANIMATIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -49,7 +50,9 @@ import java.util.ArrayList;
* Helper class to run app animations in a remote process.
*/
class RemoteAnimationController implements DeathRecipient {
private static final String TAG = TAG_WITH_CLASS_NAME ? "RemoteAnimationController" : TAG_WM;
private static final String TAG = TAG_WITH_CLASS_NAME
|| (DEBUG_REMOTE_ANIMATIONS && !DEBUG_APP_TRANSITIONS)
? "RemoteAnimationController" : TAG_WM;
private static final long TIMEOUT_MS = 2000;
private final WindowManagerService mService;
@@ -57,7 +60,7 @@ class RemoteAnimationController implements DeathRecipient {
private final ArrayList<RemoteAnimationAdapterWrapper> mPendingAnimations = new ArrayList<>();
private final Rect mTmpRect = new Rect();
private final Handler mHandler;
private final Runnable mTimeoutRunnable = this::cancelAnimation;
private final Runnable mTimeoutRunnable = () -> cancelAnimation("timeoutRunnable");
private FinishedCallback mFinishedCallback;
private boolean mCanceled;
@@ -80,6 +83,7 @@ class RemoteAnimationController implements DeathRecipient {
*/
AnimationAdapter createAnimationAdapter(AppWindowToken appWindowToken, Point position,
Rect stackBounds) {
if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "createAnimationAdapter(): token=" + appWindowToken);
final RemoteAnimationAdapterWrapper adapter = new RemoteAnimationAdapterWrapper(
appWindowToken, position, stackBounds);
mPendingAnimations.add(adapter);
@@ -90,7 +94,10 @@ class RemoteAnimationController implements DeathRecipient {
* Called when the transition is ready to be started, and all leashes have been set up.
*/
void goodToGo() {
if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "goodToGo()");
if (mPendingAnimations.isEmpty() || mCanceled) {
if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "goodToGo(): Animation finished before good to go, canceled="
+ mCanceled + " mPendingAnimations=" + mPendingAnimations.size());
onAnimationFinished();
return;
}
@@ -102,6 +109,7 @@ class RemoteAnimationController implements DeathRecipient {
final RemoteAnimationTarget[] animations = createAnimations();
if (animations.length == 0) {
if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "goodToGo(): No apps to animate");
onAnimationFinished();
return;
}
@@ -113,14 +121,20 @@ class RemoteAnimationController implements DeathRecipient {
Slog.e(TAG, "Failed to start remote animation", e);
onAnimationFinished();
}
if (DEBUG_REMOTE_ANIMATIONS) {
Slog.d(TAG, "startAnimation(): Notify animation start:");
for (int i = 0; i < mPendingAnimations.size(); i++) {
Slog.d(TAG, "\t" + mPendingAnimations.get(i).mAppWindowToken);
}
} else if (DEBUG_APP_TRANSITIONS) {
writeStartDebugStatement();
}
});
sendRunningRemoteAnimation(true);
if (DEBUG_APP_TRANSITIONS) {
writeStartDebugStatement();
}
}
private void cancelAnimation() {
private void cancelAnimation(String reason) {
if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "cancelAnimation(): reason=" + reason);
synchronized (mService.getWindowManagerLock()) {
if (mCanceled) {
return;
@@ -143,14 +157,16 @@ class RemoteAnimationController implements DeathRecipient {
}
private RemoteAnimationTarget[] createAnimations() {
if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "createAnimations()");
final ArrayList<RemoteAnimationTarget> targets = new ArrayList<>();
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
final RemoteAnimationAdapterWrapper wrapper = mPendingAnimations.get(i);
final RemoteAnimationTarget target =
mPendingAnimations.get(i).createRemoteAppAnimation();
final RemoteAnimationTarget target = wrapper.createRemoteAppAnimation();
if (target != null) {
if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "\tAdd token=" + wrapper.mAppWindowToken);
targets.add(target);
} else {
if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "\tRemove token=" + wrapper.mAppWindowToken);
// We can't really start an animation but we still need to make sure to finish the
// pending animation that was started by SurfaceAnimator
@@ -164,22 +180,29 @@ class RemoteAnimationController implements DeathRecipient {
}
private void onAnimationFinished() {
if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "onAnimationFinished(): mPendingAnimations="
+ mPendingAnimations.size());
mHandler.removeCallbacks(mTimeoutRunnable);
synchronized (mService.mWindowMap) {
unlinkToDeathOfRunner();
releaseFinishedCallback();
mService.openSurfaceTransaction();
try {
if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "onAnimationFinished(): Notify animation finished:");
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
final RemoteAnimationAdapterWrapper adapter = mPendingAnimations.get(i);
adapter.mCapturedFinishCallback.onAnimationFinished(adapter);
if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "\t" + adapter.mAppWindowToken);
}
} catch (Exception e) {
Slog.e(TAG, "Failed to finish remote animation", e);
throw e;
} finally {
mService.closeSurfaceTransaction("RemoteAnimationController#finished");
}
}
sendRunningRemoteAnimation(false);
if (DEBUG_APP_TRANSITIONS) Slog.i(TAG, "Finishing remote animation");
if (DEBUG_REMOTE_ANIMATIONS) Slog.i(TAG, "Finishing remote animation");
}
private void invokeAnimationCancelled() {
@@ -221,7 +244,7 @@ class RemoteAnimationController implements DeathRecipient {
@Override
public void binderDied() {
cancelAnimation();
cancelAnimation("binderDied");
}
private static final class FinishedCallback extends IRemoteAnimationFinishedCallback.Stub {
@@ -234,6 +257,7 @@ class RemoteAnimationController implements DeathRecipient {
@Override
public void onAnimationFinished() throws RemoteException {
if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "app-onAnimationFinished(): mOuter=" + mOuter);
final long token = Binder.clearCallingIdentity();
try {
if (mOuter != null) {
@@ -253,6 +277,7 @@ class RemoteAnimationController implements DeathRecipient {
* to prevent memory leak.
*/
void release() {
if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "app-release(): mOuter=" + mOuter);
mOuter = null;
}
};
@@ -316,6 +341,7 @@ class RemoteAnimationController implements DeathRecipient {
@Override
public void startAnimation(SurfaceControl animationLeash, Transaction t,
OnAnimationFinishedCallback finishCallback) {
if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "startAnimation");
// Restore z-layering, position and stack crop until client has a chance to modify it.
t.setLayer(animationLeash, mAppWindowToken.getPrefixOrderIndex());

View File

@@ -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;
}

View File

@@ -74,6 +74,9 @@ public class WindowManagerDebugConfig {
static final boolean SHOW_STACK_CRAWLS = false;
static final boolean DEBUG_WINDOW_CROP = false;
static final boolean DEBUG_UNKNOWN_APP_VISIBILITY = false;
// TODO (b/73188263): Reset debugging flags
static final boolean DEBUG_RECENTS_ANIMATIONS = true;
static final boolean DEBUG_REMOTE_ANIMATIONS = DEBUG_APP_TRANSITIONS || true;
static final String TAG_KEEP_SCREEN_ON = "DebugKeepScreenOn";
static final boolean DEBUG_KEEP_SCREEN_ON = false;

View File

@@ -2729,13 +2729,19 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
public void cancelRecentsAnimation(@RecentsAnimationController.ReorderMode int reorderMode) {
/**
* Cancels any running recents animation. The caller should NOT hold the WM lock while calling
* this method, as it can call back into AM, and locking will be done in the animation
* controller itself.
*/
public void cancelRecentsAnimation(@RecentsAnimationController.ReorderMode int reorderMode,
String reason) {
// Note: Do not hold the WM lock, this will lock appropriately in the call which also
// calls through to AM/RecentsAnimation.onAnimationFinished()
if (mRecentsAnimationController != null) {
// This call will call through to cleanupAnimation() below after the animation is
// canceled
mRecentsAnimationController.cancelAnimation(reorderMode);
mRecentsAnimationController.cancelAnimation(reorderMode, reason);
}
}