OSDN Git Service

Fix black frame when unlocking device via clicking on notification
authorChong Zhang <chz@google.com>
Tue, 15 Mar 2016 19:50:03 +0000 (12:50 -0700)
committerChong Zhang <chz@google.com>
Tue, 15 Mar 2016 19:50:03 +0000 (12:50 -0700)
- Make sure to tell the app to start drawing if it has been stopped, app
  could be stopped in visible state.

- When activity is started with NEW_TASK + CLEAR_TASK flags, skip
  resuming of the soon-to-be-removed activity, and run enter animation
  directly on the new activity. Resuming the old activity causes delay,
  and we also run extra enter-exit transition in short succession which
  cause glitches.

bug: 27391256
Change-Id: I390ef9fc9855d70a4a9642c06c87cbe548b8b466

services/core/java/com/android/server/am/ActivityStack.java
services/core/java/com/android/server/am/ActivityStarter.java
services/core/java/com/android/server/wm/WindowManagerService.java

index 39895ac..d15cd3d 100644 (file)
@@ -2182,10 +2182,11 @@ final class ActivityStack {
 
         ActivityStack lastStack = mStackSupervisor.getLastStack();
         if (next.app != null && next.app.thread != null) {
-            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next);
+            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next
+                    + " stopped=" + next.stopped + " visible=" + next.visible);
 
             // This activity is now becoming visible.
-            if (!next.visible) {
+            if (!next.visible || next.stopped) {
                 mWindowManager.setAppVisibility(next.appToken, true);
             }
 
index 83ad2a7..fa62c98 100644 (file)
@@ -1327,19 +1327,31 @@ class ActivityStarter {
                     intentActivity.setTaskToAffiliateWith(mSourceRecord.task);
                 }
                 mMovedHome = true;
-                final ActivityStack launchStack =
-                        getLaunchStack(mStartActivity, mLaunchFlags, mStartActivity.task,
-                                mOptions, true);
-                if (launchStack == null || launchStack == mTargetStack) {
-                    // We only want to move to the front, if we aren't going to launch on a
-                    // different stack. If we launch on a different stack, we will put the
-                    // task on top there.
-                    mTargetStack.moveTaskToFrontLocked(intentActivity.task, mNoAnimation,
-                            mOptions, mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
-                    mMovedToFront = true;
+
+                // If the launch flags carry both NEW_TASK and CLEAR_TASK, the task's activities
+                // will be cleared soon by ActivityStarter in setTaskFromIntentActivity().
+                // So no point resuming any of the activities here, it just wastes one extra
+                // resuming, plus enter AND exit transitions.
+                // Here we only want to bring the target stack forward. Transition will be applied
+                // to the new activity that's started after the old ones are gone.
+                final boolean willClearTask =
+                        (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
+                            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
+                if (!willClearTask) {
+                    final ActivityStack launchStack = getLaunchStack(
+                            mStartActivity, mLaunchFlags, mStartActivity.task, mOptions, true);
+                    if (launchStack == null || launchStack == mTargetStack) {
+                        // We only want to move to the front, if we aren't going to launch on a
+                        // different stack. If we launch on a different stack, we will put the
+                        // task on top there.
+                        mTargetStack.moveTaskToFrontLocked(
+                                intentActivity.task, mNoAnimation, mOptions,
+                                mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
+                        mMovedToFront = true;
+                    }
+                    mOptions = null;
                 }
                 updateTaskReturnToType(intentActivity.task, mLaunchFlags, focusStack);
-                mOptions = null;
             }
         }
         if (!mMovedToFront && mDoResume) {
index b20dd39..0f69bad 100644 (file)
@@ -4254,16 +4254,12 @@ public class WindowManagerService extends IWindowManager.Stub
                 wtoken.appDied = false;
                 wtoken.removeAllWindows();
             } else if (visible) {
-                if (DEBUG_ADD_REMOVE) Slog.v(
-                        TAG_WM, "No longer Stopped: " + wtoken);
-                wtoken.mAppStopped = false;
                 mOpeningApps.add(wtoken);
                 wtoken.startingMoved = false;
 
-                // If the token is currently hidden (should be the
-                // common case), then we need to set up to wait for
-                // its windows to be ready.
-                if (wtoken.hidden) {
+                // If the token is currently hidden (should be the common case), or has been
+                // stopped, then we need to set up to wait for its windows to be ready.
+                if (wtoken.hidden || wtoken.mAppStopped) {
                     wtoken.allDrawn = false;
                     wtoken.deferClearAllDrawn = false;
                     wtoken.waitingToShow = true;
@@ -4279,6 +4275,9 @@ public class WindowManagerService extends IWindowManager.Stub
                         wtoken.sendAppVisibilityToClients();
                     }
                 }
+                if (DEBUG_ADD_REMOVE) Slog.v(
+                        TAG_WM, "No longer Stopped: " + wtoken);
+                wtoken.mAppStopped = false;
             }
 
             // If we are preparing an app transition, then delay changing