Merge "Defer removal of relaunching activity window due to config change."

This commit is contained in:
Filip Gruszczynski
2015-09-04 16:18:42 +00:00
committed by Android (Google) Code Review
5 changed files with 46 additions and 1 deletions

View File

@@ -3088,6 +3088,12 @@ public final class ActivityStackSupervisor implements DisplayListener {
ensureActivitiesVisibleLocked(r, 0);
if (!kept) {
resumeTopActivitiesLocked(stack, null, null);
// We are about to relaunch the activity because its configuration changed due
// to size change. The activity will first remove the old window and then add a
// new one. This call will tell window manager about this, so it can preserve
// the old window until the new one is drawn. This prevents having a gap between
// the removal and addition, in which no window is visible.
mWindowManager.setReplacingWindow(r.appToken);
}
}
}

View File

@@ -112,6 +112,11 @@ class AppWindowToken extends WindowToken {
boolean mLaunchTaskBehind;
boolean mEnteringAnimation;
// This application will have its window replaced due to relaunch. This allows window manager
// to differentiate between simple removal of a window and replacement. In the latter case it
// will preserve the old window until the new one is drawn.
boolean mReplacingWindow;
AppWindowToken(WindowManagerService _service, IApplicationToken _token,
boolean _voiceInteraction) {
super(_service, _token.asBinder(),

View File

@@ -2065,6 +2065,15 @@ public class WindowManagerService extends IWindowManager.Stub
// If the display is frozen, just remove immediately, since the
// animation wouldn't be seen.
if (win.mHasSurface && okToDisplay()) {
final AppWindowToken appToken = win.mAppToken;
if (appToken != null && appToken.mReplacingWindow) {
// This window is going to be replaced. We need to kepp it around until the new one
// gets added, then we will get rid of this one.
if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Preserving " + win + " until the new one is "
+ "added");
win.mExiting = true;
return;
}
// If we are not currently running the exit animation, we
// need to see about starting one.
wasVisible = win.isWinVisibleLw();
@@ -2084,7 +2093,6 @@ public class WindowManagerService extends IWindowManager.Stub
mAccessibilityController.onWindowTransitionLocked(win, transit);
}
}
final AppWindowToken appToken = win.mAppToken;
final boolean isAnimating = win.mWinAnimator.isAnimating();
// The starting window is the last window in this app token and it isn't animating.
// Allow it to be removed now as there is no additional window or animation that will
@@ -9715,6 +9723,17 @@ public class WindowManagerService extends IWindowManager.Stub
return mWindowMap;
}
public void setReplacingWindow(IBinder token) {
synchronized (mWindowMap) {
AppWindowToken appWindowToken = findAppWindowToken(token);
if (appWindowToken == null) {
Slog.w(TAG, "Attempted to set replacing window on non-existing app token " + token);
return;
}
appWindowToken.mReplacingWindow = true;
}
}
private final class LocalService extends WindowManagerInternal {
@Override
public void requestTraversalFromDisplayManager() {

View File

@@ -1270,6 +1270,19 @@ final class WindowState implements WindowManagerPolicy.WindowState {
}
}
void maybeRemoveReplacedWindow() {
AppWindowToken token = mAppToken;
if (token != null && token.mReplacingWindow) {
token.mReplacingWindow = false;
for (int i = token.allAppWindows.size() - 1; i >= 0; i--) {
WindowState win = token.allAppWindows.get(i);
if (win.mExiting) {
mService.removeWindowInnerLocked(win);
}
}
}
}
private class DeathRecipient implements IBinder.DeathRecipient {
@Override
public void binderDied() {

View File

@@ -1765,6 +1765,8 @@ class WindowStateAnimator {
mWin.mAppToken.updateReportedVisibilityLocked();
}
mWin.maybeRemoveReplacedWindow();
return true;
}