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
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
</style>
|
||||
|
||||
<style name="DockedDividerHandle">
|
||||
<item name="android:layout_gravity">center_vertical</item>
|
||||
<item name="android:layout_gravity">center</item>
|
||||
<item name="android:layout_width">48dp</item>
|
||||
<item name="android:layout_height">96dp</item>
|
||||
</style>
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
</style>
|
||||
|
||||
<style name="DockedDividerHandle">
|
||||
<item name="android:layout_gravity">center_horizontal</item>
|
||||
<item name="android:layout_gravity">center</item>
|
||||
<item name="android:layout_width">96dp</item>
|
||||
<item name="android:layout_height">48dp</item>
|
||||
</style>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,12 +25,6 @@
|
||||
<item name="android:layout_gravity">center_horizontal</item>
|
||||
</style>
|
||||
|
||||
<style name="DockedDividerHandle">
|
||||
<item name="android:layout_gravity">center_vertical</item>
|
||||
<item name="android:layout_width">48dp</item>
|
||||
<item name="android:layout_height">96dp</item>
|
||||
</style>
|
||||
|
||||
<style name="DockedDividerMinimizedShadow">
|
||||
<item name="android:layout_width">8dp</item>
|
||||
<item name="android:layout_height">match_parent</item>
|
||||
|
||||
Reference in New Issue
Block a user