Merge "Introduce Client Transient flag (1/n)" into udc-dev

This commit is contained in:
TreeHugger Robot
2023-05-07 15:20:57 +00:00
committed by Android (Google) Code Review
3 changed files with 163 additions and 132 deletions

View File

@@ -300,6 +300,14 @@ public final class ViewRootImpl implements ViewParent,
public static final boolean CAPTION_ON_SHELL =
SystemProperties.getBoolean("persist.wm.debug.caption_on_shell", true);
/**
* Whether the client (system UI) is handling the transient gesture and the corresponding
* animation.
* @hide
*/
public static final boolean CLIENT_TRANSIENT =
SystemProperties.getBoolean("persist.wm.debug.client_transient", false);
/**
* Whether the client should compute the window frame on its own.
* @hide

View File

@@ -22,6 +22,7 @@ import static android.view.InsetsFrameProvider.SOURCE_ARBITRARY_RECTANGLE;
import static android.view.InsetsFrameProvider.SOURCE_CONTAINER_BOUNDS;
import static android.view.InsetsFrameProvider.SOURCE_DISPLAY;
import static android.view.InsetsFrameProvider.SOURCE_FRAME;
import static android.view.ViewRootImpl.CLIENT_TRANSIENT;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
@@ -213,7 +214,8 @@ public class DisplayPolicy {
}
}
private final SystemGesturesPointerEventListener mSystemGestures;
// Will be null in client transient mode.
private SystemGesturesPointerEventListener mSystemGestures;
final DecorInsets mDecorInsets;
@@ -408,158 +410,162 @@ public class DisplayPolicy {
final Looper looper = UiThread.getHandler().getLooper();
mHandler = new PolicyHandler(looper);
// TODO(b/181821798) Migrate SystemGesturesPointerEventListener to use window context.
mSystemGestures = new SystemGesturesPointerEventListener(mUiContext, mHandler,
new SystemGesturesPointerEventListener.Callbacks() {
if (!CLIENT_TRANSIENT) {
SystemGesturesPointerEventListener.Callbacks gesturesPointerEventCallbacks =
new SystemGesturesPointerEventListener.Callbacks() {
private static final long MOUSE_GESTURE_DELAY_MS = 500;
private static final long MOUSE_GESTURE_DELAY_MS = 500;
private Runnable mOnSwipeFromLeft = this::onSwipeFromLeft;
private Runnable mOnSwipeFromTop = this::onSwipeFromTop;
private Runnable mOnSwipeFromRight = this::onSwipeFromRight;
private Runnable mOnSwipeFromBottom = this::onSwipeFromBottom;
private Runnable mOnSwipeFromLeft = this::onSwipeFromLeft;
private Runnable mOnSwipeFromTop = this::onSwipeFromTop;
private Runnable mOnSwipeFromRight = this::onSwipeFromRight;
private Runnable mOnSwipeFromBottom = this::onSwipeFromBottom;
private Insets getControllableInsets(WindowState win) {
if (win == null) {
return Insets.NONE;
}
final InsetsSourceProvider provider = win.getControllableInsetProvider();
if (provider == null) {
return Insets.NONE;
}
return provider.getSource().calculateInsets(win.getBounds(),
true /* ignoreVisibility */);
private Insets getControllableInsets(WindowState win) {
if (win == null) {
return Insets.NONE;
}
final InsetsSourceProvider provider = win.getControllableInsetProvider();
if (provider == null) {
return Insets.NONE;
}
return provider.getSource().calculateInsets(win.getBounds(),
true /* ignoreVisibility */);
}
@Override
public void onSwipeFromTop() {
synchronized (mLock) {
requestTransientBars(mTopGestureHost,
getControllableInsets(mTopGestureHost).top > 0);
@Override
public void onSwipeFromTop() {
synchronized (mLock) {
requestTransientBars(mTopGestureHost,
getControllableInsets(mTopGestureHost).top > 0);
}
}
@Override
public void onSwipeFromBottom() {
synchronized (mLock) {
requestTransientBars(mBottomGestureHost,
getControllableInsets(mBottomGestureHost).bottom > 0);
}
}
private boolean allowsSideSwipe(Region excludedRegion) {
return mNavigationBarAlwaysShowOnSideGesture
&& !mSystemGestures.currentGestureStartedInRegion(excludedRegion);
}
@Override
public void onSwipeFromRight() {
final Region excludedRegion = Region.obtain();
synchronized (mLock) {
mDisplayContent.calculateSystemGestureExclusion(
excludedRegion, null /* outUnrestricted */);
final boolean hasWindow =
getControllableInsets(mRightGestureHost).right > 0;
if (hasWindow || allowsSideSwipe(excludedRegion)) {
requestTransientBars(mRightGestureHost, hasWindow);
}
}
excludedRegion.recycle();
}
@Override
public void onSwipeFromBottom() {
synchronized (mLock) {
requestTransientBars(mBottomGestureHost,
getControllableInsets(mBottomGestureHost).bottom > 0);
@Override
public void onSwipeFromLeft() {
final Region excludedRegion = Region.obtain();
synchronized (mLock) {
mDisplayContent.calculateSystemGestureExclusion(
excludedRegion, null /* outUnrestricted */);
final boolean hasWindow =
getControllableInsets(mLeftGestureHost).left > 0;
if (hasWindow || allowsSideSwipe(excludedRegion)) {
requestTransientBars(mLeftGestureHost, hasWindow);
}
}
excludedRegion.recycle();
}
private boolean allowsSideSwipe(Region excludedRegion) {
return mNavigationBarAlwaysShowOnSideGesture
&& !mSystemGestures.currentGestureStartedInRegion(excludedRegion);
@Override
public void onFling(int duration) {
if (mService.mPowerManagerInternal != null) {
mService.mPowerManagerInternal.setPowerBoost(
Boost.INTERACTION, duration);
}
}
@Override
public void onSwipeFromRight() {
final Region excludedRegion = Region.obtain();
synchronized (mLock) {
mDisplayContent.calculateSystemGestureExclusion(
excludedRegion, null /* outUnrestricted */);
final boolean hasWindow =
getControllableInsets(mRightGestureHost).right > 0;
if (hasWindow || allowsSideSwipe(excludedRegion)) {
requestTransientBars(mRightGestureHost, hasWindow);
}
}
excludedRegion.recycle();
}
@Override
public void onDebug() {
// no-op
}
@Override
public void onSwipeFromLeft() {
final Region excludedRegion = Region.obtain();
synchronized (mLock) {
mDisplayContent.calculateSystemGestureExclusion(
excludedRegion, null /* outUnrestricted */);
final boolean hasWindow =
getControllableInsets(mLeftGestureHost).left > 0;
if (hasWindow || allowsSideSwipe(excludedRegion)) {
requestTransientBars(mLeftGestureHost, hasWindow);
}
}
excludedRegion.recycle();
}
private WindowOrientationListener getOrientationListener() {
final DisplayRotation rotation = mDisplayContent.getDisplayRotation();
return rotation != null ? rotation.getOrientationListener() : null;
}
@Override
public void onFling(int duration) {
if (mService.mPowerManagerInternal != null) {
mService.mPowerManagerInternal.setPowerBoost(
Boost.INTERACTION, duration);
}
@Override
public void onDown() {
final WindowOrientationListener listener = getOrientationListener();
if (listener != null) {
listener.onTouchStart();
}
}
@Override
public void onDebug() {
// no-op
@Override
public void onUpOrCancel() {
final WindowOrientationListener listener = getOrientationListener();
if (listener != null) {
listener.onTouchEnd();
}
}
private WindowOrientationListener getOrientationListener() {
final DisplayRotation rotation = mDisplayContent.getDisplayRotation();
return rotation != null ? rotation.getOrientationListener() : null;
}
@Override
public void onMouseHoverAtLeft() {
mHandler.removeCallbacks(mOnSwipeFromLeft);
mHandler.postDelayed(mOnSwipeFromLeft, MOUSE_GESTURE_DELAY_MS);
}
@Override
public void onDown() {
final WindowOrientationListener listener = getOrientationListener();
if (listener != null) {
listener.onTouchStart();
}
}
@Override
public void onMouseHoverAtTop() {
mHandler.removeCallbacks(mOnSwipeFromTop);
mHandler.postDelayed(mOnSwipeFromTop, MOUSE_GESTURE_DELAY_MS);
}
@Override
public void onUpOrCancel() {
final WindowOrientationListener listener = getOrientationListener();
if (listener != null) {
listener.onTouchEnd();
}
}
@Override
public void onMouseHoverAtRight() {
mHandler.removeCallbacks(mOnSwipeFromRight);
mHandler.postDelayed(mOnSwipeFromRight, MOUSE_GESTURE_DELAY_MS);
}
@Override
public void onMouseHoverAtLeft() {
mHandler.removeCallbacks(mOnSwipeFromLeft);
mHandler.postDelayed(mOnSwipeFromLeft, MOUSE_GESTURE_DELAY_MS);
}
@Override
public void onMouseHoverAtBottom() {
mHandler.removeCallbacks(mOnSwipeFromBottom);
mHandler.postDelayed(mOnSwipeFromBottom, MOUSE_GESTURE_DELAY_MS);
}
@Override
public void onMouseHoverAtTop() {
mHandler.removeCallbacks(mOnSwipeFromTop);
mHandler.postDelayed(mOnSwipeFromTop, MOUSE_GESTURE_DELAY_MS);
}
@Override
public void onMouseLeaveFromLeft() {
mHandler.removeCallbacks(mOnSwipeFromLeft);
}
@Override
public void onMouseHoverAtRight() {
mHandler.removeCallbacks(mOnSwipeFromRight);
mHandler.postDelayed(mOnSwipeFromRight, MOUSE_GESTURE_DELAY_MS);
}
@Override
public void onMouseLeaveFromTop() {
mHandler.removeCallbacks(mOnSwipeFromTop);
}
@Override
public void onMouseHoverAtBottom() {
mHandler.removeCallbacks(mOnSwipeFromBottom);
mHandler.postDelayed(mOnSwipeFromBottom, MOUSE_GESTURE_DELAY_MS);
}
@Override
public void onMouseLeaveFromRight() {
mHandler.removeCallbacks(mOnSwipeFromRight);
}
@Override
public void onMouseLeaveFromLeft() {
mHandler.removeCallbacks(mOnSwipeFromLeft);
}
@Override
public void onMouseLeaveFromTop() {
mHandler.removeCallbacks(mOnSwipeFromTop);
}
@Override
public void onMouseLeaveFromRight() {
mHandler.removeCallbacks(mOnSwipeFromRight);
}
@Override
public void onMouseLeaveFromBottom() {
mHandler.removeCallbacks(mOnSwipeFromBottom);
}
});
displayContent.registerPointerEventListener(mSystemGestures);
@Override
public void onMouseLeaveFromBottom() {
mHandler.removeCallbacks(mOnSwipeFromBottom);
}
};
mSystemGestures = new SystemGesturesPointerEventListener(mUiContext, mHandler,
gesturesPointerEventCallbacks);
displayContent.registerPointerEventListener(mSystemGestures);
}
mAppTransitionListener = new WindowManagerInternal.AppTransitionListener() {
private Runnable mAppTransitionPending = () -> {
@@ -645,7 +651,9 @@ public class DisplayPolicy {
mContext, () -> {
synchronized (mLock) {
onConfigurationChanged();
mSystemGestures.onConfigurationChanged();
if (!CLIENT_TRANSIENT) {
mSystemGestures.onConfigurationChanged();
}
mDisplayContent.updateSystemGestureExclusion();
}
});
@@ -667,7 +675,9 @@ public class DisplayPolicy {
}
void systemReady() {
mSystemGestures.systemReady();
if (!CLIENT_TRANSIENT) {
mSystemGestures.systemReady();
}
if (mService.mPointerLocationEnabled) {
setPointerLocationEnabled(true);
}
@@ -1308,7 +1318,9 @@ public class DisplayPolicy {
}
void onDisplayInfoChanged(DisplayInfo info) {
mSystemGestures.onDisplayInfoChanged(info);
if (!CLIENT_TRANSIENT) {
mSystemGestures.onDisplayInfoChanged(info);
}
}
/**
@@ -1681,7 +1693,9 @@ public class DisplayPolicy {
// Update the latest display size, cutout.
mDisplayContent.updateDisplayInfo();
onConfigurationChanged();
mSystemGestures.onConfigurationChanged();
if (!CLIENT_TRANSIENT) {
mSystemGestures.onConfigurationChanged();
}
}
/**
@@ -1960,6 +1974,9 @@ public class DisplayPolicy {
@VisibleForTesting
void requestTransientBars(WindowState swipeTarget, boolean isGestureOnSystemBar) {
if (CLIENT_TRANSIENT) {
return;
}
if (swipeTarget == null || !mService.mPolicy.isUserSetupComplete()) {
// Swipe-up for navigation bar is disabled during setup
return;
@@ -2608,7 +2625,9 @@ public class DisplayPolicy {
final DecorInsets.Info info = mDecorInsets.mInfoForRotation[rotation];
pw.println(prefixInner + Surface.rotationToString(rotation) + "=" + info);
}
mSystemGestures.dump(pw, prefix);
if (!CLIENT_TRANSIENT) {
mSystemGestures.dump(pw, prefix);
}
pw.print(prefix); pw.println("Looper state:");
mHandler.getLooper().dump(new PrintWriterPrinter(pw), prefix + " ");

View File

@@ -22,6 +22,7 @@ import static android.view.RoundedCorners.NO_ROUNDED_CORNERS;
import static android.view.Surface.ROTATION_0;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.view.ViewRootImpl.CLIENT_TRANSIENT;
import static android.view.WindowInsets.Type.navigationBars;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
@@ -63,6 +64,7 @@ import android.view.WindowManager;
import androidx.test.filters.SmallTest;
import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -388,6 +390,7 @@ public class DisplayPolicyTests extends WindowTestsBase {
@SetupWindows(addWindows = { W_ACTIVITY, W_NAVIGATION_BAR })
@Test
public void testCanSystemBarsBeShownByUser() {
Assume.assumeFalse(CLIENT_TRANSIENT);
((TestWindowManagerPolicy) mWm.mPolicy).mIsUserSetupComplete = true;
mAppWindow.mAttrs.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
mAppWindow.setRequestedVisibleTypes(0, navigationBars());
@@ -409,6 +412,7 @@ public class DisplayPolicyTests extends WindowTestsBase {
@UseTestDisplay(addWindows = { W_NAVIGATION_BAR })
@Test
public void testTransientBarsSuppressedOnDreams() {
Assume.assumeFalse(CLIENT_TRANSIENT);
final WindowState win = createDreamWindow();
((TestWindowManagerPolicy) mWm.mPolicy).mIsUserSetupComplete = true;