From 70b7b1e2d856039582e729eb00c72e8d0baa4769 Mon Sep 17 00:00:00 2001 From: Tony Huang Date: Tue, 12 Oct 2021 16:45:03 +0800 Subject: [PATCH] Fix divider rounded corner on specific devices On large rounded corner devices, Rounded corners around divider cannot display right corner path because it need more space to draw corners and divider bounds is fixed. Fix this by enlarging the divider window bounds. However, if we only enlarge it, it will cause divider touch region too big to make app hard to interactive. Therefore, migrate touch region setting logic in legacy split to here, only set divider handle view size as touch region. Fix: 202808282 Test: flash on barbet and active split screen to check Test: pass existing tests Change-Id: If292c0d4c598d75672ec821d1fee45a8892b236f --- .../Shell/res/values-land/styles.xml | 2 +- .../WindowManager/Shell/res/values/styles.xml | 2 +- .../wm/shell/common/split/DividerView.java | 31 +++++++++++++++++++ .../wm/shell/common/split/SplitLayout.java | 28 ++++++++++++++--- .../common/split/SplitWindowManager.java | 11 ++++--- .../wm/shell/flicker/CommonAssertions.kt | 8 ++--- packages/SystemUI/res/values-land/styles.xml | 6 ---- 7 files changed, 66 insertions(+), 22 deletions(-) diff --git a/libs/WindowManager/Shell/res/values-land/styles.xml b/libs/WindowManager/Shell/res/values-land/styles.xml index 9eddac48e6dea..0ed9368aa067b 100644 --- a/libs/WindowManager/Shell/res/values-land/styles.xml +++ b/libs/WindowManager/Shell/res/values-land/styles.xml @@ -23,7 +23,7 @@ diff --git a/libs/WindowManager/Shell/res/values/styles.xml b/libs/WindowManager/Shell/res/values/styles.xml index cb6d4de71a45b..7733201d2465f 100644 --- a/libs/WindowManager/Shell/res/values/styles.xml +++ b/libs/WindowManager/Shell/res/values/styles.xml @@ -43,7 +43,7 @@ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java index 6ea806bd37993..4b125b118cebd 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java @@ -19,6 +19,8 @@ package com.android.wm.shell.common.split; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.Rect; @@ -57,6 +59,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { private final int mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); private SplitLayout mSplitLayout; + private SplitWindowManager mSplitWindowManager; private SurfaceControlViewHost mViewHost; private DividerHandleView mHandle; private View mBackground; @@ -67,6 +70,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { private int mStartPos; private GestureDetector mDoubleTapDetector; private boolean mInteractive; + private boolean mSetTouchRegion = true; /** * Tracks divider bar visible bounds in screen-based coordination. Used to calculate with @@ -93,6 +97,18 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { } }; + private AnimatorListenerAdapter mAnimatorListener = new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mSetTouchRegion = true; + } + + @Override + public void onAnimationCancel(Animator animation) { + mSetTouchRegion = true; + } + }; + public DividerView(@NonNull Context context) { super(context); } @@ -114,9 +130,11 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { /** Sets up essential dependencies of the divider bar. */ public void setup( SplitLayout layout, + SplitWindowManager splitWindowManager, SurfaceControlViewHost viewHost, InsetsState insetsState) { mSplitLayout = layout; + mSplitWindowManager = splitWindowManager; mViewHost = viewHost; mDividerBounds.set(layout.getDividerBounds()); onInsetsChanged(insetsState, false /* animate */); @@ -138,9 +156,11 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { DIVIDER_HEIGHT_PROPERTY, mDividerBounds.height(), mTempRect.height()); animator.setInterpolator(InsetsController.RESIZE_INTERPOLATOR); animator.setDuration(InsetsController.ANIMATION_DURATION_RESIZE); + animator.addListener(mAnimatorListener); animator.start(); } else { DIVIDER_HEIGHT_PROPERTY.set(this, mTempRect.height()); + mSetTouchRegion = true; } mDividerBounds.set(mTempRect); } @@ -161,6 +181,17 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { setOnTouchListener(this); } + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + if (mSetTouchRegion) { + mTempRect.set(mHandle.getLeft(), mHandle.getTop(), mHandle.getRight(), + mHandle.getBottom()); + mSplitWindowManager.setTouchRegion(mTempRect); + mSetTouchRegion = false; + } + } + @Override public boolean onTouch(View v, MotionEvent event) { if (mSplitLayout == null || !mInteractive) { 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 a9ed64c525eb0..625bcee673b54 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 @@ -40,8 +40,10 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Point; import android.graphics.Rect; +import android.view.Display; import android.view.InsetsSourceControl; import android.view.InsetsState; +import android.view.RoundedCorner; import android.view.SurfaceControl; import android.view.WindowInsets; import android.view.WindowManager; @@ -53,6 +55,7 @@ import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.DividerSnapAlgorithm; import com.android.internal.policy.DockedDividerUtils; +import com.android.wm.shell.R; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.animation.Interpolators; import com.android.wm.shell.common.DisplayImeController; @@ -133,17 +136,32 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange mDismissingEffectPolicy = new DismissingEffectPolicy(applyDismissingParallax); final Resources resources = context.getResources(); - mDividerWindowWidth = resources.getDimensionPixelSize( - com.android.internal.R.dimen.docked_stack_divider_thickness); - mDividerInsets = resources.getDimensionPixelSize( - com.android.internal.R.dimen.docked_stack_divider_insets); - mDividerSize = mDividerWindowWidth - mDividerInsets * 2; + mDividerSize = resources.getDimensionPixelSize(R.dimen.split_divider_bar_width); + mDividerInsets = getDividerInsets(resources, context.getDisplay()); + mDividerWindowWidth = mDividerSize + 2 * mDividerInsets; mRootBounds.set(configuration.windowConfiguration.getBounds()); mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds); resetDividerPosition(); } + private int getDividerInsets(Resources resources, Display display) { + final int dividerInset = resources.getDimensionPixelSize( + com.android.internal.R.dimen.docked_stack_divider_insets); + + int radius = 0; + RoundedCorner corner = display.getRoundedCorner(RoundedCorner.POSITION_TOP_LEFT); + radius = corner != null ? Math.max(radius, corner.getRadius()) : radius; + corner = display.getRoundedCorner(RoundedCorner.POSITION_TOP_RIGHT); + radius = corner != null ? Math.max(radius, corner.getRadius()) : radius; + corner = display.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT); + radius = corner != null ? Math.max(radius, corner.getRadius()) : radius; + corner = display.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT); + radius = corner != null ? Math.max(radius, corner.getRadius()) : radius; + + return Math.max(dividerInset, radius); + } + /** Gets bounds of the primary split. */ public Rect getBounds1() { return new Rect(mBounds1); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java index 08754d328772b..4903f9d46dc74 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java @@ -31,7 +31,6 @@ import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.Region; import android.os.Binder; -import android.os.IBinder; import android.view.IWindow; import android.view.InsetsState; import android.view.LayoutInflater; @@ -41,6 +40,7 @@ import android.view.SurfaceSession; import android.view.WindowManager; import android.view.WindowlessWindowManager; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.wm.shell.R; @@ -71,9 +71,10 @@ public final class SplitWindowManager extends WindowlessWindowManager { mWindowName = windowName; } - @Override - public void setTouchRegion(IBinder window, Region region) { - super.setTouchRegion(window, region); + void setTouchRegion(@NonNull Rect region) { + if (mViewHost != null) { + setTouchRegion(mViewHost.getWindowToken().asBinder(), new Region(region)); + } } @Override @@ -122,7 +123,7 @@ public final class SplitWindowManager extends WindowlessWindowManager { lp.setTitle(mWindowName); lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY; mViewHost.setView(mDividerView, lp); - mDividerView.setup(splitLayout, mViewHost, insetsState); + mDividerView.setup(splitLayout, this, mViewHost, insetsState); } /** diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt index c07f0eb115102..c4be785cff19b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt @@ -78,7 +78,7 @@ fun FlickerTestParameter.appPairsPrimaryBoundsIsVisibleAtEnd( assertLayersEnd { val dividerRegion = layer(APP_PAIR_SPLIT_DIVIDER_COMPONENT).visibleRegion.region visibleRegion(primaryComponent) - .coversExactly(getPrimaryRegion(dividerRegion, rotation)) + .overlaps(getPrimaryRegion(dividerRegion, rotation)) } } @@ -89,7 +89,7 @@ fun FlickerTestParameter.dockedStackPrimaryBoundsIsVisibleAtEnd( assertLayersEnd { val dividerRegion = layer(DOCKED_STACK_DIVIDER_COMPONENT).visibleRegion.region visibleRegion(primaryComponent) - .coversExactly(getPrimaryRegion(dividerRegion, rotation)) + .overlaps(getPrimaryRegion(dividerRegion, rotation)) } } @@ -100,7 +100,7 @@ fun FlickerTestParameter.appPairsSecondaryBoundsIsVisibleAtEnd( assertLayersEnd { val dividerRegion = layer(APP_PAIR_SPLIT_DIVIDER_COMPONENT).visibleRegion.region visibleRegion(secondaryComponent) - .coversExactly(getSecondaryRegion(dividerRegion, rotation)) + .overlaps(getSecondaryRegion(dividerRegion, rotation)) } } @@ -111,7 +111,7 @@ fun FlickerTestParameter.dockedStackSecondaryBoundsIsVisibleAtEnd( assertLayersEnd { val dividerRegion = layer(DOCKED_STACK_DIVIDER_COMPONENT).visibleRegion.region visibleRegion(secondaryComponent) - .coversExactly(getSecondaryRegion(dividerRegion, rotation)) + .overlaps(getSecondaryRegion(dividerRegion, rotation)) } } diff --git a/packages/SystemUI/res/values-land/styles.xml b/packages/SystemUI/res/values-land/styles.xml index 82cba58e48fad..f3d83645a8e0a 100644 --- a/packages/SystemUI/res/values-land/styles.xml +++ b/packages/SystemUI/res/values-land/styles.xml @@ -25,12 +25,6 @@ center_horizontal - -