From ecbcadd27d1c00fddebbd2893251b05096252ee5 Mon Sep 17 00:00:00 2001 From: Wale Ogunwale Date: Sun, 21 Feb 2016 14:18:51 -0800 Subject: [PATCH] Fixed bug with stack bounds getting out of alignment with screen rotation Before updating the stack bounds due to rotation change, we need to make sure both the configuration and the current display info. the stack is using have been updated for the current rotation. Previously we were updating is after configuration change, but the rotation might have changed again by the time we get the configuraiton changed call and TaskSack.updateDisplayInfo not called yet. Bug: 26744649 Change-Id: Idfd30e78dc9c2fb521ff1957f043c3b1696a2a31 --- .../java/com/android/server/wm/TaskStack.java | 74 +++++++++++-------- .../server/wm/WindowManagerService.java | 9 +-- 2 files changed, 48 insertions(+), 35 deletions(-) diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index 2293e4d69e569..06e5ac5d440ed 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -95,7 +95,11 @@ public class TaskStack implements DimLayer.DimLayerUser, /** Detach this stack from its display when animation completes. */ boolean mDeferDetach; - private boolean mUpdateBoundsAfterRotation = false; + + // Display rotation as of the last time the display information was updated for this stack. + private int mLastUpdateDisplayInfoRotation = -1; + // Display rotation as of the last time the configuration was updated for this stack. + private int mLastConfigChangedRotation = -1; // Whether the stack and all its tasks is currently being drag-resized private boolean mDragResizing; @@ -301,39 +305,51 @@ public class TaskStack implements DimLayer.DimLayerUser, } void updateDisplayInfo(Rect bounds) { - mUpdateBoundsAfterRotation = false; - if (mDisplayContent != null) { - for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) { - mTasks.get(taskNdx).updateDisplayInfo(mDisplayContent); - } - if (bounds != null) { - setBounds(bounds); - } else if (mFullscreen) { - setBounds(null); - } else { - mUpdateBoundsAfterRotation = true; - mTmpRect2.set(mBounds); - final int newRotation = mDisplayContent.getDisplayInfo().rotation; - if (mRotation == newRotation) { - setBounds(mTmpRect2); - } + if (mDisplayContent == null) { + return; + } - // If the rotation changes, we'll handle it in updateBoundsAfterRotation - } + for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) { + mTasks.get(taskNdx).updateDisplayInfo(mDisplayContent); + } + if (bounds != null) { + setBounds(bounds); + return; + } else if (mFullscreen) { + setBounds(null); + return; + } + + mTmpRect2.set(mBounds); + final int newRotation = mDisplayContent.getDisplayInfo().rotation; + if (mRotation == newRotation) { + setBounds(mTmpRect2); + } else { + mLastUpdateDisplayInfoRotation = newRotation; + updateBoundsAfterRotation(); } } - /** - * Updates the bounds after rotating the screen. We can't handle it in - * {@link #updateDisplayInfo} because at that point the configuration might not be fully updated - * yet. - */ + void onConfigurationChanged() { + mLastConfigChangedRotation = getDisplayInfo().rotation; + updateBoundsAfterRotation(); + } + void updateBoundsAfterRotation() { - if (!mUpdateBoundsAfterRotation) { + if (mLastConfigChangedRotation != mLastUpdateDisplayInfoRotation) { + // We wait for the rotation values after configuration change and display info. update + // to be equal before updating the bounds due to rotation change otherwise things might + // get out of alignment... return; } - mUpdateBoundsAfterRotation = false; + final int newRotation = getDisplayInfo().rotation; + + if (mRotation == newRotation) { + // Nothing to do here if the rotation didn't change + return; + } + mDisplayContent.rotateBounds(mRotation, newRotation, mTmpRect2); if (mStackId == DOCKED_STACK_ID) { snapDockedStackAfterRotation(mTmpRect2); @@ -342,8 +358,8 @@ public class TaskStack implements DimLayer.DimLayerUser, // Post message to inform activity manager of the bounds change simulating // a one-way call. We do this to prevent a deadlock between window manager // lock and activity manager lock been held. - mService.mH.sendMessage(mService.mH.obtainMessage( - RESIZE_STACK, mStackId, 0 /*allowResizeInDockedMode*/, mTmpRect2)); + mService.mH.obtainMessage( + RESIZE_STACK, mStackId, 0 /*allowResizeInDockedMode*/, mTmpRect2).sendToTarget(); } /** @@ -1109,4 +1125,4 @@ public class TaskStack implements DimLayer.DimLayerUser, public void getFullScreenBounds(Rect bounds) { getDisplayContent().getContentRect(bounds); } -} \ No newline at end of file +} diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index b5444fce8d520..142715e89c6ca 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -3549,23 +3549,20 @@ public class WindowManagerService extends IWindowManager.Stub } synchronized(mWindowMap) { - final boolean orientationChanged = mCurConfiguration.orientation != config.orientation; mCurConfiguration = new Configuration(config); if (mWaitingForConfig) { mWaitingForConfig = false; mLastFinishedFreezeSource = "new-config"; } - if (orientationChanged) { - updateTaskStackBoundsAfterRotation(); - } + onConfigurationChanged(); mWindowPlacerLocked.performSurfacePlacement(); } } - private void updateTaskStackBoundsAfterRotation() { + private void onConfigurationChanged() { for (int stackNdx = mStackIdToStack.size() - 1; stackNdx >= 0; stackNdx--) { final TaskStack stack = mStackIdToStack.valueAt(stackNdx); - stack.updateBoundsAfterRotation(); + stack.onConfigurationChanged(); } }