Merge "Introduce Client Transient flag (1/n)" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
de6724e24f
@@ -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
|
||||
|
||||
@@ -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 + " ");
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user