summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chong Zhang <chz@google.com> 2016-03-02 17:01:14 -0800
committer Chong Zhang <chz@google.com> 2016-03-08 11:30:15 -0800
commitd78ddb409a8499c391322dd1e2b2a97446f9603d (patch)
tree5df7f5b9f8919b6e4f48e863b0463a0fd2c676b6
parent4e7ad35b2f1e1a9bdcabfb56306dd162909932a8 (diff)
Some fixes for black screen when pressing home button
Pressing home button sometimes involves a rotation (eg. when app is running in landscape mode but launch is fixed portrait mode). This will trigger a screen freeze, which clears the transition. We still need to add the opening app to the opening list even if transition is unset, otherwise it doesn't wait for app to draw first frame. Also during rotation, app, launcher and wallpaper all get relaunched. The transition can't start until the first frame on the new launcher window comes back. We can't start it based on the draw state of the old window, because the old window could get removed and readded shortly after we start the transition, and it shows up as a black frame. bug: 27391256 bug: 27295820 Change-Id: I346685076657eef209d0fab68f272e218b55e011
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java2
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityRecord.java7
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java9
-rw-r--r--services/core/java/com/android/server/wm/AppWindowToken.java36
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java61
-rw-r--r--services/core/java/com/android/server/wm/WindowSurfacePlacer.java7
6 files changed, 75 insertions, 47 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 8df5b2c348f7..7e2e63e7a980 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -6650,7 +6650,7 @@ public final class ActivityManagerService extends ActivityManagerNative
synchronized(this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
- ActivityRecord.activityResumedLocked(token);
+ stack.activityResumedLocked(token);
}
}
Binder.restoreCallingIdentity(origId);
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index e430dadc0ac7..fa59e6ab5957 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -1275,13 +1275,6 @@ final class ActivityRecord {
}
}
- static void activityResumedLocked(IBinder token) {
- final ActivityRecord r = ActivityRecord.forTokenLocked(token);
- if (DEBUG_SAVED_STATE) Slog.i(TAG_STATES, "Resumed activity; dropping state of: " + r);
- r.icicle = null;
- r.haveState = false;
- }
-
static int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (r == null) {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index e50722ac04d8..39895ac54e7f 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1088,6 +1088,13 @@ final class ActivityStack {
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}
+ final void activityResumedLocked(IBinder token) {
+ final ActivityRecord r = ActivityRecord.forTokenLocked(token);
+ if (DEBUG_SAVED_STATE) Slog.i(TAG_STATES, "Resumed activity; dropping state of: " + r);
+ r.icicle = null;
+ r.haveState = false;
+ }
+
final void activityStoppedLocked(ActivityRecord r, Bundle icicle,
PersistableBundle persistentState, CharSequence description) {
if (r.state != ActivityState.STOPPING) {
@@ -4436,10 +4443,10 @@ final class ActivityStack {
"Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + r
+ " callers=" + Debug.getCallers(6));
r.forceNewConfig = false;
+ mStackSupervisor.activityRelaunchingLocked(r);
r.app.thread.scheduleRelaunchActivity(r.appToken, results, newIntents, changes,
!andResume, new Configuration(mService.mConfiguration),
new Configuration(r.task.mOverrideConfig), preserveWindow);
- mStackSupervisor.activityRelaunchingLocked(r);
// Note: don't need to call pauseIfSleepingLocked() here, because
// the caller will only pass in 'andResume' if this activity is
// currently resumed, which implies we aren't sleeping.
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 2731f42991a5..9795c93e8e02 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -129,6 +129,7 @@ class AppWindowToken extends WindowToken {
boolean mAlwaysFocusable;
boolean mAppStopped;
+ int mPendingRelaunchCount;
ArrayDeque<Rect> mFrozenBounds = new ArrayDeque<>();
@@ -531,6 +532,26 @@ class AppWindowToken extends WindowToken {
}
}
+ boolean isRelaunching() {
+ return mPendingRelaunchCount > 0;
+ }
+
+ void startRelaunching() {
+ if (canFreezeBounds()) {
+ freezeBounds();
+ }
+ mPendingRelaunchCount++;
+ }
+
+ void finishRelaunching() {
+ if (canFreezeBounds()) {
+ unfreezeBounds();
+ }
+ if (mPendingRelaunchCount > 0) {
+ mPendingRelaunchCount--;
+ }
+ }
+
void addWindow(WindowState w) {
for (int i = allAppWindows.size() - 1; i >= 0; i--) {
WindowState candidate = allAppWindows.get(i);
@@ -579,20 +600,26 @@ class AppWindowToken extends WindowToken {
}
}
+ private boolean canFreezeBounds() {
+ // For freeform windows, we can't freeze the bounds at the moment because this would make
+ // the resizing unresponsive.
+ return mTask != null && !mTask.inFreeformWorkspace();
+ }
+
/**
* Freezes the task bounds. The size of this task reported the app will be fixed to the bounds
* freezed by {@link Task#prepareFreezingBounds} until {@link #unfreezeBounds} gets called, even
* if they change in the meantime. If the bounds are already frozen, the bounds will be frozen
* with a queue.
*/
- void freezeBounds() {
+ private void freezeBounds() {
mFrozenBounds.offer(new Rect(mTask.mPreparedFrozenBounds));
}
/**
* Unfreezes the previously frozen bounds. See {@link #freezeBounds}.
*/
- void unfreezeBounds() {
+ private void unfreezeBounds() {
mFrozenBounds.remove();
for (int i = windows.size() - 1; i >= 0; i--) {
final WindowState win = windows.get(i);
@@ -658,7 +685,10 @@ class AppWindowToken extends WindowToken {
pw.print(" startingMoved="); pw.println(startingMoved);
}
if (!mFrozenBounds.isEmpty()) {
- pw.print(prefix); pw.print("mFrozenBounds="); pw.print(mFrozenBounds);
+ pw.print(prefix); pw.print("mFrozenBounds="); pw.println(mFrozenBounds);
+ }
+ if (mPendingRelaunchCount != 0) {
+ pw.print(prefix); pw.print("mPendingRelaunchCount="); pw.println(mPendingRelaunchCount);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index b64aaa89475a..4e3dd9c0b7fe 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2340,6 +2340,7 @@ public class WindowManagerService extends IWindowManager.Stub
mTokenMap.remove(token.token);
} else if (atoken != null) {
atoken.firstWindowDrawn = false;
+ atoken.allDrawn = false;
}
}
@@ -4251,6 +4252,28 @@ public class WindowManagerService extends IWindowManager.Stub
TAG_WM, "No longer Stopped: " + wtoken);
wtoken.mAppStopped = false;
wtoken.setWindowsExiting(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) {
+ wtoken.allDrawn = false;
+ wtoken.deferClearAllDrawn = false;
+ wtoken.waitingToShow = true;
+
+ if (wtoken.clientHidden) {
+ // In the case where we are making an app visible
+ // but holding off for a transition, we still need
+ // to tell the client to make its windows visible so
+ // they get drawn. Otherwise, we will wait on
+ // performing the transition until all windows have
+ // been drawn, they never will be, and we are sad.
+ wtoken.clientHidden = false;
+ wtoken.sendAppVisibilityToClients();
+ }
+ }
}
// If we are preparing an app transition, then delay changing
@@ -4268,29 +4291,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
wtoken.inPendingTransaction = true;
if (visible) {
- mOpeningApps.add(wtoken);
- wtoken.startingMoved = false;
wtoken.mEnteringAnimation = true;
-
- // 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) {
- wtoken.allDrawn = false;
- wtoken.deferClearAllDrawn = false;
- wtoken.waitingToShow = true;
-
- if (wtoken.clientHidden) {
- // In the case where we are making an app visible
- // but holding off for a transition, we still need
- // to tell the client to make its windows visible so
- // they get drawn. Otherwise, we will wait on
- // performing the transition until all windows have
- // been drawn, they never will be, and we are sad.
- wtoken.clientHidden = false;
- wtoken.sendAppVisibilityToClients();
- }
- }
} else {
wtoken.setWindowsExiting(true);
mClosingApps.add(wtoken);
@@ -9636,8 +9637,8 @@ public class WindowManagerService extends IWindowManager.Stub
public void notifyAppRelaunching(IBinder token) {
synchronized (mWindowMap) {
AppWindowToken appWindow = findAppWindowToken(token);
- if (canFreezeBounds(appWindow)) {
- appWindow.freezeBounds();
+ if (appWindow != null) {
+ appWindow.startRelaunching();
}
}
}
@@ -9645,20 +9646,12 @@ public class WindowManagerService extends IWindowManager.Stub
public void notifyAppRelaunchingFinished(IBinder token) {
synchronized (mWindowMap) {
AppWindowToken appWindow = findAppWindowToken(token);
- if (canFreezeBounds(appWindow)) {
- appWindow.unfreezeBounds();
+ if (appWindow != null) {
+ appWindow.finishRelaunching();
}
}
}
- private boolean canFreezeBounds(AppWindowToken appWindow) {
-
- // For freeform windows, we can't freeze the bounds at the moment because this would make
- // the resizing unresponsive.
- return appWindow != null && appWindow.mTask != null
- && !appWindow.mTask.inFreeformWorkspace();
- }
-
@Override
public int getDockedDividerInsetsLw() {
return getDefaultDisplayContentLocked().getDockedDividerController().getContentInsets();
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index e3955fe00f39..ba4e1f10887f 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -1278,7 +1278,12 @@ class WindowSurfacePlacer {
"Check opening app=" + wtoken + ": allDrawn="
+ wtoken.allDrawn + " startingDisplayed="
+ wtoken.startingDisplayed + " startingMoved="
- + wtoken.startingMoved);
+ + wtoken.startingMoved + " isRelaunching()="
+ + wtoken.isRelaunching());
+
+ if (wtoken.isRelaunching()) {
+ return false;
+ }
final boolean drawnBeforeRestoring = wtoken.allDrawn;
wtoken.restoreSavedSurfaces();