diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 639f509915b30..81704862710cd 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -7412,6 +7412,14 @@ public static void setShowGTalkServiceStatusForUser(ContentResolver cr, boolean */ public static final String GESTURE_NAVBAR_HEIGHT_MODE = "gesture_navbar_height_mode"; + /** + * Controls the amount of space reserved for the gesture navigation bar. + * Supported modes: 0 for default, 1 for compact and 2 for minimal. + * @hide + */ + public static final String GESTURE_NAVBAR_SPACE_MODE = + "gesture_navbar_space_mode"; + /** * Whether allowing pocket service to register sensors and dispatch informations. * 0 = disabled diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 2ff2e71dcefc6..33cb3a53f9eec 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -65,6 +65,7 @@ import static android.view.WindowManagerGlobal.ADD_OKAY; import static android.view.WindowManagerPolicyConstants.ACTION_HDMI_PLUGGED; import static android.view.WindowManagerPolicyConstants.EXTRA_HDMI_PLUGGED_STATE; +import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; import static android.window.DesktopExperienceFlags.ENABLE_RESTRICT_FREEFORM_HIDDEN_SYSTEM_BARS_TO_FILLING_TASKS; import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED; @@ -191,6 +192,13 @@ public class DisplayPolicy { private static final int INSETS_OVERRIDE_INDEX_INVALID = -1; + private static final int GESTURE_NAVBAR_SPACE_DEFAULT = 0; + private static final int GESTURE_NAVBAR_SPACE_COMPACT = 1; + private static final int GESTURE_NAVBAR_SPACE_MINIMAL = 2; + + // Compact uses 50% of the provider's original inset. + private static final float GESTURE_NAVBAR_COMPACT_SCALE = 0.50f; + // TODO(b/266197298): Remove this by a more general protocol from the insets providers. private static final boolean USE_CACHED_INSETS_FOR_DISPLAY_SWITCH = SystemProperties.getBoolean("persist.wm.debug.cached_insets_switch", true); @@ -260,6 +268,8 @@ UiModeManagerInternal getUiModeManagerInternal() { private volatile boolean mHasStatusBar; private volatile boolean mHasNavigationBar; private volatile boolean mTaskBarEnabled; + private volatile int mGestureNavbarSpaceMode = + GESTURE_NAVBAR_SPACE_DEFAULT; // Can the navigation bar ever move to the side? private volatile boolean mNavigationBarCanMove; private volatile boolean mNavigationBarAlwaysShowOnSideGesture; @@ -457,13 +467,23 @@ public SettingsObserver(Handler handler) { resolver.registerContentObserver(LineageSettings.System.getUriFor( LineageSettings.System.ENABLE_TASKBAR), false, this, UserHandle.USER_ALL); + resolver.registerContentObserver( + Settings.System.getUriFor( + Settings.System.GESTURE_NAVBAR_SPACE_MODE), + false, + this, + UserHandle.USER_ALL); updateSettings(); } @Override public void onChange(boolean selfChange) { - updateSettings(); + synchronized (mLock) { + updateSettings(); + mDisplayContent.setLayoutNeeded(); + mService.requestTraversal(); + } } } @@ -799,6 +819,12 @@ public void updateSettings() { mTaskBarEnabled = LineageSettings.System.getIntForUser(resolver, LineageSettings.System.ENABLE_TASKBAR, isTablet() ? 1 : 0, UserHandle.USER_CURRENT) != 0; + + mGestureNavbarSpaceMode = Settings.System.getIntForUser( + resolver, + Settings.System.GESTURE_NAVBAR_SPACE_MODE, + GESTURE_NAVBAR_SPACE_DEFAULT, + UserHandle.USER_CURRENT); } private boolean isTablet() { @@ -1328,8 +1354,51 @@ void addWindowLw(WindowState win, WindowManager.LayoutParams attrs) { } } + private static int scaleGestureNavbarInset(int value) { + if (value <= 0) { + return value; + } + return Math.max( + 1, + Math.round(value * GESTURE_NAVBAR_COMPACT_SCALE)); + } + + @Nullable + private Insets adjustGestureNavbarInsets( + InsetsFrameProvider provider, + @Nullable Insets originalInsets) { + if (provider.getType() != Type.navigationBars()) { + return originalInsets; + } + + final int interactionMode = getCurrentUserResources().getInteger( + R.integer.config_navBarInteractionMode); + if (interactionMode != NAV_BAR_MODE_GESTURAL) { + return originalInsets; + } + + switch (mGestureNavbarSpaceMode) { + case GESTURE_NAVBAR_SPACE_COMPACT: + if (originalInsets == null) { + return null; + } + return Insets.of( + scaleGestureNavbarInset(originalInsets.left), + scaleGestureNavbarInset(originalInsets.top), + scaleGestureNavbarInset(originalInsets.right), + scaleGestureNavbarInset(originalInsets.bottom)); + + case GESTURE_NAVBAR_SPACE_MINIMAL: + return Insets.NONE; + + case GESTURE_NAVBAR_SPACE_DEFAULT: + default: + return originalInsets; + } + } + @NonNull - private static TriFunction getFrameProvider( + private TriFunction getFrameProvider( WindowState win, int index, int overrideIndex) { return (displayFrames, windowState, inOutFrame) -> { final LayoutParams lp = win.mAttrs.forRotation(displayFrames.mRotation); @@ -1352,10 +1421,12 @@ private static TriFunction getFramePr inOutFrame.set(ifp.getArbitraryRectangle()); break; } - final Insets insetsSize = overrideIndex == INSETS_OVERRIDE_INDEX_INVALID + Insets insetsSize = overrideIndex == INSETS_OVERRIDE_INDEX_INVALID ? ifp.getInsetsSize() : ifp.getInsetsSizeOverrides()[overrideIndex].getInsetsSize(); + insetsSize = adjustGestureNavbarInsets(ifp, insetsSize); + if (ifp.getMinimalInsetsSizeInDisplayCutoutSafe() != null) { sTmpRect2.set(inOutFrame); }