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 = public static final boolean CAPTION_ON_SHELL =
SystemProperties.getBoolean("persist.wm.debug.caption_on_shell", true); 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. * Whether the client should compute the window frame on its own.
* @hide * @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_CONTAINER_BOUNDS;
import static android.view.InsetsFrameProvider.SOURCE_DISPLAY; import static android.view.InsetsFrameProvider.SOURCE_DISPLAY;
import static android.view.InsetsFrameProvider.SOURCE_FRAME; 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_NAVIGATION_BARS;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_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; final DecorInsets mDecorInsets;
@@ -408,158 +410,162 @@ public class DisplayPolicy {
final Looper looper = UiThread.getHandler().getLooper(); final Looper looper = UiThread.getHandler().getLooper();
mHandler = new PolicyHandler(looper); mHandler = new PolicyHandler(looper);
// TODO(b/181821798) Migrate SystemGesturesPointerEventListener to use window context. // TODO(b/181821798) Migrate SystemGesturesPointerEventListener to use window context.
mSystemGestures = new SystemGesturesPointerEventListener(mUiContext, mHandler, if (!CLIENT_TRANSIENT) {
new SystemGesturesPointerEventListener.Callbacks() { 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 mOnSwipeFromLeft = this::onSwipeFromLeft;
private Runnable mOnSwipeFromTop = this::onSwipeFromTop; private Runnable mOnSwipeFromTop = this::onSwipeFromTop;
private Runnable mOnSwipeFromRight = this::onSwipeFromRight; private Runnable mOnSwipeFromRight = this::onSwipeFromRight;
private Runnable mOnSwipeFromBottom = this::onSwipeFromBottom; private Runnable mOnSwipeFromBottom = this::onSwipeFromBottom;
private Insets getControllableInsets(WindowState win) { private Insets getControllableInsets(WindowState win) {
if (win == null) { if (win == null) {
return Insets.NONE; return Insets.NONE;
}
final InsetsSourceProvider provider = win.getControllableInsetProvider();
if (provider == null) {
return Insets.NONE;
}
return provider.getSource().calculateInsets(win.getBounds(),
true /* ignoreVisibility */);
} }
final InsetsSourceProvider provider = win.getControllableInsetProvider();
if (provider == null) {
return Insets.NONE;
}
return provider.getSource().calculateInsets(win.getBounds(),
true /* ignoreVisibility */);
}
@Override @Override
public void onSwipeFromTop() { public void onSwipeFromTop() {
synchronized (mLock) { synchronized (mLock) {
requestTransientBars(mTopGestureHost, requestTransientBars(mTopGestureHost,
getControllableInsets(mTopGestureHost).top > 0); 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 @Override
public void onSwipeFromBottom() { public void onSwipeFromLeft() {
synchronized (mLock) { final Region excludedRegion = Region.obtain();
requestTransientBars(mBottomGestureHost, synchronized (mLock) {
getControllableInsets(mBottomGestureHost).bottom > 0); 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) { @Override
return mNavigationBarAlwaysShowOnSideGesture public void onFling(int duration) {
&& !mSystemGestures.currentGestureStartedInRegion(excludedRegion); if (mService.mPowerManagerInternal != null) {
mService.mPowerManagerInternal.setPowerBoost(
Boost.INTERACTION, duration);
} }
}
@Override @Override
public void onSwipeFromRight() { public void onDebug() {
final Region excludedRegion = Region.obtain(); // no-op
synchronized (mLock) { }
mDisplayContent.calculateSystemGestureExclusion(
excludedRegion, null /* outUnrestricted */);
final boolean hasWindow =
getControllableInsets(mRightGestureHost).right > 0;
if (hasWindow || allowsSideSwipe(excludedRegion)) {
requestTransientBars(mRightGestureHost, hasWindow);
}
}
excludedRegion.recycle();
}
@Override private WindowOrientationListener getOrientationListener() {
public void onSwipeFromLeft() { final DisplayRotation rotation = mDisplayContent.getDisplayRotation();
final Region excludedRegion = Region.obtain(); return rotation != null ? rotation.getOrientationListener() : null;
synchronized (mLock) { }
mDisplayContent.calculateSystemGestureExclusion(
excludedRegion, null /* outUnrestricted */);
final boolean hasWindow =
getControllableInsets(mLeftGestureHost).left > 0;
if (hasWindow || allowsSideSwipe(excludedRegion)) {
requestTransientBars(mLeftGestureHost, hasWindow);
}
}
excludedRegion.recycle();
}
@Override @Override
public void onFling(int duration) { public void onDown() {
if (mService.mPowerManagerInternal != null) { final WindowOrientationListener listener = getOrientationListener();
mService.mPowerManagerInternal.setPowerBoost( if (listener != null) {
Boost.INTERACTION, duration); listener.onTouchStart();
}
} }
}
@Override @Override
public void onDebug() { public void onUpOrCancel() {
// no-op final WindowOrientationListener listener = getOrientationListener();
if (listener != null) {
listener.onTouchEnd();
} }
}
private WindowOrientationListener getOrientationListener() { @Override
final DisplayRotation rotation = mDisplayContent.getDisplayRotation(); public void onMouseHoverAtLeft() {
return rotation != null ? rotation.getOrientationListener() : null; mHandler.removeCallbacks(mOnSwipeFromLeft);
} mHandler.postDelayed(mOnSwipeFromLeft, MOUSE_GESTURE_DELAY_MS);
}
@Override @Override
public void onDown() { public void onMouseHoverAtTop() {
final WindowOrientationListener listener = getOrientationListener(); mHandler.removeCallbacks(mOnSwipeFromTop);
if (listener != null) { mHandler.postDelayed(mOnSwipeFromTop, MOUSE_GESTURE_DELAY_MS);
listener.onTouchStart(); }
}
}
@Override @Override
public void onUpOrCancel() { public void onMouseHoverAtRight() {
final WindowOrientationListener listener = getOrientationListener(); mHandler.removeCallbacks(mOnSwipeFromRight);
if (listener != null) { mHandler.postDelayed(mOnSwipeFromRight, MOUSE_GESTURE_DELAY_MS);
listener.onTouchEnd(); }
}
}
@Override @Override
public void onMouseHoverAtLeft() { public void onMouseHoverAtBottom() {
mHandler.removeCallbacks(mOnSwipeFromLeft); mHandler.removeCallbacks(mOnSwipeFromBottom);
mHandler.postDelayed(mOnSwipeFromLeft, MOUSE_GESTURE_DELAY_MS); mHandler.postDelayed(mOnSwipeFromBottom, MOUSE_GESTURE_DELAY_MS);
} }
@Override @Override
public void onMouseHoverAtTop() { public void onMouseLeaveFromLeft() {
mHandler.removeCallbacks(mOnSwipeFromTop); mHandler.removeCallbacks(mOnSwipeFromLeft);
mHandler.postDelayed(mOnSwipeFromTop, MOUSE_GESTURE_DELAY_MS); }
}
@Override @Override
public void onMouseHoverAtRight() { public void onMouseLeaveFromTop() {
mHandler.removeCallbacks(mOnSwipeFromRight); mHandler.removeCallbacks(mOnSwipeFromTop);
mHandler.postDelayed(mOnSwipeFromRight, MOUSE_GESTURE_DELAY_MS); }
}
@Override @Override
public void onMouseHoverAtBottom() { public void onMouseLeaveFromRight() {
mHandler.removeCallbacks(mOnSwipeFromBottom); mHandler.removeCallbacks(mOnSwipeFromRight);
mHandler.postDelayed(mOnSwipeFromBottom, MOUSE_GESTURE_DELAY_MS); }
}
@Override @Override
public void onMouseLeaveFromLeft() { public void onMouseLeaveFromBottom() {
mHandler.removeCallbacks(mOnSwipeFromLeft); mHandler.removeCallbacks(mOnSwipeFromBottom);
} }
};
@Override mSystemGestures = new SystemGesturesPointerEventListener(mUiContext, mHandler,
public void onMouseLeaveFromTop() { gesturesPointerEventCallbacks);
mHandler.removeCallbacks(mOnSwipeFromTop); displayContent.registerPointerEventListener(mSystemGestures);
} }
@Override
public void onMouseLeaveFromRight() {
mHandler.removeCallbacks(mOnSwipeFromRight);
}
@Override
public void onMouseLeaveFromBottom() {
mHandler.removeCallbacks(mOnSwipeFromBottom);
}
});
displayContent.registerPointerEventListener(mSystemGestures);
mAppTransitionListener = new WindowManagerInternal.AppTransitionListener() { mAppTransitionListener = new WindowManagerInternal.AppTransitionListener() {
private Runnable mAppTransitionPending = () -> { private Runnable mAppTransitionPending = () -> {
@@ -645,7 +651,9 @@ public class DisplayPolicy {
mContext, () -> { mContext, () -> {
synchronized (mLock) { synchronized (mLock) {
onConfigurationChanged(); onConfigurationChanged();
mSystemGestures.onConfigurationChanged(); if (!CLIENT_TRANSIENT) {
mSystemGestures.onConfigurationChanged();
}
mDisplayContent.updateSystemGestureExclusion(); mDisplayContent.updateSystemGestureExclusion();
} }
}); });
@@ -667,7 +675,9 @@ public class DisplayPolicy {
} }
void systemReady() { void systemReady() {
mSystemGestures.systemReady(); if (!CLIENT_TRANSIENT) {
mSystemGestures.systemReady();
}
if (mService.mPointerLocationEnabled) { if (mService.mPointerLocationEnabled) {
setPointerLocationEnabled(true); setPointerLocationEnabled(true);
} }
@@ -1308,7 +1318,9 @@ public class DisplayPolicy {
} }
void onDisplayInfoChanged(DisplayInfo info) { 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. // Update the latest display size, cutout.
mDisplayContent.updateDisplayInfo(); mDisplayContent.updateDisplayInfo();
onConfigurationChanged(); onConfigurationChanged();
mSystemGestures.onConfigurationChanged(); if (!CLIENT_TRANSIENT) {
mSystemGestures.onConfigurationChanged();
}
} }
/** /**
@@ -1960,6 +1974,9 @@ public class DisplayPolicy {
@VisibleForTesting @VisibleForTesting
void requestTransientBars(WindowState swipeTarget, boolean isGestureOnSystemBar) { void requestTransientBars(WindowState swipeTarget, boolean isGestureOnSystemBar) {
if (CLIENT_TRANSIENT) {
return;
}
if (swipeTarget == null || !mService.mPolicy.isUserSetupComplete()) { if (swipeTarget == null || !mService.mPolicy.isUserSetupComplete()) {
// Swipe-up for navigation bar is disabled during setup // Swipe-up for navigation bar is disabled during setup
return; return;
@@ -2608,7 +2625,9 @@ public class DisplayPolicy {
final DecorInsets.Info info = mDecorInsets.mInfoForRotation[rotation]; final DecorInsets.Info info = mDecorInsets.mInfoForRotation[rotation];
pw.println(prefixInner + Surface.rotationToString(rotation) + "=" + info); 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:"); pw.print(prefix); pw.println("Looper state:");
mHandler.getLooper().dump(new PrintWriterPrinter(pw), prefix + " "); 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.Surface.ROTATION_0;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; 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.WindowInsets.Type.navigationBars;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; 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 androidx.test.filters.SmallTest;
import org.junit.Assume;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@@ -388,6 +390,7 @@ public class DisplayPolicyTests extends WindowTestsBase {
@SetupWindows(addWindows = { W_ACTIVITY, W_NAVIGATION_BAR }) @SetupWindows(addWindows = { W_ACTIVITY, W_NAVIGATION_BAR })
@Test @Test
public void testCanSystemBarsBeShownByUser() { public void testCanSystemBarsBeShownByUser() {
Assume.assumeFalse(CLIENT_TRANSIENT);
((TestWindowManagerPolicy) mWm.mPolicy).mIsUserSetupComplete = true; ((TestWindowManagerPolicy) mWm.mPolicy).mIsUserSetupComplete = true;
mAppWindow.mAttrs.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; mAppWindow.mAttrs.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
mAppWindow.setRequestedVisibleTypes(0, navigationBars()); mAppWindow.setRequestedVisibleTypes(0, navigationBars());
@@ -409,6 +412,7 @@ public class DisplayPolicyTests extends WindowTestsBase {
@UseTestDisplay(addWindows = { W_NAVIGATION_BAR }) @UseTestDisplay(addWindows = { W_NAVIGATION_BAR })
@Test @Test
public void testTransientBarsSuppressedOnDreams() { public void testTransientBarsSuppressedOnDreams() {
Assume.assumeFalse(CLIENT_TRANSIENT);
final WindowState win = createDreamWindow(); final WindowState win = createDreamWindow();
((TestWindowManagerPolicy) mWm.mPolicy).mIsUserSetupComplete = true; ((TestWindowManagerPolicy) mWm.mPolicy).mIsUserSetupComplete = true;