Allow remote inset transient bar configuration
Allow an OEM to configure the show transient behavior when using a
RemoteInsetsControlTarget.
Bug: 231351266
Test: manual, atest
com.android.server.wm.DisplayPolicyTests#testCanSystemBarsBeShownByUser
Change-Id: I2555b437ed62ea26f85dade6faa9c3a3cbc24593
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 622414e..abcee9d 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -757,6 +757,15 @@
bar for all apps. -->
<bool name="config_remoteInsetsControllerControlsSystemBars">false</bool>
+ <!-- Control whether the system bars can be requested when using a remote insets control target.
+ This allows for specifying whether or not system bars can be shown by the user (via swipe
+ or other means) when they are hidden by the logic defined by the remote insets controller.
+ This is useful for cases where the system provides alternative affordances for showing and
+ hiding the bars or for cases in which it's desired the bars not be shown for any reason.
+ This configuration will only apply when config_remoteInsetsControllerControlsSystemBars.
+ is set to true. -->
+ <bool name="config_remoteInsetsControllerSystemBarsCanBeShownByUserAction">false</bool>
+
<!-- HDMI behavior -->
<!-- The number of degrees to rotate the display when the device has HDMI connected
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 872da62..bc2c62c 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1726,6 +1726,7 @@
<java-symbol type="bool" name="config_enableLockBeforeUnlockScreen" />
<java-symbol type="bool" name="config_enableLockScreenRotation" />
<java-symbol type="bool" name="config_remoteInsetsControllerControlsSystemBars" />
+ <java-symbol type="bool" name="config_remoteInsetsControllerSystemBarsCanBeShownByUserAction" />
<java-symbol type="bool" name="config_lidControlsScreenLock" />
<java-symbol type="bool" name="config_lidControlsSleep" />
<java-symbol type="bool" name="config_lockDayNightMode" />
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 7ffa55f..a70282e 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -228,6 +228,7 @@
import android.window.IDisplayAreaOrganizer;
import android.window.TransitionRequestInfo;
+import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -1074,7 +1075,7 @@
mDisplayPolicy = new DisplayPolicy(mWmService, this);
mDisplayRotation = new DisplayRotation(mWmService, this);
mCloseToSquareMaxAspectRatio = mWmService.mContext.getResources().getFloat(
- com.android.internal.R.dimen.config_closeToSquareDisplayMaxAspectRatio);
+ R.dimen.config_closeToSquareDisplayMaxAspectRatio);
if (isDefaultDisplay) {
// The policy may be invoked right after here, so it requires the necessary default
// fields of this display content.
@@ -1566,7 +1567,7 @@
mAtmService.mContext.createConfigurationContext(getConfiguration());
final float minimalSize =
displayConfigurationContext.getResources().getDimension(
- com.android.internal.R.dimen.default_minimal_size_resizable_task);
+ R.dimen.default_minimal_size_resizable_task);
if (Double.compare(mDisplayMetrics.density, 0.0) == 0) {
throw new IllegalArgumentException("Display with ID=" + getDisplayId() + "has invalid "
+ "DisplayMetrics.density= 0.0");
@@ -4550,9 +4551,9 @@
// if the wallpaper service is disabled on the device, we're never going to have
// wallpaper, don't bother waiting for it
boolean wallpaperEnabled = mWmService.mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_enableWallpaperService)
+ R.bool.config_enableWallpaperService)
&& mWmService.mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_checkWallpaperAtBoot);
+ R.bool.config_checkWallpaperAtBoot);
final boolean haveBootMsg = drawnWindowTypes.get(TYPE_BOOT_PROGRESS);
final boolean haveApp = drawnWindowTypes.get(TYPE_BASE_APPLICATION);
@@ -6505,9 +6506,12 @@
class RemoteInsetsControlTarget implements InsetsControlTarget {
private final IDisplayWindowInsetsController mRemoteInsetsController;
private final InsetsVisibilities mRequestedVisibilities = new InsetsVisibilities();
+ private final boolean mCanShowTransient;
RemoteInsetsControlTarget(IDisplayWindowInsetsController controller) {
mRemoteInsetsController = controller;
+ mCanShowTransient = mWmService.mContext.getResources().getBoolean(
+ R.bool.config_remoteInsetsControllerSystemBarsCanBeShownByUserAction);
}
/**
@@ -6563,6 +6567,11 @@
}
@Override
+ public boolean canShowTransient() {
+ return mCanShowTransient;
+ }
+
+ @Override
public boolean getRequestedVisibility(@InternalInsetsType int type) {
if (type == ITYPE_IME) {
return getInsetsStateController().getImeSourceProvider().isImeShowing();
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 98a51a9..e5282f7 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -219,6 +219,7 @@
@Px
private int mRightGestureInset;
+ private boolean mCanSystemBarsBeShownByUser;
private boolean mNavButtonForcedVisible;
StatusBarManagerInternal getStatusBarManagerInternal() {
@@ -424,6 +425,9 @@
final Resources r = mContext.getResources();
mCarDockEnablesAccelerometer = r.getBoolean(R.bool.config_carDockEnablesAccelerometer);
mDeskDockEnablesAccelerometer = r.getBoolean(R.bool.config_deskDockEnablesAccelerometer);
+ mCanSystemBarsBeShownByUser = !r.getBoolean(
+ R.bool.config_remoteInsetsControllerControlsSystemBars) || r.getBoolean(
+ R.bool.config_remoteInsetsControllerSystemBarsCanBeShownByUserAction);
mAccessibilityManager = (AccessibilityManager) mContext.getSystemService(
Context.ACCESSIBILITY_SERVICE);
@@ -616,7 +620,7 @@
displayContent.mAppTransition.registerListenerLocked(mAppTransitionListener);
displayContent.mTransitionController.registerLegacyListener(mAppTransitionListener);
mImmersiveModeConfirmation = new ImmersiveModeConfirmation(mContext, looper,
- mService.mVrModeEnabled);
+ mService.mVrModeEnabled, mCanSystemBarsBeShownByUser);
// TODO: Make it can take screenshot on external display
mScreenshotHelper = displayContent.isDefaultDisplay
@@ -2019,6 +2023,11 @@
return lp.width;
}
+ @VisibleForTesting
+ void setCanSystemBarsBeShownByUser(boolean canBeShown) {
+ mCanSystemBarsBeShownByUser = canBeShown;
+ }
+
void notifyDisplayReady() {
mHandler.post(() -> {
final int displayId = getDisplayId();
@@ -2256,11 +2265,17 @@
updateSystemBarAttributes();
}
- private void requestTransientBars(WindowState swipeTarget, boolean isGestureOnSystemBar) {
+ @VisibleForTesting
+ void requestTransientBars(WindowState swipeTarget, boolean isGestureOnSystemBar) {
if (swipeTarget == null || !mService.mPolicy.isUserSetupComplete()) {
// Swipe-up for navigation bar is disabled during setup
return;
}
+ if (!mCanSystemBarsBeShownByUser) {
+ Slog.d(TAG, "Remote insets controller disallows showing system bars - ignoring "
+ + "request");
+ return;
+ }
final InsetsSourceProvider provider = swipeTarget.getControllableInsetProvider();
final InsetsControlTarget controlTarget = provider != null
? provider.getControlTarget() : null;
diff --git a/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java b/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java
index 93bdf16..4c18d0b 100644
--- a/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java
+++ b/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java
@@ -99,9 +99,11 @@
// Local copy of vr mode enabled state, to avoid calling into VrManager with
// the lock held.
private boolean mVrModeEnabled;
+ private boolean mCanSystemBarsBeShownByUser;
private int mLockTaskState = LOCK_TASK_MODE_NONE;
- ImmersiveModeConfirmation(Context context, Looper looper, boolean vrModeEnabled) {
+ ImmersiveModeConfirmation(Context context, Looper looper, boolean vrModeEnabled,
+ boolean canSystemBarsBeShownByUser) {
final Display display = context.getDisplay();
final Context uiContext = ActivityThread.currentActivityThread().getSystemUiContext();
mContext = display.getDisplayId() == DEFAULT_DISPLAY
@@ -111,6 +113,7 @@
mPanicThresholdMs = context.getResources()
.getInteger(R.integer.config_immersive_mode_confirmation_panic);
mVrModeEnabled = vrModeEnabled;
+ mCanSystemBarsBeShownByUser = canSystemBarsBeShownByUser;
}
private long getNavBarExitDuration() {
@@ -171,6 +174,7 @@
if ((DEBUG_SHOW_EVERY_TIME || !sConfirmed)
&& userSetupComplete
&& !mVrModeEnabled
+ && mCanSystemBarsBeShownByUser
&& !navBarEmpty
&& !UserManager.isDeviceInDemoMode(mContext)
&& (mLockTaskState != LOCK_TASK_MODE_LOCKED)) {
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 2b131e1..8f2e9b4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -45,7 +45,12 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.graphics.PixelFormat;
@@ -344,4 +349,24 @@
final InsetsSource navBarSource = state.peekSource(ITYPE_NAVIGATION_BAR);
assertEquals(attrs.height - 10, navBarSource.getFrame().height());
}
+
+ @Test
+ public void testCanSystemBarsBeShownByUser() {
+ ((TestWindowManagerPolicy) mWm.mPolicy).mIsUserSetupComplete = true;
+ final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
+ final WindowState windowState = mock(WindowState.class);
+ final InsetsSourceProvider provider = mock(InsetsSourceProvider.class);
+ final InsetsControlTarget controlTarget = mock(InsetsControlTarget.class);
+ when(provider.getControlTarget()).thenReturn(controlTarget);
+ when(windowState.getControllableInsetProvider()).thenReturn(provider);
+ when(controlTarget.getRequestedVisibility(anyInt())).thenReturn(true);
+
+ displayPolicy.setCanSystemBarsBeShownByUser(false);
+ displayPolicy.requestTransientBars(windowState, true);
+ verify(controlTarget, never()).showInsets(anyInt(), anyBoolean());
+
+ displayPolicy.setCanSystemBarsBeShownByUser(true);
+ displayPolicy.requestTransientBars(windowState, true);
+ verify(controlTarget).showInsets(anyInt(), anyBoolean());
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 92457c7..851be9d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -40,6 +40,7 @@
boolean mKeyguardShowingAndNotOccluded = false;
boolean mOkToAnimate = true;
+ boolean mIsUserSetupComplete = false;
TestWindowManagerPolicy() {
}
@@ -284,7 +285,7 @@
@Override
public boolean isUserSetupComplete() {
- return false;
+ return mIsUserSetupComplete;
}
@Override