diff options
8 files changed, 96 insertions, 42 deletions
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index 4a13136fa8d9..81da6af20eb2 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -2033,7 +2033,7 @@ public class Am extends BaseCommand { } try { - mAm.resizeStack(stackId, bounds); + mAm.resizeStack(stackId, bounds, false); Thread.sleep(delayMs); } catch (RemoteException e) { showError("Error: resizing stack " + e); @@ -2127,8 +2127,8 @@ public class Am extends BaseCommand { } // Resize stacks - mAm.resizeStack(currentStackInfo.stackId, currentStackBounds); - mAm.resizeStack(newStackInfo.stackId, newStackBounds); + mAm.resizeStack(currentStackInfo.stackId, currentStackBounds, false); + mAm.resizeStack(newStackInfo.stackId, newStackBounds, false); } catch (RemoteException e) { } } diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index faa3a43f6c2e..b97f94735b9f 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -757,9 +757,10 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM case RESIZE_STACK_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); - int stackId = data.readInt(); + final int stackId = data.readInt(); Rect r = Rect.CREATOR.createFromParcel(data); - resizeStack(stackId, r); + final boolean allowResizeInDockedMode = data.readInt() == 1; + resizeStack(stackId, r, allowResizeInDockedMode); reply.writeNoException(); return true; } @@ -3554,13 +3555,15 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); } @Override - public void resizeStack(int stackId, Rect r) throws RemoteException + public void resizeStack(int stackId, Rect r, boolean allowResizeInDockedMode) + throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeInt(stackId); r.writeToParcel(data, 0); + data.writeInt(allowResizeInDockedMode ? 1 : 0); mRemote.transact(RESIZE_STACK_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index e23620d9b0ea..c26a44cae57c 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -143,7 +143,7 @@ public interface IActivityManager extends IInterface { public void moveTaskToStack(int taskId, int stackId, boolean toTop) throws RemoteException; public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop) throws RemoteException; - public void resizeStack(int stackId, Rect bounds) throws RemoteException; + public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode) throws RemoteException; public void positionTaskInStack(int taskId, int stackId, int position) throws RemoteException; public List<StackInfo> getAllStackInfos() throws RemoteException; public StackInfo getStackInfo(int stackId) throws RemoteException; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 759a4f380ba4..e7601c2ec93e 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -9161,13 +9161,14 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override - public void resizeStack(int stackId, Rect bounds) { + public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode) { enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, "resizeStack()"); long ident = Binder.clearCallingIdentity(); try { synchronized (this) { - mStackSupervisor.resizeStackLocked(stackId, bounds, !PRESERVE_WINDOWS); + mStackSupervisor.resizeStackLocked( + stackId, bounds, !PRESERVE_WINDOWS, allowResizeInDockedMode); } } finally { Binder.restoreCallingIdentity(ident); diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 8bec7f7cad97..4a58b1fa6fe2 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -2972,13 +2972,21 @@ public final class ActivityStackSupervisor implements DisplayListener { } } - void resizeStackLocked(int stackId, Rect bounds, boolean preserveWindows) { + void resizeStackLocked(int stackId, Rect bounds, boolean preserveWindows, + boolean allowResizeInDockedMode) { final ActivityStack stack = getStack(stackId); if (stack == null) { Slog.w(TAG, "resizeStack: stackId " + stackId + " not found."); return; } + if (!allowResizeInDockedMode + && stackId != DOCKED_STACK_ID && getStack(DOCKED_STACK_ID) != null) { + // If the docked stack exist we don't allow resizes of stacks not caused by the docked + // stack size changing so things don't get out of sync. + return; + } + Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeStack_" + stackId); ActivityRecord r = stack.topRunningActivityLocked(); @@ -3013,7 +3021,7 @@ public final class ActivityStackSupervisor implements DisplayListener { // docked stack tasks to the fullscreen stack. for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) { if (i != DOCKED_STACK_ID && getStack(i) != null) { - resizeStackLocked(i, null, preserveWindows); + resizeStackLocked(i, null, preserveWindows, true); } } @@ -3028,23 +3036,15 @@ public final class ActivityStackSupervisor implements DisplayListener { } else { // Docked stacks occupy a dedicated region on screen so the size of all other // static stacks need to be adjusted so they don't overlap with the docked stack. - final int leftChange = stack.mBounds.left - bounds.left; - final int rightChange = stack.mBounds.right - bounds.right; - final int topChange = stack.mBounds.top - bounds.top; - final int bottomChange = stack.mBounds.bottom - bounds.bottom; + // We get the bounds to use from window manager which has been adjusted for any + // screen controls and is also the same for all stacks. + mWindowManager.getStackDockedModeBounds(HOME_STACK_ID, tempRect); for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) { if (i != DOCKED_STACK_ID) { ActivityStack otherStack = getStack(i); if (otherStack != null) { - tempRect.set(otherStack.mBounds); - // We adjust the opposing sides of the other stacks to - // the side in the dock stack that changed. - tempRect.left -= rightChange; - tempRect.right -= leftChange; - tempRect.top -= bottomChange; - tempRect.bottom -= topChange; - resizeStackLocked(i, tempRect, PRESERVE_WINDOWS); + resizeStackLocked(i, tempRect, PRESERVE_WINDOWS, true); } } } diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java index 3c2864853fab..2d8712375757 100644 --- a/services/core/java/com/android/server/wm/DockedStackDividerController.java +++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java @@ -206,7 +206,8 @@ public class DockedStackDividerController implements View.OnTouchListener, DimLa } if (distance <= mSideMargin) { try { - mDisplayContent.mService.mActivityManager.resizeStack(mTaskStack.mStackId, null); + mDisplayContent.mService.mActivityManager.resizeStack( + mTaskStack.mStackId, null, true); } catch (RemoteException e) { // This can't happen because we are in the same process. } @@ -364,7 +365,7 @@ public class DockedStackDividerController implements View.OnTouchListener, DimLa } mLastResizeRect.set(mTmpRect); try { - mDisplayContent.mService.mActivityManager.resizeStack(DOCKED_STACK_ID, mTmpRect); + mDisplayContent.mService.mActivityManager.resizeStack(DOCKED_STACK_ID, mTmpRect, true); } catch (RemoteException e) { // This can't happen because we are in the same process. } diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index ca358b15bbb8..b409cea249c2 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -238,8 +238,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, UNUSED, mBounds)); + mService.mH.sendMessage(mService.mH.obtainMessage( + RESIZE_STACK, mStackId, 0 /*allowResizeInDockedMode*/, mBounds)); } } } @@ -399,8 +399,11 @@ public class TaskStack implements DimLayer.DimLayerUser { if (dockedStack != null) { dockedStack.getRawBounds(mTmpRect2); } - getInitialDockedStackBounds(mTmpRect, bounds, mStackId, mTmpRect2, - mDisplayContent.mDividerControllerLocked.getWidthAdjustment()); + final boolean dockedOnTopOrLeft = WindowManagerService.sDockedStackCreateMode + == DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; + getStackDockedModeBounds(mTmpRect, bounds, mStackId, mTmpRect2, + mDisplayContent.mDividerControllerLocked.getWidthAdjustment(), + dockedOnTopOrLeft); } updateDisplayInfo(bounds); @@ -413,28 +416,60 @@ public class TaskStack implements DimLayer.DimLayerUser { } } + void getStackDockedModeBoundsLocked(Rect outBounds) { + if (mStackId == DOCKED_STACK_ID + || mStackId > LAST_STATIC_STACK_ID + || mDisplayContent == null) { + outBounds.set(mBounds); + return; + } + + final TaskStack dockedStack = mDisplayContent.getDockedStackLocked(); + if (dockedStack == null) { + // Not sure why you are calling this method when there is no docked stack... + throw new IllegalStateException( + "Calling getStackDockedModeBoundsLocked() when there is no docked stack."); + } + + @DockSide + final int dockedSide = dockedStack.getDockSide(); + if (dockedSide == DOCKED_INVALID) { + // Not sure how you got here...Only thing we can do is return current bounds. + Slog.e(TAG, "Failed to get valid docked side for docked stack=" + dockedStack); + outBounds.set(mBounds); + return; + } + + mDisplayContent.getLogicalDisplayRect(mTmpRect); + dockedStack.getRawBounds(mTmpRect2); + final boolean dockedOnTopOrLeft = dockedSide == DOCKED_TOP || dockedSide == DOCKED_LEFT; + getStackDockedModeBounds(mTmpRect, outBounds, mStackId, mTmpRect2, + mDisplayContent.mDividerControllerLocked.getWidthAdjustment(), dockedOnTopOrLeft); + + } + /** - * Outputs the initial bounds a stack should be given the presence of a docked stack on the - * display. + * Outputs the bounds a stack should be given the presence of a docked stack on the display. * @param displayRect The bounds of the display the docked stack is on. * @param outBounds Output bounds that should be used for the stack. * @param stackId Id of stack we are calculating the bounds for. * @param dockedBounds Bounds of the docked stack. - * @param adjustment + * @param adjustment Additional adjustment to make to the output bounds close to the side of the + * dock. + * @param dockOntopOrLeft If the docked stack is on the top or left side of the screen. */ - private static void getInitialDockedStackBounds( - Rect displayRect, Rect outBounds, int stackId, Rect dockedBounds, int adjustment) { + private static void getStackDockedModeBounds( + Rect displayRect, Rect outBounds, int stackId, Rect dockedBounds, int adjustment, + boolean dockOntopOrLeft) { final boolean dockedStack = stackId == DOCKED_STACK_ID; final boolean splitHorizontally = displayRect.width() > displayRect.height(); - final boolean topOrLeftCreateMode = - WindowManagerService.sDockedStackCreateMode == DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; outBounds.set(displayRect); if (dockedStack) { // The initial bounds of the docked stack when it is created half the screen space and // its bounds can be adjusted after that. The bounds of all other stacks are adjusted // to occupy whatever screen space the docked stack isn't occupying. - if (topOrLeftCreateMode) { + if (dockOntopOrLeft) { if (splitHorizontally) { outBounds.right = displayRect.centerX() - adjustment; } else { @@ -451,7 +486,7 @@ public class TaskStack implements DimLayer.DimLayerUser { } // Other stacks occupy whatever space is left by the docked stack. - if (!topOrLeftCreateMode) { + if (!dockOntopOrLeft) { if (splitHorizontally) { outBounds.right = dockedBounds.left - adjustment; } else { @@ -477,8 +512,10 @@ public class TaskStack implements DimLayer.DimLayerUser { final Rect bounds = new Rect(); mDisplayContent.getLogicalDisplayRect(bounds); if (!fullscreen) { - getInitialDockedStackBounds(bounds, bounds, FULLSCREEN_WORKSPACE_STACK_ID, dockedBounds, - mDisplayContent.mDividerControllerLocked.getWidth()); + final boolean dockedOnTopOrLeft = WindowManagerService.sDockedStackCreateMode + == DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; + getStackDockedModeBounds(bounds, bounds, FULLSCREEN_WORKSPACE_STACK_ID, dockedBounds, + mDisplayContent.mDividerControllerLocked.getWidth(), dockedOnTopOrLeft); } final int count = mService.mStackIdToStack.size(); @@ -489,7 +526,8 @@ public class TaskStack implements DimLayer.DimLayerUser { && otherStackId >= FIRST_STATIC_STACK_ID && otherStackId <= LAST_STATIC_STACK_ID) { mService.mH.sendMessage( - mService.mH.obtainMessage(RESIZE_STACK, otherStackId, UNUSED, bounds)); + mService.mH.obtainMessage(RESIZE_STACK, otherStackId, + 1 /*allowResizeInDockedMode*/, bounds)); } } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 0170bb965540..264af41a9de4 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -4617,6 +4617,17 @@ public class WindowManagerService extends IWindowManager.Stub } } + public void getStackDockedModeBounds(int stackId, Rect bounds) { + synchronized (mWindowMap) { + final TaskStack stack = mStackIdToStack.get(stackId); + if (stack != null) { + stack.getStackDockedModeBoundsLocked(bounds); + return; + } + bounds.setEmpty(); + } + } + public void getStackBounds(int stackId, Rect bounds) { synchronized (mWindowMap) { final TaskStack stack = mStackIdToStack.get(stackId); @@ -7777,7 +7788,7 @@ public class WindowManagerService extends IWindowManager.Stub break; case RESIZE_STACK: { try { - mActivityManager.resizeStack(msg.arg1, (Rect) msg.obj); + mActivityManager.resizeStack(msg.arg1, (Rect) msg.obj, msg.arg2 == 1); } catch (RemoteException e) { // This will not happen since we are in the same process. } |