Refactor force visible nav bar into new secure setting.

Decouples force visible from kids mode setting.

Bug: 217668440
Test: manual
Change-Id: I363a2507cd1b073f44ed91e96b1dce7b3cd347c4
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index e460638..c6e36a3 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -335,7 +335,7 @@
      * Constant for {@link #setNavBarMode(int)} indicating kids navbar mode.
      *
      * <p>When used, back and home icons will change drawables and layout, recents will be hidden,
-     * and the navbar will remain visible when apps are in immersive mode.
+     * and enables the setting to force navbar visible, even when apps are in immersive mode.
      *
      * @hide
      */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 528156f..03e3d45 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10259,6 +10259,14 @@
                 "theme_customization_overlay_packages";
 
         /**
+         * Indicates whether the nav bar is forced to always be visible, even in immersive mode.
+         * <p>Type: int (0 for false, 1 for true)
+         *
+         * @hide
+         */
+        public static final String NAV_BAR_FORCE_VISIBLE = "nav_bar_force_visible";
+
+        /**
          * Indicates whether the device is in kids nav mode.
          * <p>Type: int (0 for false, 1 for true)
          *
diff --git a/core/java/com/android/internal/policy/ForceShowNavigationBarSettingsObserver.java b/core/java/com/android/internal/policy/ForceShowNavigationBarSettingsObserver.java
index 3e72564..75dce5a 100644
--- a/core/java/com/android/internal/policy/ForceShowNavigationBarSettingsObserver.java
+++ b/core/java/com/android/internal/policy/ForceShowNavigationBarSettingsObserver.java
@@ -26,7 +26,7 @@
 /**
  * A ContentObserver for listening force show navigation bar relative setting keys:
  *  - {@link Settings.Secure#NAVIGATION_MODE}
- *  - {@link Settings.Secure#NAV_BAR_KIDS_MODE}
+ *  - {@link Settings.Secure#NAV_BAR_FORCE_VISIBLE}
  *
  * @hide
  */
@@ -52,7 +52,7 @@
                 Settings.Secure.getUriFor(Settings.Secure.NAVIGATION_MODE),
                 false, this, UserHandle.USER_ALL);
         r.registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.NAV_BAR_KIDS_MODE),
+                Settings.Secure.getUriFor(Settings.Secure.NAV_BAR_FORCE_VISIBLE),
                 false, this, UserHandle.USER_ALL);
     }
 
@@ -78,6 +78,6 @@
         return Settings.Secure.getIntForUser(mContext.getContentResolver(),
                 Settings.Secure.NAVIGATION_MODE, 0, UserHandle.USER_CURRENT) == 0
                 && Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                Settings.Secure.NAV_BAR_KIDS_MODE, 0, UserHandle.USER_CURRENT) == 1;
+                Settings.Secure.NAV_BAR_FORCE_VISIBLE, 0, UserHandle.USER_CURRENT) == 1;
     }
 }
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 4c0ba8c..6a421f0 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -385,7 +385,18 @@
 
     optional SettingProto multi_press_timeout = 38 [ (android.privacy).dest = DEST_AUTOMATIC ];
 
-    optional SettingProto nav_bar_kids_mode = 91 [ (android.privacy).dest = DEST_AUTOMATIC ];
+    message NavBar {
+        option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+        // Nav bar is forced to always be visible, even in immersive mode.
+        optional SettingProto nav_bar_force_visible = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        // Indicates whether the device is in kids nav mode.
+        optional SettingProto nav_bar_kids_mode = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+    }
+    optional NavBar nav_bar = 92;
+    reserved 91; // Formerly nav_bar_kids_mode
+    reserved "nav_bar_kids_mode"; // Moved to message NavBar
+
     optional SettingProto navigation_mode = 76 [ (android.privacy).dest = DEST_AUTOMATIC ];
 
     message NfcPayment {
@@ -668,5 +679,5 @@
 
     // Please insert fields in alphabetical order and group them into messages
     // if possible (to avoid reaching the method limit).
-    // Next tag = 92;
+    // Next tag = 93;
 }
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 5f549fd..71b3ee8 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -229,6 +229,7 @@
         VALIDATORS.put(Secure.SKIP_DIRECTION, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.SILENCE_GESTURE, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES, JSON_OBJECT_VALIDATOR);
+        VALIDATORS.put(Secure.NAV_BAR_FORCE_VISIBLE, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.NAV_BAR_KIDS_MODE, BOOLEAN_VALIDATOR);
         VALIDATORS.put(
                 Secure.NAVIGATION_MODE, new DiscreteValueValidator(new String[] {"0", "1", "2"}));
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index a2b6992..1c5bf81 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2253,8 +2253,11 @@
                 SecureSettingsProto.MULTI_PRESS_TIMEOUT);
 
         dumpSetting(s, p,
+                Settings.Secure.NAV_BAR_FORCE_VISIBLE,
+                SecureSettingsProto.NavBar.NAV_BAR_FORCE_VISIBLE);
+        dumpSetting(s, p,
                 Settings.Secure.NAV_BAR_KIDS_MODE,
-                SecureSettingsProto.NAV_BAR_KIDS_MODE);
+                SecureSettingsProto.NavBar.NAV_BAR_KIDS_MODE);
 
         dumpSetting(s, p,
                 Settings.Secure.NAVIGATION_MODE,
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index e4a969b..35d2f18 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -1952,8 +1952,7 @@
     public void setNavBarMode(@NavBarMode int navBarMode) {
         enforceStatusBar();
         if (navBarMode != NAV_BAR_MODE_DEFAULT && navBarMode != NAV_BAR_MODE_KIDS) {
-            throw new UnsupportedOperationException(
-                    "Supplied navBarMode not supported: " + navBarMode);
+            throw new IllegalArgumentException("Supplied navBarMode not supported: " + navBarMode);
         }
 
         final int userId = mCurrentUserId;
@@ -1961,6 +1960,8 @@
         try {
             Settings.Secure.putIntForUser(mContext.getContentResolver(),
                     Settings.Secure.NAV_BAR_KIDS_MODE, navBarMode, userId);
+            Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                    Settings.Secure.NAV_BAR_FORCE_VISIBLE, navBarMode, userId);
 
             IOverlayManager overlayManager = getOverlayManager();
             if (overlayManager != null && navBarMode == NAV_BAR_MODE_KIDS