diff options
| author | 2016-02-19 19:54:39 -0800 | |
|---|---|---|
| committer | 2016-02-23 10:50:34 -0500 | |
| commit | 8fa4522b24065d15535e17eed7cd5370b878a4c5 (patch) | |
| tree | 1f8ae9531a481ff54121b4894e99266d6921a819 | |
| parent | 5060bd891068b78bcbe72e1d8b61efac2da02c20 (diff) | |
Recents transition fixes
- Make sure to destroy the saved surfaces while we resize a task. The
usual destroying mechanism doesn't work here because we don't add the
windows to WMS.mResizingWindows.
- Make sure not to save the surface when a resize happened after the
window has been marked as gone (exiting). In this case, we resize the
task, so we add the window to mResizingWindows, but then when we don't
layout the window because win.isGoneForLayout() == true, so it would
save a surface that has the wrong size.
- Ensure the configuration of the top task when dismissing the docked
stack. First, this speeds up when the user navigates to it in the
fullscreen stack. Second, it fixes some other weirdness with saving
surfaces.
- Only exclude windows from layout when hidden is requested, so when
transitioning from hidden -> shown, the app immediately gets the
updated size when the task was resized when the window was hidden.
Bug: 27276087
Change-Id: I6faf016724136d984b259d184af58d41684f3425
5 files changed, 59 insertions, 29 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 49503d9e901d..6f2d843345f4 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -17768,36 +17768,42 @@ public final class ActivityManagerService extends ActivityManagerNative final long origId = Binder.clearCallingIdentity(); final ActivityStack stack = mStackSupervisor.getStack(fromStackId); if (stack != null) { - if (fromStackId == DOCKED_STACK_ID) { - - // We are moving all tasks from the docked stack to the fullscreen stack, which - // is dismissing the docked stack, so resize all other stacks to fullscreen here - // already so we don't end up with resize trashing. - for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) { - if (StackId.isResizeableByDockedStack(i)) { - ActivityStack otherStack = mStackSupervisor.getStack(i); - if (otherStack != null) { - mStackSupervisor.resizeStackLocked(i, - null, null, null, PRESERVE_WINDOWS, - true /* allowResizeInDockedMode */); + mWindowManager.deferSurfaceLayout(); + try { + if (fromStackId == DOCKED_STACK_ID) { + + // We are moving all tasks from the docked stack to the fullscreen stack, + // which is dismissing the docked stack, so resize all other stacks to + // fullscreen here already so we don't end up with resize trashing. + for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) { + if (StackId.isResizeableByDockedStack(i)) { + ActivityStack otherStack = mStackSupervisor.getStack(i); + if (otherStack != null) { + mStackSupervisor.resizeStackLocked(i, + null, null, null, PRESERVE_WINDOWS, + true /* allowResizeInDockedMode */); + } } } } - } - final ArrayList<TaskRecord> tasks = stack.getAllTasks(); - final int size = tasks.size(); - if (onTop) { - for (int i = 0; i < size; i++) { - mStackSupervisor.moveTaskToStackLocked(tasks.get(i).taskId, - FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP, !FORCE_FOCUS, - "moveTasksToFullscreenStack", ANIMATE); - } - } else { - for (int i = size - 1; i >= 0; i--) { - mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId, - FULLSCREEN_WORKSPACE_STACK_ID, 0); + final ArrayList<TaskRecord> tasks = stack.getAllTasks(); + final int size = tasks.size(); + if (onTop) { + for (int i = 0; i < size; i++) { + mStackSupervisor.moveTaskToStackLocked(tasks.get(i).taskId, + FULLSCREEN_WORKSPACE_STACK_ID, onTop, !FORCE_FOCUS, + "moveTasksToFullscreenStack", ANIMATE); + } + } else { + for (int i = size - 1; i >= 0; i--) { + mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId, + FULLSCREEN_WORKSPACE_STACK_ID, 0); + } } + } finally { + mWindowManager.continueSurfaceLayout(); } + } Binder.restoreCallingIdentity(origId); } diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index c143474ce0c8..648c2387d2b5 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -2396,6 +2396,8 @@ public final class ActivityStackSupervisor implements DisplayListener { stack.positionTask(task, position); // The task might have already been running and its visibility needs to be synchronized with // the visibility of the stack / windows. + stack.ensureActivityConfigurationLocked(task.topRunningActivityLocked(), 0, + !PRESERVE_WINDOWS); stack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); resumeFocusedStackTopActivityLocked(); } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 325005bb2206..807355202f90 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -247,7 +247,7 @@ class Task implements DimLayer.DimLayerUser { mStack.removeTask(this); } stack.positionTask(this, position, showForAllUsers()); - setBounds(bounds, config); + resizeLocked(bounds, config, false /* force */); } boolean removeAppToken(AppWindowToken wtoken) { @@ -272,7 +272,7 @@ class Task implements DimLayer.DimLayerUser { } /** Set the task bounds. Passing in null sets the bounds to fullscreen. */ - int setBounds(Rect bounds, Configuration config) { + private int setBounds(Rect bounds, Configuration config) { if (config == null) { config = Configuration.EMPTY; } @@ -598,13 +598,21 @@ class Task implements DimLayer.DimLayerUser { void resizeWindows() { final ArrayList<WindowState> resizingWindows = mService.mResizingWindows; for (int activityNdx = mAppTokens.size() - 1; activityNdx >= 0; --activityNdx) { - final ArrayList<WindowState> windows = mAppTokens.get(activityNdx).allAppWindows; + final AppWindowToken atoken = mAppTokens.get(activityNdx); + + // Some windows won't go through the resizing process, if they don't have a surface, so + // destroy all saved surfaces here. + atoken.destroySavedSurfaces(); + final ArrayList<WindowState> windows = atoken.allAppWindows; for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) { final WindowState win = windows.get(winNdx); if (win.mHasSurface && !resizingWindows.contains(win)) { if (DEBUG_RESIZE) Slog.d(TAG, "resizeWindows: Resizing " + win); resizingWindows.add(win); } + if (win.isGoneForLayoutLw()) { + win.mResizedWhileGone = true; + } } } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index b5444fce8d52..cc97e68b6876 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2758,6 +2758,9 @@ public class WindowManagerService extends IWindowManager.Stub winAnimator.mReportSurfaceResized = false; result |= WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED; } + if (!win.isGoneForLayoutLw()) { + win.mResizedWhileGone = false; + } outFrame.set(win.mCompatFrame); outOverscanInsets.set(win.mOverscanInsets); outContentInsets.set(win.mContentInsets); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index f30c8d3f751b..8ad8ea0e420a 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -448,6 +448,11 @@ final class WindowState implements WindowManagerPolicy.WindowState { final private Rect mTmpRect = new Rect(); + /** + * Whether the window was resized by us while it was gone for layout. + */ + boolean mResizedWhileGone = false; + WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, WindowState attachedWindow, int appOp, int seq, WindowManager.LayoutParams a, int viewVisibility, final DisplayContent displayContent) { @@ -1235,7 +1240,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { return mViewVisibility == View.GONE || !mRelayoutCalled || (atoken == null && mRootToken.hidden) - || (atoken != null && (atoken.hiddenRequested || atoken.hidden)) + || (atoken != null && atoken.hiddenRequested) || mAttachedHidden || (mAnimatingExit && !isAnimatingLw()) || mDestroying; @@ -1836,6 +1841,12 @@ final class WindowState implements WindowManagerPolicy.WindowState { return false; } + if (mResizedWhileGone) { + // Somebody resized our window while we were gone for layout, which means that the + // client got an old size, so we have an outdated surface here. + return false; + } + if (DEBUG_DISABLE_SAVING_SURFACES) { return false; } |