From 4defffd0438df8de0072ee308d5e84afff736d9c Mon Sep 17 00:00:00 2001 From: Yunfan Chen Date: Mon, 17 Apr 2023 07:09:36 +0000 Subject: Introduce Client Transient flag (1/n) This is a feature flag to develop transient related features on the system UI side. Currently it's handled by the system server. This change introduced the flag and set it by default to false, in the meanwhile, wrapped existing server side logic with the flag to make the future clean-up easier. If the flag is flipped without system UI side feature complete, the transient animation will not work. Other insets related functionality will not be affected. SystemGesturesPointerEventListener should be simplified or changed to a class instead of an interface with the feature development. Bug: 277290737 Test: DisplayPolicyTests Test: DisplayPolicyInsetsTests Change-Id: I243407d233d71b40807d29660090e674b8dd5d31 --- core/java/android/view/ViewRootImpl.java | 8 + .../java/com/android/server/wm/DisplayPolicy.java | 273 +++++++++++---------- .../com/android/server/wm/DisplayPolicyTests.java | 4 + 3 files changed, 158 insertions(+), 127 deletions(-) diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 6bd9538a9f65..e7fff0ef0184 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -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 diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 747819e93ff2..b5a471e61ddf 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -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; @@ -214,7 +215,8 @@ public class DisplayPolicy { } } - private final SystemGesturesPointerEventListener mSystemGestures; + // Will be null in client transient mode. + private SystemGesturesPointerEventListener mSystemGestures; final DecorInsets mDecorInsets; @@ -411,158 +413,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; } - - @Override - public void onSwipeFromTop() { - synchronized (mLock) { - requestTransientBars(mTopGestureHost, - getControllableInsets(mTopGestureHost).top > 0); - } + final InsetsSourceProvider provider = win.getControllableInsetProvider(); + if (provider == null) { + return Insets.NONE; } + return provider.getSource().calculateInsets(win.getBounds(), + true /* ignoreVisibility */); + } - @Override - public void onSwipeFromBottom() { - synchronized (mLock) { - requestTransientBars(mBottomGestureHost, - getControllableInsets(mBottomGestureHost).bottom > 0); - } + @Override + public void onSwipeFromTop() { + synchronized (mLock) { + requestTransientBars(mTopGestureHost, + getControllableInsets(mTopGestureHost).top > 0); } + } - private boolean allowsSideSwipe(Region excludedRegion) { - return mNavigationBarAlwaysShowOnSideGesture - && !mSystemGestures.currentGestureStartedInRegion(excludedRegion); + @Override + public void onSwipeFromBottom() { + synchronized (mLock) { + requestTransientBars(mBottomGestureHost, + getControllableInsets(mBottomGestureHost).bottom > 0); } + } - @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(); - } + private boolean allowsSideSwipe(Region excludedRegion) { + return mNavigationBarAlwaysShowOnSideGesture + && !mSystemGestures.currentGestureStartedInRegion(excludedRegion); + } - @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); - } + @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(); } + excludedRegion.recycle(); + } - @Override - public void onFling(int duration) { - if (mService.mPowerManagerInternal != null) { - mService.mPowerManagerInternal.setPowerBoost( - Boost.INTERACTION, duration); + @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(); + } - @Override - public void onDebug() { - // no-op + @Override + public void onFling(int duration) { + if (mService.mPowerManagerInternal != null) { + mService.mPowerManagerInternal.setPowerBoost( + Boost.INTERACTION, duration); } + } - private WindowOrientationListener getOrientationListener() { - final DisplayRotation rotation = mDisplayContent.getDisplayRotation(); - return rotation != null ? rotation.getOrientationListener() : null; - } + @Override + public void onDebug() { + // no-op + } - @Override - public void onDown() { - final WindowOrientationListener listener = getOrientationListener(); - if (listener != null) { - listener.onTouchStart(); - } - } + private WindowOrientationListener getOrientationListener() { + final DisplayRotation rotation = mDisplayContent.getDisplayRotation(); + return rotation != null ? rotation.getOrientationListener() : null; + } - @Override - public void onUpOrCancel() { - final WindowOrientationListener listener = getOrientationListener(); - if (listener != null) { - listener.onTouchEnd(); - } + @Override + public void onDown() { + final WindowOrientationListener listener = getOrientationListener(); + if (listener != null) { + listener.onTouchStart(); } + } - @Override - public void onMouseHoverAtLeft() { - mHandler.removeCallbacks(mOnSwipeFromLeft); - mHandler.postDelayed(mOnSwipeFromLeft, MOUSE_GESTURE_DELAY_MS); + @Override + public void onUpOrCancel() { + final WindowOrientationListener listener = getOrientationListener(); + if (listener != null) { + listener.onTouchEnd(); } + } - @Override - public void onMouseHoverAtTop() { - mHandler.removeCallbacks(mOnSwipeFromTop); - mHandler.postDelayed(mOnSwipeFromTop, MOUSE_GESTURE_DELAY_MS); - } + @Override + public void onMouseHoverAtLeft() { + mHandler.removeCallbacks(mOnSwipeFromLeft); + mHandler.postDelayed(mOnSwipeFromLeft, MOUSE_GESTURE_DELAY_MS); + } - @Override - public void onMouseHoverAtRight() { - mHandler.removeCallbacks(mOnSwipeFromRight); - mHandler.postDelayed(mOnSwipeFromRight, MOUSE_GESTURE_DELAY_MS); - } + @Override + public void onMouseHoverAtTop() { + mHandler.removeCallbacks(mOnSwipeFromTop); + mHandler.postDelayed(mOnSwipeFromTop, MOUSE_GESTURE_DELAY_MS); + } - @Override - public void onMouseHoverAtBottom() { - mHandler.removeCallbacks(mOnSwipeFromBottom); - mHandler.postDelayed(mOnSwipeFromBottom, MOUSE_GESTURE_DELAY_MS); - } + @Override + public void onMouseHoverAtRight() { + mHandler.removeCallbacks(mOnSwipeFromRight); + mHandler.postDelayed(mOnSwipeFromRight, MOUSE_GESTURE_DELAY_MS); + } - @Override - public void onMouseLeaveFromLeft() { - mHandler.removeCallbacks(mOnSwipeFromLeft); - } + @Override + public void onMouseHoverAtBottom() { + mHandler.removeCallbacks(mOnSwipeFromBottom); + mHandler.postDelayed(mOnSwipeFromBottom, MOUSE_GESTURE_DELAY_MS); + } - @Override - public void onMouseLeaveFromTop() { - mHandler.removeCallbacks(mOnSwipeFromTop); - } + @Override + public void onMouseLeaveFromLeft() { + mHandler.removeCallbacks(mOnSwipeFromLeft); + } - @Override - public void onMouseLeaveFromRight() { - mHandler.removeCallbacks(mOnSwipeFromRight); - } + @Override + public void onMouseLeaveFromTop() { + mHandler.removeCallbacks(mOnSwipeFromTop); + } - @Override - public void onMouseLeaveFromBottom() { - mHandler.removeCallbacks(mOnSwipeFromBottom); - } - }); - displayContent.registerPointerEventListener(mSystemGestures); + @Override + public void onMouseLeaveFromRight() { + mHandler.removeCallbacks(mOnSwipeFromRight); + } + + @Override + public void onMouseLeaveFromBottom() { + mHandler.removeCallbacks(mOnSwipeFromBottom); + } + }; + mSystemGestures = new SystemGesturesPointerEventListener(mUiContext, mHandler, + gesturesPointerEventCallbacks); + displayContent.registerPointerEventListener(mSystemGestures); + } mAppTransitionListener = new WindowManagerInternal.AppTransitionListener() { private Runnable mAppTransitionPending = () -> { @@ -648,7 +654,9 @@ public class DisplayPolicy { mContext, () -> { synchronized (mLock) { onConfigurationChanged(); - mSystemGestures.onConfigurationChanged(); + if (!CLIENT_TRANSIENT) { + mSystemGestures.onConfigurationChanged(); + } mDisplayContent.updateSystemGestureExclusion(); } }); @@ -670,7 +678,9 @@ public class DisplayPolicy { } void systemReady() { - mSystemGestures.systemReady(); + if (!CLIENT_TRANSIENT) { + mSystemGestures.systemReady(); + } if (mService.mPointerLocationEnabled) { setPointerLocationEnabled(true); } @@ -1317,7 +1327,9 @@ public class DisplayPolicy { } void onDisplayInfoChanged(DisplayInfo info) { - mSystemGestures.onDisplayInfoChanged(info); + if (!CLIENT_TRANSIENT) { + mSystemGestures.onDisplayInfoChanged(info); + } } /** @@ -1690,7 +1702,9 @@ public class DisplayPolicy { // Update the latest display size, cutout. mDisplayContent.updateDisplayInfo(); onConfigurationChanged(); - mSystemGestures.onConfigurationChanged(); + if (!CLIENT_TRANSIENT) { + mSystemGestures.onConfigurationChanged(); + } } /** @@ -1963,6 +1977,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; @@ -2613,7 +2630,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 + " "); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java index c8fdee06f3e4..beabfde45aa0 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java @@ -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; @@ -61,6 +62,7 @@ import android.view.WindowManager; import androidx.test.filters.SmallTest; +import org.junit.Assume; import org.junit.Test; import org.junit.runner.RunWith; @@ -379,6 +381,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()); @@ -400,6 +403,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; -- cgit v1.2.3-59-g8ed1b