From a57326c97fb83b568da1935c118b2675a6cc1e63 Mon Sep 17 00:00:00 2001 From: Jerry Chang Date: Thu, 17 Feb 2022 17:02:49 +0000 Subject: [PATCH] Fix extra offset of the split layout Use parent based coordinate instead of screen based coordinate when indicating split surfaces' position so they won't be offset unexpectedly when its parent is not at (0, 0). Fix: 210696145 Test: check split UI when enabled "render apps below cutout area" Change-Id: I65399f5ef2975e7ef376d161c41de2cfb7ed29dc --- .../wm/shell/common/split/SplitLayout.java | 40 +++++++++++++++---- .../shell/splitscreen/StageCoordinator.java | 3 +- .../wm/shell/splitscreen/SplitTestUtils.java | 2 + 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java index f7c92fed55225..8a482fbfa1c40 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java @@ -144,21 +144,42 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange return Math.max(dividerInset, radius); } - /** Gets bounds of the primary split. */ + /** Gets bounds of the primary split with screen based coordinate. */ public Rect getBounds1() { return new Rect(mBounds1); } - /** Gets bounds of the secondary split. */ + /** Gets bounds of the primary split with parent based coordinate. */ + public Rect getRefBounds1() { + Rect outBounds = getBounds1(); + outBounds.offset(-mRootBounds.left, -mRootBounds.top); + return outBounds; + } + + /** Gets bounds of the secondary split with screen based coordinate. */ public Rect getBounds2() { return new Rect(mBounds2); } - /** Gets bounds of divider window. */ + /** Gets bounds of the secondary split with parent based coordinate. */ + public Rect getRefBounds2() { + final Rect outBounds = getBounds2(); + outBounds.offset(-mRootBounds.left, -mRootBounds.top); + return outBounds; + } + + /** Gets bounds of divider window with screen based coordinate. */ public Rect getDividerBounds() { return new Rect(mDividerBounds); } + /** Gets bounds of divider window with parent based coordinate. */ + public Rect getRefDividerBounds() { + final Rect outBounds = getDividerBounds(); + outBounds.offset(-mRootBounds.left, -mRootBounds.top); + return outBounds; + } + /** Returns leash of the current divider bar. */ @Nullable public SurfaceControl getDividerLeash() { @@ -452,14 +473,17 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange SurfaceControl leash2, SurfaceControl dimLayer1, SurfaceControl dimLayer2) { final SurfaceControl dividerLeash = getDividerLeash(); if (dividerLeash != null) { - t.setPosition(dividerLeash, mDividerBounds.left, mDividerBounds.top); + mTempRect.set(getRefDividerBounds()); + t.setPosition(dividerLeash, mTempRect.left, mTempRect.top); // Resets layer of divider bar to make sure it is always on top. t.setLayer(dividerLeash, SPLIT_DIVIDER_LAYER); } - t.setPosition(leash1, mBounds1.left, mBounds1.top) - .setWindowCrop(leash1, mBounds1.width(), mBounds1.height()); - t.setPosition(leash2, mBounds2.left, mBounds2.top) - .setWindowCrop(leash2, mBounds2.width(), mBounds2.height()); + mTempRect.set(getRefBounds1()); + t.setPosition(leash1, mTempRect.left, mTempRect.top) + .setWindowCrop(leash1, mTempRect.width(), mTempRect.height()); + mTempRect.set(getRefBounds2()); + t.setPosition(leash2, mTempRect.left, mTempRect.top) + .setWindowCrop(leash2, mTempRect.width(), mTempRect.height()); if (mImePositionProcessor.adjustSurfaceLayoutForIme( t, dividerLeash, leash1, leash2, dimLayer1, dimLayer2)) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index 81dacdb753a74..76641f0e6c21a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -979,7 +979,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, t.setAlpha(dividerLeash, 1); t.setLayer(dividerLeash, SPLIT_DIVIDER_LAYER); t.setPosition(dividerLeash, - mSplitLayout.getDividerBounds().left, mSplitLayout.getDividerBounds().top); + mSplitLayout.getRefDividerBounds().left, + mSplitLayout.getRefDividerBounds().top); } else { t.hide(dividerLeash); } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java index dda1a8295e515..85527c81ad9ec 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java @@ -18,6 +18,7 @@ package com.android.wm.shell.splitscreen; import static android.view.Display.DEFAULT_DISPLAY; import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER; + import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -51,6 +52,7 @@ public class SplitTestUtils { final SurfaceControl leash = createMockSurface(); SplitLayout out = mock(SplitLayout.class); doReturn(dividerBounds).when(out).getDividerBounds(); + doReturn(dividerBounds).when(out).getRefDividerBounds(); doReturn(leash).when(out).getDividerLeash(); return out; }