From 77d0f36c26acfc477c87cdf424ad064cce84b4b6 Mon Sep 17 00:00:00 2001 From: Jorim Jaggi Date: Fri, 16 Mar 2018 17:49:49 +0100 Subject: [PATCH] Fix lockscreen notification launch animation When launching a notification from the lockscreen, we immediately start an app transition because the app is started in invisible /stopped state. Then, we try to take a screenshot, but nothing is visible yet because the AppWindowToken is hidden. Furthermore this fixes a bug where we were starting a remote animation too aggressively. Test: Launch anything from lockscreen Test: go/wm-smoke Change-Id: Iea9366813fa5780460a9ab2738f2a17f65fbeb15 Fixes: 73187454 --- .../statusbar/notification/ActivityLaunchAnimator.java | 3 +++ .../com/android/systemui/statusbar/phone/StatusBar.java | 7 +++++-- .../android/server/wm/AppWindowContainerController.java | 3 ++- .../core/java/com/android/server/wm/AppWindowToken.java | 7 +++++++ .../java/com/android/server/wm/TaskSnapshotController.java | 3 ++- 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java index 1d9cdf73b9c28..3bbfe3c1062cb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java @@ -77,6 +77,9 @@ public class ActivityLaunchAnimator { public RemoteAnimationAdapter getLaunchAnimation( ExpandableNotificationRow sourceNotification) { + if (mStatusBar.getBarState() != StatusBarState.SHADE) { + return null; + } AnimationRunner animationRunner = new AnimationRunner(sourceNotification); return new RemoteAnimationAdapter(animationRunner, ANIMATION_DURATION, 0 /* statusBarTransitionDelay */); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 2e45b120a75f9..a0c3c467731a9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -5043,8 +5043,11 @@ public class StatusBar extends SystemUI implements DemoMode, RemoteAnimationAdapter adapter = mActivityLaunchAnimator.getLaunchAnimation( row); try { - ActivityManager.getService().registerRemoteAnimationForNextActivityStart( - intent.getCreatorPackage(), adapter); + if (adapter != null) { + ActivityManager.getService() + .registerRemoteAnimationForNextActivityStart( + intent.getCreatorPackage(), adapter); + } launchResult = intent.sendAndReturnResult(mContext, 0, fillInIntent, null, null, null, getActivityOptions(adapter)); mActivityLaunchAnimator.setLaunchResult(launchResult); diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java index 1170148d67819..1575694dc825d 100644 --- a/services/core/java/com/android/server/wm/AppWindowContainerController.java +++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java @@ -617,7 +617,8 @@ public class AppWindowContainerController if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Schedule remove starting " + mContainer + " startingWindow=" + mContainer.startingWindow - + " startingView=" + mContainer.startingSurface); + + " startingView=" + mContainer.startingSurface + + " Callers=" + Debug.getCallers(5)); // Use the same thread to remove the window as we used to add it, as otherwise we end up // with things in the view hierarchy being called from different threads. diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index fef615d651b10..b70a8cd0ea5f7 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -2073,6 +2073,13 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree super.prepareSurfaces(); } + /** + * @return Whether our {@link #getSurfaceControl} is currently showing. + */ + boolean isSurfaceShowing() { + return mLastSurfaceShowing; + } + boolean isFreezingScreen() { return mFreezingScreen; } diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java index 9310dc488c747..970a8d76a0abe 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotController.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java @@ -247,7 +247,8 @@ class TaskSnapshotController { // Ensure at least one window for the top app is visible before attempting to take // a screenshot. Visible here means that the WSA surface is shown and has an alpha // greater than 0. - ws -> ws.mWinAnimator != null && ws.mWinAnimator.getShown() + ws -> (ws.mAppToken == null || ws.mAppToken.isSurfaceShowing()) + && ws.mWinAnimator != null && ws.mWinAnimator.getShown() && ws.mWinAnimator.mLastAlpha > 0f, true); if (!hasVisibleChild) {