From a9f9b37823a5f046078594c96c262c127afdee1c Mon Sep 17 00:00:00 2001 From: Wale Ogunwale Date: Thu, 4 Feb 2016 18:04:39 -0800 Subject: [PATCH] Reset docked divider to the middle of the screen if sys-ui dies It is possible for the docked divider to be in an unstable location when sys-ui dies. E.g sys-ui animating the divider from behind the nav bar. When this occurs we reset the divider to the middle of the screen so that the system remains in a useable state. Otherwise, the docked stack can be fullscreen always preventing the user from going into any other application. Bug: 26965731 Change-Id: Icd254fffe69da4ee3f2efb4ff1d210a778703f64 --- .../java/com/android/server/wm/TaskStack.java | 19 ++++++++++++++++--- .../com/android/server/wm/WindowState.java | 9 +++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index 5b939799cec34..40ca1c5a688cb 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -585,7 +585,8 @@ public class TaskStack implements DimLayer.DimLayerUser, } void getStackDockedModeBoundsLocked(Rect outBounds, boolean ignoreVisibility) { - if (!StackId.isResizeableByDockedStack(mStackId) || mDisplayContent == null) { + if ((mStackId != DOCKED_STACK_ID && !StackId.isResizeableByDockedStack(mStackId)) + || mDisplayContent == null) { outBounds.set(mBounds); return; } @@ -614,8 +615,7 @@ public class TaskStack implements DimLayer.DimLayerUser, mDisplayContent.getLogicalDisplayRect(mTmpRect); dockedStack.getRawBounds(mTmpRect2); - final boolean dockedOnTopOrLeft = dockedSide == DOCKED_TOP - || dockedSide == DOCKED_LEFT; + final boolean dockedOnTopOrLeft = dockedSide == DOCKED_TOP || dockedSide == DOCKED_LEFT; getStackDockedModeBounds(mTmpRect, outBounds, mStackId, mTmpRect2, mDisplayContent.mDividerControllerLocked.getContentWidth(), dockedOnTopOrLeft); @@ -720,6 +720,19 @@ public class TaskStack implements DimLayer.DimLayerUser, } } + void resetDockedStackToMiddle() { + if (mStackId != DOCKED_STACK_ID) { + throw new IllegalStateException("Not a docked stack=" + this); + } + + mService.mDockedStackCreateBounds = null; + + final Rect bounds = new Rect(); + getStackDockedModeBoundsLocked(bounds, true /*ignoreVisibility*/); + mService.mH.obtainMessage(RESIZE_STACK, DOCKED_STACK_ID, + 1 /*allowResizeInDockedMode*/, bounds).sendToTarget(); + } + void detachDisplay() { EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 1f7b810b9f931..2f916d918974f 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -57,6 +57,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import static android.app.ActivityManager.StackId; +import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; import static android.app.ActivityManager.StackId.INVALID_STACK_ID; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT; @@ -1608,6 +1609,14 @@ final class WindowState implements WindowManagerPolicy.WindowState { win.mAppToken.appDied = true; } mService.removeWindowLocked(win); + if (win.mAttrs.type == TYPE_DOCK_DIVIDER) { + // The owner of the docked divider died :( We reset the docked stack, + // just in case they have the divider at an unstable position. + final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID); + if (stack != null) { + stack.resetDockedStackToMiddle(); + } + } } else if (mHasSurface) { Slog.e(TAG, "!!! LEAK !!! Window removed but surface still valid."); mService.removeWindowLocked(WindowState.this);