Merge "Controls in Lockscreen Dialog" into sc-dev
diff --git a/apct-tests/perftests/core/src/android/app/ResourcesManagerPerfTest.java b/apct-tests/perftests/core/src/android/app/ResourcesManagerPerfTest.java
index d3938f4..afd8e29 100644
--- a/apct-tests/perftests/core/src/android/app/ResourcesManagerPerfTest.java
+++ b/apct-tests/perftests/core/src/android/app/ResourcesManagerPerfTest.java
@@ -77,7 +77,7 @@
     }
 
     private void getResourcesForPath(String path) {
-        ResourcesManager.getInstance().getResources(null, path, null, null, null,
+        ResourcesManager.getInstance().getResources(null, path, null, null, null, null,
                 Display.DEFAULT_DISPLAY, null, sContext.getResources().getCompatibilityInfo(),
                 null, null);
     }
diff --git a/apct-tests/perftests/core/src/android/app/ResourcesThemePerfTest.java b/apct-tests/perftests/core/src/android/app/ResourcesThemePerfTest.java
index f4c0a17..45c723b 100644
--- a/apct-tests/perftests/core/src/android/app/ResourcesThemePerfTest.java
+++ b/apct-tests/perftests/core/src/android/app/ResourcesThemePerfTest.java
@@ -95,8 +95,9 @@
                 ? Configuration.ORIENTATION_LANDSCAPE : Configuration.ORIENTATION_PORTRAIT;
 
         Resources destResources = resourcesManager.getResources(null, ai.sourceDir,
-                ai.splitSourceDirs, ai.resourceDirs, ai.sharedLibraryFiles, Display.DEFAULT_DISPLAY,
-                c, mContext.getResources().getCompatibilityInfo(), null, null);
+                ai.splitSourceDirs, ai.resourceDirs, ai.overlayPaths, ai.sharedLibraryFiles,
+                Display.DEFAULT_DISPLAY, c, mContext.getResources().getCompatibilityInfo(),
+                null, null);
         Assert.assertNotEquals(destResources.getAssets(), mContext.getAssets());
 
         Resources.Theme destTheme = destResources.newTheme();
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
index 3bbc945..271129b 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -38,6 +38,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.Log;
 
 import com.android.internal.util.Preconditions;
@@ -49,6 +50,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 
 /** TODO(b/142567528): add comments when implement this class */
 public class AppSearchManagerService extends SystemService {
@@ -56,6 +58,9 @@
     private PackageManagerInternal mPackageManagerInternal;
     private ImplInstanceManager mImplInstanceManager;
 
+    // Cache of unlocked user ids so we don't have to query UserManager service each time.
+    private final Set<Integer> mUnlockedUserIds = new ArraySet<>();
+
     public AppSearchManagerService(Context context) {
         super(context);
     }
@@ -67,6 +72,11 @@
         mImplInstanceManager = ImplInstanceManager.getInstance(getContext());
     }
 
+    @Override
+    public void onUserUnlocked(@NonNull TargetUser user) {
+        mUnlockedUserIds.add(user.getUserIdentifier());
+    }
+
     private class Stub extends IAppSearchManager.Stub {
         @Override
         public void setSchema(
@@ -86,6 +96,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 verifyCallingPackage(callingUid, packageName);
                 List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
                 for (int i = 0; i < schemaBundles.size(); i++) {
@@ -133,6 +144,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 verifyCallingPackage(callingUid, packageName);
                 AppSearchImpl impl =
                         mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
@@ -165,6 +177,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 verifyCallingPackage(callingUid, packageName);
                 AppSearchBatchResult.Builder<String, Void> resultBuilder =
                         new AppSearchBatchResult.Builder<>();
@@ -207,6 +220,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 verifyCallingPackage(callingUid, packageName);
                 AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
                         new AppSearchBatchResult.Builder<>();
@@ -253,6 +267,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 verifyCallingPackage(callingUid, packageName);
                 AppSearchImpl impl =
                         mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
@@ -287,6 +302,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 verifyCallingPackage(callingUid, packageName);
                 AppSearchImpl impl =
                         mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
@@ -318,6 +334,7 @@
             // TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
             // opened it
             try {
+                verifyUserUnlocked(callingUserId);
                 AppSearchImpl impl =
                         mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
                 SearchResultPage searchResultPage = impl.getNextPage(nextPageToken);
@@ -337,6 +354,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 AppSearchImpl impl =
                         mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
                 impl.invalidateNextPageToken(nextPageToken);
@@ -364,6 +382,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 AppSearchImpl impl =
                         mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
                 impl.reportUsage(packageName, databaseName, namespace, uri, usageTimeMillis);
@@ -392,6 +411,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 verifyCallingPackage(callingUid, packageName);
                 AppSearchBatchResult.Builder<String, Void> resultBuilder =
                         new AppSearchBatchResult.Builder<>();
@@ -431,6 +451,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 verifyCallingPackage(callingUid, packageName);
                 AppSearchImpl impl =
                         mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
@@ -453,6 +474,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 AppSearchImpl impl =
                         mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
                 impl.persistToDisk();
@@ -470,6 +492,7 @@
             int callingUserId = handleIncomingUser(userId, callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
+                verifyUserUnlocked(callingUserId);
                 mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
                 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
             } catch (Throwable t) {
@@ -479,6 +502,13 @@
             }
         }
 
+        private void verifyUserUnlocked(int callingUserId) {
+            if (!mUnlockedUserIds.contains(callingUserId)) {
+                throw new IllegalStateException(
+                        "User " + callingUserId + " is locked or not running.");
+            }
+        }
+
         private void verifyCallingPackage(int callingUid, @NonNull String callingPackage) {
             Preconditions.checkNotNull(callingPackage);
             if (mPackageManagerInternal.getPackageUid(
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java b/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java
index 97b1a8c..5ea2a02 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java
@@ -73,8 +73,8 @@
     /**
      * Gets an instance of AppSearchImpl for the given user.
      *
-     * <p>If no AppSearchImpl instance exists for this user, Icing will be initialized and one will
-     * be created.
+     * <p>If no AppSearchImpl instance exists for the unlocked user, Icing will be initialized and
+     * one will be created.
      *
      * @param context The context
      * @param userId The multi-user userId of the device user calling AppSearch
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 0774ac1..bb6a774 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2289,11 +2289,12 @@
      * Creates the top level resources for the given package. Will return an existing
      * Resources if one has already been created.
      */
-    Resources getTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs,
-            String[] libDirs, LoadedApk pkgInfo, Configuration overrideConfig) {
-        return mResourcesManager.getResources(null, resDir, splitResDirs, overlayDirs, libDirs,
-                null, overrideConfig, pkgInfo.getCompatibilityInfo(), pkgInfo.getClassLoader(),
-                null);
+    Resources getTopLevelResources(String resDir, String[] splitResDirs, String[] legacyOverlayDirs,
+                    String[] overlayPaths, String[] libDirs, LoadedApk pkgInfo,
+                    Configuration overrideConfig) {
+        return mResourcesManager.getResources(null, resDir, splitResDirs, legacyOverlayDirs,
+                overlayPaths, libDirs, null, overrideConfig, pkgInfo.getCompatibilityInfo(),
+                pkgInfo.getClassLoader(), null);
     }
 
     @UnsupportedAppUsage
@@ -2462,12 +2463,15 @@
     private static boolean isLoadedApkResourceDirsUpToDate(LoadedApk loadedApk,
             ApplicationInfo appInfo) {
         Resources packageResources = loadedApk.mResources;
-        String[] overlayDirs = ArrayUtils.defeatNullable(loadedApk.getOverlayDirs());
-        String[] resourceDirs = ArrayUtils.defeatNullable(appInfo.resourceDirs);
+        boolean resourceDirsUpToDate = Arrays.equals(
+                ArrayUtils.defeatNullable(appInfo.resourceDirs),
+                ArrayUtils.defeatNullable(loadedApk.getOverlayDirs()));
+        boolean overlayPathsUpToDate = Arrays.equals(
+                ArrayUtils.defeatNullable(appInfo.overlayPaths),
+                ArrayUtils.defeatNullable(loadedApk.getOverlayPaths()));
 
         return (packageResources == null || packageResources.getAssets().isUpToDate())
-                && overlayDirs.length == resourceDirs.length
-                && ArrayUtils.containsAll(overlayDirs, resourceDirs);
+                && resourceDirsUpToDate && overlayPathsUpToDate;
     }
 
     @UnsupportedAppUsage
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 8ac9139..062cab4 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1728,7 +1728,7 @@
         final Resources r = mContext.mMainThread.getTopLevelResources(
                 sameUid ? app.sourceDir : app.publicSourceDir,
                 sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
-                app.resourceDirs, app.sharedLibraryFiles,
+                app.resourceDirs, app.overlayPaths, app.sharedLibraryFiles,
                 mContext.mPackageInfo, configuration);
         if (r != null) {
             return r;
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 4ddeb8f..9a20e0f 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2345,6 +2345,7 @@
                 pi.getResDir(),
                 splitResDirs,
                 pi.getOverlayDirs(),
+                pi.getOverlayPaths(),
                 pi.getApplicationInfo().sharedLibraryFiles,
                 overrideDisplayId,
                 overrideConfig,
@@ -2442,6 +2443,7 @@
                 mPackageInfo.getResDir(),
                 paths,
                 mPackageInfo.getOverlayDirs(),
+                mPackageInfo.getOverlayPaths(),
                 mPackageInfo.getApplicationInfo().sharedLibraryFiles,
                 mForceDisplayOverrideInResources ? getDisplayId() : null,
                 null,
@@ -2558,7 +2560,8 @@
     Resources createWindowContextResources() {
         final String resDir = mPackageInfo.getResDir();
         final String[] splitResDirs = mPackageInfo.getSplitResDirs();
-        final String[] overlayDirs = mPackageInfo.getOverlayDirs();
+        final String[] legacyOverlayDirs = mPackageInfo.getOverlayDirs();
+        final String[] overlayPaths = mPackageInfo.getOverlayPaths();
         final String[] libDirs = mPackageInfo.getApplicationInfo().sharedLibraryFiles;
         final int displayId = getDisplayId();
         final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
@@ -2567,7 +2570,7 @@
         final List<ResourcesLoader> loaders = mResources.getLoaders();
 
         return mResourcesManager.createBaseTokenResources(mToken, resDir, splitResDirs,
-                overlayDirs, libDirs, displayId, null /* overrideConfig */,
+                legacyOverlayDirs, overlayPaths, libDirs, displayId, null /* overrideConfig */,
                 compatInfo, mClassLoader, loaders);
     }
 
@@ -2855,6 +2858,7 @@
                 packageInfo.getResDir(),
                 splitDirs,
                 packageInfo.getOverlayDirs(),
+                packageInfo.getOverlayPaths(),
                 packageInfo.getApplicationInfo().sharedLibraryFiles,
                 displayId,
                 overrideConfiguration,
diff --git a/core/java/android/app/GameManager.java b/core/java/android/app/GameManager.java
index 8b6570f..ac1fa1e 100644
--- a/core/java/android/app/GameManager.java
+++ b/core/java/android/app/GameManager.java
@@ -16,7 +16,9 @@
 
 package android.app;
 
+import android.Manifest;
 import android.annotation.IntDef;
+import android.annotation.RequiresPermission;
 import android.annotation.SystemService;
 import android.annotation.UserHandleAware;
 import android.content.Context;
@@ -73,8 +75,8 @@
     /**
      * Returns the game mode for the given package.
      */
-    // TODO(b/178111358): Add @RequiresPermission.
     @UserHandleAware
+    @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
     public @GameMode int getGameMode(String packageName) {
         try {
             return mService.getGameMode(packageName, mContext.getUserId());
@@ -86,8 +88,8 @@
     /**
      * Sets the game mode for the given package.
      */
-    // TODO(b/178111358): Add @RequiresPermission.
     @UserHandleAware
+    @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
     public void setGameMode(String packageName, @GameMode int gameMode) {
         try {
             mService.setGameMode(packageName, gameMode, mContext.getUserId());
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index c01b5a3..be426aa 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -113,7 +113,8 @@
     private String mAppDir;
     @UnsupportedAppUsage
     private String mResDir;
-    private String[] mOverlayDirs;
+    private String[] mLegacyOverlayDirs;
+    private String[] mOverlayPaths;
     @UnsupportedAppUsage
     private String mDataDir;
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -222,7 +223,8 @@
         mSplitAppDirs = null;
         mSplitResDirs = null;
         mSplitClassLoaderNames = null;
-        mOverlayDirs = null;
+        mLegacyOverlayDirs = null;
+        mOverlayPaths = null;
         mDataDir = null;
         mDataDirFile = null;
         mDeviceProtectedDataDirFile = null;
@@ -364,8 +366,8 @@
                 }
 
                 mResources = ResourcesManager.getInstance().getResources(null, mResDir,
-                        splitPaths, mOverlayDirs, mApplicationInfo.sharedLibraryFiles,
-                        null, null, getCompatibilityInfo(),
+                        splitPaths, mLegacyOverlayDirs, mOverlayPaths,
+                        mApplicationInfo.sharedLibraryFiles, null, null, getCompatibilityInfo(),
                         getClassLoader(), mApplication == null ? null
                                 : mApplication.getResources().getLoaders());
             }
@@ -379,7 +381,8 @@
         mApplicationInfo = aInfo;
         mAppDir = aInfo.sourceDir;
         mResDir = aInfo.uid == myUid ? aInfo.sourceDir : aInfo.publicSourceDir;
-        mOverlayDirs = aInfo.resourceDirs;
+        mLegacyOverlayDirs = aInfo.resourceDirs;
+        mOverlayPaths = aInfo.overlayPaths;
         mDataDir = aInfo.dataDir;
         mLibDir = aInfo.nativeLibraryDir;
         mDataDirFile = FileUtils.newFileOrNull(aInfo.dataDir);
@@ -1213,9 +1216,19 @@
         return mSplitResDirs;
     }
 
+    /**
+     * Corresponds to {@link ApplicationInfo#resourceDirs}.
+     */
     @UnsupportedAppUsage
     public String[] getOverlayDirs() {
-        return mOverlayDirs;
+        return mLegacyOverlayDirs;
+    }
+
+    /**
+     * Corresponds to {@link ApplicationInfo#overlayPaths}.
+     */
+    public String[] getOverlayPaths() {
+        return mOverlayPaths;
     }
 
     public String getDataDir() {
@@ -1252,8 +1265,8 @@
             }
 
             mResources = ResourcesManager.getInstance().getResources(null, mResDir,
-                    splitPaths, mOverlayDirs, mApplicationInfo.sharedLibraryFiles,
-                    null, null, getCompatibilityInfo(),
+                    splitPaths, mLegacyOverlayDirs, mOverlayPaths,
+                    mApplicationInfo.sharedLibraryFiles, null, null, getCompatibilityInfo(),
                     getClassLoader(), null);
         }
         return mResources;
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 772833cc..ac8d3a2 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -39,6 +39,7 @@
 import android.os.Process;
 import android.os.Trace;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.Pair;
@@ -60,6 +61,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Objects;
 import java.util.WeakHashMap;
@@ -174,8 +176,8 @@
          * based on.
          *
          * @see #activityResources
-         * @see #getResources(IBinder, String, String[], String[], String[], Integer, Configuration,
-         * CompatibilityInfo, ClassLoader, List)
+         * @see #getResources(IBinder, String, String[], String[], String[], String[], Integer,
+         * Configuration, CompatibilityInfo, ClassLoader, List)
          */
         public final Configuration overrideConfig = new Configuration();
 
@@ -482,8 +484,8 @@
             }
         }
 
-        if (key.mOverlayDirs != null) {
-            for (final String idmapPath : key.mOverlayDirs) {
+        if (key.mOverlayPaths != null) {
+            for (final String idmapPath : key.mOverlayPaths) {
                 apkKeys.add(new ApkKey(idmapPath, false /*sharedLib*/, true /*overlay*/));
             }
         }
@@ -783,14 +785,16 @@
 
     /**
      * Creates base resources for a binder token. Calls to
-     * {@link #getResources(IBinder, String, String[], String[], String[], Integer, Configuration,
-     * CompatibilityInfo, ClassLoader, List)} with the same binder token will have their override
-     * configurations merged with the one specified here.
+     *
+     * {@link #getResources(IBinder, String, String[], String[], String[], String[], Integer,
+     * Configuration, CompatibilityInfo, ClassLoader, List)} with the same binder token will have
+     * their override configurations merged with the one specified here.
      *
      * @param token Represents an {@link Activity} or {@link WindowContext}.
      * @param resDir The base resource path. Can be null (only framework resources will be loaded).
      * @param splitResDirs An array of split resource paths. Can be null.
-     * @param overlayDirs An array of overlay paths. Can be null.
+     * @param legacyOverlayDirs An array of overlay APK paths. Can be null.
+     * @param overlayPaths An array of overlay APK and non-APK paths. Can be null.
      * @param libDirs An array of resource library paths. Can be null.
      * @param displayId The ID of the display for which to create the resources.
      * @param overrideConfig The configuration to apply on top of the base configuration. Can be
@@ -804,7 +808,8 @@
     public @Nullable Resources createBaseTokenResources(@NonNull IBinder token,
             @Nullable String resDir,
             @Nullable String[] splitResDirs,
-            @Nullable String[] overlayDirs,
+            @Nullable String[] legacyOverlayDirs,
+            @Nullable String[] overlayPaths,
             @Nullable String[] libDirs,
             int displayId,
             @Nullable Configuration overrideConfig,
@@ -817,7 +822,7 @@
             final ResourcesKey key = new ResourcesKey(
                     resDir,
                     splitResDirs,
-                    overlayDirs,
+                    combinedOverlayPaths(legacyOverlayDirs, overlayPaths),
                     libDirs,
                     displayId,
                     overrideConfig,
@@ -1043,7 +1048,8 @@
      * @param activityToken Represents an Activity. If null, global resources are assumed.
      * @param resDir The base resource path. Can be null (only framework resources will be loaded).
      * @param splitResDirs An array of split resource paths. Can be null.
-     * @param overlayDirs An array of overlay paths. Can be null.
+     * @param legacyOverlayDirs An array of overlay APK paths. Can be null.
+     * @param overlayPaths An array of overlay APK and non-APK paths. Can be null.
      * @param libDirs An array of resource library paths. Can be null.
      * @param overrideDisplayId The ID of the display for which the returned Resources should be
      * based. This will cause display-based configuration properties to override those of the base
@@ -1063,7 +1069,8 @@
             @Nullable IBinder activityToken,
             @Nullable String resDir,
             @Nullable String[] splitResDirs,
-            @Nullable String[] overlayDirs,
+            @Nullable String[] legacyOverlayDirs,
+            @Nullable String[] overlayPaths,
             @Nullable String[] libDirs,
             @Nullable Integer overrideDisplayId,
             @Nullable Configuration overrideConfig,
@@ -1075,7 +1082,7 @@
             final ResourcesKey key = new ResourcesKey(
                     resDir,
                     splitResDirs,
-                    overlayDirs,
+                    combinedOverlayPaths(legacyOverlayDirs, overlayPaths),
                     libDirs,
                     overrideDisplayId != null ? overrideDisplayId : INVALID_DISPLAY,
                     overrideConfig,
@@ -1250,7 +1257,7 @@
 
         // Create the new ResourcesKey with the rebased override config.
         final ResourcesKey newKey = new ResourcesKey(oldKey.mResDir,
-                oldKey.mSplitResDirs, oldKey.mOverlayDirs, oldKey.mLibDirs,
+                oldKey.mSplitResDirs, oldKey.mOverlayPaths, oldKey.mLibDirs,
                 displayId, rebasedOverrideConfig, oldKey.mCompatInfo, oldKey.mLoaders);
 
         if (DEBUG) {
@@ -1393,7 +1400,7 @@
                         updatedResourceKeys.put(impl, new ResourcesKey(
                                 key.mResDir,
                                 key.mSplitResDirs,
-                                key.mOverlayDirs,
+                                key.mOverlayPaths,
                                 newLibAssets,
                                 key.mDisplayId,
                                 key.mOverrideConfiguration,
@@ -1423,7 +1430,8 @@
 
             // ApplicationInfo is mutable, so clone the arrays to prevent outside modification
             String[] copiedSplitDirs = ArrayUtils.cloneOrNull(newSplitDirs);
-            String[] copiedResourceDirs = ArrayUtils.cloneOrNull(appInfo.resourceDirs);
+            String[] copiedResourceDirs = combinedOverlayPaths(appInfo.resourceDirs,
+                    appInfo.overlayPaths);
 
             final ArrayMap<ResourcesImpl, ResourcesKey> updatedResourceKeys = new ArrayMap<>();
             final int implCount = mResourceImpls.size();
@@ -1458,6 +1466,39 @@
         }
     }
 
+    /**
+     * Creates an array with the contents of {@param overlayPaths} and the unique elements of
+     * {@param resourceDirs}.
+     *
+     * {@link ApplicationInfo#resourceDirs} only contains paths of overlays APKs.
+     * {@link ApplicationInfo#overlayPaths} was created to contain paths of overlay of varying file
+     * formats. It also contains the contents of {@code resourceDirs} because the order of loaded
+     * overlays matter. In case {@code resourceDirs} contains overlay APK paths that are not present
+     * in overlayPaths (perhaps an app inserted an additional overlay path into a
+     * {@code resourceDirs}), this method is used to combine the contents of {@code resourceDirs}
+     * that do not exist in {@code overlayPaths}} and {@code overlayPaths}}.
+     */
+    @Nullable
+    private static String[] combinedOverlayPaths(@Nullable String[] resourceDirs,
+            @Nullable String[] overlayPaths) {
+        if (resourceDirs == null) {
+            return ArrayUtils.cloneOrNull(overlayPaths);
+        } else if(overlayPaths == null) {
+            return ArrayUtils.cloneOrNull(resourceDirs);
+        } else {
+            final ArrayList<String> paths = new ArrayList<>();
+            for (final String path : overlayPaths) {
+                paths.add(path);
+            }
+            for (final String path : resourceDirs) {
+                if (!paths.contains(path)) {
+                    paths.add(path);
+                }
+            }
+            return paths.toArray(new String[0]);
+        }
+    }
+
     private void redirectResourcesToNewImplLocked(
             @NonNull final ArrayMap<ResourcesImpl, ResourcesKey> updatedResourceKeys) {
         // Bail early if there is no work to do.
@@ -1559,7 +1600,7 @@
                 final ResourcesKey newKey = new ResourcesKey(
                         oldKey.mResDir,
                         oldKey.mSplitResDirs,
-                        oldKey.mOverlayDirs,
+                        oldKey.mOverlayPaths,
                         oldKey.mLibDirs,
                         oldKey.mDisplayId,
                         oldKey.mOverrideConfiguration,
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 82255c8..ff41d1c8 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -13328,6 +13328,7 @@
      * @return true if the app can grant device sensors-related permissions, false otherwise.
      */
     public boolean canAdminGrantSensorsPermissions() {
+        throwIfParentInstance("canAdminGrantSensorsPermissions");
         return canAdminGrantSensorsPermissionsForUser(myUserId());
     }
 
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 6ec1169..01ff432 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -923,6 +923,14 @@
     public String[] resourceDirs;
 
     /**
+     * Contains the contents of {@link #resourceDirs} and along with paths for overlays that may or
+     * may not be APK packages.
+     *
+     * {@hide}
+     */
+    public String[] overlayPaths;
+
+    /**
      * String retrieved from the seinfo tag found in selinux policy. This value can be set through
      * the mac_permissions.xml policy construct. This value is used for setting an SELinux security
      * context on the process as well as its data directory.
@@ -1472,6 +1480,9 @@
         if (resourceDirs != null) {
             pw.println(prefix + "resourceDirs=" + Arrays.toString(resourceDirs));
         }
+        if (overlayPaths != null) {
+            pw.println(prefix + "overlayPaths=" + Arrays.toString(overlayPaths));
+        }
         if ((dumpFlags & DUMP_FLAG_DETAILS) != 0 && seInfo != null) {
             pw.println(prefix + "seinfo=" + seInfo);
             pw.println(prefix + "seinfoUser=" + seInfoUser);
@@ -1568,6 +1579,11 @@
                 proto.write(ApplicationInfoProto.RESOURCE_DIRS, dir);
             }
         }
+        if (overlayPaths != null) {
+            for (String dir : overlayPaths) {
+                proto.write(ApplicationInfoProto.OVERLAY_PATHS, dir);
+            }
+        }
         proto.write(ApplicationInfoProto.DATA_DIR, dataDir);
         proto.write(ApplicationInfoProto.CLASS_LOADER_NAME, classLoaderName);
         if (!ArrayUtils.isEmpty(splitClassLoaderNames)) {
@@ -1717,6 +1733,7 @@
         primaryCpuAbi = orig.primaryCpuAbi;
         secondaryCpuAbi = orig.secondaryCpuAbi;
         resourceDirs = orig.resourceDirs;
+        overlayPaths = orig.overlayPaths;
         seInfo = orig.seInfo;
         seInfoUser = orig.seInfoUser;
         sharedLibraryFiles = orig.sharedLibraryFiles;
@@ -1803,6 +1820,7 @@
         dest.writeString8(primaryCpuAbi);
         dest.writeString8(secondaryCpuAbi);
         dest.writeString8Array(resourceDirs);
+        dest.writeString8Array(overlayPaths);
         dest.writeString8(seInfo);
         dest.writeString8(seInfoUser);
         dest.writeString8Array(sharedLibraryFiles);
@@ -1886,6 +1904,7 @@
         primaryCpuAbi = source.readString8();
         secondaryCpuAbi = source.readString8();
         resourceDirs = source.createString8Array();
+        overlayPaths = source.createString8Array();
         seInfo = source.readString8();
         seInfoUser = source.readString8();
         sharedLibraryFiles = source.createString8Array();
@@ -2282,7 +2301,9 @@
      * @hide
      */
     public String[] getAllApkPaths() {
-        final String[][] inputLists = { splitSourceDirs, sharedLibraryFiles, resourceDirs };
+        final String[][] inputLists = {
+                splitSourceDirs, sharedLibraryFiles, resourceDirs, overlayPaths
+        };
         final List<String> output = new ArrayList<>(10);
         if (sourceDir != null) {
             output.add(sourceDir);
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index e6c0f6a..0819d17 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -54,6 +54,7 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.overlay.OverlayPaths;
 import android.content.pm.split.SplitAssetLoader;
 import android.content.res.ApkAssets;
 import android.content.res.AssetManager;
@@ -7969,7 +7970,11 @@
             ai.category = FallbackCategoryProvider.getFallbackCategory(ai.packageName);
         }
         ai.seInfoUser = SELinuxUtil.assignSeinfoUser(state);
-        ai.resourceDirs = state.getAllOverlayPaths();
+        final OverlayPaths overlayPaths = state.getAllOverlayPaths();
+        if (overlayPaths != null) {
+            ai.resourceDirs = overlayPaths.getResourceDirs().toArray(new String[0]);
+            ai.overlayPaths = overlayPaths.getOverlayPaths().toArray(new String[0]);
+        }
         ai.icon = (sUseRoundIcon && ai.roundIconRes != 0) ? ai.roundIconRes : ai.iconRes;
     }
 
@@ -8600,6 +8605,7 @@
                 null,
                 null,
                 androidAppInfo.resourceDirs,
+                androidAppInfo.overlayPaths,
                 androidAppInfo.sharedLibraryFiles,
                 null,
                 null,
diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java
index 5cc74c0..e115597 100644
--- a/core/java/android/content/pm/PackageUserState.java
+++ b/core/java/android/content/pm/PackageUserState.java
@@ -31,6 +31,7 @@
 import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
+import android.content.pm.overlay.OverlayPaths;
 import android.content.pm.parsing.component.ParsedMainComponent;
 import android.os.BaseBundle;
 import android.os.Debug;
@@ -53,7 +54,6 @@
 
 import java.io.IOException;
 import java.util.Arrays;
-import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Objects;
 
@@ -85,9 +85,10 @@
     public ArraySet<String> disabledComponents;
     public ArraySet<String> enabledComponents;
 
-    private String[] overlayPaths;
-    private ArrayMap<String, String[]> sharedLibraryOverlayPaths; // Lib name to overlay paths
-    private String[] cachedOverlayPaths;
+    private OverlayPaths overlayPaths;
+    // Maps library name to overlay paths.
+    private ArrayMap<String, OverlayPaths> sharedLibraryOverlayPaths;
+    private OverlayPaths cachedOverlayPaths;
 
     @Nullable
     private ArrayMap<ComponentName, Pair<String, Integer>> componentLabelIconOverrideMap;
@@ -121,8 +122,7 @@
         uninstallReason = o.uninstallReason;
         disabledComponents = ArrayUtils.cloneOrNull(o.disabledComponents);
         enabledComponents = ArrayUtils.cloneOrNull(o.enabledComponents);
-        overlayPaths =
-            o.overlayPaths == null ? null : Arrays.copyOf(o.overlayPaths, o.overlayPaths.length);
+        overlayPaths = o.overlayPaths;
         if (o.sharedLibraryOverlayPaths != null) {
             sharedLibraryOverlayPaths = new ArrayMap<>(o.sharedLibraryOverlayPaths);
         }
@@ -132,25 +132,55 @@
         }
     }
 
-    public String[] getOverlayPaths() {
+    @Nullable
+    public OverlayPaths getOverlayPaths() {
         return overlayPaths;
     }
 
-    public void setOverlayPaths(String[] paths) {
-        overlayPaths = paths;
-        cachedOverlayPaths = null;
-    }
-
-    public Map<String, String[]> getSharedLibraryOverlayPaths() {
+    @Nullable
+    public Map<String, OverlayPaths> getSharedLibraryOverlayPaths() {
         return sharedLibraryOverlayPaths;
     }
 
-    public void setSharedLibraryOverlayPaths(String library, String[] paths) {
+    /**
+     * Sets the path of overlays currently enabled for this package and user combination.
+     * @return true if the path contents differ than what they were previously
+     */
+    @Nullable
+    public boolean setOverlayPaths(@Nullable OverlayPaths paths) {
+        if (Objects.equals(paths, overlayPaths)) {
+            return false;
+        }
+        if ((overlayPaths == null && paths.isEmpty())
+                || (paths == null && overlayPaths.isEmpty())) {
+            return false;
+        }
+        overlayPaths = paths;
+        cachedOverlayPaths = null;
+        return true;
+    }
+
+    /**
+     * Sets the path of overlays currently enabled for a library that this package uses.
+     *
+     * @return true if the path contents for the library differ than what they were previously
+     */
+    public boolean setSharedLibraryOverlayPaths(@NonNull String library,
+            @Nullable OverlayPaths paths) {
         if (sharedLibraryOverlayPaths == null) {
             sharedLibraryOverlayPaths = new ArrayMap<>();
         }
-        sharedLibraryOverlayPaths.put(library, paths);
+        final OverlayPaths currentPaths = sharedLibraryOverlayPaths.get(library);
+        if (Objects.equals(paths, currentPaths)) {
+            return false;
+        }
         cachedOverlayPaths = null;
+        if (paths == null || paths.isEmpty()) {
+            return sharedLibraryOverlayPaths.remove(library) != null;
+        } else {
+            sharedLibraryOverlayPaths.put(library, paths);
+            return true;
+        }
     }
 
     /**
@@ -332,35 +362,21 @@
         return isComponentEnabled;
     }
 
-    public String[] getAllOverlayPaths() {
+    public OverlayPaths getAllOverlayPaths() {
         if (overlayPaths == null && sharedLibraryOverlayPaths == null) {
             return null;
         }
-
         if (cachedOverlayPaths != null) {
             return cachedOverlayPaths;
         }
-
-        final LinkedHashSet<String> paths = new LinkedHashSet<>();
-        if (overlayPaths != null) {
-            final int N = overlayPaths.length;
-            for (int i = 0; i < N; i++) {
-                paths.add(overlayPaths[i]);
-            }
-        }
-
+        final OverlayPaths.Builder newPaths = new OverlayPaths.Builder();
+        newPaths.addAll(overlayPaths);
         if (sharedLibraryOverlayPaths != null) {
-            for (String[] libOverlayPaths : sharedLibraryOverlayPaths.values()) {
-                if (libOverlayPaths != null) {
-                    final int N = libOverlayPaths.length;
-                    for (int i = 0; i < N; i++) {
-                        paths.add(libOverlayPaths[i]);
-                    }
-                }
+            for (final OverlayPaths libOverlayPaths : sharedLibraryOverlayPaths.values()) {
+                newPaths.addAll(libOverlayPaths);
             }
         }
-
-        cachedOverlayPaths = paths.toArray(new String[0]);
+        cachedOverlayPaths = newPaths.build();
         return cachedOverlayPaths;
     }
 
diff --git a/core/java/android/content/pm/overlay/OverlayPaths.java b/core/java/android/content/pm/overlay/OverlayPaths.java
new file mode 100644
index 0000000..a4db733
--- /dev/null
+++ b/core/java/android/content/pm/overlay/OverlayPaths.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm.overlay;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import com.android.internal.util.DataClass;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/** @hide */
+@DataClass(genConstructor = false, genBuilder = false, genHiddenBuilder = false,
+        genEqualsHashCode = true, genToString = true)
+public class OverlayPaths {
+    /**
+     * Represents {@link android.content.pm.ApplicationInfo#resourceDirs}.
+     * Only contains paths to APKs of overlays that can have their idmap resolved from their base
+     * APK path. Currently all overlay APKs can have their idmap path resolved from their idmap
+     * path.
+     */
+    @NonNull
+    private final List<String> mResourceDirs = new ArrayList<>();
+
+    /**
+     * Represents {@link android.content.pm.ApplicationInfo#overlayPaths}.
+     * Contains the contents of {@link #getResourceDirs()} and along with paths for overlays
+     * that are not APKs.
+     */
+    @NonNull
+    private final List<String> mOverlayPaths = new ArrayList<>();
+
+    public static class Builder {
+        final OverlayPaths mPaths = new OverlayPaths();
+
+        /**
+         * Adds a non-APK path to the contents of {@link OverlayPaths#getOverlayPaths()}.
+         */
+        public Builder addNonApkPath(@NonNull String idmapPath) {
+            mPaths.mOverlayPaths.add(idmapPath);
+            return this;
+        }
+
+        /**
+         * Adds a overlay APK path to the contents of {@link OverlayPaths#getResourceDirs()} and
+         * {@link OverlayPaths#getOverlayPaths()}.
+         */
+        public Builder addApkPath(@NonNull String overlayPath) {
+            addUniquePath(mPaths.mResourceDirs, overlayPath);
+            addUniquePath(mPaths.mOverlayPaths, overlayPath);
+            return this;
+        }
+
+        public Builder addAll(@Nullable OverlayPaths other) {
+            if (other != null) {
+                for (final String path : other.getResourceDirs()) {
+                    addUniquePath(mPaths.mResourceDirs, path);
+                }
+                for (final String path : other.getOverlayPaths()) {
+                    addUniquePath(mPaths.mOverlayPaths, path);
+                }
+            }
+            return this;
+        }
+
+        public OverlayPaths build() {
+            return mPaths;
+        }
+
+        private static void addUniquePath(@NonNull List<String> paths, @NonNull String path) {
+            if (!paths.contains(path)) {
+                paths.add(path);
+            }
+        }
+    }
+
+    /**
+     * Returns whether {@link #getOverlayPaths()} and {@link #getOverlayPaths} are empty.
+     */
+    public boolean isEmpty() {
+        return mResourceDirs.isEmpty() && mOverlayPaths.isEmpty();
+    }
+
+    private OverlayPaths() {
+    }
+
+
+
+    // Code below generated by codegen v1.0.22.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/overlay/OverlayPaths.java
+    //
+    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+    //   Settings > Editor > Code Style > Formatter Control
+    //@formatter:off
+
+
+    /**
+     * Represents {@link android.content.pm.ApplicationInfo#resourceDirs}.
+     * Only contains paths to APKs of overlays that can have their idmap resolved from their base
+     * APK path. Currently all overlay APKs can have their idmap path resolved from their idmap
+     * path.
+     */
+    @DataClass.Generated.Member
+    public @NonNull List<String> getResourceDirs() {
+        return mResourceDirs;
+    }
+
+    /**
+     * Represents {@link android.content.pm.ApplicationInfo#overlayPaths}.
+     * Contains the contents of {@link #getResourceDirs()} and along with paths for overlays
+     * that are not APKs.
+     */
+    @DataClass.Generated.Member
+    public @NonNull List<String> getOverlayPaths() {
+        return mOverlayPaths;
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public String toString() {
+        // You can override field toString logic by defining methods like:
+        // String fieldNameToString() { ... }
+
+        return "OverlayPaths { " +
+                "resourceDirs = " + mResourceDirs + ", " +
+                "overlayPaths = " + mOverlayPaths +
+                " }";
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public boolean equals(@android.annotation.Nullable Object o) {
+        // You can override field equality logic by defining either of the methods like:
+        // boolean fieldNameEquals(OverlayPaths other) { ... }
+        // boolean fieldNameEquals(FieldType otherValue) { ... }
+
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        @SuppressWarnings("unchecked")
+        OverlayPaths that = (OverlayPaths) o;
+        //noinspection PointlessBooleanExpression
+        return true
+                && Objects.equals(mResourceDirs, that.mResourceDirs)
+                && Objects.equals(mOverlayPaths, that.mOverlayPaths);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int hashCode() {
+        // You can override field hashCode logic by defining methods like:
+        // int fieldNameHashCode() { ... }
+
+        int _hash = 1;
+        _hash = 31 * _hash + Objects.hashCode(mResourceDirs);
+        _hash = 31 * _hash + Objects.hashCode(mOverlayPaths);
+        return _hash;
+    }
+
+    @DataClass.Generated(
+            time = 1612307813586L,
+            codegenVersion = "1.0.22",
+            sourceFile = "frameworks/base/core/java/android/content/pm/overlay/OverlayPaths.java",
+            inputSignatures = "private final @android.annotation.NonNull java.util.List<java.lang.String> mResourceDirs\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mOverlayPaths\npublic  boolean isEmpty()\nclass OverlayPaths extends java.lang.Object implements []\nfinal  android.content.pm.overlay.OverlayPaths mPaths\npublic  android.content.pm.overlay.OverlayPaths.Builder addNonApkPath(java.lang.String)\npublic  android.content.pm.overlay.OverlayPaths.Builder addApkPath(java.lang.String)\npublic  android.content.pm.overlay.OverlayPaths.Builder addAll(android.content.pm.overlay.OverlayPaths)\npublic  android.content.pm.overlay.OverlayPaths build()\nprivate static  void addUniquePath(java.util.List<java.lang.String>,java.lang.String)\nclass Builder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=false, genHiddenBuilder=false, genEqualsHashCode=true, genToString=true)")
+    @Deprecated
+    private void __metadata() {}
+
+
+    //@formatter:on
+    // End of generated code
+
+}
diff --git a/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java b/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java
index b7365b3..fb0d904 100644
--- a/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java
+++ b/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java
@@ -41,6 +41,7 @@
 import android.content.pm.ServiceInfo;
 import android.content.pm.Signature;
 import android.content.pm.SigningInfo;
+import android.content.pm.overlay.OverlayPaths;
 import android.content.pm.parsing.component.ComponentParseUtils;
 import android.content.pm.parsing.component.ParsedActivity;
 import android.content.pm.parsing.component.ParsedAttribution;
@@ -412,7 +413,11 @@
             ai.category = FallbackCategoryProvider.getFallbackCategory(ai.packageName);
         }
         ai.seInfoUser = SELinuxUtil.assignSeinfoUser(state);
-        ai.resourceDirs = state.getAllOverlayPaths();
+        final OverlayPaths overlayPaths = state.getAllOverlayPaths();
+        if (overlayPaths != null) {
+            ai.resourceDirs = overlayPaths.getResourceDirs().toArray(new String[0]);
+            ai.overlayPaths = overlayPaths.getOverlayPaths().toArray(new String[0]);
+        }
 
         return ai;
     }
diff --git a/core/java/android/content/res/ResourcesKey.java b/core/java/android/content/res/ResourcesKey.java
index 05769dd..99b56a8 100644
--- a/core/java/android/content/res/ResourcesKey.java
+++ b/core/java/android/content/res/ResourcesKey.java
@@ -38,7 +38,7 @@
     public final String[] mSplitResDirs;
 
     @Nullable
-    public final String[] mOverlayDirs;
+    public final String[] mOverlayPaths;
 
     @Nullable
     public final String[] mLibDirs;
@@ -67,7 +67,7 @@
 
     public ResourcesKey(@Nullable String resDir,
                         @Nullable String[] splitResDirs,
-                        @Nullable String[] overlayDirs,
+                        @Nullable String[] overlayPaths,
                         @Nullable String[] libDirs,
                         int overrideDisplayId,
                         @Nullable Configuration overrideConfig,
@@ -75,7 +75,7 @@
                         @Nullable ResourcesLoader[] loader) {
         mResDir = resDir;
         mSplitResDirs = splitResDirs;
-        mOverlayDirs = overlayDirs;
+        mOverlayPaths = overlayPaths;
         mLibDirs = libDirs;
         mLoaders = (loader != null && loader.length == 0) ? null : loader;
         mDisplayId = overrideDisplayId;
@@ -86,7 +86,7 @@
         int hash = 17;
         hash = 31 * hash + Objects.hashCode(mResDir);
         hash = 31 * hash + Arrays.hashCode(mSplitResDirs);
-        hash = 31 * hash + Arrays.hashCode(mOverlayDirs);
+        hash = 31 * hash + Arrays.hashCode(mOverlayPaths);
         hash = 31 * hash + Arrays.hashCode(mLibDirs);
         hash = 31 * hash + Objects.hashCode(mDisplayId);
         hash = 31 * hash + Objects.hashCode(mOverrideConfiguration);
@@ -98,12 +98,12 @@
     @UnsupportedAppUsage
     public ResourcesKey(@Nullable String resDir,
             @Nullable String[] splitResDirs,
-            @Nullable String[] overlayDirs,
+            @Nullable String[] overlayPaths,
             @Nullable String[] libDirs,
             int displayId,
             @Nullable Configuration overrideConfig,
             @Nullable CompatibilityInfo compatInfo) {
-        this(resDir, splitResDirs, overlayDirs, libDirs, displayId, overrideConfig, compatInfo,
+        this(resDir, splitResDirs, overlayPaths, libDirs, displayId, overrideConfig, compatInfo,
                 null);
     }
 
@@ -115,7 +115,7 @@
         if (mResDir != null && mResDir.startsWith(path)) {
             return true;
         } else {
-            return anyStartsWith(mSplitResDirs, path) || anyStartsWith(mOverlayDirs, path)
+            return anyStartsWith(mSplitResDirs, path) || anyStartsWith(mOverlayPaths, path)
                     || anyStartsWith(mLibDirs, path);
         }
     }
@@ -154,7 +154,7 @@
         if (!Arrays.equals(mSplitResDirs, peer.mSplitResDirs)) {
             return false;
         }
-        if (!Arrays.equals(mOverlayDirs, peer.mOverlayDirs)) {
+        if (!Arrays.equals(mOverlayPaths, peer.mOverlayPaths)) {
             return false;
         }
         if (!Arrays.equals(mLibDirs, peer.mLibDirs)) {
@@ -186,8 +186,8 @@
         }
         builder.append("]");
         builder.append(" mOverlayDirs=[");
-        if (mOverlayDirs != null) {
-            builder.append(TextUtils.join(",", mOverlayDirs));
+        if (mOverlayPaths != null) {
+            builder.append(TextUtils.join(",", mOverlayPaths));
         }
         builder.append("]");
         builder.append(" mLibDirs=[");
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a29fcb1..ef81ed7 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -44,6 +44,7 @@
 import android.content.IContentProvider;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
@@ -89,8 +90,11 @@
 import com.android.internal.widget.ILockSettings;
 
 import java.io.IOException;
+import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Field;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -99,7 +103,6 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
-
 /**
  * The Settings provider contains global system-level device preferences.
  */
@@ -2490,7 +2493,7 @@
     public static final String EXTRA_NUMBER_OF_CERTIFICATES =
             "android.settings.extra.number_of_certificates";
 
-    private static final String JID_RESOURCE_PREFIX = "android";
+    private static final String SYSTEM_PACKAGE_NAME = "android";
 
     public static final String AUTHORITY = "settings";
 
@@ -2659,22 +2662,30 @@
         private final String mCallListCommand;
         private final String mCallSetAllCommand;
 
+        private final ArraySet<String> mReadableFields;
+        private final ArraySet<String> mAllFields;
+
         @GuardedBy("this")
         private GenerationTracker mGenerationTracker;
 
-        public NameValueCache(Uri uri, String getCommand, String setCommand,
-                ContentProviderHolder providerHolder) {
-            this(uri, getCommand, setCommand, null, null, providerHolder);
+        <T extends NameValueTable> NameValueCache(Uri uri, String getCommand,
+                String setCommand, ContentProviderHolder providerHolder, Class<T> callerClass) {
+            this(uri, getCommand, setCommand, null, null, providerHolder,
+                    callerClass);
         }
 
-        NameValueCache(Uri uri, String getCommand, String setCommand, String listCommand,
-                String setAllCommand, ContentProviderHolder providerHolder) {
+        private <T extends NameValueTable> NameValueCache(Uri uri, String getCommand,
+                String setCommand, String listCommand, String setAllCommand,
+                ContentProviderHolder providerHolder, Class<T> callerClass) {
             mUri = uri;
             mCallGetCommand = getCommand;
             mCallSetCommand = setCommand;
             mCallListCommand = listCommand;
             mCallSetAllCommand = setAllCommand;
             mProviderHolder = providerHolder;
+            mReadableFields = new ArraySet<>();
+            mAllFields = new ArraySet<>();
+            getPublicSettingsForClass(callerClass, mAllFields, mReadableFields);
         }
 
         public boolean putStringForUser(ContentResolver cr, String name, String value,
@@ -2726,6 +2737,19 @@
 
         @UnsupportedAppUsage
         public String getStringForUser(ContentResolver cr, String name, final int userHandle) {
+            // Check if the target settings key is readable. Reject if the caller is not system and
+            // is trying to access a settings key defined in the Settings.Secure, Settings.System or
+            // Settings.Global and is not annotated as @Readable.
+            // Notice that a key string that is not defined in any of the Settings.* classes will
+            // still be regarded as readable.
+            // TODO(b/175024829): provide a register method.
+            if (!Settings.isInSystemServer() && !isSystemOrPrivilegedApp()
+                    && mAllFields.contains(name) && !mReadableFields.contains(name)) {
+                throw new SecurityException(
+                        "Settings key: <" + name + "> is not readable. From S+, new public "
+                        + "settings keys need to be annotated with @Readable unless they are "
+                        + "annotated with @hide.");
+            }
             final boolean isSelf = (userHandle == UserHandle.myUserId());
             int currentGeneration = -1;
             if (isSelf) {
@@ -2900,6 +2924,19 @@
             }
         }
 
+        private static boolean isSystemOrPrivilegedApp() {
+            if (UserHandle.getAppId(Binder.getCallingUid()) < Process.FIRST_APPLICATION_UID) {
+                return true;
+            }
+            final Application application = ActivityThread.currentApplication();
+            if (application == null || application.getApplicationInfo() == null) {
+                return false;
+            }
+            final ApplicationInfo applicationInfo = application.getApplicationInfo();
+            return applicationInfo.isSystemApp() || applicationInfo.isPrivilegedApp()
+                    || applicationInfo.isSignedWithPlatformKey();
+        }
+
         public ArrayMap<String, String> getStringsForPrefix(ContentResolver cr, String prefix,
                 List<String> names) {
             String namespace = prefix.substring(0, prefix.length() - 1);
@@ -3067,6 +3104,39 @@
     }
 
     /**
+     * This annotation indicates that the value of a setting is allowed to be read
+     * with the get* methods. The following settings should be readable:
+     * 1) all the public settings
+     * 2) all the hidden settings added before S
+     */
+    @Target({ ElementType.FIELD })
+    @Retention(RetentionPolicy.RUNTIME)
+    private @interface Readable {
+    }
+
+    private static <T extends NameValueTable> void getPublicSettingsForClass(
+            Class<T> callerClass, Set<String> allKeys, Set<String> readableKeys) {
+        final Field[] allFields = callerClass.getDeclaredFields();
+        try {
+            for (int i = 0; i < allFields.length; i++) {
+                final Field field = allFields[i];
+                if (!field.getType().equals(String.class)) {
+                    continue;
+                }
+                final Object value = field.get(callerClass);
+                if (!value.getClass().equals(String.class)) {
+                    continue;
+                }
+                allKeys.add((String) value);
+                if (field.getAnnotation(Readable.class) != null) {
+                    readableKeys.add((String) value);
+                }
+            }
+        } catch (IllegalAccessException ignored) {
+        }
+    }
+
+    /**
      * System settings, containing miscellaneous system preferences.  This
      * table holds simple name/value pairs.  There are convenience
      * functions for accessing individual settings entries.
@@ -3093,7 +3163,8 @@
                 CONTENT_URI,
                 CALL_METHOD_GET_SYSTEM,
                 CALL_METHOD_PUT_SYSTEM,
-                sProviderHolder);
+                sProviderHolder,
+                System.class);
 
         @UnsupportedAppUsage
         private static final HashSet<String> MOVED_TO_SECURE;
@@ -3147,8 +3218,11 @@
             MOVED_TO_SECURE_THEN_GLOBAL.add(Global.BLUETOOTH_ON);
             MOVED_TO_SECURE_THEN_GLOBAL.add(Global.DATA_ROAMING);
             MOVED_TO_SECURE_THEN_GLOBAL.add(Global.DEVICE_PROVISIONED);
-            MOVED_TO_SECURE_THEN_GLOBAL.add(Global.USB_MASS_STORAGE_ENABLED);
             MOVED_TO_SECURE_THEN_GLOBAL.add(Global.HTTP_PROXY);
+            MOVED_TO_SECURE_THEN_GLOBAL.add(Global.NETWORK_PREFERENCE);
+            MOVED_TO_SECURE_THEN_GLOBAL.add(Global.USB_MASS_STORAGE_ENABLED);
+            MOVED_TO_SECURE_THEN_GLOBAL.add(Global.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS);
+            MOVED_TO_SECURE_THEN_GLOBAL.add(Global.WIFI_MAX_DHCP_RETRY_COUNT);
 
             // these are moving directly from system to global
             MOVED_TO_GLOBAL.add(Settings.Global.AIRPLANE_MODE_ON);
@@ -3186,6 +3260,12 @@
             MOVED_TO_GLOBAL.add(Settings.Global.SMS_SHORT_CODES_UPDATE_METADATA_URL);
             MOVED_TO_GLOBAL.add(Settings.Global.CERT_PIN_UPDATE_CONTENT_URL);
             MOVED_TO_GLOBAL.add(Settings.Global.CERT_PIN_UPDATE_METADATA_URL);
+            MOVED_TO_GLOBAL.add(Settings.Global.RADIO_NFC);
+            MOVED_TO_GLOBAL.add(Settings.Global.RADIO_CELL);
+            MOVED_TO_GLOBAL.add(Settings.Global.RADIO_WIFI);
+            MOVED_TO_GLOBAL.add(Settings.Global.RADIO_BLUETOOTH);
+            MOVED_TO_GLOBAL.add(Settings.Global.RADIO_WIMAX);
+            MOVED_TO_GLOBAL.add(Settings.Global.SHOW_PROCESSES);
         }
 
         /** @hide */
@@ -3210,6 +3290,11 @@
             sNameValueCache.clearGenerationTrackerForTest();
         }
 
+        /** @hide */
+        public static void getPublicSettings(Set<String> allKeys, Set<String> readableKeys) {
+            getPublicSettingsForClass(System.class, allKeys, readableKeys);
+        }
+
         /**
          * Look up a name in the database.
          * @param resolver to access the database with
@@ -3234,6 +3319,7 @@
                         + " to android.provider.Settings.Global, returning read-only value.");
                 return Global.getStringForUser(resolver, name, userHandle);
             }
+
             return sNameValueCache.getStringForUser(resolver, name, userHandle);
         }
 
@@ -3711,6 +3797,7 @@
          * 3 - The end button goes to the home screen.  If the user is already on the
          * home screen, it puts the device to sleep.
          */
+        @Readable
         public static final String END_BUTTON_BEHAVIOR = "end_button_behavior";
 
         /**
@@ -3735,6 +3822,7 @@
          * Is advanced settings mode turned on. 0 == no, 1 == yes
          * @hide
          */
+        @Readable
         public static final String ADVANCED_SETTINGS = "advanced_settings";
 
         /**
@@ -3835,6 +3923,7 @@
          * @deprecated Use {@link WifiManager} instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_USE_STATIC_IP = "wifi_use_static_ip";
 
         /**
@@ -3845,6 +3934,7 @@
          * @deprecated Use {@link WifiManager} instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_STATIC_IP = "wifi_static_ip";
 
         /**
@@ -3855,6 +3945,7 @@
          * @deprecated Use {@link WifiManager} instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_STATIC_GATEWAY = "wifi_static_gateway";
 
         /**
@@ -3865,6 +3956,7 @@
          * @deprecated Use {@link WifiManager} instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_STATIC_NETMASK = "wifi_static_netmask";
 
         /**
@@ -3875,6 +3967,7 @@
          * @deprecated Use {@link WifiManager} instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_STATIC_DNS1 = "wifi_static_dns1";
 
         /**
@@ -3885,6 +3978,7 @@
          * @deprecated Use {@link WifiManager} instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_STATIC_DNS2 = "wifi_static_dns2";
 
         /**
@@ -3895,6 +3989,7 @@
          * 1 -- connectable but not discoverable
          * 0 -- neither connectable nor discoverable
          */
+        @Readable
         public static final String BLUETOOTH_DISCOVERABILITY =
             "bluetooth_discoverability";
 
@@ -3903,6 +3998,7 @@
          * Bluetooth becomes discoverable for a certain number of seconds,
          * after which is becomes simply connectable.  The value is in seconds.
          */
+        @Readable
         public static final String BLUETOOTH_DISCOVERABILITY_TIMEOUT =
             "bluetooth_discoverability_timeout";
 
@@ -3936,11 +4032,13 @@
          * @deprecated Use {@link android.app.AlarmManager#getNextAlarmClock()}.
          */
         @Deprecated
+        @Readable
         public static final String NEXT_ALARM_FORMATTED = "next_alarm_formatted";
 
         /**
          * Scaling factor for fonts, float.
          */
+        @Readable
         public static final String FONT_SCALE = "font_scale";
 
         /**
@@ -3952,6 +4050,7 @@
          * instead.
          * @hide
          */
+        @Readable
         public static final String SYSTEM_LOCALES = "system_locales";
 
 
@@ -3977,12 +4076,14 @@
          * @deprecated This setting is no longer used.
          */
         @Deprecated
+        @Readable
         public static final String DIM_SCREEN = "dim_screen";
 
         /**
          * The display color mode.
          * @hide
          */
+        @Readable
         public static final String DISPLAY_COLOR_MODE = "display_color_mode";
 
         /**
@@ -3990,6 +4091,7 @@
          * unset or a match is not made, only the standard color modes will be restored.
          * @hide
          */
+        @Readable
         public static final String DISPLAY_COLOR_MODE_VENDOR_HINT =
                 "display_color_mode_vendor_hint";
 
@@ -3999,6 +4101,7 @@
          * If this isn't set, 0 will be used.
          * @hide
          */
+        @Readable
         public static final String MIN_REFRESH_RATE = "min_refresh_rate";
 
         /**
@@ -4007,6 +4110,7 @@
          * If this isn't set, the system falls back to a device specific default.
          * @hide
          */
+        @Readable
         public static final String PEAK_REFRESH_RATE = "peak_refresh_rate";
 
         /**
@@ -4019,23 +4123,27 @@
          * This value is bounded by maximum timeout set by
          * {@link android.app.admin.DevicePolicyManager#setMaximumTimeToLock(ComponentName, long)}.
          */
+        @Readable
         public static final String SCREEN_OFF_TIMEOUT = "screen_off_timeout";
 
         /**
          * The screen backlight brightness between 0 and 255.
          */
+        @Readable
         public static final String SCREEN_BRIGHTNESS = "screen_brightness";
 
         /**
          * The screen backlight brightness between 0 and 255.
          * @hide
          */
+        @Readable
         public static final String SCREEN_BRIGHTNESS_FOR_VR = "screen_brightness_for_vr";
 
         /**
          * The screen backlight brightness between 0.0f and 1.0f.
          * @hide
          */
+        @Readable
         public static final String SCREEN_BRIGHTNESS_FOR_VR_FLOAT =
                 "screen_brightness_for_vr_float";
 
@@ -4043,11 +4151,13 @@
          * The screen backlight brightness between 0.0f and 1.0f.
          * @hide
          */
+        @Readable
         public static final String SCREEN_BRIGHTNESS_FLOAT = "screen_brightness_float";
 
         /**
          * Control whether to enable automatic brightness mode.
          */
+        @Readable
         public static final String SCREEN_BRIGHTNESS_MODE = "screen_brightness_mode";
 
         /**
@@ -4056,6 +4166,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String SCREEN_AUTO_BRIGHTNESS_ADJ = "screen_auto_brightness_adj";
 
         /**
@@ -4073,6 +4184,8 @@
          * @deprecated Use {@link android.provider.Settings.Secure#ADAPTIVE_SLEEP} instead.
          * @hide
          */
+        @Deprecated
+        @Readable
         public static final String ADAPTIVE_SLEEP = "adaptive_sleep";
 
         /**
@@ -4099,6 +4212,7 @@
          * stream type's bit should be set to 1 if it should be muted when going
          * into an inaudible ringer mode.
          */
+        @Readable
         public static final String MODE_RINGER_STREAMS_AFFECTED = "mode_ringer_streams_affected";
 
         /**
@@ -4106,12 +4220,14 @@
           * stream type's bit should be set to 1 if it should be muted when a mute request
           * is received.
           */
+        @Readable
         public static final String MUTE_STREAMS_AFFECTED = "mute_streams_affected";
 
         /**
          * Whether vibrate is on for different events. This is used internally,
          * changing this value will not change the vibrate. See AudioManager.
          */
+        @Readable
         public static final String VIBRATE_ON = "vibrate_on";
 
         /**
@@ -4126,6 +4242,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String VIBRATE_INPUT_DEVICES = "vibrate_input_devices";
 
         /**
@@ -4142,6 +4259,7 @@
          * 3 - Strong vibrations
          * @hide
          */
+        @Readable
         public static final String NOTIFICATION_VIBRATION_INTENSITY =
                 "notification_vibration_intensity";
         /**
@@ -4158,6 +4276,7 @@
          * 3 - Strong vibrations
          * @hide
          */
+        @Readable
         public static final String RING_VIBRATION_INTENSITY =
                 "ring_vibration_intensity";
 
@@ -4175,6 +4294,7 @@
          * 3 - Strong vibrations
          * @hide
          */
+        @Readable
         public static final String HAPTIC_FEEDBACK_INTENSITY =
                 "haptic_feedback_intensity";
 
@@ -4184,6 +4304,7 @@
          *
          * @removed Not used by anything since API 2.
          */
+        @Readable
         public static final String VOLUME_RING = "volume_ring";
 
         /**
@@ -4192,6 +4313,7 @@
          *
          * @removed Not used by anything since API 2.
          */
+        @Readable
         public static final String VOLUME_SYSTEM = "volume_system";
 
         /**
@@ -4200,6 +4322,7 @@
          *
          * @removed Not used by anything since API 2.
          */
+        @Readable
         public static final String VOLUME_VOICE = "volume_voice";
 
         /**
@@ -4208,6 +4331,7 @@
          *
          * @removed Not used by anything since API 2.
          */
+        @Readable
         public static final String VOLUME_MUSIC = "volume_music";
 
         /**
@@ -4216,6 +4340,7 @@
          *
          * @removed Not used by anything since API 2.
          */
+        @Readable
         public static final String VOLUME_ALARM = "volume_alarm";
 
         /**
@@ -4224,6 +4349,7 @@
          *
          * @removed Not used by anything since API 2.
          */
+        @Readable
         public static final String VOLUME_NOTIFICATION = "volume_notification";
 
         /**
@@ -4232,6 +4358,7 @@
          *
          * @removed Not used by anything since API 2.
          */
+        @Readable
         public static final String VOLUME_BLUETOOTH_SCO = "volume_bluetooth_sco";
 
         /**
@@ -4239,12 +4366,14 @@
          * Acessibility volume. This is used internally, changing this
          * value will not change the volume.
          */
+        @Readable
         public static final String VOLUME_ACCESSIBILITY = "volume_a11y";
 
         /**
          * @hide
          * Volume index for virtual assistant.
          */
+        @Readable
         public static final String VOLUME_ASSISTANT = "volume_assistant";
 
         /**
@@ -4252,6 +4381,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String VOLUME_MASTER = "volume_master";
 
         /**
@@ -4260,6 +4390,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String MASTER_MONO = "master_mono";
 
         /**
@@ -4267,6 +4398,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String MASTER_BALANCE = "master_balance";
 
         /**
@@ -4284,6 +4416,7 @@
          * @deprecated
          */
         @Deprecated
+        @Readable
         public static final String NOTIFICATIONS_USE_RING_VOLUME =
             "notifications_use_ring_volume";
 
@@ -4300,6 +4433,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String VIBRATE_IN_SILENT = "vibrate_in_silent";
 
         /**
@@ -4335,6 +4469,7 @@
          *
          * @removed  Not used by anything since API 2.
          */
+        @Readable
         public static final String APPEND_FOR_LAST_AUDIBLE = "_last_audible";
 
         /**
@@ -4346,6 +4481,7 @@
          *
          * @see #DEFAULT_RINGTONE_URI
          */
+        @Readable
         public static final String RINGTONE = "ringtone";
 
         /**
@@ -4359,6 +4495,7 @@
         public static final Uri DEFAULT_RINGTONE_URI = getUriFor(RINGTONE);
 
         /** {@hide} */
+        @Readable
         public static final String RINGTONE_CACHE = "ringtone_cache";
         /** {@hide} */
         public static final Uri RINGTONE_CACHE_URI = getUriFor(RINGTONE_CACHE);
@@ -4369,6 +4506,7 @@
          * @see #RINGTONE
          * @see #DEFAULT_NOTIFICATION_URI
          */
+        @Readable
         public static final String NOTIFICATION_SOUND = "notification_sound";
 
         /**
@@ -4380,6 +4518,7 @@
         public static final Uri DEFAULT_NOTIFICATION_URI = getUriFor(NOTIFICATION_SOUND);
 
         /** {@hide} */
+        @Readable
         public static final String NOTIFICATION_SOUND_CACHE = "notification_sound_cache";
         /** {@hide} */
         public static final Uri NOTIFICATION_SOUND_CACHE_URI = getUriFor(NOTIFICATION_SOUND_CACHE);
@@ -4390,6 +4529,7 @@
          * @see #RINGTONE
          * @see #DEFAULT_ALARM_ALERT_URI
          */
+        @Readable
         public static final String ALARM_ALERT = "alarm_alert";
 
         /**
@@ -4401,6 +4541,7 @@
         public static final Uri DEFAULT_ALARM_ALERT_URI = getUriFor(ALARM_ALERT);
 
         /** {@hide} */
+        @Readable
         public static final String ALARM_ALERT_CACHE = "alarm_alert_cache";
         /** {@hide} */
         public static final Uri ALARM_ALERT_CACHE_URI = getUriFor(ALARM_ALERT_CACHE);
@@ -4410,29 +4551,35 @@
          *
          * @hide
          */
+        @Readable
         public static final String MEDIA_BUTTON_RECEIVER = "media_button_receiver";
 
         /**
          * Setting to enable Auto Replace (AutoText) in text editors. 1 = On, 0 = Off
          */
+        @Readable
         public static final String TEXT_AUTO_REPLACE = "auto_replace";
 
         /**
          * Setting to enable Auto Caps in text editors. 1 = On, 0 = Off
          */
+        @Readable
         public static final String TEXT_AUTO_CAPS = "auto_caps";
 
         /**
          * Setting to enable Auto Punctuate in text editors. 1 = On, 0 = Off. This
          * feature converts two spaces to a "." and space.
          */
+        @Readable
         public static final String TEXT_AUTO_PUNCTUATE = "auto_punctuate";
 
         /**
          * Setting to showing password characters in text editors. 1 = On, 0 = Off
          */
+        @Readable
         public static final String TEXT_SHOW_PASSWORD = "show_password";
 
+        @Readable
         public static final String SHOW_GTALK_SERVICE_STATUS =
                 "SHOW_GTALK_SERVICE_STATUS";
 
@@ -4442,6 +4589,7 @@
          * @deprecated Use {@link WallpaperManager} instead.
          */
         @Deprecated
+        @Readable
         public static final String WALLPAPER_ACTIVITY = "wallpaper_activity";
 
         /**
@@ -4463,6 +4611,7 @@
          *   12
          *   24
          */
+        @Readable
         public static final String TIME_12_24 = "time_12_24";
 
         /**
@@ -4471,6 +4620,7 @@
          *   dd/mm/yyyy
          *   yyyy/mm/dd
          */
+        @Readable
         public static final String DATE_FORMAT = "date_format";
 
         /**
@@ -4480,6 +4630,7 @@
          * nonzero = it has been run in the past
          * 0 = it has not been run in the past
          */
+        @Readable
         public static final String SETUP_WIZARD_HAS_RUN = "setup_wizard_has_run";
 
         /**
@@ -4516,6 +4667,7 @@
          * by the application; if 1, it will be used by default unless explicitly
          * disabled by the application.
          */
+        @Readable
         public static final String ACCELEROMETER_ROTATION = "accelerometer_rotation";
 
         /**
@@ -4526,6 +4678,7 @@
          *
          * @see Display#getRotation
          */
+        @Readable
         public static final String USER_ROTATION = "user_rotation";
 
         /**
@@ -4540,6 +4693,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY =
                 "hide_rotation_lock_toggle_for_accessibility";
 
@@ -4553,6 +4707,7 @@
          * relied on the setting, while this is purely about the vibration setting for incoming
          * calls.
          */
+        @Readable
         public static final String VIBRATE_WHEN_RINGING = "vibrate_when_ringing";
 
         /**
@@ -4560,6 +4715,7 @@
          * {@code 0}, enhanced call blocking functionality is disabled.
          * @hide
          */
+        @Readable
         public static final String DEBUG_ENABLE_ENHANCED_CALL_BLOCKING =
                 "debug.enable_enhanced_calling";
 
@@ -4567,6 +4723,7 @@
          * Whether the audible DTMF tones are played by the dialer when dialing. The value is
          * boolean (1 or 0).
          */
+        @Readable
         public static final String DTMF_TONE_WHEN_DIALING = "dtmf_tone";
 
         /**
@@ -4575,6 +4732,7 @@
          *                 0 = Normal
          *                 1 = Long
          */
+        @Readable
         public static final String DTMF_TONE_TYPE_WHEN_DIALING = "dtmf_tone_type";
 
         /**
@@ -4583,6 +4741,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String HEARING_AID = "hearing_aid";
 
         /**
@@ -4595,18 +4754,21 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String TTY_MODE = "tty_mode";
 
         /**
          * Whether the sounds effects (key clicks, lid open ...) are enabled. The value is
          * boolean (1 or 0).
          */
+        @Readable
         public static final String SOUND_EFFECTS_ENABLED = "sound_effects_enabled";
 
         /**
          * Whether haptic feedback (Vibrate on tap) is enabled. The value is
          * boolean (1 or 0).
          */
+        @Readable
         public static final String HAPTIC_FEEDBACK_ENABLED = "haptic_feedback_enabled";
 
         /**
@@ -4614,6 +4776,7 @@
          * setting for this.
          */
         @Deprecated
+        @Readable
         public static final String SHOW_WEB_SUGGESTIONS = "show_web_suggestions";
 
         /**
@@ -4622,6 +4785,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String NOTIFICATION_LIGHT_PULSE = "notification_light_pulse";
 
         /**
@@ -4631,6 +4795,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String POINTER_LOCATION = "pointer_location";
 
         /**
@@ -4640,6 +4805,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String SHOW_TOUCHES = "show_touches";
 
         /**
@@ -4650,6 +4816,7 @@
          * 1 = yes
          * @hide
          */
+        @Readable
         public static final String WINDOW_ORIENTATION_LISTENER_LOG =
                 "window_orientation_listener_log";
 
@@ -4675,12 +4842,14 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String LOCKSCREEN_SOUNDS_ENABLED = "lockscreen_sounds_enabled";
 
         /**
          * Whether the lockscreen should be completely disabled.
          * @hide
          */
+        @Readable
         public static final String LOCKSCREEN_DISABLED = "lockscreen.disabled";
 
         /**
@@ -4751,6 +4920,7 @@
          * 1 = yes
          * @hide
          */
+        @Readable
         public static final String SIP_RECEIVE_CALLS = "sip_receive_calls";
 
         /**
@@ -4759,18 +4929,21 @@
          * "SIP_ADDRESS_ONLY" : Only if destination is a SIP address
          * @hide
          */
+        @Readable
         public static final String SIP_CALL_OPTIONS = "sip_call_options";
 
         /**
          * One of the sip call options: Always use SIP with network access.
          * @hide
          */
+        @Readable
         public static final String SIP_ALWAYS = "SIP_ALWAYS";
 
         /**
          * One of the sip call options: Only if destination is a SIP address.
          * @hide
          */
+        @Readable
         public static final String SIP_ADDRESS_ONLY = "SIP_ADDRESS_ONLY";
 
         /**
@@ -4781,6 +4954,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String SIP_ASK_ME_EACH_TIME = "SIP_ASK_ME_EACH_TIME";
 
         /**
@@ -4792,12 +4966,14 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String POINTER_SPEED = "pointer_speed";
 
         /**
          * Whether lock-to-app will be triggered by long-press on recents.
          * @hide
          */
+        @Readable
         public static final String LOCK_TO_APP_ENABLED = "lock_to_app_enabled";
 
         /**
@@ -4807,6 +4983,7 @@
          * Backward-compatible with <code>PrefGetPreference(prefAllowEasterEggs)</code>.
          * @hide
          */
+        @Readable
         public static final String EGG_MODE = "egg_mode";
 
         /**
@@ -4815,6 +4992,7 @@
          *    1 - Show percentage
          * @hide
          */
+        @Readable
         public static final String SHOW_BATTERY_PERCENT = "status_bar_show_battery_percent";
 
         /**
@@ -4823,6 +5001,7 @@
          * for instance pausing media apps when another starts.
          * @hide
          */
+        @Readable
         public static final String MULTI_AUDIO_FOCUS_ENABLED = "multi_audio_focus_enabled";
 
         /**
@@ -5017,6 +5196,7 @@
          * @see android.telephony.TelephonyManager.WifiCallingChoices
          * @hide
          */
+        @Readable
         public static final String WHEN_TO_MAKE_WIFI_CALLS = "when_to_make_wifi_calls";
 
         // Settings moved to Settings.Secure
@@ -5173,6 +5353,7 @@
          * instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE =
                 Secure.WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE;
 
@@ -5187,6 +5368,7 @@
          * {@link android.provider.Settings.Secure#WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS} instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS =
                 Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS;
 
@@ -5195,6 +5377,7 @@
          * {@link android.provider.Settings.Secure#WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED} instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED =
                 Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED;
 
@@ -5204,6 +5387,7 @@
          * instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS =
                 Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS;
 
@@ -5212,6 +5396,7 @@
          * {@link android.provider.Settings.Secure#WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT} instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT =
             Secure.WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT;
 
@@ -5246,6 +5431,7 @@
          * instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_PING_TIMEOUT_MS =
             Secure.WIFI_WATCHDOG_PING_TIMEOUT_MS;
 
@@ -5295,7 +5481,8 @@
                 CONTENT_URI,
                 CALL_METHOD_GET_SECURE,
                 CALL_METHOD_PUT_SECURE,
-                sProviderHolder);
+                sProviderHolder,
+                Secure.class);
 
         private static ILockSettings sLockSettings = null;
 
@@ -5433,6 +5620,11 @@
             sNameValueCache.clearGenerationTrackerForTest();
         }
 
+        /** @hide */
+        public static void getPublicSettings(Set<String> allKeys, Set<String> readableKeys) {
+            getPublicSettingsForClass(Secure.class, allKeys, readableKeys);
+        }
+
         /**
          * Look up a name in the database.
          * @param resolver to access the database with
@@ -5928,6 +6120,7 @@
          * Control whether to enable adaptive sleep mode.
          * @hide
          */
+        @Readable
         public static final String ADAPTIVE_SLEEP = "adaptive_sleep";
 
         /**
@@ -5935,6 +6128,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAMERA_AUTOROTATE = "camera_autorotate";
 
         /**
@@ -5952,6 +6146,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String BUGREPORT_IN_POWER_MENU = "bugreport_in_power_menu";
 
         /**
@@ -5969,6 +6164,7 @@
          * @deprecated This settings is not used anymore.
          */
         @Deprecated
+        @Readable
         public static final String ALLOW_MOCK_LOCATION = "mock_location";
 
         /**
@@ -5977,6 +6173,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String ODI_CAPTIONS_ENABLED = "odi_captions_enabled";
 
         /**
@@ -6016,6 +6213,7 @@
          * to the Instant App, it is generated when the Instant App is first installed and reset if
          * the user clears the Instant App.
          */
+        @Readable
         public static final String ANDROID_ID = "android_id";
 
         /**
@@ -6034,12 +6232,14 @@
          * Setting to record the input method used by default, holding the ID
          * of the desired method.
          */
+        @Readable
         public static final String DEFAULT_INPUT_METHOD = "default_input_method";
 
         /**
          * Setting to record the input method subtype used by default, holding the ID
          * of the desired method.
          */
+        @Readable
         public static final String SELECTED_INPUT_METHOD_SUBTYPE =
                 "selected_input_method_subtype";
 
@@ -6048,12 +6248,14 @@
          * and its last used subtype.
          * @hide
          */
+        @Readable
         public static final String INPUT_METHODS_SUBTYPE_HISTORY =
                 "input_methods_subtype_history";
 
         /**
          * Setting to record the visibility of input method selector
          */
+        @Readable
         public static final String INPUT_METHOD_SELECTOR_VISIBILITY =
                 "input_method_selector_visibility";
 
@@ -6062,6 +6264,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String VOICE_INTERACTION_SERVICE = "voice_interaction_service";
 
         /**
@@ -6069,6 +6272,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String AUTOFILL_SERVICE = "autofill_service";
 
         /**
@@ -6079,6 +6283,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String AUTOFILL_FEATURE_FIELD_CLASSIFICATION =
                 "autofill_field_classification";
 
@@ -6087,6 +6292,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DARK_MODE_DIALOG_SEEN =
                 "dark_mode_dialog_seen";
 
@@ -6095,6 +6301,7 @@
          * Represented as milliseconds from midnight (e.g. 79200000 == 10pm).
          * @hide
          */
+        @Readable
         public static final String DARK_THEME_CUSTOM_START_TIME =
                 "dark_theme_custom_start_time";
 
@@ -6103,6 +6310,7 @@
          * Represented as milliseconds from midnight (e.g. 79200000 == 10pm).
          * @hide
          */
+        @Readable
         public static final String DARK_THEME_CUSTOM_END_TIME =
                 "dark_theme_custom_end_time";
 
@@ -6112,6 +6320,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String AUTOFILL_USER_DATA_MAX_USER_DATA_SIZE =
                 "autofill_user_data_max_user_data_size";
 
@@ -6122,6 +6331,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String AUTOFILL_USER_DATA_MAX_FIELD_CLASSIFICATION_IDS_SIZE =
                 "autofill_user_data_max_field_classification_size";
 
@@ -6132,6 +6342,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String AUTOFILL_USER_DATA_MAX_CATEGORY_COUNT =
                 "autofill_user_data_max_category_count";
 
@@ -6141,6 +6352,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String AUTOFILL_USER_DATA_MAX_VALUE_LENGTH =
                 "autofill_user_data_max_value_length";
 
@@ -6150,6 +6362,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String AUTOFILL_USER_DATA_MIN_VALUE_LENGTH =
                 "autofill_user_data_min_value_length";
 
@@ -6162,6 +6375,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String CONTENT_CAPTURE_ENABLED = "content_capture_enabled";
 
         /**
@@ -6179,6 +6393,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String MANAGED_PROVISIONING_DPC_DOWNLOADED =
                 "managed_provisioning_dpc_downloaded";
 
@@ -6189,6 +6404,7 @@
          * <p>
          * Type: int (0 for false, 1 for true)
          */
+        @Readable
         public static final String SECURE_FRP_MODE = "secure_frp_mode";
 
         /**
@@ -6199,6 +6415,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String USER_SETUP_COMPLETE = "user_setup_complete";
 
         /**
@@ -6254,6 +6471,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String USER_SETUP_PERSONALIZATION_STATE =
                 "user_setup_personalization_state";
 
@@ -6264,6 +6482,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String TV_USER_SETUP_COMPLETE = "tv_user_setup_complete";
 
         /**
@@ -6275,6 +6494,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String COMPLETED_CATEGORY_PREFIX = "suggested.completed_category.";
 
         /**
@@ -6285,6 +6505,7 @@
          * Format like "ime0;subtype0;subtype1;subtype2:ime1:ime2;subtype0"
          * where imeId is ComponentName and subtype is int32.
          */
+        @Readable
         public static final String ENABLED_INPUT_METHODS = "enabled_input_methods";
 
         /**
@@ -6293,6 +6514,7 @@
          * by ':'.
          * @hide
          */
+        @Readable
         public static final String DISABLED_SYSTEM_INPUT_METHODS = "disabled_system_input_methods";
 
         /**
@@ -6301,6 +6523,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         @SuppressLint("NoSettingsProvider")
         public static final String SHOW_IME_WITH_HARD_KEYBOARD = "show_ime_with_hard_keyboard";
 
@@ -6318,6 +6541,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ALWAYS_ON_VPN_APP = "always_on_vpn_app";
 
         /**
@@ -6326,6 +6550,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ALWAYS_ON_VPN_LOCKDOWN = "always_on_vpn_lockdown";
 
         /**
@@ -6335,6 +6560,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ALWAYS_ON_VPN_LOCKDOWN_WHITELIST =
                 "always_on_vpn_lockdown_whitelist";
 
@@ -6348,6 +6574,8 @@
          * {@link PackageManager#canRequestPackageInstalls()}
          * @see PackageManager#canRequestPackageInstalls()
          */
+        @Deprecated
+        @Readable
         public static final String INSTALL_NON_MARKET_APPS = "install_non_market_apps";
 
         /**
@@ -6359,6 +6587,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String UNKNOWN_SOURCES_DEFAULT_REVERSED =
                 "unknown_sources_default_reversed";
 
@@ -6372,6 +6601,7 @@
          * instead.
          */
         @Deprecated
+        @Readable
         public static final String LOCATION_PROVIDERS_ALLOWED = "location_providers_allowed";
 
         /**
@@ -6383,12 +6613,14 @@
          * {@link LocationManager#MODE_CHANGED_ACTION}.
          */
         @Deprecated
+        @Readable
         public static final String LOCATION_MODE = "location_mode";
 
         /**
          * The App or module that changes the location mode.
          * @hide
          */
+        @Readable
         public static final String LOCATION_CHANGER = "location_changer";
 
         /**
@@ -6457,6 +6689,7 @@
          * android.app.timezonedetector.TimeZoneDetector#updateConfiguration} to update.
          * @hide
          */
+        @Readable
         public static final String LOCATION_TIME_ZONE_DETECTION_ENABLED =
                 "location_time_zone_detection_enabled";
 
@@ -6466,6 +6699,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String LOCATION_COARSE_ACCURACY_M = "locationCoarseAccuracy";
 
         /**
@@ -6473,6 +6707,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String LOCK_BIOMETRIC_WEAK_FLAGS =
                 "lock_biometric_weak_flags";
 
@@ -6480,6 +6715,7 @@
          * Whether lock-to-app will lock the keyguard when exiting.
          * @hide
          */
+        @Readable
         public static final String LOCK_TO_APP_EXIT_LOCKED = "lock_to_app_exit_locked";
 
         /**
@@ -6490,6 +6726,7 @@
          *             {@link VERSION_CODES#M} or later throws a {@code SecurityException}.
          */
         @Deprecated
+        @Readable
         public static final String LOCK_PATTERN_ENABLED = "lock_pattern_autolock";
 
         /**
@@ -6499,6 +6736,7 @@
          *             {@link VERSION_CODES#M} or later throws a {@code SecurityException}.
          */
         @Deprecated
+        @Readable
         public static final String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern";
 
         /**
@@ -6512,6 +6750,7 @@
          *             {@link VERSION_CODES#M} or later throws a {@code SecurityException}.
          */
         @Deprecated
+        @Readable
         public static final String
                 LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED = "lock_pattern_tactile_feedback_enabled";
 
@@ -6521,6 +6760,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String LOCK_SCREEN_LOCK_AFTER_TIMEOUT = "lock_screen_lock_after_timeout";
 
 
@@ -6530,6 +6770,7 @@
          * @deprecated
          */
         @Deprecated
+        @Readable
         public static final String LOCK_SCREEN_OWNER_INFO = "lock_screen_owner_info";
 
         /**
@@ -6537,6 +6778,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String LOCK_SCREEN_APPWIDGET_IDS =
             "lock_screen_appwidget_ids";
 
@@ -6545,6 +6787,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String LOCK_SCREEN_FALLBACK_APPWIDGET_ID =
             "lock_screen_fallback_appwidget_id";
 
@@ -6553,6 +6796,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String LOCK_SCREEN_STICKY_APPWIDGET =
             "lock_screen_sticky_appwidget";
 
@@ -6563,6 +6807,7 @@
          */
         @Deprecated
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String LOCK_SCREEN_OWNER_INFO_ENABLED =
             "lock_screen_owner_info_enabled";
 
@@ -6575,6 +6820,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS =
                 "lock_screen_allow_private_notifications";
 
@@ -6583,6 +6829,7 @@
          * without having to unlock
          * @hide
          */
+        @Readable
         public static final String LOCK_SCREEN_ALLOW_REMOTE_INPUT =
                 "lock_screen_allow_remote_input";
 
@@ -6592,12 +6839,14 @@
          *     {"clock": id, "_applied_timestamp": timestamp}
          * @hide
          */
+        @Readable
         public static final String LOCK_SCREEN_CUSTOM_CLOCK_FACE = "lock_screen_custom_clock_face";
 
         /**
          * Indicates which clock face to show on lock screen and AOD while docked.
          * @hide
          */
+        @Readable
         public static final String DOCKED_CLOCK_FACE = "docked_clock_face";
 
         /**
@@ -6605,6 +6854,7 @@
          * the lockscreen notification policy.
          * @hide
          */
+        @Readable
         public static final String SHOW_NOTE_ABOUT_NOTIFICATION_HIDING =
                 "show_note_about_notification_hiding";
 
@@ -6612,6 +6862,7 @@
          * Set to 1 by the system after trust agents have been initialized.
          * @hide
          */
+        @Readable
         public static final String TRUST_AGENTS_INITIALIZED =
                 "trust_agents_initialized";
 
@@ -6622,6 +6873,7 @@
          * many collisions.  It should not be used.
          */
         @Deprecated
+        @Readable
         public static final String LOGGING_ID = "logging_id";
 
         /**
@@ -6633,16 +6885,19 @@
         /**
          * No longer supported.
          */
+        @Readable
         public static final String PARENTAL_CONTROL_ENABLED = "parental_control_enabled";
 
         /**
          * No longer supported.
          */
+        @Readable
         public static final String PARENTAL_CONTROL_LAST_UPDATE = "parental_control_last_update";
 
         /**
          * No longer supported.
          */
+        @Readable
         public static final String PARENTAL_CONTROL_REDIRECT_URL = "parental_control_redirect_url";
 
         /**
@@ -6651,6 +6906,7 @@
          * and new Settings apps.
          */
         // TODO: 881807
+        @Readable
         public static final String SETTINGS_CLASSNAME = "settings_classname";
 
         /**
@@ -6668,12 +6924,14 @@
         /**
          * If accessibility is enabled.
          */
+        @Readable
         public static final String ACCESSIBILITY_ENABLED = "accessibility_enabled";
 
         /**
          * Setting specifying if the accessibility shortcut is enabled.
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN =
                 "accessibility_shortcut_on_lock_screen";
 
@@ -6681,6 +6939,7 @@
          * Setting specifying if the accessibility shortcut dialog has been shown to this user.
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN =
                 "accessibility_shortcut_dialog_shown";
 
@@ -6695,6 +6954,7 @@
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         @TestApi
+        @Readable
         public static final String ACCESSIBILITY_SHORTCUT_TARGET_SERVICE =
                 "accessibility_shortcut_target_service";
 
@@ -6705,6 +6965,7 @@
          * accessibility feature.
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_BUTTON_TARGET_COMPONENT =
                 "accessibility_button_target_component";
 
@@ -6717,6 +6978,7 @@
          * accessibility feature.
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_BUTTON_TARGETS = "accessibility_button_targets";
 
         /**
@@ -6725,17 +6987,20 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER =
                 "com.android.server.accessibility.MagnificationController";
 
         /**
          * If touch exploration is enabled.
          */
+        @Readable
         public static final String TOUCH_EXPLORATION_ENABLED = "touch_exploration_enabled";
 
         /**
          * List of the enabled accessibility providers.
          */
+        @Readable
         public static final String ENABLED_ACCESSIBILITY_SERVICES =
             "enabled_accessibility_services";
 
@@ -6745,6 +7010,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES =
             "touch_exploration_granted_accessibility_services";
 
@@ -6752,12 +7018,14 @@
          * Whether the Global Actions Panel is enabled.
          * @hide
          */
+        @Readable
         public static final String GLOBAL_ACTIONS_PANEL_ENABLED = "global_actions_panel_enabled";
 
         /**
          * Whether the Global Actions Panel can be toggled on or off in Settings.
          * @hide
          */
+        @Readable
         public static final String GLOBAL_ACTIONS_PANEL_AVAILABLE =
                 "global_actions_panel_available";
 
@@ -6765,6 +7033,7 @@
          * Enables debug mode for the Global Actions Panel.
          * @hide
          */
+        @Readable
         public static final String GLOBAL_ACTIONS_PANEL_DEBUG_ENABLED =
                 "global_actions_panel_debug_enabled";
 
@@ -6773,24 +7042,28 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String HUSH_GESTURE_USED = "hush_gesture_used";
 
         /**
          * Number of times the user has manually clicked the ringer toggle
          * @hide
          */
+        @Readable
         public static final String MANUAL_RINGER_TOGGLE_COUNT = "manual_ringer_toggle_count";
 
         /**
          * Whether to play a sound for charging events.
          * @hide
          */
+        @Readable
         public static final String CHARGING_SOUNDS_ENABLED = "charging_sounds_enabled";
 
         /**
          * Whether to vibrate for charging events.
          * @hide
          */
+        @Readable
         public static final String CHARGING_VIBRATION_ENABLED = "charging_vibration_enabled";
 
         /**
@@ -6800,6 +7073,7 @@
          * user to specify a duration.
          * @hide
          */
+        @Readable
         public static final String ZEN_DURATION = "zen_duration";
 
         /** @hide */ public static final int ZEN_DURATION_PROMPT = -1;
@@ -6809,24 +7083,28 @@
          * If nonzero, will show the zen upgrade notification when the user toggles DND on/off.
          * @hide
          */
+        @Readable
         public static final String SHOW_ZEN_UPGRADE_NOTIFICATION = "show_zen_upgrade_notification";
 
         /**
          * If nonzero, will show the zen update settings suggestion.
          * @hide
          */
+        @Readable
         public static final String SHOW_ZEN_SETTINGS_SUGGESTION = "show_zen_settings_suggestion";
 
         /**
          * If nonzero, zen has not been updated to reflect new changes.
          * @hide
          */
+        @Readable
         public static final String ZEN_SETTINGS_UPDATED = "zen_settings_updated";
 
         /**
          * If nonzero, zen setting suggestion has been viewed by user
          * @hide
          */
+        @Readable
         public static final String ZEN_SETTINGS_SUGGESTION_VIEWED =
                 "zen_settings_suggestion_viewed";
 
@@ -6835,6 +7113,7 @@
          * boolean (1 or 0).
          * @hide
          */
+        @Readable
         public static final String IN_CALL_NOTIFICATION_ENABLED = "in_call_notification_enabled";
 
         /**
@@ -6843,6 +7122,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String KEYGUARD_SLICE_URI = "keyguard_slice_uri";
 
         /**
@@ -6855,6 +7135,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String FONT_WEIGHT_ADJUSTMENT = "font_weight_adjustment";
 
         /**
@@ -6865,6 +7146,7 @@
          * at all times, which was the behavior when this value was {@code true}.
          */
         @Deprecated
+        @Readable
         public static final String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password";
 
         /**
@@ -6872,6 +7154,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED =
                 "high_text_contrast_enabled";
 
@@ -6885,6 +7168,7 @@
          */
         @UnsupportedAppUsage
         @TestApi
+        @Readable
         public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED =
                 "accessibility_display_magnification_enabled";
 
@@ -6900,6 +7184,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED =
                 "accessibility_display_magnification_navbar_enabled";
 
@@ -6913,6 +7198,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE =
                 "accessibility_display_magnification_scale";
 
@@ -6923,6 +7209,7 @@
          * @deprecated
          */
         @Deprecated
+        @Readable
         public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE =
                 "accessibility_display_magnification_auto_update";
 
@@ -6932,6 +7219,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_SOFT_KEYBOARD_MODE =
                 "accessibility_soft_keyboard_mode";
 
@@ -6965,6 +7253,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_CAPTIONING_ENABLED =
                 "accessibility_captioning_enabled";
 
@@ -6975,6 +7264,7 @@
          * @see java.util.Locale#toString
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_CAPTIONING_LOCALE =
                 "accessibility_captioning_locale";
 
@@ -6989,6 +7279,7 @@
          * @see java.util.Locale#toString
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_CAPTIONING_PRESET =
                 "accessibility_captioning_preset";
 
@@ -6999,6 +7290,7 @@
          * @see android.graphics.Color#argb
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR =
                 "accessibility_captioning_background_color";
 
@@ -7009,6 +7301,7 @@
          * @see android.graphics.Color#argb
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR =
                 "accessibility_captioning_foreground_color";
 
@@ -7023,6 +7316,7 @@
          * @see #ACCESSIBILITY_CAPTIONING_EDGE_COLOR
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_CAPTIONING_EDGE_TYPE =
                 "accessibility_captioning_edge_type";
 
@@ -7034,6 +7328,7 @@
          * @see android.graphics.Color#argb
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_CAPTIONING_EDGE_COLOR =
                 "accessibility_captioning_edge_color";
 
@@ -7044,6 +7339,7 @@
          * @see android.graphics.Color#argb
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_CAPTIONING_WINDOW_COLOR =
                 "accessibility_captioning_window_color";
 
@@ -7060,6 +7356,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String ACCESSIBILITY_CAPTIONING_TYPEFACE =
                 "accessibility_captioning_typeface";
 
@@ -7068,12 +7365,14 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_CAPTIONING_FONT_SCALE =
                 "accessibility_captioning_font_scale";
 
         /**
          * Setting that specifies whether display color inversion is enabled.
          */
+        @Readable
         public static final String ACCESSIBILITY_DISPLAY_INVERSION_ENABLED =
                 "accessibility_display_inversion_enabled";
 
@@ -7084,6 +7383,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED =
                 "accessibility_display_daltonizer_enabled";
 
@@ -7100,6 +7400,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String ACCESSIBILITY_DISPLAY_DALTONIZER =
                 "accessibility_display_daltonizer";
 
@@ -7110,6 +7411,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String ACCESSIBILITY_AUTOCLICK_ENABLED =
                 "accessibility_autoclick_enabled";
 
@@ -7120,6 +7422,7 @@
          * @see #ACCESSIBILITY_AUTOCLICK_ENABLED
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_AUTOCLICK_DELAY =
                 "accessibility_autoclick_delay";
 
@@ -7130,6 +7433,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String ACCESSIBILITY_LARGE_POINTER_ICON =
                 "accessibility_large_pointer_icon";
 
@@ -7138,6 +7442,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String LONG_PRESS_TIMEOUT = "long_press_timeout";
 
         /**
@@ -7145,6 +7450,7 @@
          * down event for an interaction to be considered part of the same multi-press.
          * @hide
          */
+        @Readable
         public static final String MULTI_PRESS_TIMEOUT = "multi_press_timeout";
 
         /**
@@ -7153,6 +7459,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_NON_INTERACTIVE_UI_TIMEOUT_MS =
                 "accessibility_non_interactive_ui_timeout_ms";
 
@@ -7162,6 +7469,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS =
                 "accessibility_interactive_ui_timeout_ms";
 
@@ -7172,6 +7480,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String REDUCE_BRIGHT_COLORS_ACTIVATED =
                 "reduce_bright_colors_activated";
 
@@ -7181,6 +7490,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String REDUCE_BRIGHT_COLORS_LEVEL =
                 "reduce_bright_colors_level";
 
@@ -7189,6 +7499,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String REDUCE_BRIGHT_COLORS_PERSIST_ACROSS_REBOOTS =
                 "reduce_bright_colors_persist_across_reboots";
 
@@ -7201,6 +7512,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String ENABLED_PRINT_SERVICES =
             "enabled_print_services";
 
@@ -7210,6 +7522,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String DISABLED_PRINT_SERVICES =
             "disabled_print_services";
 
@@ -7220,6 +7533,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DISPLAY_DENSITY_FORCED = "display_density_forced";
 
         /**
@@ -7232,21 +7546,25 @@
          * the framework text to speech APIs as of the Ice Cream Sandwich release.
          */
         @Deprecated
+        @Readable
         public static final String TTS_USE_DEFAULTS = "tts_use_defaults";
 
         /**
          * Default text-to-speech engine speech rate. 100 = 1x
          */
+        @Readable
         public static final String TTS_DEFAULT_RATE = "tts_default_rate";
 
         /**
          * Default text-to-speech engine pitch. 100 = 1x
          */
+        @Readable
         public static final String TTS_DEFAULT_PITCH = "tts_default_pitch";
 
         /**
          * Default text-to-speech engine.
          */
+        @Readable
         public static final String TTS_DEFAULT_SYNTH = "tts_default_synth";
 
         /**
@@ -7258,6 +7576,7 @@
          * locale. {@link TextToSpeech#getLanguage()}.
          */
         @Deprecated
+        @Readable
         public static final String TTS_DEFAULT_LANG = "tts_default_lang";
 
         /**
@@ -7269,6 +7588,7 @@
          * locale. {@link TextToSpeech#getLanguage()}.
          */
         @Deprecated
+        @Readable
         public static final String TTS_DEFAULT_COUNTRY = "tts_default_country";
 
         /**
@@ -7280,6 +7600,7 @@
          * locale that is in use {@link TextToSpeech#getLanguage()}.
          */
         @Deprecated
+        @Readable
         public static final String TTS_DEFAULT_VARIANT = "tts_default_variant";
 
         /**
@@ -7294,11 +7615,13 @@
          *
          * @hide
          */
+        @Readable
         public static final String TTS_DEFAULT_LOCALE = "tts_default_locale";
 
         /**
          * Space delimited list of plugin packages that are enabled.
          */
+        @Readable
         public static final String TTS_ENABLED_PLUGINS = "tts_enabled_plugins";
 
         /**
@@ -7338,6 +7661,7 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE =
                 "wifi_watchdog_acceptable_packet_loss_percentage";
 
@@ -7347,6 +7671,7 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_AP_COUNT = "wifi_watchdog_ap_count";
 
         /**
@@ -7354,6 +7679,7 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS =
                 "wifi_watchdog_background_check_delay_ms";
 
@@ -7363,6 +7689,7 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED =
                 "wifi_watchdog_background_check_enabled";
 
@@ -7371,6 +7698,7 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS =
                 "wifi_watchdog_background_check_timeout_ms";
 
@@ -7382,6 +7710,7 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT =
             "wifi_watchdog_initial_ignored_ping_count";
 
@@ -7393,12 +7722,14 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_MAX_AP_CHECKS = "wifi_watchdog_max_ap_checks";
 
         /**
          * @deprecated Use {@link android.provider.Settings.Global#WIFI_WATCHDOG_ON} instead
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_ON = "wifi_watchdog_on";
 
         /**
@@ -7406,6 +7737,7 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_WATCH_LIST = "wifi_watchdog_watch_list";
 
         /**
@@ -7413,6 +7745,7 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_PING_COUNT = "wifi_watchdog_ping_count";
 
         /**
@@ -7420,6 +7753,7 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_PING_DELAY_MS = "wifi_watchdog_ping_delay_ms";
 
         /**
@@ -7427,6 +7761,7 @@
          * @deprecated This setting is not used.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_WATCHDOG_PING_TIMEOUT_MS = "wifi_watchdog_ping_timeout_ms";
 
         /**
@@ -7451,6 +7786,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS =
                 "connectivity_release_pending_intent_delay_ms";
 
@@ -7464,12 +7800,14 @@
          *             now appear disconnected.
          */
         @Deprecated
+        @Readable
         public static final String BACKGROUND_DATA = "background_data";
 
         /**
          * Origins for which browsers should allow geolocation by default.
          * The value is a space-separated list of origins.
          */
+        @Readable
         public static final String ALLOWED_GEOLOCATION_ORIGINS
                 = "allowed_geolocation_origins";
 
@@ -7480,6 +7818,7 @@
          *                            3 = TTY VCO
          * @hide
          */
+        @Readable
         public static final String PREFERRED_TTY_MODE =
                 "preferred_tty_mode";
 
@@ -7489,6 +7828,7 @@
          * 1 = enhanced voice privacy
          * @hide
          */
+        @Readable
         public static final String ENHANCED_VOICE_PRIVACY_ENABLED = "enhanced_voice_privacy_enabled";
 
         /**
@@ -7497,6 +7837,7 @@
          * 1 = enabled
          * @hide
          */
+        @Readable
         public static final String TTY_MODE_ENABLED = "tty_mode_enabled";
 
         /**
@@ -7505,6 +7846,7 @@
          * 0 = OFF
          * 1 = ON
          */
+        @Readable
         public static final String RTT_CALLING_MODE = "rtt_calling_mode";
 
         /**
@@ -7514,6 +7856,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String BACKUP_ENABLED = "backup_enabled";
 
         /**
@@ -7523,6 +7866,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String BACKUP_AUTO_RESTORE = "backup_auto_restore";
 
         /**
@@ -7531,6 +7875,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String BACKUP_PROVISIONED = "backup_provisioned";
 
         /**
@@ -7538,6 +7883,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String BACKUP_TRANSPORT = "backup_transport";
 
         /**
@@ -7547,6 +7893,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String LAST_SETUP_SHOWN = "last_setup_shown";
 
         /**
@@ -7569,6 +7916,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SEARCH_GLOBAL_SEARCH_ACTIVITY =
                 "search_global_search_activity";
 
@@ -7576,21 +7924,25 @@
          * The number of promoted sources in GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_NUM_PROMOTED_SOURCES = "search_num_promoted_sources";
         /**
          * The maximum number of suggestions returned by GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_MAX_RESULTS_TO_DISPLAY = "search_max_results_to_display";
         /**
          * The number of suggestions GlobalSearch will ask each non-web search source for.
          * @hide
          */
+        @Readable
         public static final String SEARCH_MAX_RESULTS_PER_SOURCE = "search_max_results_per_source";
         /**
          * The number of suggestions the GlobalSearch will ask the web search source for.
          * @hide
          */
+        @Readable
         public static final String SEARCH_WEB_RESULTS_OVERRIDE_LIMIT =
                 "search_web_results_override_limit";
         /**
@@ -7598,69 +7950,81 @@
          * promoted sources before continuing with all other sources.
          * @hide
          */
+        @Readable
         public static final String SEARCH_PROMOTED_SOURCE_DEADLINE_MILLIS =
                 "search_promoted_source_deadline_millis";
         /**
          * The number of milliseconds before GlobalSearch aborts search suggesiton queries.
          * @hide
          */
+        @Readable
         public static final String SEARCH_SOURCE_TIMEOUT_MILLIS = "search_source_timeout_millis";
         /**
          * The maximum number of milliseconds that GlobalSearch shows the previous results
          * after receiving a new query.
          * @hide
          */
+        @Readable
         public static final String SEARCH_PREFILL_MILLIS = "search_prefill_millis";
         /**
          * The maximum age of log data used for shortcuts in GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_MAX_STAT_AGE_MILLIS = "search_max_stat_age_millis";
         /**
          * The maximum age of log data used for source ranking in GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_MAX_SOURCE_EVENT_AGE_MILLIS =
                 "search_max_source_event_age_millis";
         /**
          * The minimum number of impressions needed to rank a source in GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_MIN_IMPRESSIONS_FOR_SOURCE_RANKING =
                 "search_min_impressions_for_source_ranking";
         /**
          * The minimum number of clicks needed to rank a source in GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_MIN_CLICKS_FOR_SOURCE_RANKING =
                 "search_min_clicks_for_source_ranking";
         /**
          * The maximum number of shortcuts shown by GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_MAX_SHORTCUTS_RETURNED = "search_max_shortcuts_returned";
         /**
          * The size of the core thread pool for suggestion queries in GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_QUERY_THREAD_CORE_POOL_SIZE =
                 "search_query_thread_core_pool_size";
         /**
          * The maximum size of the thread pool for suggestion queries in GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_QUERY_THREAD_MAX_POOL_SIZE =
                 "search_query_thread_max_pool_size";
         /**
          * The size of the core thread pool for shortcut refreshing in GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_SHORTCUT_REFRESH_CORE_POOL_SIZE =
                 "search_shortcut_refresh_core_pool_size";
         /**
          * The maximum size of the thread pool for shortcut refreshing in GlobalSearch.
          * @hide
          */
+        @Readable
         public static final String SEARCH_SHORTCUT_REFRESH_MAX_POOL_SIZE =
                 "search_shortcut_refresh_max_pool_size";
         /**
@@ -7668,12 +8032,14 @@
          * wait before terminating.
          * @hide
          */
+        @Readable
         public static final String SEARCH_THREAD_KEEPALIVE_SECONDS =
                 "search_thread_keepalive_seconds";
         /**
          * The maximum number of concurrent suggestion queries to each source.
          * @hide
          */
+        @Readable
         public static final String SEARCH_PER_SOURCE_CONCURRENT_QUERY_LIMIT =
                 "search_per_source_concurrent_query_limit";
 
@@ -7682,24 +8048,28 @@
          * (0 = false, 1 = true)
          * @hide
          */
+        @Readable
         public static final String MOUNT_PLAY_NOTIFICATION_SND = "mount_play_not_snd";
 
         /**
          * Whether or not UMS auto-starts on UMS host detection. (0 = false, 1 = true)
          * @hide
          */
+        @Readable
         public static final String MOUNT_UMS_AUTOSTART = "mount_ums_autostart";
 
         /**
          * Whether or not a notification is displayed on UMS host detection. (0 = false, 1 = true)
          * @hide
          */
+        @Readable
         public static final String MOUNT_UMS_PROMPT = "mount_ums_prompt";
 
         /**
          * Whether or not a notification is displayed while UMS is enabled. (0 = false, 1 = true)
          * @hide
          */
+        @Readable
         public static final String MOUNT_UMS_NOTIFY_ENABLED = "mount_ums_notify_enabled";
 
         /**
@@ -7711,6 +8081,7 @@
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         @TestApi
+        @Readable
         @SuppressLint("NoSettingsProvider")
         public static final String ANR_SHOW_BACKGROUND = "anr_show_background";
 
@@ -7720,6 +8091,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         @SuppressLint("NoSettingsProvider")
         public static final String SHOW_FIRST_CRASH_DIALOG_DEV_OPTION =
                 "show_first_crash_dialog_dev_option";
@@ -7731,6 +8103,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String VOICE_RECOGNITION_SERVICE = "voice_recognition_service";
 
         /**
@@ -7741,6 +8114,7 @@
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         @TestApi
+        @Readable
         @SuppressLint("NoSettingsProvider")
         public static final String SELECTED_SPELL_CHECKER = "selected_spell_checker";
 
@@ -7753,6 +8127,7 @@
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         @TestApi
+        @Readable
         @SuppressLint("NoSettingsProvider")
         public static final String SELECTED_SPELL_CHECKER_SUBTYPE =
                 "selected_spell_checker_subtype";
@@ -7762,6 +8137,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SPELL_CHECKER_ENABLED = "spell_checker_enabled";
 
         /**
@@ -7774,6 +8150,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String INCALL_POWER_BUTTON_BEHAVIOR = "incall_power_button_behavior";
 
         /**
@@ -7788,6 +8165,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String MINIMAL_POST_PROCESSING_ALLOWED =
                 "minimal_post_processing_allowed";
 
@@ -7832,6 +8210,7 @@
          * @see #MATCH_CONTENT_FRAMERATE_ALWAYS
          * @hide
          */
+        @Readable
         public static final String MATCH_CONTENT_FRAME_RATE =
                 "match_content_frame_rate";
 
@@ -7863,6 +8242,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String INCALL_BACK_BUTTON_BEHAVIOR = "incall_back_button_behavior";
 
         /**
@@ -7888,6 +8268,7 @@
          * Whether the device should wake when the wake gesture sensor detects motion.
          * @hide
          */
+        @Readable
         public static final String WAKE_GESTURE_ENABLED = "wake_gesture_enabled";
 
         /**
@@ -7895,6 +8276,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String DOZE_ENABLED = "doze_enabled";
 
         /**
@@ -7905,36 +8287,42 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String DOZE_ALWAYS_ON = "doze_always_on";
 
         /**
          * Whether the device should pulse on pick up gesture.
          * @hide
          */
+        @Readable
         public static final String DOZE_PICK_UP_GESTURE = "doze_pulse_on_pick_up";
 
         /**
          * Whether the device should pulse on long press gesture.
          * @hide
          */
+        @Readable
         public static final String DOZE_PULSE_ON_LONG_PRESS = "doze_pulse_on_long_press";
 
         /**
          * Whether the device should pulse on double tap gesture.
          * @hide
          */
+        @Readable
         public static final String DOZE_DOUBLE_TAP_GESTURE = "doze_pulse_on_double_tap";
 
         /**
          * Whether the device should respond to the SLPI tap gesture.
          * @hide
          */
+        @Readable
         public static final String DOZE_TAP_SCREEN_GESTURE = "doze_tap_gesture";
 
         /**
          * Gesture that wakes up the display, showing some version of the lock screen.
          * @hide
          */
+        @Readable
         public static final String DOZE_WAKE_LOCK_SCREEN_GESTURE = "doze_wake_screen_gesture";
 
         /**
@@ -7942,84 +8330,98 @@
          * {@link Display.STATE_DOZE}.
          * @hide
          */
+        @Readable
         public static final String DOZE_WAKE_DISPLAY_GESTURE = "doze_wake_display_gesture";
 
         /**
          * Whether the device should suppress the current doze configuration and disable dozing.
          * @hide
          */
+        @Readable
         public static final String SUPPRESS_DOZE = "suppress_doze";
 
         /**
          * Gesture that skips media.
          * @hide
          */
+        @Readable
         public static final String SKIP_GESTURE = "skip_gesture";
 
         /**
          * Count of successful gestures.
          * @hide
          */
+        @Readable
         public static final String SKIP_GESTURE_COUNT = "skip_gesture_count";
 
         /**
          * Count of non-gesture interaction.
          * @hide
          */
+        @Readable
         public static final String SKIP_TOUCH_COUNT = "skip_touch_count";
 
         /**
          * Direction to advance media for skip gesture
          * @hide
          */
+        @Readable
         public static final String SKIP_DIRECTION = "skip_gesture_direction";
 
         /**
          * Gesture that silences sound (alarms, notification, calls).
          * @hide
          */
+        @Readable
         public static final String SILENCE_GESTURE = "silence_gesture";
 
         /**
          * Count of successful silence alarms gestures.
          * @hide
          */
+        @Readable
         public static final String SILENCE_ALARMS_GESTURE_COUNT = "silence_alarms_gesture_count";
 
         /**
          * Count of successful silence timer gestures.
          * @hide
          */
+        @Readable
         public static final String SILENCE_TIMER_GESTURE_COUNT = "silence_timer_gesture_count";
 
         /**
          * Count of successful silence call gestures.
          * @hide
          */
+        @Readable
         public static final String SILENCE_CALL_GESTURE_COUNT = "silence_call_gesture_count";
 
         /**
          * Count of non-gesture interaction.
          * @hide
          */
+        @Readable
         public static final String SILENCE_ALARMS_TOUCH_COUNT = "silence_alarms_touch_count";
 
         /**
          * Count of non-gesture interaction.
          * @hide
          */
+        @Readable
         public static final String SILENCE_TIMER_TOUCH_COUNT = "silence_timer_touch_count";
 
         /**
          * Count of non-gesture interaction.
          * @hide
          */
+        @Readable
         public static final String SILENCE_CALL_TOUCH_COUNT = "silence_call_touch_count";
 
         /**
          * Number of successful "Motion Sense" tap gestures to pause media.
          * @hide
          */
+        @Readable
         public static final String AWARE_TAP_PAUSE_GESTURE_COUNT = "aware_tap_pause_gesture_count";
 
         /**
@@ -8027,12 +8429,14 @@
          * have been used.
          * @hide
          */
+        @Readable
         public static final String AWARE_TAP_PAUSE_TOUCH_COUNT = "aware_tap_pause_touch_count";
 
         /**
          * For user preference if swipe bottom to expand notification gesture enabled.
          * @hide
          */
+        @Readable
         public static final String SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED =
                 "swipe_bottom_to_notification_enabled";
 
@@ -8040,24 +8444,28 @@
          * For user preference if One-Handed Mode enabled.
          * @hide
          */
+        @Readable
         public static final String ONE_HANDED_MODE_ENABLED = "one_handed_mode_enabled";
 
         /**
          * For user preference if One-Handed Mode timeout.
          * @hide
          */
+        @Readable
         public static final String ONE_HANDED_MODE_TIMEOUT = "one_handed_mode_timeout";
 
         /**
          * For user taps app to exit One-Handed Mode.
          * @hide
          */
+        @Readable
         public static final String TAPS_APP_TO_EXIT = "taps_app_to_exit";
 
         /**
          * Internal use, one handed mode tutorial showed times.
          * @hide
          */
+        @Readable
         public static final String ONE_HANDED_TUTORIAL_SHOW_COUNT =
                 "one_handed_tutorial_show_count";
 
@@ -8067,6 +8475,7 @@
          * UiModeManager.
          * @hide
          */
+        @Readable
         public static final String UI_NIGHT_MODE = "ui_night_mode";
 
         /**
@@ -8075,12 +8484,14 @@
          * UiModeManager.
          * @hide
          */
+        @Readable
         public static final String UI_NIGHT_MODE_OVERRIDE_ON = "ui_night_mode_override_on";
 
         /**
          * The last computed night mode bool the last time the phone was on
          * @hide
          */
+        @Readable
         public static final String UI_NIGHT_MODE_LAST_COMPUTED = "ui_night_mode_last_computed";
 
         /**
@@ -8089,12 +8500,14 @@
          * UiModeManager.
          * @hide
          */
+        @Readable
         public static final String UI_NIGHT_MODE_OVERRIDE_OFF = "ui_night_mode_override_off";
 
         /**
          * Whether screensavers are enabled.
          * @hide
          */
+        @Readable
         public static final String SCREENSAVER_ENABLED = "screensaver_enabled";
 
         /**
@@ -8104,6 +8517,7 @@
          * battery, or upon dock insertion (if SCREENSAVER_ACTIVATE_ON_DOCK is set to 1).
          * @hide
          */
+        @Readable
         public static final String SCREENSAVER_COMPONENTS = "screensaver_components";
 
         /**
@@ -8111,6 +8525,7 @@
          * when the device is inserted into a (desk) dock.
          * @hide
          */
+        @Readable
         public static final String SCREENSAVER_ACTIVATE_ON_DOCK = "screensaver_activate_on_dock";
 
         /**
@@ -8118,12 +8533,14 @@
          * when the screen times out when not on battery.
          * @hide
          */
+        @Readable
         public static final String SCREENSAVER_ACTIVATE_ON_SLEEP = "screensaver_activate_on_sleep";
 
         /**
          * If screensavers are enabled, the default screensaver component.
          * @hide
          */
+        @Readable
         public static final String SCREENSAVER_DEFAULT_COMPONENT = "screensaver_default_component";
 
         /**
@@ -8132,12 +8549,14 @@
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         @TestApi
+        @Readable
         public static final String NFC_PAYMENT_DEFAULT_COMPONENT = "nfc_payment_default_component";
 
         /**
          * Whether NFC payment is handled by the foreground application or a default.
          * @hide
          */
+        @Readable
         public static final String NFC_PAYMENT_FOREGROUND = "nfc_payment_foreground";
 
         /**
@@ -8145,6 +8564,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String SMS_DEFAULT_APPLICATION = "sms_default_application";
 
         /**
@@ -8152,6 +8572,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String DIALER_DEFAULT_APPLICATION = "dialer_default_application";
 
         /**
@@ -8159,6 +8580,7 @@
          * application
          * @hide
          */
+        @Readable
         public static final String CALL_SCREENING_DEFAULT_COMPONENT =
                 "call_screening_default_component";
 
@@ -8169,6 +8591,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String EMERGENCY_ASSISTANCE_APPLICATION = "emergency_assistance_application";
 
         /**
@@ -8177,6 +8600,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ASSIST_STRUCTURE_ENABLED = "assist_structure_enabled";
 
         /**
@@ -8185,6 +8609,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ASSIST_SCREENSHOT_ENABLED = "assist_screenshot_enabled";
 
         /**
@@ -8196,6 +8621,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ASSIST_DISCLOSURE_ENABLED = "assist_disclosure_enabled";
 
         /**
@@ -8207,7 +8633,7 @@
          *
          * @hide
          */
-
+        @Readable
         public static final String SHOW_ROTATION_SUGGESTIONS = "show_rotation_suggestions";
 
         /**
@@ -8234,6 +8660,7 @@
          * introduced to rotation suggestions.
          * @hide
          */
+        @Readable
         public static final String NUM_ROTATION_SUGGESTIONS_ACCEPTED =
                 "num_rotation_suggestions_accepted";
 
@@ -8246,6 +8673,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String ENABLED_NOTIFICATION_ASSISTANT =
                 "enabled_notification_assistant";
 
@@ -8259,6 +8687,7 @@
          */
         @Deprecated
         @UnsupportedAppUsage
+        @Readable
         public static final String ENABLED_NOTIFICATION_LISTENERS = "enabled_notification_listeners";
 
         /**
@@ -8270,6 +8699,7 @@
          */
         @Deprecated
         @TestApi
+        @Readable
         public static final String ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES =
                 "enabled_notification_policy_access_packages";
 
@@ -8283,6 +8713,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
         public static final String SYNC_PARENT_SOUNDS = "sync_parent_sounds";
 
@@ -8291,6 +8722,7 @@
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         @TestApi
+        @Readable
         public static final String IMMERSIVE_MODE_CONFIRMATIONS = "immersive_mode_confirmations";
 
         /**
@@ -8298,6 +8730,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String PRINT_SERVICE_SEARCH_URI = "print_service_search_uri";
 
         /**
@@ -8305,6 +8738,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String PAYMENT_SERVICE_SEARCH_URI = "payment_service_search_uri";
 
         /**
@@ -8312,6 +8746,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String AUTOFILL_SERVICE_SEARCH_URI = "autofill_service_search_uri";
 
         /**
@@ -8320,6 +8755,7 @@
          * <p>
          * Type : int (0 to show hints, 1 to skip showing hints)
          */
+        @Readable
         public static final String SKIP_FIRST_USE_HINTS = "skip_first_use_hints";
 
         /**
@@ -8327,6 +8763,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String UNSAFE_VOLUME_MUSIC_ACTIVE_MS = "unsafe_volume_music_active_ms";
 
         /**
@@ -8337,6 +8774,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String LOCK_SCREEN_SHOW_NOTIFICATIONS =
                 "lock_screen_show_notifications";
 
@@ -8347,6 +8785,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS =
                 "lock_screen_show_silent_notifications";
 
@@ -8357,6 +8796,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SHOW_NOTIFICATION_SNOOZE = "show_notification_snooze";
 
         /**
@@ -8365,6 +8805,7 @@
          * {@link android.net.Uri#encode(String)} and separated by ':'.
          * @hide
          */
+        @Readable
         public static final String TV_INPUT_HIDDEN_INPUTS = "tv_input_hidden_inputs";
 
         /**
@@ -8373,6 +8814,7 @@
          * and separated by ','. Each pair is separated by ':'.
          * @hide
          */
+        @Readable
         public static final String TV_INPUT_CUSTOM_LABELS = "tv_input_custom_labels";
 
         /**
@@ -8390,6 +8832,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String TV_APP_USES_NON_SYSTEM_INPUTS = "tv_app_uses_non_system_inputs";
 
         /**
@@ -8399,6 +8842,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String USB_AUDIO_AUTOMATIC_ROUTING_DISABLED =
                 "usb_audio_automatic_routing_disabled";
 
@@ -8414,6 +8858,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SLEEP_TIMEOUT = "sleep_timeout";
 
         /**
@@ -8428,12 +8873,14 @@
          *
          * @hide
          */
+        @Readable
         public static final String ATTENTIVE_TIMEOUT = "attentive_timeout";
 
         /**
          * Controls whether double tap to wake is enabled.
          * @hide
          */
+        @Readable
         public static final String DOUBLE_TAP_TO_WAKE = "double_tap_to_wake";
 
         /**
@@ -8447,6 +8894,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String ASSISTANT = "assistant";
 
         /**
@@ -8454,6 +8902,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAMERA_GESTURE_DISABLED = "camera_gesture_disabled";
 
         /**
@@ -8461,6 +8910,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String EMERGENCY_GESTURE_ENABLED = "emergency_gesture_enabled";
 
         /**
@@ -8468,6 +8918,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String EMERGENCY_GESTURE_SOUND_ENABLED =
                 "emergency_gesture_sound_enabled";
 
@@ -8477,6 +8928,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED =
                 "camera_double_tap_power_gesture_disabled";
 
@@ -8486,6 +8938,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED =
                 "camera_double_twist_to_flip_enabled";
 
@@ -8495,6 +8948,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAMERA_LIFT_TRIGGER_ENABLED = "camera_lift_trigger_enabled";
 
         /**
@@ -8510,6 +8964,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String FLASHLIGHT_AVAILABLE = "flashlight_available";
 
         /**
@@ -8517,18 +8972,21 @@
          *
          * @hide
          */
+        @Readable
         public static final String FLASHLIGHT_ENABLED = "flashlight_enabled";
 
         /**
          * Whether or not face unlock is allowed on Keyguard.
          * @hide
          */
+        @Readable
         public static final String FACE_UNLOCK_KEYGUARD_ENABLED = "face_unlock_keyguard_enabled";
 
         /**
          * Whether or not face unlock dismisses the keyguard.
          * @hide
          */
+        @Readable
         public static final String FACE_UNLOCK_DISMISSES_KEYGUARD =
                 "face_unlock_dismisses_keyguard";
 
@@ -8536,6 +8994,7 @@
          * Whether or not media is shown automatically when bypassing as a heads up.
          * @hide
          */
+        @Readable
         public static final String SHOW_MEDIA_WHEN_BYPASSING =
                 "show_media_when_bypassing";
 
@@ -8544,6 +9003,7 @@
          * truth is obtained through the HAL.
          * @hide
          */
+        @Readable
         public static final String FACE_UNLOCK_ATTENTION_REQUIRED =
                 "face_unlock_attention_required";
 
@@ -8552,6 +9012,7 @@
          * cached value, the source of truth is obtained through the HAL.
          * @hide
          */
+        @Readable
         public static final String FACE_UNLOCK_DIVERSITY_REQUIRED =
                 "face_unlock_diversity_required";
 
@@ -8560,6 +9021,7 @@
          * Whether or not face unlock is allowed for apps (through BiometricPrompt).
          * @hide
          */
+        @Readable
         public static final String FACE_UNLOCK_APP_ENABLED = "face_unlock_app_enabled";
 
         /**
@@ -8569,6 +9031,7 @@
          * setConfirmationRequired API.
          * @hide
          */
+        @Readable
         public static final String FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION =
                 "face_unlock_always_require_confirmation";
 
@@ -8583,12 +9046,14 @@
          *
          * @hide
          */
+        @Readable
         public static final String FACE_UNLOCK_RE_ENROLL = "face_unlock_re_enroll";
 
         /**
          * Whether or not debugging is enabled.
          * @hide
          */
+        @Readable
         public static final String BIOMETRIC_DEBUG_ENABLED =
                 "biometric_debug_enabled";
 
@@ -8597,6 +9062,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ASSIST_GESTURE_ENABLED = "assist_gesture_enabled";
 
         /**
@@ -8604,6 +9070,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ASSIST_GESTURE_SENSITIVITY = "assist_gesture_sensitivity";
 
         /**
@@ -8611,6 +9078,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ASSIST_GESTURE_SILENCE_ALERTS_ENABLED =
                 "assist_gesture_silence_alerts_enabled";
 
@@ -8619,6 +9087,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ASSIST_GESTURE_WAKE_ENABLED =
                 "assist_gesture_wake_enabled";
 
@@ -8630,36 +9099,42 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String ASSIST_GESTURE_SETUP_COMPLETE = "assist_gesture_setup_complete";
 
         /**
          * Control whether Trust Agents are in active unlock or extend unlock mode.
          * @hide
          */
+        @Readable
         public static final String TRUST_AGENTS_EXTEND_UNLOCK = "trust_agents_extend_unlock";
 
         /**
          * Control whether the screen locks when trust is lost.
          * @hide
          */
+        @Readable
         public static final String LOCK_SCREEN_WHEN_TRUST_LOST = "lock_screen_when_trust_lost";
 
         /**
          * Control whether Night display is currently activated.
          * @hide
          */
+        @Readable
         public static final String NIGHT_DISPLAY_ACTIVATED = "night_display_activated";
 
         /**
          * Control whether Night display will automatically activate/deactivate.
          * @hide
          */
+        @Readable
         public static final String NIGHT_DISPLAY_AUTO_MODE = "night_display_auto_mode";
 
         /**
          * Control the color temperature of Night Display, represented in Kelvin.
          * @hide
          */
+        @Readable
         public static final String NIGHT_DISPLAY_COLOR_TEMPERATURE =
                 "night_display_color_temperature";
 
@@ -8668,6 +9143,7 @@
          * Represented as milliseconds from midnight (e.g. 79200000 == 10pm).
          * @hide
          */
+        @Readable
         public static final String NIGHT_DISPLAY_CUSTOM_START_TIME =
                 "night_display_custom_start_time";
 
@@ -8676,6 +9152,7 @@
          * Represented as milliseconds from midnight (e.g. 21600000 == 6am).
          * @hide
          */
+        @Readable
         public static final String NIGHT_DISPLAY_CUSTOM_END_TIME = "night_display_custom_end_time";
 
         /**
@@ -8684,6 +9161,7 @@
          * legacy cases, this is represented by the time in milliseconds (since epoch).
          * @hide
          */
+        @Readable
         public static final String NIGHT_DISPLAY_LAST_ACTIVATED_TIME =
                 "night_display_last_activated_time";
 
@@ -8691,6 +9169,7 @@
          * Control whether display white balance is currently enabled.
          * @hide
          */
+        @Readable
         public static final String DISPLAY_WHITE_BALANCE_ENABLED = "display_white_balance_enabled";
 
         /**
@@ -8701,6 +9180,7 @@
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         @TestApi
+        @Readable
         public static final String ENABLED_VR_LISTENERS = "enabled_vr_listeners";
 
         /**
@@ -8710,6 +9190,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String VR_DISPLAY_MODE = "vr_display_mode";
 
         /**
@@ -8743,6 +9224,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CARRIER_APPS_HANDLED = "carrier_apps_handled";
 
         /**
@@ -8750,6 +9232,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String MANAGED_PROFILE_CONTACT_REMOTE_SEARCH =
                 "managed_profile_contact_remote_search";
 
@@ -8758,6 +9241,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CROSS_PROFILE_CALENDAR_ENABLED =
                 "cross_profile_calendar_enabled";
 
@@ -8766,6 +9250,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String AUTOMATIC_STORAGE_MANAGER_ENABLED =
                 "automatic_storage_manager_enabled";
 
@@ -8774,6 +9259,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN =
                 "automatic_storage_manager_days_to_retain";
 
@@ -8789,6 +9275,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String AUTOMATIC_STORAGE_MANAGER_BYTES_CLEARED =
                 "automatic_storage_manager_bytes_cleared";
 
@@ -8797,6 +9284,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String AUTOMATIC_STORAGE_MANAGER_LAST_RUN =
                 "automatic_storage_manager_last_run";
         /**
@@ -8806,6 +9294,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String AUTOMATIC_STORAGE_MANAGER_TURNED_OFF_BY_POLICY =
                 "automatic_storage_manager_turned_off_by_policy";
 
@@ -8813,6 +9302,7 @@
          * Whether SystemUI navigation keys is enabled.
          * @hide
          */
+        @Readable
         public static final String SYSTEM_NAVIGATION_KEYS_ENABLED =
                 "system_navigation_keys_enabled";
 
@@ -8821,6 +9311,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String QS_TILES = "sysui_qs_tiles";
 
         /**
@@ -8831,6 +9322,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CONTROLS_ENABLED = "controls_enabled";
 
         /**
@@ -8840,6 +9332,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String POWER_MENU_LOCKED_SHOW_CONTENT =
                 "power_menu_locked_show_content";
 
@@ -8849,18 +9342,21 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String INSTANT_APPS_ENABLED = "instant_apps_enabled";
 
         /**
          * Has this pairable device been paired or upgraded from a previously paired system.
          * @hide
          */
+        @Readable
         public static final String DEVICE_PAIRED = "device_paired";
 
         /**
          * Specifies additional package name for broadcasting the CMAS messages.
          * @hide
          */
+        @Readable
         public static final String CMAS_ADDITIONAL_BROADCAST_PKG = "cmas_additional_broadcast_pkg";
 
         /**
@@ -8870,6 +9366,7 @@
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         @TestApi
+        @Readable
         public static final String NOTIFICATION_BADGING = "notification_badging";
 
         /**
@@ -8879,6 +9376,7 @@
          * The value 1 - enable, 0 - disable
          * @hide
          */
+        @Readable
         public static final String NOTIFICATION_HISTORY_ENABLED = "notification_history_enabled";
 
         /**
@@ -8887,6 +9385,7 @@
          * The value 1 - enable, 0 - disable
          * @hide
          */
+        @Readable
         public static final String BUBBLE_IMPORTANT_CONVERSATIONS
                 = "bubble_important_conversations";
 
@@ -8896,18 +9395,21 @@
          *
          * @hide
          */
+        @Readable
         public static final String NOTIFICATION_DISMISS_RTL = "notification_dismiss_rtl";
 
         /**
          * Comma separated list of QS tiles that have been auto-added already.
          * @hide
          */
+        @Readable
         public static final String QS_AUTO_ADDED_TILES = "qs_auto_tiles";
 
         /**
          * Whether the Lockdown button should be shown in the power menu.
          * @hide
          */
+        @Readable
         public static final String LOCKDOWN_IN_POWER_MENU = "lockdown_in_power_menu";
 
         /**
@@ -8935,6 +9437,7 @@
          * Type: string
          * @hide
          */
+        @Readable
         public static final String BACKUP_MANAGER_CONSTANTS = "backup_manager_constants";
 
 
@@ -8952,6 +9455,7 @@
          * Type: string
          * @hide
          */
+        @Readable
         public static final String BACKUP_LOCAL_TRANSPORT_PARAMETERS =
                 "backup_local_transport_parameters";
 
@@ -8960,6 +9464,7 @@
          * the user is driving.
          * @hide
          */
+        @Readable
         public static final String BLUETOOTH_ON_WHILE_DRIVING = "bluetooth_on_while_driving";
 
         /**
@@ -8969,6 +9474,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String VOLUME_HUSH_GESTURE = "volume_hush_gesture";
 
         /** @hide */
@@ -8985,6 +9491,7 @@
          * The number of times (integer) the user has manually enabled battery saver.
          * @hide
          */
+        @Readable
         public static final String LOW_POWER_MANUAL_ACTIVATION_COUNT =
                 "low_power_manual_activation_count";
 
@@ -8994,6 +9501,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String LOW_POWER_WARNING_ACKNOWLEDGED =
                 "low_power_warning_acknowledged";
 
@@ -9002,6 +9510,7 @@
          * suppressed.
          * @hide
          */
+        @Readable
         public static final String SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION =
                 "suppress_auto_battery_saver_suggestion";
 
@@ -9010,6 +9519,7 @@
          * Type: string
          * @hide
          */
+        @Readable
         public static final String PACKAGES_TO_CLEAR_DATA_BEFORE_FULL_RESTORE =
                 "packages_to_clear_data_before_full_restore";
 
@@ -9018,6 +9528,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String LOCATION_ACCESS_CHECK_INTERVAL_MILLIS =
                 "location_access_check_interval_millis";
 
@@ -9026,6 +9537,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String LOCATION_ACCESS_CHECK_DELAY_MILLIS =
                 "location_access_check_delay_millis";
 
@@ -9035,6 +9547,7 @@
          */
         @SystemApi
         @Deprecated
+        @Readable
         public static final String LOCATION_PERMISSIONS_UPGRADE_TO_Q_MODE =
                 "location_permissions_upgrade_to_q_mode";
 
@@ -9043,6 +9556,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String AUTO_REVOKE_DISABLED = "auto_revoke_disabled";
 
         /**
@@ -9053,6 +9567,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String THEME_CUSTOMIZATION_OVERLAY_PACKAGES =
                 "theme_customization_overlay_packages";
 
@@ -9063,6 +9578,7 @@
          *  2 = fully gestural
          * @hide
          */
+        @Readable
         public static final String NAVIGATION_MODE =
                 "navigation_mode";
 
@@ -9070,6 +9586,7 @@
          * Scale factor for the back gesture inset size on the left side of the screen.
          * @hide
          */
+        @Readable
         public static final String BACK_GESTURE_INSET_SCALE_LEFT =
                 "back_gesture_inset_scale_left";
 
@@ -9077,6 +9594,7 @@
          * Scale factor for the back gesture inset size on the right side of the screen.
          * @hide
          */
+        @Readable
         public static final String BACK_GESTURE_INSET_SCALE_RIGHT =
                 "back_gesture_inset_scale_right";
 
@@ -9086,30 +9604,35 @@
          * No VALIDATOR as this setting will not be backed up.
          * @hide
          */
+        @Readable
         public static final String NEARBY_SHARING_COMPONENT = "nearby_sharing_component";
 
         /**
          * Controls whether aware is enabled.
          * @hide
          */
+        @Readable
         public static final String AWARE_ENABLED = "aware_enabled";
 
         /**
          * Controls whether aware_lock is enabled.
          * @hide
          */
+        @Readable
         public static final String AWARE_LOCK_ENABLED = "aware_lock_enabled";
 
         /**
          * Controls whether tap gesture is enabled.
          * @hide
          */
+        @Readable
         public static final String TAP_GESTURE = "tap_gesture";
 
         /**
          * Controls whether the people strip is enabled.
          * @hide
          */
+        @Readable
         public static final String PEOPLE_STRIP = "people_strip";
 
         /**
@@ -9119,6 +9642,7 @@
          * @see Settings.Global#SHOW_MEDIA_ON_QUICK_SETTINGS
          * @hide
          */
+        @Readable
         public static final String MEDIA_CONTROLS_RESUME = "qs_media_resumption";
 
         /**
@@ -9127,6 +9651,7 @@
          * @see Settings.Secure#MEDIA_CONTROLS_RESUME
          * @hide
          */
+        @Readable
         public static final String MEDIA_CONTROLS_RESUME_BLOCKED = "qs_media_resumption_blocked";
 
         /**
@@ -9138,6 +9663,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String ACCESSIBILITY_MAGNIFICATION_MODE =
                 "accessibility_magnification_mode";
 
@@ -9173,6 +9699,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String ACCESSIBILITY_MAGNIFICATION_CAPABILITY =
                 "accessibility_magnification_capability";
 
@@ -9182,6 +9709,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_SHOW_WINDOW_MAGNIFICATION_PROMPT =
                 "accessibility_show_window_magnification_prompt";
 
@@ -9198,6 +9726,7 @@
          * @see #ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_BUTTON_MODE =
                 "accessibility_button_mode";
 
@@ -9226,6 +9755,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_FLOATING_MENU_SIZE =
                 "accessibility_floating_menu_size";
 
@@ -9238,6 +9768,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_FLOATING_MENU_ICON_TYPE =
                 "accessibility_floating_menu_icon_type";
 
@@ -9246,6 +9777,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_FLOATING_MENU_FADE_ENABLED =
                 "accessibility_floating_menu_fade_enabled";
 
@@ -9255,6 +9787,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ACCESSIBILITY_FLOATING_MENU_OPACITY =
                 "accessibility_floating_menu_opacity";
 
@@ -9263,6 +9796,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ADAPTIVE_CONNECTIVITY_ENABLED = "adaptive_connectivity_enabled";
 
         /**
@@ -9274,6 +9808,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String[] LEGACY_RESTORE_SETTINGS = {
                 ENABLED_NOTIFICATION_LISTENERS,
                 ENABLED_NOTIFICATION_ASSISTANT,
@@ -9285,6 +9820,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ASSIST_HANDLES_LEARNING_TIME_ELAPSED_MILLIS =
                 "reminder_exp_learning_time_elapsed";
 
@@ -9293,6 +9829,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ASSIST_HANDLES_LEARNING_EVENT_COUNT =
                 "reminder_exp_learning_event_count";
 
@@ -9406,6 +9943,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String NOTIFICATION_BUBBLES = "notification_bubbles";
 
         /**
@@ -9414,6 +9952,7 @@
          * Type: int
          * @hide
          */
+        @Readable
         public static final String ADD_USERS_WHEN_LOCKED = "add_users_when_locked";
 
         /**
@@ -9421,6 +9960,7 @@
          * <p>1 = apply ramping ringer
          * <p>0 = do not apply ramping ringer
          */
+        @Readable
         public static final String APPLY_RAMPING_RINGER = "apply_ramping_ringer";
 
         /**
@@ -9432,12 +9972,14 @@
          * No longer used. Should be removed once all dependencies have been updated.
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED =
                 "enable_accessibility_global_gesture_enabled";
 
         /**
          * Whether Airplane Mode is on.
          */
+        @Readable
         public static final String AIRPLANE_MODE_ON = "airplane_mode_on";
 
         /**
@@ -9445,30 +9987,36 @@
          * {@hide}
          */
         @SystemApi
+        @Readable
         public static final String THEATER_MODE_ON = "theater_mode_on";
 
         /**
          * Constant for use in AIRPLANE_MODE_RADIOS to specify Bluetooth radio.
          */
+        @Readable
         public static final String RADIO_BLUETOOTH = "bluetooth";
 
         /**
          * Constant for use in AIRPLANE_MODE_RADIOS to specify Wi-Fi radio.
          */
+        @Readable
         public static final String RADIO_WIFI = "wifi";
 
         /**
          * {@hide}
          */
+        @Readable
         public static final String RADIO_WIMAX = "wimax";
         /**
          * Constant for use in AIRPLANE_MODE_RADIOS to specify Cellular radio.
          */
+        @Readable
         public static final String RADIO_CELL = "cell";
 
         /**
          * Constant for use in AIRPLANE_MODE_RADIOS to specify NFC radio.
          */
+        @Readable
         public static final String RADIO_NFC = "nfc";
 
         /**
@@ -9476,6 +10024,7 @@
          * is on. This overrides WIFI_ON and BLUETOOTH_ON, if Wi-Fi and bluetooth are
          * included in the comma separated list.
          */
+        @Readable
         public static final String AIRPLANE_MODE_RADIOS = "airplane_mode_radios";
 
         /**
@@ -9487,6 +10036,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String AIRPLANE_MODE_TOGGLEABLE_RADIOS = "airplane_mode_toggleable_radios";
 
         /**
@@ -9494,6 +10044,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BLUETOOTH_CLASS_OF_DEVICE = "bluetooth_class_of_device";
 
         /**
@@ -9501,6 +10052,7 @@
          * See {@link android.bluetooth.BluetoothProfile}.
          * {@hide}
          */
+        @Readable
         public static final String BLUETOOTH_DISABLED_PROFILES = "bluetooth_disabled_profiles";
 
         /**
@@ -9513,6 +10065,7 @@
          *   "00:11:22,0;01:02:03:04,2"
          * @hide
          */
+        @Readable
        public static final String BLUETOOTH_INTEROPERABILITY_LIST = "bluetooth_interoperability_list";
 
         /**
@@ -9525,6 +10078,7 @@
          * @deprecated This is no longer used or set by the platform.
          */
         @Deprecated
+        @Readable
         public static final String WIFI_SLEEP_POLICY = "wifi_sleep_policy";
 
         /**
@@ -9556,60 +10110,70 @@
          * Value to specify if the user prefers the date, time and time zone
          * to be automatically fetched from the network (NITZ). 1=yes, 0=no
          */
+        @Readable
         public static final String AUTO_TIME = "auto_time";
 
         /**
          * Value to specify if the user prefers the time zone
          * to be automatically fetched from the network (NITZ). 1=yes, 0=no
          */
+        @Readable
         public static final String AUTO_TIME_ZONE = "auto_time_zone";
 
         /**
          * URI for the car dock "in" event sound.
          * @hide
          */
+        @Readable
         public static final String CAR_DOCK_SOUND = "car_dock_sound";
 
         /**
          * URI for the car dock "out" event sound.
          * @hide
          */
+        @Readable
         public static final String CAR_UNDOCK_SOUND = "car_undock_sound";
 
         /**
          * URI for the desk dock "in" event sound.
          * @hide
          */
+        @Readable
         public static final String DESK_DOCK_SOUND = "desk_dock_sound";
 
         /**
          * URI for the desk dock "out" event sound.
          * @hide
          */
+        @Readable
         public static final String DESK_UNDOCK_SOUND = "desk_undock_sound";
 
         /**
          * Whether to play a sound for dock events.
          * @hide
          */
+        @Readable
         public static final String DOCK_SOUNDS_ENABLED = "dock_sounds_enabled";
 
         /**
          * Whether to play a sound for dock events, only when an accessibility service is on.
          * @hide
          */
+        @Readable
         public static final String DOCK_SOUNDS_ENABLED_WHEN_ACCESSIBILITY = "dock_sounds_enabled_when_accessbility";
 
         /**
          * URI for the "device locked" (keyguard shown) sound.
          * @hide
          */
+        @Readable
         public static final String LOCK_SOUND = "lock_sound";
 
         /**
          * URI for the "device unlocked" sound.
          * @hide
          */
+        @Readable
         public static final String UNLOCK_SOUND = "unlock_sound";
 
         /**
@@ -9617,24 +10181,28 @@
          * state without unlocking.
          * @hide
          */
+        @Readable
         public static final String TRUSTED_SOUND = "trusted_sound";
 
         /**
          * URI for the low battery sound file.
          * @hide
          */
+        @Readable
         public static final String LOW_BATTERY_SOUND = "low_battery_sound";
 
         /**
          * Whether to play a sound for low-battery alerts.
          * @hide
          */
+        @Readable
         public static final String POWER_SOUNDS_ENABLED = "power_sounds_enabled";
 
         /**
          * URI for the "wireless charging started" sound.
          * @hide
          */
+        @Readable
         public static final String WIRELESS_CHARGING_STARTED_SOUND =
                 "wireless_charging_started_sound";
 
@@ -9642,6 +10210,7 @@
          * URI for "wired charging started" sound.
          * @hide
          */
+        @Readable
         public static final String CHARGING_STARTED_SOUND = "charging_started_sound";
 
         /**
@@ -9671,6 +10240,7 @@
          * </ul>
          * These values can be OR-ed together.
          */
+        @Readable
         public static final String STAY_ON_WHILE_PLUGGED_IN = "stay_on_while_plugged_in";
 
         /**
@@ -9678,6 +10248,7 @@
          * in the power menu.
          * @hide
          */
+        @Readable
         public static final String BUGREPORT_IN_POWER_MENU = "bugreport_in_power_menu";
 
         /**
@@ -9686,6 +10257,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CUSTOM_BUGREPORT_HANDLER_APP = "custom_bugreport_handler_app";
 
         /**
@@ -9694,29 +10266,34 @@
          *
          * @hide
          */
+        @Readable
         public static final String CUSTOM_BUGREPORT_HANDLER_USER = "custom_bugreport_handler_user";
 
         /**
          * Whether ADB over USB is enabled.
          */
+        @Readable
         public static final String ADB_ENABLED = "adb_enabled";
 
         /**
          * Whether ADB over Wifi is enabled.
          * @hide
          */
+        @Readable
         public static final String ADB_WIFI_ENABLED = "adb_wifi_enabled";
 
         /**
          * Whether Views are allowed to save their attribute data.
          * @hide
          */
+        @Readable
         public static final String DEBUG_VIEW_ATTRIBUTES = "debug_view_attributes";
 
         /**
          * Which application package is allowed to save View attribute data.
          * @hide
          */
+        @Readable
         public static final String DEBUG_VIEW_ATTRIBUTES_APPLICATION_PACKAGE =
                 "debug_view_attributes_application_package";
 
@@ -9724,12 +10301,14 @@
          * Whether assisted GPS should be enabled or not.
          * @hide
          */
+        @Readable
         public static final String ASSISTED_GPS_ENABLED = "assisted_gps_enabled";
 
         /**
          * Whether bluetooth is enabled/disabled
          * 0=disabled. 1=enabled.
          */
+        @Readable
         public static final String BLUETOOTH_ON = "bluetooth_on";
 
         /**
@@ -9738,6 +10317,7 @@
          *                            1 = CDMA Cell Broadcast SMS enabled
          * @hide
          */
+        @Readable
         public static final String CDMA_CELL_BROADCAST_SMS =
                 "cdma_cell_broadcast_sms";
 
@@ -9747,6 +10327,7 @@
          *                       2 = Roaming on any networks
          * @hide
          */
+        @Readable
         public static final String CDMA_ROAMING_MODE = "roaming_settings";
 
         /**
@@ -9754,6 +10335,7 @@
          *                                1 = NV
          * @hide
          */
+        @Readable
         public static final String CDMA_SUBSCRIPTION_MODE = "subscription_mode";
 
         /**
@@ -9763,44 +10345,49 @@
          *
          * @hide
          */
+        @Readable
         public static final String DEFAULT_RESTRICT_BACKGROUND_DATA =
                 "default_restrict_background_data";
 
         /** Inactivity timeout to track mobile data activity.
-        *
-        * If set to a positive integer, it indicates the inactivity timeout value in seconds to
-        * infer the data activity of mobile network. After a period of no activity on mobile
-        * networks with length specified by the timeout, an {@code ACTION_DATA_ACTIVITY_CHANGE}
-        * intent is fired to indicate a transition of network status from "active" to "idle". Any
-        * subsequent activity on mobile networks triggers the firing of {@code
-        * ACTION_DATA_ACTIVITY_CHANGE} intent indicating transition from "idle" to "active".
-        *
-        * Network activity refers to transmitting or receiving data on the network interfaces.
-        *
-        * Tracking is disabled if set to zero or negative value.
-        *
-        * @hide
-        */
-       public static final String DATA_ACTIVITY_TIMEOUT_MOBILE = "data_activity_timeout_mobile";
+         *
+         * If set to a positive integer, it indicates the inactivity timeout value in seconds to
+         * infer the data activity of mobile network. After a period of no activity on mobile
+         * networks with length specified by the timeout, an {@code ACTION_DATA_ACTIVITY_CHANGE}
+         * intent is fired to indicate a transition of network status from "active" to "idle". Any
+         * subsequent activity on mobile networks triggers the firing of {@code
+         * ACTION_DATA_ACTIVITY_CHANGE} intent indicating transition from "idle" to "active".
+         *
+         * Network activity refers to transmitting or receiving data on the network interfaces.
+         *
+         * Tracking is disabled if set to zero or negative value.
+         *
+         * @hide
+         */
+        @Readable
+        public static final String DATA_ACTIVITY_TIMEOUT_MOBILE = "data_activity_timeout_mobile";
 
-       /** Timeout to tracking Wifi data activity. Same as {@code DATA_ACTIVITY_TIMEOUT_MOBILE}
-        * but for Wifi network.
-        * @hide
-        */
-       public static final String DATA_ACTIVITY_TIMEOUT_WIFI = "data_activity_timeout_wifi";
+        /** Timeout to tracking Wifi data activity. Same as {@code DATA_ACTIVITY_TIMEOUT_MOBILE}
+         * but for Wifi network.
+         * @hide
+         */
+        @Readable
+        public static final String DATA_ACTIVITY_TIMEOUT_WIFI = "data_activity_timeout_wifi";
 
-       /**
-        * Whether or not data roaming is enabled. (0 = false, 1 = true)
-        */
-       public static final String DATA_ROAMING = "data_roaming";
+        /**
+         * Whether or not data roaming is enabled. (0 = false, 1 = true)
+         */
+        @Readable
+        public static final String DATA_ROAMING = "data_roaming";
 
-       /**
-        * The value passed to a Mobile DataConnection via bringUp which defines the
-        * number of retries to preform when setting up the initial connection. The default
-        * value defined in DataConnectionTrackerBase#DEFAULT_MDC_INITIAL_RETRY is currently 1.
-        * @hide
-        */
-       public static final String MDC_INITIAL_MAX_RETRY = "mdc_initial_max_retry";
+        /**
+         * The value passed to a Mobile DataConnection via bringUp which defines the
+         * number of retries to perform when setting up the initial connection. The default
+         * value defined in DataConnectionTrackerBase#DEFAULT_MDC_INITIAL_RETRY is currently 1.
+         * @hide
+         */
+        @Readable
+        public static final String MDC_INITIAL_MAX_RETRY = "mdc_initial_max_retry";
 
         /**
          * Whether any package can be on external storage. When this is true, any
@@ -9808,6 +10395,7 @@
          * or moving onto external storage. (0 = false, 1 = true)
          * @hide
          */
+        @Readable
         public static final String FORCE_ALLOW_ON_EXTERNAL = "force_allow_on_external";
 
         /**
@@ -9822,6 +10410,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String DEFAULT_SM_DP_PLUS = "default_sm_dp_plus";
 
         /**
@@ -9833,6 +10422,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String EUICC_PROVISIONED = "euicc_provisioned";
 
         /**
@@ -9848,6 +10438,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String EUICC_SUPPORTED_COUNTRIES = "euicc_supported_countries";
 
         /**
@@ -9863,6 +10454,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String EUICC_UNSUPPORTED_COUNTRIES = "euicc_unsupported_countries";
 
         /**
@@ -9871,6 +10463,7 @@
          * (0 = false, 1 = true)
          * @hide
          */
+        @Readable
         public static final String DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES
                 = "force_resizable_activities";
 
@@ -9878,6 +10471,7 @@
          * Whether to enable experimental freeform support for windows.
          * @hide
          */
+        @Readable
         public static final String DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT
                 = "enable_freeform_support";
 
@@ -9885,6 +10479,7 @@
          * Whether to enable experimental desktop mode on secondary displays.
          * @hide
          */
+        @Readable
         public static final String DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS =
                 "force_desktop_mode_on_external_displays";
 
@@ -9896,6 +10491,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String DEVELOPMENT_ENABLE_SIZECOMPAT_FREEFORM =
                 "enable_sizecompat_freeform";
 
@@ -9906,6 +10502,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         @SuppressLint("NoSettingsProvider")
         public static final String DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW =
                 "enable_non_resizable_multi_window";
@@ -9917,6 +10514,7 @@
          * (0 = false, 1 = true)
          * @hide
          */
+        @Readable
         public static final String DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR =
                 "render_shadows_in_compositor";
 
@@ -9925,6 +10523,7 @@
          * (0 = false, 1 = true)
          * @hide
          */
+        @Readable
         public static final String DEVELOPMENT_USE_BLAST_ADAPTER_VR =
                 "use_blast_adapter_vr";
 
@@ -9933,6 +10532,7 @@
          * (0 = false, 1 = true)
          * @hide
          */
+        @Readable
         public static final String DEVELOPMENT_USE_BLAST_ADAPTER_SV =
                 "use_blast_adapter_sv";
 
@@ -9942,21 +10542,24 @@
          *
          * @hide
          */
+        @Readable
         public static final String DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH =
                 "wm_display_settings_path";
 
-       /**
+        /**
         * Whether user has enabled development settings.
         */
-       public static final String DEVELOPMENT_SETTINGS_ENABLED = "development_settings_enabled";
+        @Readable
+        public static final String DEVELOPMENT_SETTINGS_ENABLED = "development_settings_enabled";
 
-       /**
+        /**
         * Whether the device has been provisioned (0 = false, 1 = true).
         * <p>On a multiuser device with a separate system user, the screen may be locked
         * as soon as this is set to true and further activities cannot be launched on the
         * system user unless they are marked to show over keyguard.
         */
-       public static final String DEVICE_PROVISIONED = "device_provisioned";
+        @Readable
+        public static final String DEVICE_PROVISIONED = "device_provisioned";
 
         /**
          * Indicates whether mobile data should be allowed while the device is being provisioned.
@@ -9969,52 +10572,58 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String DEVICE_PROVISIONING_MOBILE_DATA_ENABLED =
                 "device_provisioning_mobile_data";
 
-       /**
+        /**
         * The saved value for WindowManagerService.setForcedDisplaySize().
         * Two integers separated by a comma.  If unset, then use the real display size.
         * @hide
         */
-       public static final String DISPLAY_SIZE_FORCED = "display_size_forced";
+        @Readable
+        public static final String DISPLAY_SIZE_FORCED = "display_size_forced";
 
-       /**
+        /**
         * The saved value for WindowManagerService.setForcedDisplayScalingMode().
         * 0 or unset if scaling is automatic, 1 if scaling is disabled.
         * @hide
         */
-       public static final String DISPLAY_SCALING_FORCE = "display_scaling_force";
+        @Readable
+        public static final String DISPLAY_SCALING_FORCE = "display_scaling_force";
 
-       /**
+        /**
         * The maximum size, in bytes, of a download that the download manager will transfer over
         * a non-wifi connection.
         * @hide
         */
-       public static final String DOWNLOAD_MAX_BYTES_OVER_MOBILE =
+        @Readable
+        public static final String DOWNLOAD_MAX_BYTES_OVER_MOBILE =
                "download_manager_max_bytes_over_mobile";
 
-       /**
+        /**
         * The recommended maximum size, in bytes, of a download that the download manager should
         * transfer over a non-wifi connection. Over this size, the use will be warned, but will
         * have the option to start the download over the mobile connection anyway.
         * @hide
         */
-       public static final String DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE =
+        @Readable
+        public static final String DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE =
                "download_manager_recommended_max_bytes_over_mobile";
 
-       /**
+        /**
         * @deprecated Use {@link android.provider.Settings.Secure#INSTALL_NON_MARKET_APPS} instead
         */
-       @Deprecated
-       public static final String INSTALL_NON_MARKET_APPS = Secure.INSTALL_NON_MARKET_APPS;
+        @Deprecated
+        public static final String INSTALL_NON_MARKET_APPS = Secure.INSTALL_NON_MARKET_APPS;
 
-       /**
+        /**
         * Whether HDMI control shall be enabled. If disabled, no CEC/MHL command will be
         * sent or processed. (0 = false, 1 = true)
         * @hide
         */
-       public static final String HDMI_CONTROL_ENABLED = "hdmi_control_enabled";
+        @Readable
+        public static final String HDMI_CONTROL_ENABLED = "hdmi_control_enabled";
 
         /**
          * Controls whether volume control commands via HDMI CEC are enabled. (0 = false, 1 =
@@ -10050,16 +10659,18 @@
          * @hide
          * @see android.hardware.hdmi.HdmiControlManager#setHdmiCecVolumeControlEnabled(boolean)
          */
+        @Readable
         public static final String HDMI_CONTROL_VOLUME_CONTROL_ENABLED =
                 "hdmi_control_volume_control_enabled";
 
-       /**
+        /**
         * Whether HDMI System Audio Control feature is enabled. If enabled, TV will try to turn on
         * system audio mode if there's a connected CEC-enabled AV Receiver. Then audio stream will
         * be played on AVR instead of TV spaeker. If disabled, the system audio mode will never be
         * activated.
         * @hide
         */
+        @Readable
         public static final String HDMI_SYSTEM_AUDIO_CONTROL_ENABLED =
                 "hdmi_system_audio_control_enabled";
 
@@ -10069,6 +10680,7 @@
          * disabled, you can only switch the input via controls on this device.
          * @hide
          */
+        @Readable
         public static final String HDMI_CEC_SWITCH_ENABLED =
                 "hdmi_cec_switch_enabled";
 
@@ -10076,6 +10688,7 @@
          * HDMI CEC version to use. Defaults to v1.4b.
          * @hide
          */
+        @Readable
         public static final String HDMI_CEC_VERSION =
                 "hdmi_cec_version";
 
@@ -10085,6 +10698,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String HDMI_CONTROL_AUTO_WAKEUP_ENABLED =
                 "hdmi_control_auto_wakeup_enabled";
 
@@ -10094,6 +10708,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED =
                 "hdmi_control_auto_device_off_enabled";
 
@@ -10115,6 +10730,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String HDMI_CONTROL_SEND_STANDBY_ON_SLEEP =
                 "hdmi_control_send_standby_on_sleep";
 
@@ -10122,6 +10738,7 @@
          * Whether or not media is shown automatically when bypassing as a heads up.
          * @hide
          */
+        @Readable
         public static final String SHOW_MEDIA_ON_QUICK_SETTINGS =
                 "qs_media_player";
 
@@ -10131,6 +10748,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS =
                 "location_background_throttle_interval_ms";
 
@@ -10139,6 +10757,7 @@
          * to request.
          * @hide
          */
+        @Readable
         public static final String LOCATION_BACKGROUND_THROTTLE_PROXIMITY_ALERT_INTERVAL_MS =
                 "location_background_throttle_proximity_alert_interval_ms";
 
@@ -10146,6 +10765,7 @@
          * Packages that are whitelisted for background throttling (throttling will not be applied).
          * @hide
          */
+        @Readable
         public static final String LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST =
             "location_background_throttle_package_whitelist";
 
@@ -10155,6 +10775,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST =
                 "location_ignore_settings_package_whitelist";
 
@@ -10163,23 +10784,26 @@
         * (0 = false, 1 = true)
         * @hide
         */
-       public static final String MHL_INPUT_SWITCHING_ENABLED = "mhl_input_switching_enabled";
+        @Readable
+        public static final String MHL_INPUT_SWITCHING_ENABLED = "mhl_input_switching_enabled";
 
-       /**
+        /**
         * Whether TV will charge the mobile device connected at MHL port. (0 = false, 1 = true)
         * @hide
         */
-       public static final String MHL_POWER_CHARGE_ENABLED = "mhl_power_charge_enabled";
+        @Readable
+        public static final String MHL_POWER_CHARGE_ENABLED = "mhl_power_charge_enabled";
 
-       /**
+        /**
         * Whether mobile data connections are allowed by the user.  See
         * ConnectivityManager for more info.
         * @hide
         */
-       @UnsupportedAppUsage
-       public static final String MOBILE_DATA = "mobile_data";
+        @UnsupportedAppUsage
+        @Readable
+        public static final String MOBILE_DATA = "mobile_data";
 
-       /**
+        /**
         * Whether the mobile data connection should remain active even when higher
         * priority networks like WiFi are active, to help make network switching faster.
         *
@@ -10188,7 +10812,8 @@
         * (0 = disabled, 1 = enabled)
         * @hide
         */
-       public static final String MOBILE_DATA_ALWAYS_ON = "mobile_data_always_on";
+        @Readable
+        public static final String MOBILE_DATA_ALWAYS_ON = "mobile_data_always_on";
 
         /**
          * Whether the wifi data connection should remain active even when higher
@@ -10201,195 +10826,249 @@
          * (0 = disabled, 1 = enabled)
          * @hide
          */
+        @Readable
         public static final String WIFI_ALWAYS_REQUESTED = "wifi_always_requested";
 
         /**
          * Size of the event buffer for IP connectivity metrics.
          * @hide
          */
+        @Readable
         public static final String CONNECTIVITY_METRICS_BUFFER_SIZE =
               "connectivity_metrics_buffer_size";
 
-       /** {@hide} */
-       public static final String NETSTATS_ENABLED = "netstats_enabled";
-       /** {@hide} */
-       public static final String NETSTATS_POLL_INTERVAL = "netstats_poll_interval";
-       /** {@hide} */
-       @Deprecated
-       public static final String NETSTATS_TIME_CACHE_MAX_AGE = "netstats_time_cache_max_age";
-       /** {@hide} */
-       public static final String NETSTATS_GLOBAL_ALERT_BYTES = "netstats_global_alert_bytes";
-       /** {@hide} */
-       public static final String NETSTATS_SAMPLE_ENABLED = "netstats_sample_enabled";
-       /** {@hide} */
-       public static final String NETSTATS_AUGMENT_ENABLED = "netstats_augment_enabled";
-       /** {@hide} */
-       public static final String NETSTATS_COMBINE_SUBTYPE_ENABLED = "netstats_combine_subtype_enabled";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_ENABLED = "netstats_enabled";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_POLL_INTERVAL = "netstats_poll_interval";
+        /**
+         * @deprecated
+         * {@hide}
+         */
+        @Deprecated
+        @Readable
+        public static final String NETSTATS_TIME_CACHE_MAX_AGE = "netstats_time_cache_max_age";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_GLOBAL_ALERT_BYTES = "netstats_global_alert_bytes";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_SAMPLE_ENABLED = "netstats_sample_enabled";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_AUGMENT_ENABLED = "netstats_augment_enabled";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_COMBINE_SUBTYPE_ENABLED =
+                "netstats_combine_subtype_enabled";
 
-       /** {@hide} */
-       public static final String NETSTATS_DEV_BUCKET_DURATION = "netstats_dev_bucket_duration";
-       /** {@hide} */
-       public static final String NETSTATS_DEV_PERSIST_BYTES = "netstats_dev_persist_bytes";
-       /** {@hide} */
-       public static final String NETSTATS_DEV_ROTATE_AGE = "netstats_dev_rotate_age";
-       /** {@hide} */
-       public static final String NETSTATS_DEV_DELETE_AGE = "netstats_dev_delete_age";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_DEV_BUCKET_DURATION = "netstats_dev_bucket_duration";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_DEV_PERSIST_BYTES = "netstats_dev_persist_bytes";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_DEV_ROTATE_AGE = "netstats_dev_rotate_age";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_DEV_DELETE_AGE = "netstats_dev_delete_age";
 
-       /** {@hide} */
-       public static final String NETSTATS_UID_BUCKET_DURATION = "netstats_uid_bucket_duration";
-       /** {@hide} */
-       public static final String NETSTATS_UID_PERSIST_BYTES = "netstats_uid_persist_bytes";
-       /** {@hide} */
-       public static final String NETSTATS_UID_ROTATE_AGE = "netstats_uid_rotate_age";
-       /** {@hide} */
-       public static final String NETSTATS_UID_DELETE_AGE = "netstats_uid_delete_age";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_UID_BUCKET_DURATION = "netstats_uid_bucket_duration";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_UID_PERSIST_BYTES = "netstats_uid_persist_bytes";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_UID_ROTATE_AGE = "netstats_uid_rotate_age";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_UID_DELETE_AGE = "netstats_uid_delete_age";
 
-       /** {@hide} */
-       public static final String NETSTATS_UID_TAG_BUCKET_DURATION = "netstats_uid_tag_bucket_duration";
-       /** {@hide} */
-       public static final String NETSTATS_UID_TAG_PERSIST_BYTES = "netstats_uid_tag_persist_bytes";
-       /** {@hide} */
-       public static final String NETSTATS_UID_TAG_ROTATE_AGE = "netstats_uid_tag_rotate_age";
-       /** {@hide} */
-       public static final String NETSTATS_UID_TAG_DELETE_AGE = "netstats_uid_tag_delete_age";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_UID_TAG_BUCKET_DURATION =
+                "netstats_uid_tag_bucket_duration";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_UID_TAG_PERSIST_BYTES =
+                "netstats_uid_tag_persist_bytes";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_UID_TAG_ROTATE_AGE = "netstats_uid_tag_rotate_age";
+        /** {@hide} */
+        @Readable
+        public static final String NETSTATS_UID_TAG_DELETE_AGE = "netstats_uid_tag_delete_age";
 
-       /** {@hide} */
-       public static final String NETPOLICY_QUOTA_ENABLED = "netpolicy_quota_enabled";
-       /** {@hide} */
-       public static final String NETPOLICY_QUOTA_UNLIMITED = "netpolicy_quota_unlimited";
-       /** {@hide} */
-       public static final String NETPOLICY_QUOTA_LIMITED = "netpolicy_quota_limited";
-       /** {@hide} */
-       public static final String NETPOLICY_QUOTA_FRAC_JOBS = "netpolicy_quota_frac_jobs";
-       /** {@hide} */
-       public static final String NETPOLICY_QUOTA_FRAC_MULTIPATH = "netpolicy_quota_frac_multipath";
+        /** {@hide} */
+        @Readable
+        public static final String NETPOLICY_QUOTA_ENABLED = "netpolicy_quota_enabled";
+        /** {@hide} */
+        @Readable
+        public static final String NETPOLICY_QUOTA_UNLIMITED = "netpolicy_quota_unlimited";
+        /** {@hide} */
+        @Readable
+        public static final String NETPOLICY_QUOTA_LIMITED = "netpolicy_quota_limited";
+        /** {@hide} */
+        @Readable
+        public static final String NETPOLICY_QUOTA_FRAC_JOBS = "netpolicy_quota_frac_jobs";
+        /** {@hide} */
+        @Readable
+        public static final String NETPOLICY_QUOTA_FRAC_MULTIPATH =
+                "netpolicy_quota_frac_multipath";
 
-       /** {@hide} */
-       public static final String NETPOLICY_OVERRIDE_ENABLED = "netpolicy_override_enabled";
+        /** {@hide} */
+        @Readable
+        public static final String NETPOLICY_OVERRIDE_ENABLED = "netpolicy_override_enabled";
 
-       /**
+        /**
         * User preference for which network(s) should be used. Only the
         * connectivity service should touch this.
         */
-       public static final String NETWORK_PREFERENCE = "network_preference";
+        @Readable
+        public static final String NETWORK_PREFERENCE = "network_preference";
 
-       /**
+        /**
         * Which package name to use for network scoring. If null, or if the package is not a valid
         * scorer app, external network scores will neither be requested nor accepted.
         * @hide
         */
-       @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-       public static final String NETWORK_SCORER_APP = "network_scorer_app";
+        @Readable
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public static final String NETWORK_SCORER_APP = "network_scorer_app";
 
         /**
          * Whether night display forced auto mode is available.
          * 0 = unavailable, 1 = available.
          * @hide
          */
+        @Readable
         public static final String NIGHT_DISPLAY_FORCED_AUTO_MODE_AVAILABLE =
                 "night_display_forced_auto_mode_available";
 
-       /**
+        /**
         * If the NITZ_UPDATE_DIFF time is exceeded then an automatic adjustment
         * to SystemClock will be allowed even if NITZ_UPDATE_SPACING has not been
         * exceeded.
         * @hide
         */
-       public static final String NITZ_UPDATE_DIFF = "nitz_update_diff";
+        @Readable
+        public static final String NITZ_UPDATE_DIFF = "nitz_update_diff";
 
-       /**
+        /**
         * The length of time in milli-seconds that automatic small adjustments to
         * SystemClock are ignored if NITZ_UPDATE_DIFF is not exceeded.
         * @hide
         */
-       public static final String NITZ_UPDATE_SPACING = "nitz_update_spacing";
+        @Readable
+        public static final String NITZ_UPDATE_SPACING = "nitz_update_spacing";
 
-       /** Preferred NTP server. {@hide} */
-       public static final String NTP_SERVER = "ntp_server";
-       /** Timeout in milliseconds to wait for NTP server. {@hide} */
-       public static final String NTP_TIMEOUT = "ntp_timeout";
+        /** Preferred NTP server. {@hide} */
+        @Readable
+        public static final String NTP_SERVER = "ntp_server";
+        /** Timeout in milliseconds to wait for NTP server. {@hide} */
+        @Readable
+        public static final String NTP_TIMEOUT = "ntp_timeout";
 
-       /** {@hide} */
-       public static final String STORAGE_BENCHMARK_INTERVAL = "storage_benchmark_interval";
+        /** {@hide} */
+        @Readable
+        public static final String STORAGE_BENCHMARK_INTERVAL = "storage_benchmark_interval";
 
         /**
          * Whether or not Settings should enable psd API.
          * {@hide}
          */
+        @Readable
         public static final String SETTINGS_USE_PSD_API = "settings_use_psd_api";
 
         /**
          * Whether or not Settings should enable external provider API.
          * {@hide}
          */
+        @Readable
         public static final String SETTINGS_USE_EXTERNAL_PROVIDER_API =
                 "settings_use_external_provider_api";
 
-       /**
+        /**
         * Sample validity in seconds to configure for the system DNS resolver.
         * {@hide}
         */
-       public static final String DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS =
+        @Readable
+        public static final String DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS =
                "dns_resolver_sample_validity_seconds";
 
-       /**
+        /**
         * Success threshold in percent for use with the system DNS resolver.
         * {@hide}
         */
-       public static final String DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT =
+        @Readable
+        public static final String DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT =
                 "dns_resolver_success_threshold_percent";
 
-       /**
+        /**
         * Minimum number of samples needed for statistics to be considered meaningful in the
         * system DNS resolver.
         * {@hide}
         */
-       public static final String DNS_RESOLVER_MIN_SAMPLES = "dns_resolver_min_samples";
+        @Readable
+        public static final String DNS_RESOLVER_MIN_SAMPLES = "dns_resolver_min_samples";
 
-       /**
+        /**
         * Maximum number taken into account for statistics purposes in the system DNS resolver.
         * {@hide}
         */
-       public static final String DNS_RESOLVER_MAX_SAMPLES = "dns_resolver_max_samples";
+        @Readable
+        public static final String DNS_RESOLVER_MAX_SAMPLES = "dns_resolver_max_samples";
 
-       /**
+        /**
         * Whether to disable the automatic scheduling of system updates.
         * 1 = system updates won't be automatically scheduled (will always
         * present notification instead).
         * 0 = system updates will be automatically scheduled. (default)
         * @hide
         */
-       @SystemApi
-       public static final String OTA_DISABLE_AUTOMATIC_UPDATE = "ota_disable_automatic_update";
+        @SystemApi
+        @Readable
+        public static final String OTA_DISABLE_AUTOMATIC_UPDATE = "ota_disable_automatic_update";
 
-       /** Timeout for package verification.
+        /** Timeout for package verification.
         * @hide */
-       public static final String PACKAGE_VERIFIER_TIMEOUT = "verifier_timeout";
+        @Readable
+        public static final String PACKAGE_VERIFIER_TIMEOUT = "verifier_timeout";
 
         /** Timeout for app integrity verification.
          * @hide */
+        @Readable
         public static final String APP_INTEGRITY_VERIFICATION_TIMEOUT =
                 "app_integrity_verification_timeout";
 
-       /** Default response code for package verification.
+        /** Default response code for package verification.
         * @hide */
-       public static final String PACKAGE_VERIFIER_DEFAULT_RESPONSE = "verifier_default_response";
+        @Readable
+        public static final String PACKAGE_VERIFIER_DEFAULT_RESPONSE = "verifier_default_response";
 
-       /**
+        /**
         * Show package verification setting in the Settings app.
         * 1 = show (default)
         * 0 = hide
         * @hide
         */
-       public static final String PACKAGE_VERIFIER_SETTING_VISIBLE = "verifier_setting_visible";
+        @Readable
+        public static final String PACKAGE_VERIFIER_SETTING_VISIBLE = "verifier_setting_visible";
 
-       /**
+        /**
         * Run package verification on apps installed through ADB/ADT/USB
         * 1 = perform package verification on ADB installs (default)
         * 0 = bypass package verification on ADB installs
         * @hide
         */
-       public static final String PACKAGE_VERIFIER_INCLUDE_ADB = "verifier_verify_adb_installs";
+        @Readable
+        public static final String PACKAGE_VERIFIER_INCLUDE_ADB = "verifier_verify_adb_installs";
 
         /**
          * Run integrity checks for integrity rule providers.
@@ -10397,117 +11076,131 @@
          * 1 = perform integrity verification on installs from rule providers
          * @hide
          */
+        @Readable
         public static final String INTEGRITY_CHECK_INCLUDES_RULE_PROVIDER =
                 "verify_integrity_for_rule_provider";
 
-       /**
+        /**
         * Time since last fstrim (milliseconds) after which we force one to happen
         * during device startup.  If unset, the default is 3 days.
         * @hide
         */
-       public static final String FSTRIM_MANDATORY_INTERVAL = "fstrim_mandatory_interval";
+        @Readable
+        public static final String FSTRIM_MANDATORY_INTERVAL = "fstrim_mandatory_interval";
 
-       /**
+        /**
         * The interval in milliseconds at which to check packet counts on the
         * mobile data interface when screen is on, to detect possible data
         * connection problems.
         * @hide
         */
-       public static final String PDP_WATCHDOG_POLL_INTERVAL_MS =
+        @Readable
+        public static final String PDP_WATCHDOG_POLL_INTERVAL_MS =
                "pdp_watchdog_poll_interval_ms";
 
-       /**
+        /**
         * The interval in milliseconds at which to check packet counts on the
         * mobile data interface when screen is off, to detect possible data
         * connection problems.
         * @hide
         */
-       public static final String PDP_WATCHDOG_LONG_POLL_INTERVAL_MS =
+        @Readable
+        public static final String PDP_WATCHDOG_LONG_POLL_INTERVAL_MS =
                "pdp_watchdog_long_poll_interval_ms";
 
-       /**
+        /**
         * The interval in milliseconds at which to check packet counts on the
         * mobile data interface after {@link #PDP_WATCHDOG_TRIGGER_PACKET_COUNT}
         * outgoing packets has been reached without incoming packets.
         * @hide
         */
-       public static final String PDP_WATCHDOG_ERROR_POLL_INTERVAL_MS =
+        @Readable
+        public static final String PDP_WATCHDOG_ERROR_POLL_INTERVAL_MS =
                "pdp_watchdog_error_poll_interval_ms";
 
-       /**
+        /**
         * The number of outgoing packets sent without seeing an incoming packet
         * that triggers a countdown (of {@link #PDP_WATCHDOG_ERROR_POLL_COUNT}
         * device is logged to the event log
         * @hide
         */
-       public static final String PDP_WATCHDOG_TRIGGER_PACKET_COUNT =
+        @Readable
+        public static final String PDP_WATCHDOG_TRIGGER_PACKET_COUNT =
                "pdp_watchdog_trigger_packet_count";
 
-       /**
+        /**
         * The number of polls to perform (at {@link #PDP_WATCHDOG_ERROR_POLL_INTERVAL_MS})
         * after hitting {@link #PDP_WATCHDOG_TRIGGER_PACKET_COUNT} before
         * attempting data connection recovery.
         * @hide
         */
-       public static final String PDP_WATCHDOG_ERROR_POLL_COUNT =
+        @Readable
+        public static final String PDP_WATCHDOG_ERROR_POLL_COUNT =
                "pdp_watchdog_error_poll_count";
 
-       /**
+        /**
         * The number of failed PDP reset attempts before moving to something more
         * drastic: re-registering to the network.
         * @hide
         */
-       public static final String PDP_WATCHDOG_MAX_PDP_RESET_FAIL_COUNT =
+        @Readable
+        public static final String PDP_WATCHDOG_MAX_PDP_RESET_FAIL_COUNT =
                "pdp_watchdog_max_pdp_reset_fail_count";
 
-       /**
+        /**
         * URL to open browser on to allow user to manage a prepay account
         * @hide
         */
-       public static final String SETUP_PREPAID_DATA_SERVICE_URL =
+        @Readable
+        public static final String SETUP_PREPAID_DATA_SERVICE_URL =
                "setup_prepaid_data_service_url";
 
-       /**
+        /**
         * URL to attempt a GET on to see if this is a prepay device
         * @hide
         */
-       public static final String SETUP_PREPAID_DETECTION_TARGET_URL =
+        @Readable
+        public static final String SETUP_PREPAID_DETECTION_TARGET_URL =
                "setup_prepaid_detection_target_url";
 
-       /**
+        /**
         * Host to check for a redirect to after an attempt to GET
         * SETUP_PREPAID_DETECTION_TARGET_URL. (If we redirected there,
         * this is a prepaid device with zero balance.)
         * @hide
         */
-       public static final String SETUP_PREPAID_DETECTION_REDIR_HOST =
+        @Readable
+        public static final String SETUP_PREPAID_DETECTION_REDIR_HOST =
                "setup_prepaid_detection_redir_host";
 
-       /**
+        /**
         * The interval in milliseconds at which to check the number of SMS sent out without asking
         * for use permit, to limit the un-authorized SMS usage.
         *
         * @hide
         */
-       public static final String SMS_OUTGOING_CHECK_INTERVAL_MS =
+        @Readable
+        public static final String SMS_OUTGOING_CHECK_INTERVAL_MS =
                "sms_outgoing_check_interval_ms";
 
-       /**
+        /**
         * The number of outgoing SMS sent without asking for user permit (of {@link
         * #SMS_OUTGOING_CHECK_INTERVAL_MS}
         *
         * @hide
         */
-       public static final String SMS_OUTGOING_CHECK_MAX_COUNT =
+        @Readable
+        public static final String SMS_OUTGOING_CHECK_MAX_COUNT =
                "sms_outgoing_check_max_count";
 
-       /**
+        /**
         * Used to disable SMS short code confirmation - defaults to true.
         * True indcates we will do the check, etc.  Set to false to disable.
         * @see com.android.internal.telephony.SmsUsageMonitor
         * @hide
         */
-       public static final String SMS_SHORT_CODE_CONFIRMATION = "sms_short_code_confirmation";
+        @Readable
+        public static final String SMS_SHORT_CODE_CONFIRMATION = "sms_short_code_confirmation";
 
         /**
          * Used to select which country we use to determine premium sms codes.
@@ -10516,6 +11209,7 @@
          * or com.android.internal.telephony.SMSDispatcher.PREMIUM_RULE_USE_BOTH.
          * @hide
          */
+        @Readable
         public static final String SMS_SHORT_CODE_RULE = "sms_short_code_rule";
 
         /**
@@ -10523,6 +11217,7 @@
          * build config value.
          * @hide
          */
+        @Readable
         public static final String TCP_DEFAULT_INIT_RWND = "tcp_default_init_rwnd";
 
         /**
@@ -10530,6 +11225,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String TETHER_SUPPORTED = "tether_supported";
 
         /**
@@ -10537,6 +11233,7 @@
          * which defaults to false.
          * @hide
          */
+        @Readable
         public static final String TETHER_DUN_REQUIRED = "tether_dun_required";
 
         /**
@@ -10548,6 +11245,7 @@
          * note that empty fields can be omitted: "name,apn,,,,,,,,,310,260,,DUN"
          * @hide
          */
+        @Readable
         public static final String TETHER_DUN_APN = "tether_dun_apn";
 
         /**
@@ -10558,6 +11256,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String TETHER_OFFLOAD_DISABLED = "tether_offload_disabled";
 
         /**
@@ -10567,6 +11266,7 @@
          * is interpreted as |false|.
          * @hide
          */
+        @Readable
         public static final String TETHER_ENABLE_LEGACY_DHCP_SERVER =
                 "tether_enable_legacy_dhcp_server";
 
@@ -10581,6 +11281,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String CARRIER_APP_WHITELIST = "carrier_app_whitelist";
 
         /**
@@ -10591,62 +11292,71 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String CARRIER_APP_NAMES = "carrier_app_names";
 
-       /**
+        /**
         * USB Mass Storage Enabled
         */
-       public static final String USB_MASS_STORAGE_ENABLED = "usb_mass_storage_enabled";
+        @Readable
+        public static final String USB_MASS_STORAGE_ENABLED = "usb_mass_storage_enabled";
 
-       /**
+        /**
         * If this setting is set (to anything), then all references
         * to Gmail on the device must change to Google Mail.
         */
-       public static final String USE_GOOGLE_MAIL = "use_google_mail";
+        @Readable
+        public static final String USE_GOOGLE_MAIL = "use_google_mail";
 
         /**
          * Whether or not switching/creating users is enabled by user.
          * @hide
          */
+        @Readable
         public static final String USER_SWITCHER_ENABLED = "user_switcher_enabled";
 
         /**
          * Webview Data reduction proxy key.
          * @hide
          */
+        @Readable
         public static final String WEBVIEW_DATA_REDUCTION_PROXY_KEY =
                 "webview_data_reduction_proxy_key";
 
-       /**
+        /**
         * Name of the package used as WebView provider (if unset the provider is instead determined
         * by the system).
         * @hide
         */
-       @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-       public static final String WEBVIEW_PROVIDER = "webview_provider";
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
+        public static final String WEBVIEW_PROVIDER = "webview_provider";
 
-       /**
+        /**
         * Developer setting to enable WebView multiprocess rendering.
         * @hide
         */
-       @SystemApi
-       public static final String WEBVIEW_MULTIPROCESS = "webview_multiprocess";
+        @SystemApi
+        @Readable
+        public static final String WEBVIEW_MULTIPROCESS = "webview_multiprocess";
 
-       /**
+        /**
         * The maximum number of notifications shown in 24 hours when switching networks.
         * @hide
         */
-       public static final String NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT =
+        @Readable
+        public static final String NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT =
               "network_switch_notification_daily_limit";
 
-       /**
+        /**
         * The minimum time in milliseconds between notifications when switching networks.
         * @hide
         */
-       public static final String NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS =
+        @Readable
+        public static final String NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS =
               "network_switch_notification_rate_limit_millis";
 
-       /**
+        /**
         * Whether to automatically switch away from wifi networks that lose Internet access.
         * Only meaningful if config_networkAvoidBadWifi is set to 0, otherwise the system always
         * avoids such networks. Valid values are:
@@ -10657,16 +11367,18 @@
         *
         * @hide
         */
-       public static final String NETWORK_AVOID_BAD_WIFI = "network_avoid_bad_wifi";
+        @Readable
+        public static final String NETWORK_AVOID_BAD_WIFI = "network_avoid_bad_wifi";
 
-       /**
+        /**
         * User setting for ConnectivityManager.getMeteredMultipathPreference(). This value may be
         * overridden by the system based on device or application state. If null, the value
         * specified by config_networkMeteredMultipathPreference is used.
         *
         * @hide
         */
-       public static final String NETWORK_METERED_MULTIPATH_PREFERENCE =
+        @Readable
+        public static final String NETWORK_METERED_MULTIPATH_PREFERENCE =
                "network_metered_multipath_preference";
 
         /**
@@ -10675,6 +11387,7 @@
          * from data plan or data limit/warning set by the user.
          * @hide
          */
+        @Readable
         public static final String NETWORK_DEFAULT_DAILY_MULTIPATH_QUOTA_BYTES =
                 "network_default_daily_multipath_quota_bytes";
 
@@ -10682,10 +11395,11 @@
          * Network watchlist last report time.
          * @hide
          */
+        @Readable
         public static final String NETWORK_WATCHLIST_LAST_REPORT_TIME =
                 "network_watchlist_last_report_time";
 
-       /**
+        /**
         * The thresholds of the wifi throughput badging (SD, HD etc.) as a comma-delimited list of
         * colon-delimited key-value pairs. The key is the badging enum value defined in
         * android.net.ScoredNetwork and the value is the minimum sustained network throughput in
@@ -10693,25 +11407,28 @@
         *
         * @hide
         */
-       @SystemApi
-       public static final String WIFI_BADGING_THRESHOLDS = "wifi_badging_thresholds";
+        @SystemApi
+        @Readable
+        public static final String WIFI_BADGING_THRESHOLDS = "wifi_badging_thresholds";
 
-       /**
+        /**
         * Whether Wifi display is enabled/disabled
         * 0=disabled. 1=enabled.
         * @hide
         */
-       public static final String WIFI_DISPLAY_ON = "wifi_display_on";
+        @Readable
+        public static final String WIFI_DISPLAY_ON = "wifi_display_on";
 
-       /**
+        /**
         * Whether Wifi display certification mode is enabled/disabled
         * 0=disabled. 1=enabled.
         * @hide
         */
-       public static final String WIFI_DISPLAY_CERTIFICATION_ON =
+        @Readable
+        public static final String WIFI_DISPLAY_CERTIFICATION_ON =
                "wifi_display_certification_on";
 
-       /**
+        /**
         * WPS Configuration method used by Wifi display, this setting only
         * takes effect when WIFI_DISPLAY_CERTIFICATION_ON is 1 (enabled).
         *
@@ -10723,10 +11440,11 @@
         * WpsInfo.DISPLAY: use Display
         * @hide
         */
-       public static final String WIFI_DISPLAY_WPS_CONFIG =
+        @Readable
+        public static final String WIFI_DISPLAY_WPS_CONFIG =
            "wifi_display_wps_config";
 
-       /**
+        /**
         * Whether to notify the user of open networks.
         * <p>
         * If not connected and the scan results have an open network, we will
@@ -10738,68 +11456,78 @@
         * @deprecated This feature is no longer controlled by this setting in
         * {@link android.os.Build.VERSION_CODES#O}.
         */
-       @Deprecated
-       public static final String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON =
+        @Deprecated
+        @Readable
+        public static final String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON =
                "wifi_networks_available_notification_on";
 
-       /**
+        /**
         * {@hide}
         */
-       public static final String WIMAX_NETWORKS_AVAILABLE_NOTIFICATION_ON =
+        @Readable
+        public static final String WIMAX_NETWORKS_AVAILABLE_NOTIFICATION_ON =
                "wimax_networks_available_notification_on";
 
-       /**
+        /**
         * Delay (in seconds) before repeating the Wi-Fi networks available notification.
         * Connecting to a network will reset the timer.
         * @deprecated This is no longer used or set by the platform.
         */
-       @Deprecated
-       public static final String WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY =
+        @Deprecated
+        @Readable
+        public static final String WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY =
                "wifi_networks_available_repeat_delay";
 
-       /**
+        /**
         * 802.11 country code in ISO 3166 format
         * @hide
         */
-       public static final String WIFI_COUNTRY_CODE = "wifi_country_code";
+        @Readable
+        public static final String WIFI_COUNTRY_CODE = "wifi_country_code";
 
-       /**
+        /**
         * The interval in milliseconds to issue wake up scans when wifi needs
         * to connect. This is necessary to connect to an access point when
         * device is on the move and the screen is off.
         * @hide
         */
-       public static final String WIFI_FRAMEWORK_SCAN_INTERVAL_MS =
+        @Readable
+        public static final String WIFI_FRAMEWORK_SCAN_INTERVAL_MS =
                "wifi_framework_scan_interval_ms";
 
-       /**
+        /**
         * The interval in milliseconds after which Wi-Fi is considered idle.
         * When idle, it is possible for the device to be switched from Wi-Fi to
         * the mobile data network.
         * @hide
         */
-       public static final String WIFI_IDLE_MS = "wifi_idle_ms";
+        @Readable
+        public static final String WIFI_IDLE_MS = "wifi_idle_ms";
 
-       /**
+        /**
         * When the number of open networks exceeds this number, the
         * least-recently-used excess networks will be removed.
         * @deprecated This is no longer used or set by the platform.
         */
-       @Deprecated
-       public static final String WIFI_NUM_OPEN_NETWORKS_KEPT = "wifi_num_open_networks_kept";
+        @Deprecated
+        @Readable
+        public static final String WIFI_NUM_OPEN_NETWORKS_KEPT = "wifi_num_open_networks_kept";
 
-       /**
+        /**
         * Whether the Wi-Fi should be on.  Only the Wi-Fi service should touch this.
         */
-       public static final String WIFI_ON = "wifi_on";
+        @Readable
+        public static final String WIFI_ON = "wifi_on";
 
-       /**
+        /**
         * Setting to allow scans to be enabled even wifi is turned off for connectivity.
         * @hide
         * @deprecated To be removed. Use {@link WifiManager#setScanAlwaysAvailable(boolean)} for
         * setting the value and {@link WifiManager#isScanAlwaysAvailable()} for query.
         */
-       public static final String WIFI_SCAN_ALWAYS_AVAILABLE =
+        @Deprecated
+        @Readable
+        public static final String WIFI_SCAN_ALWAYS_AVAILABLE =
                 "wifi_scan_always_enabled";
 
         /**
@@ -10809,6 +11537,8 @@
          * @hide
          * @deprecated To be removed.
          */
+        @Deprecated
+        @Readable
         public static final String WIFI_P2P_PENDING_FACTORY_RESET =
                 "wifi_p2p_pending_factory_reset";
 
@@ -10821,6 +11551,8 @@
          * setAutoShutdownEnabled(boolean)} for setting the value and {@link SoftApConfiguration#
          * isAutoShutdownEnabled()} for query.
          */
+        @Deprecated
+        @Readable
         public static final String SOFT_AP_TIMEOUT_ENABLED = "soft_ap_timeout_enabled";
 
         /**
@@ -10833,6 +11565,7 @@
          */
         @Deprecated
         @SystemApi
+        @Readable
         public static final String WIFI_WAKEUP_ENABLED = "wifi_wakeup_enabled";
 
         /**
@@ -10842,6 +11575,7 @@
          * Type: int (0 for false, 1 for true)
          * @hide
          */
+        @Readable
         public static final String WIFI_MIGRATION_COMPLETED = "wifi_migration_completed";
 
         /**
@@ -10850,6 +11584,7 @@
          * Type: int (0 for false, 1 for true)
          * @hide
          */
+        @Readable
         public static final String NETWORK_SCORING_UI_ENABLED = "network_scoring_ui_enabled";
 
         /**
@@ -10859,6 +11594,7 @@
          * Type: long
          * @hide
          */
+        @Readable
         public static final String SPEED_LABEL_CACHE_EVICTION_AGE_MILLIS =
                 "speed_label_cache_eviction_age_millis";
 
@@ -10877,6 +11613,8 @@
          * @hide
          * @deprecated To be removed.
          */
+        @Deprecated
+        @Readable
         public static final String NETWORK_RECOMMENDATIONS_ENABLED =
                 "network_recommendations_enabled";
 
@@ -10890,6 +11628,7 @@
          * Type: string - package name
          * @hide
          */
+        @Readable
         public static final String NETWORK_RECOMMENDATIONS_PACKAGE =
                 "network_recommendations_package";
 
@@ -10901,6 +11640,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String USE_OPEN_WIFI_PACKAGE = "use_open_wifi_package";
 
         /**
@@ -10910,6 +11650,7 @@
          * Type: long
          * @hide
          */
+        @Readable
         public static final String RECOMMENDED_NETWORK_EVALUATOR_CACHE_EXPIRY_MS =
                 "recommended_network_evaluator_cache_expiry_ms";
 
@@ -10921,6 +11662,8 @@
          * @deprecated Use {@link WifiManager#setScanThrottleEnabled(boolean)} for setting the value
          * and {@link WifiManager#isScanThrottleEnabled()} for query.
          */
+        @Deprecated
+        @Readable
         public static final String WIFI_SCAN_THROTTLE_ENABLED = "wifi_scan_throttle_enabled";
 
         /**
@@ -10928,24 +11671,28 @@
         * connectivity.
         * @hide
         */
+        @Readable
         public static final String BLE_SCAN_ALWAYS_AVAILABLE = "ble_scan_always_enabled";
 
         /**
          * The length in milliseconds of a BLE scan window in a low-power scan mode.
          * @hide
          */
+        @Readable
         public static final String BLE_SCAN_LOW_POWER_WINDOW_MS = "ble_scan_low_power_window_ms";
 
         /**
          * The length in milliseconds of a BLE scan window in a balanced scan mode.
          * @hide
          */
+        @Readable
         public static final String BLE_SCAN_BALANCED_WINDOW_MS = "ble_scan_balanced_window_ms";
 
         /**
          * The length in milliseconds of a BLE scan window in a low-latency scan mode.
          * @hide
          */
+        @Readable
         public static final String BLE_SCAN_LOW_LATENCY_WINDOW_MS =
                 "ble_scan_low_latency_window_ms";
 
@@ -10953,6 +11700,7 @@
          * The length in milliseconds of a BLE scan interval in a low-power scan mode.
          * @hide
          */
+        @Readable
         public static final String BLE_SCAN_LOW_POWER_INTERVAL_MS =
                 "ble_scan_low_power_interval_ms";
 
@@ -10960,6 +11708,7 @@
          * The length in milliseconds of a BLE scan interval in a balanced scan mode.
          * @hide
          */
+        @Readable
         public static final String BLE_SCAN_BALANCED_INTERVAL_MS =
                 "ble_scan_balanced_interval_ms";
 
@@ -10967,6 +11716,7 @@
          * The length in milliseconds of a BLE scan interval in a low-latency scan mode.
          * @hide
          */
+        @Readable
         public static final String BLE_SCAN_LOW_LATENCY_INTERVAL_MS =
                 "ble_scan_low_latency_interval_ms";
 
@@ -10974,26 +11724,30 @@
          * The mode that BLE scanning clients will be moved to when in the background.
          * @hide
          */
+        @Readable
         public static final String BLE_SCAN_BACKGROUND_MODE = "ble_scan_background_mode";
 
-       /**
+        /**
         * The interval in milliseconds to scan as used by the wifi supplicant
         * @hide
         */
-       public static final String WIFI_SUPPLICANT_SCAN_INTERVAL_MS =
+        @Readable
+        public static final String WIFI_SUPPLICANT_SCAN_INTERVAL_MS =
                "wifi_supplicant_scan_interval_ms";
 
         /**
          * whether frameworks handles wifi auto-join
          * @hide
          */
-       public static final String WIFI_ENHANCED_AUTO_JOIN =
+        @Readable
+        public static final String WIFI_ENHANCED_AUTO_JOIN =
                 "wifi_enhanced_auto_join";
 
         /**
          * whether settings show RSSI
          * @hide
          */
+        @Readable
         public static final String WIFI_NETWORK_SHOW_RSSI =
                 "wifi_network_show_rssi";
 
@@ -11001,31 +11755,36 @@
         * The interval in milliseconds to scan at supplicant when p2p is connected
         * @hide
         */
-       public static final String WIFI_SCAN_INTERVAL_WHEN_P2P_CONNECTED_MS =
+        @Readable
+        public static final String WIFI_SCAN_INTERVAL_WHEN_P2P_CONNECTED_MS =
                "wifi_scan_interval_p2p_connected_ms";
 
-       /**
+        /**
         * Whether the Wi-Fi watchdog is enabled.
         */
-       public static final String WIFI_WATCHDOG_ON = "wifi_watchdog_on";
+        @Readable
+        public static final String WIFI_WATCHDOG_ON = "wifi_watchdog_on";
 
-       /**
+        /**
         * Setting to turn off poor network avoidance on Wi-Fi. Feature is enabled by default and
         * the setting needs to be set to 0 to disable it.
         * @hide
         */
-       @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-       public static final String WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED =
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
+        public static final String WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED =
                "wifi_watchdog_poor_network_test_enabled";
 
-       /**
+        /**
         * Setting to enable verbose logging in Wi-Fi; disabled by default, and setting to 1
         * will enable it. In the future, additional values may be supported.
         * @hide
         * @deprecated Use {@link WifiManager#setVerboseLoggingEnabled(boolean)} for setting the
         * value and {@link WifiManager#isVerboseLoggingEnabled()} for query.
         */
-       public static final String WIFI_VERBOSE_LOGGING_ENABLED =
+        @Deprecated
+        @Readable
+        public static final String WIFI_VERBOSE_LOGGING_ENABLED =
                "wifi_verbose_logging_enabled";
 
         /**
@@ -11035,6 +11794,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED =
                 "wifi_connected_mac_randomization_enabled";
 
@@ -11051,24 +11811,28 @@
          * @hide
          * @deprecated This is no longer used or set by the platform.
          */
+        @Deprecated
+        @Readable
         public static final String WIFI_SCORE_PARAMS =
                 "wifi_score_params";
 
-       /**
+        /**
         * The maximum number of times we will retry a connection to an access
         * point for which we have failed in acquiring an IP address from DHCP.
         * A value of N means that we will make N+1 connection attempts in all.
         */
-       public static final String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count";
+        @Readable
+        public static final String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count";
 
-       /**
+        /**
         * Maximum amount of time in milliseconds to hold a wakelock while waiting for mobile
         * data connectivity to be established after a disconnect from Wi-Fi.
         */
-       public static final String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS =
+        @Readable
+        public static final String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS =
            "wifi_mobile_data_transition_wakelock_timeout_ms";
 
-       /**
+        /**
         * This setting controls whether WiFi configurations created by a Device Owner app
         * should be locked down (that is, be editable or removable only by the Device Owner App,
         * not even by Settings app).
@@ -11076,10 +11840,11 @@
         * are locked down. Value of zero means they are not. Default value in the absence of
         * actual value to this setting is 0.
         */
-       public static final String WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN =
+        @Readable
+        public static final String WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN =
                "wifi_device_owner_configs_lockdown";
 
-       /**
+        /**
         * The operational wifi frequency band
         * Set to one of {@link WifiManager#WIFI_FREQUENCY_BAND_AUTO},
         * {@link WifiManager#WIFI_FREQUENCY_BAND_5GHZ} or
@@ -11087,18 +11852,21 @@
         *
         * @hide
         */
-       public static final String WIFI_FREQUENCY_BAND = "wifi_frequency_band";
+        @Readable
+        public static final String WIFI_FREQUENCY_BAND = "wifi_frequency_band";
 
-       /**
+        /**
         * The Wi-Fi peer-to-peer device name
         * @hide
         * @deprecated Use {@link WifiP2pManager#setDeviceName(WifiP2pManager.Channel, String,
         * WifiP2pManager.ActionListener)} for setting the value and
         * {@link android.net.wifi.p2p.WifiP2pDevice#deviceName} for query.
         */
-       public static final String WIFI_P2P_DEVICE_NAME = "wifi_p2p_device_name";
+        @Deprecated
+        @Readable
+        public static final String WIFI_P2P_DEVICE_NAME = "wifi_p2p_device_name";
 
-       /**
+        /**
         * Timeout for ephemeral networks when all known BSSIDs go out of range. We will disconnect
         * from an ephemeral network if there is no BSSID for that network with a non-null score that
         * has been seen in this time period.
@@ -11107,53 +11875,60 @@
         * for a non-null score from the currently connected or target BSSID.
         * @hide
         */
-       public static final String WIFI_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS =
+        @Readable
+        public static final String WIFI_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS =
                "wifi_ephemeral_out_of_range_timeout_ms";
 
-       /**
+        /**
         * The number of milliseconds to delay when checking for data stalls during
         * non-aggressive detection. (screen is turned off.)
         * @hide
         */
-       public static final String DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS =
+        @Readable
+        public static final String DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS =
                "data_stall_alarm_non_aggressive_delay_in_ms";
 
-       /**
+        /**
         * The number of milliseconds to delay when checking for data stalls during
         * aggressive detection. (screen on or suspected data stall)
         * @hide
         */
-       public static final String DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS =
+        @Readable
+        public static final String DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS =
                "data_stall_alarm_aggressive_delay_in_ms";
 
-       /**
+        /**
         * The number of milliseconds to allow the provisioning apn to remain active
         * @hide
         */
-       public static final String PROVISIONING_APN_ALARM_DELAY_IN_MS =
+        @Readable
+        public static final String PROVISIONING_APN_ALARM_DELAY_IN_MS =
                "provisioning_apn_alarm_delay_in_ms";
 
-       /**
+        /**
         * The interval in milliseconds at which to check gprs registration
         * after the first registration mismatch of gprs and voice service,
         * to detect possible data network registration problems.
         *
         * @hide
         */
-       public static final String GPRS_REGISTER_CHECK_PERIOD_MS =
+        @Readable
+        public static final String GPRS_REGISTER_CHECK_PERIOD_MS =
                "gprs_register_check_period_ms";
 
-       /**
+        /**
         * Nonzero causes Log.wtf() to crash.
         * @hide
         */
-       public static final String WTF_IS_FATAL = "wtf_is_fatal";
+        @Readable
+        public static final String WTF_IS_FATAL = "wtf_is_fatal";
 
-       /**
+        /**
         * Ringer mode. This is used internally, changing this value will not
         * change the ringer mode. See AudioManager.
         */
-       public static final String MODE_RINGER = "mode_ringer";
+        @Readable
+        public static final String MODE_RINGER = "mode_ringer";
 
         /**
          * Overlay display devices setting.
@@ -11194,6 +11969,7 @@
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         @TestApi
+        @Readable
         public static final String OVERLAY_DISPLAY_DEVICES = "overlay_display_devices";
 
         /**
@@ -11202,10 +11978,12 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 BATTERY_DISCHARGE_DURATION_THRESHOLD = "battery_discharge_duration_threshold";
 
         /** @hide */
+        @Readable
         public static final String BATTERY_DISCHARGE_THRESHOLD = "battery_discharge_threshold";
 
         /**
@@ -11217,6 +11995,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SEND_ACTION_APP_ERROR = "send_action_app_error";
 
         /**
@@ -11224,6 +12003,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DROPBOX_AGE_SECONDS = "dropbox_age_seconds";
 
         /**
@@ -11232,6 +12012,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DROPBOX_MAX_FILES = "dropbox_max_files";
 
         /**
@@ -11240,6 +12021,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DROPBOX_QUOTA_KB = "dropbox_quota_kb";
 
         /**
@@ -11248,6 +12030,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DROPBOX_QUOTA_PERCENT = "dropbox_quota_percent";
 
         /**
@@ -11256,6 +12039,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DROPBOX_RESERVE_PERCENT = "dropbox_reserve_percent";
 
         /**
@@ -11263,6 +12047,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DROPBOX_TAG_PREFIX = "dropbox:";
 
         /**
@@ -11273,6 +12058,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ERROR_LOGCAT_PREFIX = "logcat_for_";
 
         /**
@@ -11286,6 +12072,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String MAX_ERROR_BYTES_PREFIX = "max_error_bytes_for_";
 
         /**
@@ -11294,6 +12081,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SYS_FREE_STORAGE_LOG_INTERVAL = "sys_free_storage_log_interval";
 
         /**
@@ -11303,6 +12091,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 DISK_FREE_CHANGE_REPORTING_THRESHOLD = "disk_free_change_reporting_threshold";
 
@@ -11315,6 +12104,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 SYS_STORAGE_THRESHOLD_PERCENTAGE = "sys_storage_threshold_percentage";
 
@@ -11326,6 +12116,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 SYS_STORAGE_THRESHOLD_MAX_BYTES = "sys_storage_threshold_max_bytes";
 
@@ -11336,6 +12127,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 SYS_STORAGE_FULL_THRESHOLD_BYTES = "sys_storage_full_threshold_bytes";
 
@@ -11345,6 +12137,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 SYS_STORAGE_CACHE_PERCENTAGE = "sys_storage_cache_percentage";
 
@@ -11354,6 +12147,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 SYS_STORAGE_CACHE_MAX_BYTES = "sys_storage_cache_max_bytes";
 
@@ -11363,6 +12157,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 SYNC_MAX_RETRY_DELAY_IN_SECONDS = "sync_max_retry_delay_in_seconds";
 
@@ -11372,6 +12167,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CONNECTIVITY_CHANGE_DELAY = "connectivity_change_delay";
 
 
@@ -11381,7 +12177,7 @@
          *
          * @hide
          */
-
+        @Readable
         public static final String CONNECTIVITY_SAMPLING_INTERVAL_IN_SECONDS =
                 "connectivity_sampling_interval_in_seconds";
 
@@ -11391,6 +12187,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String PAC_CHANGE_DELAY = "pac_change_delay";
 
         /**
@@ -11423,6 +12220,7 @@
          * The default for this setting is CAPTIVE_PORTAL_MODE_PROMPT.
          * @hide
          */
+        @Readable
         public static final String CAPTIVE_PORTAL_MODE = "captive_portal_mode";
 
         /**
@@ -11433,6 +12231,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String
                 CAPTIVE_PORTAL_DETECTION_ENABLED = "captive_portal_detection_enabled";
 
@@ -11443,6 +12242,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAPTIVE_PORTAL_SERVER = "captive_portal_server";
 
         /**
@@ -11451,6 +12251,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAPTIVE_PORTAL_HTTPS_URL = "captive_portal_https_url";
 
         /**
@@ -11459,6 +12260,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAPTIVE_PORTAL_HTTP_URL = "captive_portal_http_url";
 
         /**
@@ -11467,6 +12269,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAPTIVE_PORTAL_FALLBACK_URL = "captive_portal_fallback_url";
 
         /**
@@ -11475,6 +12278,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAPTIVE_PORTAL_OTHER_FALLBACK_URLS =
                 "captive_portal_other_fallback_urls";
 
@@ -11484,6 +12288,7 @@
          * by "@@,@@".
          * @hide
          */
+        @Readable
         public static final String CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS =
                 "captive_portal_fallback_probe_specs";
 
@@ -11494,6 +12299,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAPTIVE_PORTAL_USE_HTTPS = "captive_portal_use_https";
 
         /**
@@ -11502,6 +12308,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CAPTIVE_PORTAL_USER_AGENT = "captive_portal_user_agent";
 
         /**
@@ -11509,6 +12316,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DATA_STALL_RECOVERY_ON_BAD_NETWORK =
                 "data_stall_recovery_on_bad_network";
 
@@ -11517,6 +12325,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String MIN_DURATION_BETWEEN_RECOVERY_STEPS_IN_MS =
                 "min_duration_between_recovery_steps";
         /**
@@ -11524,6 +12333,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String NSD_ON = "nsd_on";
 
         /**
@@ -11531,6 +12341,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SET_INSTALL_LOCATION = "set_install_location";
 
         /**
@@ -11540,6 +12351,7 @@
          * 2 = sdcard
          * @hide
          */
+        @Readable
         public static final String DEFAULT_INSTALL_LOCATION = "default_install_location";
 
         /**
@@ -11548,6 +12360,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 INET_CONDITION_DEBOUNCE_UP_DELAY = "inet_condition_debounce_up_delay";
 
@@ -11557,10 +12370,12 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 INET_CONDITION_DEBOUNCE_DOWN_DELAY = "inet_condition_debounce_down_delay";
 
         /** {@hide} */
+        @Readable
         public static final String
                 READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT = "read_external_storage_enforced_default";
 
@@ -11568,6 +12383,7 @@
          * Host name and port for global http proxy. Uses ':' seperator for
          * between host and port.
          */
+        @Readable
         public static final String HTTP_PROXY = "http_proxy";
 
         /**
@@ -11575,6 +12391,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String GLOBAL_HTTP_PROXY_HOST = "global_http_proxy_host";
 
         /**
@@ -11582,6 +12399,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String GLOBAL_HTTP_PROXY_PORT = "global_http_proxy_port";
 
         /**
@@ -11593,6 +12411,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String
                 GLOBAL_HTTP_PROXY_EXCLUSION_LIST = "global_http_proxy_exclusion_list";
 
@@ -11600,6 +12419,7 @@
          * The location PAC File for the proxy.
          * @hide
          */
+        @Readable
         public static final String
                 GLOBAL_HTTP_PROXY_PAC = "global_proxy_pac_url";
 
@@ -11609,6 +12429,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SET_GLOBAL_HTTP_PROXY = "set_global_http_proxy";
 
         /**
@@ -11616,6 +12437,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DEFAULT_DNS_SERVER = "default_dns_server";
 
         /**
@@ -11628,11 +12450,13 @@
          *
          * @hide
          */
+        @Readable
         public static final String PRIVATE_DNS_MODE = "private_dns_mode";
 
         /**
          * @hide
          */
+        @Readable
         public static final String PRIVATE_DNS_SPECIFIER = "private_dns_specifier";
 
         /**
@@ -11644,46 +12468,60 @@
           *
           * {@hide}
           */
+        @Readable
         public static final String PRIVATE_DNS_DEFAULT_MODE = "private_dns_default_mode";
 
 
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_BTSNOOP_DEFAULT_MODE = "bluetooth_btsnoop_default_mode";
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_HEADSET_PRIORITY_PREFIX = "bluetooth_headset_priority_";
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_A2DP_SINK_PRIORITY_PREFIX = "bluetooth_a2dp_sink_priority_";
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_A2DP_SRC_PRIORITY_PREFIX = "bluetooth_a2dp_src_priority_";
         /** {@hide} */
+        @Readable
         public static final String BLUETOOTH_A2DP_SUPPORTS_OPTIONAL_CODECS_PREFIX =
                 "bluetooth_a2dp_supports_optional_codecs_";
         /** {@hide} */
+        @Readable
         public static final String BLUETOOTH_A2DP_OPTIONAL_CODECS_ENABLED_PREFIX =
                 "bluetooth_a2dp_optional_codecs_enabled_";
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_INPUT_DEVICE_PRIORITY_PREFIX = "bluetooth_input_device_priority_";
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_MAP_PRIORITY_PREFIX = "bluetooth_map_priority_";
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_MAP_CLIENT_PRIORITY_PREFIX = "bluetooth_map_client_priority_";
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_PBAP_CLIENT_PRIORITY_PREFIX = "bluetooth_pbap_client_priority_";
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_SAP_PRIORITY_PREFIX = "bluetooth_sap_priority_";
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_PAN_PRIORITY_PREFIX = "bluetooth_pan_priority_";
         /** {@hide} */
+        @Readable
         public static final String
                 BLUETOOTH_HEARING_AID_PRIORITY_PREFIX = "bluetooth_hearing_aid_priority_";
 
@@ -11692,6 +12530,7 @@
          *
          * {@hide}
          */
+        @Readable
         public static final String
                 ENABLE_RADIO_BUG_DETECTION = "enable_radio_bug_detection";
 
@@ -11700,6 +12539,7 @@
          *
          * {@hide}
          */
+        @Readable
         public static final String
                 RADIO_BUG_WAKELOCK_TIMEOUT_COUNT_THRESHOLD =
                 "radio_bug_wakelock_timeout_count_threshold";
@@ -11709,6 +12549,7 @@
          *
          * {@hide}
          */
+        @Readable
         public static final String
                 RADIO_BUG_SYSTEM_ERROR_COUNT_THRESHOLD =
                 "radio_bug_system_error_count_threshold";
@@ -11755,6 +12596,7 @@
          * @hide
          * @see com.android.server.am.ActivityManagerConstants
          */
+        @Readable
         public static final String ACTIVITY_MANAGER_CONSTANTS = "activity_manager_constants";
 
         /**
@@ -11763,6 +12605,7 @@
          * Default: 1
          * @hide
          */
+        @Readable
         public static final String ACTIVITY_STARTS_LOGGING_ENABLED
                 = "activity_starts_logging_enabled";
 
@@ -11772,6 +12615,7 @@
          * Default: 1
          * @hide
          */
+        @Readable
         public static final String FOREGROUND_SERVICE_STARTS_LOGGING_ENABLED =
                 "foreground_service_starts_logging_enabled";
 
@@ -11779,6 +12623,7 @@
          * @hide
          * @see com.android.server.appbinding.AppBindingConstants
          */
+        @Readable
         public static final String APP_BINDING_CONSTANTS = "app_binding_constants";
 
         /**
@@ -11801,6 +12646,7 @@
          * @see com.android.server.AppOpsService.Constants
          */
         @TestApi
+        @Readable
         public static final String APP_OPS_CONSTANTS = "app_ops_constants";
 
         /**
@@ -11836,6 +12682,7 @@
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         @TestApi
+        @Readable
         public static final String BATTERY_SAVER_CONSTANTS = "battery_saver_constants";
 
         /**
@@ -11853,6 +12700,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS =
                 "battery_saver_device_specific_constants";
 
@@ -11882,6 +12730,7 @@
          * </pre>
          * @hide
          */
+        @Readable
         public static final String BATTERY_TIP_CONSTANTS = "battery_tip_constants";
 
         /**
@@ -11907,6 +12756,7 @@
          * </pre>
          * @hide
          */
+        @Readable
         public static final String ANOMALY_DETECTION_CONSTANTS = "anomaly_detection_constants";
 
         /**
@@ -11914,6 +12764,7 @@
          * current version is 1.
          * @hide
          */
+        @Readable
         public static final String ANOMALY_CONFIG_VERSION = "anomaly_config_version";
 
         /**
@@ -11921,6 +12772,7 @@
          * {@link android.app.StatsManager}.
          * @hide
          */
+        @Readable
         public static final String ANOMALY_CONFIG = "anomaly_config";
 
         /**
@@ -11940,6 +12792,7 @@
          * </pre>
          * @hide
          */
+        @Readable
         public static final String ALWAYS_ON_DISPLAY_CONSTANTS = "always_on_display_constants";
 
         /**
@@ -11950,6 +12803,7 @@
         * Any other value defaults to enabled.
         * @hide
         */
+        @Readable
         public static final String SYS_UIDCPUPOWER = "sys_uidcpupower";
 
         /**
@@ -11961,6 +12815,7 @@
         * Any other value defaults to disabled.
         * @hide
         */
+        @Readable
         public static final String SYS_TRACED = "sys_traced";
 
         /**
@@ -11969,6 +12824,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String FPS_DEVISOR = "fps_divisor";
 
         /**
@@ -11978,6 +12834,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DISPLAY_PANEL_LPM = "display_panel_lpm";
 
         /**
@@ -11992,6 +12849,7 @@
          * Need to reboot the device for this setting to take effect.
          * @hide
          */
+        @Readable
         public static final String APP_TIME_LIMIT_USAGE_SOURCE = "app_time_limit_usage_source";
 
         /**
@@ -11999,6 +12857,7 @@
          * 0 = disable, 1 = enable.
          * @hide
          */
+        @Readable
         public static final String ART_VERIFIER_VERIFY_DEBUGGABLE =
                 "art_verifier_verify_debuggable";
 
@@ -12019,6 +12878,7 @@
          * @hide
          * @see com.android.server.power.PowerManagerConstants
          */
+        @Readable
         public static final String POWER_MANAGER_CONSTANTS = "power_manager_constants";
 
         /**
@@ -12044,6 +12904,7 @@
          * @hide
          * @see com.android.server.pm.ShortcutService.ConfigConstants
          */
+        @Readable
         public static final String SHORTCUT_MANAGER_CONSTANTS = "shortcut_manager_constants";
 
         /**
@@ -12061,6 +12922,7 @@
          * @hide
          * see also com.android.server.devicepolicy.DevicePolicyConstants
          */
+        @Readable
         public static final String DEVICE_POLICY_CONSTANTS = "device_policy_constants";
 
         /**
@@ -12097,6 +12959,7 @@
          * @hide
          * see also android.view.textclassifier.TextClassificationConstants
          */
+        @Readable
         public static final String TEXT_CLASSIFIER_CONSTANTS = "text_classifier_constants";
 
         /**
@@ -12121,6 +12984,7 @@
          * @hide
          * see also com.android.internal.os.BatteryStatsImpl.Constants
          */
+        @Readable
         public static final String BATTERY_STATS_CONSTANTS = "battery_stats_constants";
 
         /**
@@ -12131,6 +12995,7 @@
          * @hide
          * @see com.android.server.content.SyncManagerConstants
          */
+        @Readable
         public static final String SYNC_MANAGER_CONSTANTS = "sync_manager_constants";
 
         /**
@@ -12150,6 +13015,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BROADCAST_FG_CONSTANTS = "bcast_fg_constants";
 
         /**
@@ -12160,6 +13026,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BROADCAST_BG_CONSTANTS = "bcast_bg_constants";
 
         /**
@@ -12170,6 +13037,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BROADCAST_OFFLOAD_CONSTANTS = "bcast_offload_constants";
 
         /**
@@ -12182,6 +13050,7 @@
          * @see #ADAPTIVE_BATTERY_MANAGEMENT_ENABLED
          */
         @SystemApi
+        @Readable
         public static final String APP_STANDBY_ENABLED = "app_standby_enabled";
 
         /**
@@ -12192,6 +13061,7 @@
          * @hide
          * @see #APP_STANDBY_ENABLED
          */
+        @Readable
         public static final String ADAPTIVE_BATTERY_MANAGEMENT_ENABLED =
                 "adaptive_battery_management_enabled";
 
@@ -12203,6 +13073,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ENABLE_RESTRICTED_BUCKET = "enable_restricted_bucket";
 
         /**
@@ -12220,6 +13091,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String APP_AUTO_RESTRICTION_ENABLED =
                 "app_auto_restriction_enabled";
 
@@ -12229,6 +13101,7 @@
          * Default: 1
          * @hide
          */
+        @Readable
         public static final String FORCED_APP_STANDBY_ENABLED = "forced_app_standby_enabled";
 
         /**
@@ -12237,6 +13110,7 @@
          * Default: 0
          * @hide
          */
+        @Readable
         public static final String FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED
                 = "forced_app_standby_for_small_battery_enabled";
 
@@ -12246,6 +13120,7 @@
          * Default: 0
          * @hide
          */
+        @Readable
         public static final String USER_ABSENT_RADIOS_OFF_FOR_SMALL_BATTERY_ENABLED
                 = "user_absent_radios_off_for_small_battery_enabled";
 
@@ -12255,6 +13130,7 @@
          * Default: 0
          * @hide
          */
+        @Readable
         public static final String USER_ABSENT_TOUCH_OFF_FOR_SMALL_BATTERY_ENABLED
                 = "user_absent_touch_off_for_small_battery_enabled";
 
@@ -12264,6 +13140,7 @@
          * Default: 1
          * @hide
          */
+        @Readable
         public static final String WIFI_ON_WHEN_PROXY_DISCONNECTED
                 = "wifi_on_when_proxy_disconnected";
 
@@ -12282,6 +13159,7 @@
          * Type: string
          * @hide
          */
+        @Readable
         public static final String TIME_ONLY_MODE_CONSTANTS
                 = "time_only_mode_constants";
 
@@ -12292,6 +13170,7 @@
          * Default: 0
          * @hide
          */
+        @Readable
         public static final String UNGAZE_SLEEP_ENABLED = "ungaze_sleep_enabled";
 
         /**
@@ -12300,6 +13179,7 @@
          * Default: 0
          * @hide
          */
+        @Readable
         public static final String NETWORK_WATCHLIST_ENABLED = "network_watchlist_enabled";
 
         /**
@@ -12308,6 +13188,7 @@
          * Default: 1
          * @hide
          */
+        @Readable
         public static final String SHOW_HIDDEN_LAUNCHER_ICON_APPS_ENABLED =
                 "show_hidden_icon_apps_enabled";
 
@@ -12317,6 +13198,7 @@
          * Default: 0
          * @hide
          */
+        @Readable
         public static final String SHOW_NEW_APP_INSTALLED_NOTIFICATION_ENABLED =
                 "show_new_app_installed_notification_enabled";
 
@@ -12330,6 +13212,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String KEEP_PROFILE_IN_BACKGROUND = "keep_profile_in_background";
 
         /**
@@ -12351,6 +13234,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ADB_ALLOWED_CONNECTION_TIME =
                 "adb_allowed_connection_time";
 
@@ -12358,12 +13242,14 @@
          * Scaling factor for normal window animations. Setting to 0 will
          * disable window animations.
          */
+        @Readable
         public static final String WINDOW_ANIMATION_SCALE = "window_animation_scale";
 
         /**
          * Scaling factor for activity transition animations. Setting to 0 will
          * disable window animations.
          */
+        @Readable
         public static final String TRANSITION_ANIMATION_SCALE = "transition_animation_scale";
 
         /**
@@ -12371,6 +13257,7 @@
          * start delay and duration of all such animations. Setting to 0 will
          * cause animations to end immediately. The default value is 1.
          */
+        @Readable
         public static final String ANIMATOR_DURATION_SCALE = "animator_duration_scale";
 
         /**
@@ -12379,6 +13266,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String FANCY_IME_ANIMATIONS = "fancy_ime_animations";
 
         /**
@@ -12387,6 +13275,7 @@
          * TODO: remove this settings before code freeze (bug/1907571)
          * @hide
          */
+        @Readable
         public static final String COMPATIBILITY_MODE = "compatibility_mode";
 
         /**
@@ -12396,6 +13285,7 @@
          *                 2 = Vibrate
          * @hide
          */
+        @Readable
         public static final String EMERGENCY_TONE = "emergency_tone";
 
         /**
@@ -12404,6 +13294,7 @@
          * boolean (1 or 0).
          * @hide
          */
+        @Readable
         public static final String CALL_AUTO_RETRY = "call_auto_retry";
 
         /**
@@ -12411,6 +13302,7 @@
          * The value is a boolean (1 or 0).
          * @hide
          */
+        @Readable
         public static final String EMERGENCY_AFFORDANCE_NEEDED = "emergency_affordance_needed";
 
         /**
@@ -12420,6 +13312,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS =
                 "enable_automatic_system_server_heap_dumps";
 
@@ -12428,18 +13321,21 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String PREFERRED_NETWORK_MODE =
                 "preferred_network_mode";
 
         /**
          * Name of an application package to be debugged.
          */
+        @Readable
         public static final String DEBUG_APP = "debug_app";
 
         /**
          * If 1, when launching DEBUG_APP it will wait for the debugger before
          * starting user code.  If 0, it will run normally.
          */
+        @Readable
         public static final String WAIT_FOR_DEBUGGER = "wait_for_debugger";
 
         /**
@@ -12448,12 +13344,14 @@
          * 1 = yes
          * @hide
          */
+        @Readable
         public static final String ENABLE_GPU_DEBUG_LAYERS = "enable_gpu_debug_layers";
 
         /**
          * App allowed to load GPU debug layers
          * @hide
          */
+        @Readable
         public static final String GPU_DEBUG_APP = "gpu_debug_app";
 
         /**
@@ -12461,6 +13359,7 @@
          * to dumpable apps that opt-in.
          * @hide
          */
+        @Readable
         public static final String ANGLE_DEBUG_PACKAGE = "angle_debug_package";
 
         /**
@@ -12468,12 +13367,14 @@
          * The value is a boolean (1 or 0).
          * @hide
          */
+        @Readable
         public static final String ANGLE_GL_DRIVER_ALL_ANGLE = "angle_gl_driver_all_angle";
 
         /**
          * List of PKGs that have an OpenGL driver selected
          * @hide
          */
+        @Readable
         public static final String ANGLE_GL_DRIVER_SELECTION_PKGS =
                 "angle_gl_driver_selection_pkgs";
 
@@ -12481,6 +13382,7 @@
          * List of selected OpenGL drivers, corresponding to the PKGs in GLOBAL_SETTINGS_DRIVER_PKGS
          * @hide
          */
+        @Readable
         public static final String ANGLE_GL_DRIVER_SELECTION_VALUES =
                 "angle_gl_driver_selection_values";
 
@@ -12488,6 +13390,7 @@
          * List of package names that should check ANGLE rules
          * @hide
          */
+        @Readable
         public static final String ANGLE_ALLOWLIST = "angle_allowlist";
 
         /**
@@ -12497,6 +13400,7 @@
          * e.g. feature1:feature2:feature3,feature1:feature3:feature5
          * @hide
          */
+        @Readable
         public static final String ANGLE_EGL_FEATURES = "angle_egl_features";
 
         /**
@@ -12504,6 +13408,7 @@
          * The value is a boolean (1 or 0).
          * @hide
          */
+        @Readable
         public static final String SHOW_ANGLE_IN_USE_DIALOG_BOX = "show_angle_in_use_dialog_box";
 
         /**
@@ -12514,6 +13419,7 @@
          * 3 = All Apps use system graphics driver
          * @hide
          */
+        @Readable
         public static final String UPDATABLE_DRIVER_ALL_APPS = "updatable_driver_all_apps";
 
         /**
@@ -12521,6 +13427,7 @@
          * i.e. <pkg1>,<pkg2>,...,<pkgN>
          * @hide
          */
+        @Readable
         public static final String UPDATABLE_DRIVER_PRODUCTION_OPT_IN_APPS =
                 "updatable_driver_production_opt_in_apps";
 
@@ -12529,6 +13436,7 @@
          * i.e. <pkg1>,<pkg2>,...,<pkgN>
          * @hide
          */
+        @Readable
         public static final String UPDATABLE_DRIVER_PRERELEASE_OPT_IN_APPS =
                 "updatable_driver_prerelease_opt_in_apps";
 
@@ -12537,6 +13445,7 @@
          * i.e. <pkg1>,<pkg2>,...,<pkgN>
          * @hide
          */
+        @Readable
         public static final String UPDATABLE_DRIVER_PRODUCTION_OPT_OUT_APPS =
                 "updatable_driver_production_opt_out_apps";
 
@@ -12544,6 +13453,7 @@
          * Apps on the denylist that are forbidden to use updatable production driver.
          * @hide
          */
+        @Readable
         public static final String UPDATABLE_DRIVER_PRODUCTION_DENYLIST =
                 "updatable_driver_production_denylist";
 
@@ -12552,6 +13462,7 @@
          * updatable production driver.
          * @hide
          */
+        @Readable
         public static final String UPDATABLE_DRIVER_PRODUCTION_DENYLISTS =
                 "updatable_driver_production_denylists";
 
@@ -12561,6 +13472,7 @@
          * i.e. <apk1>,<apk2>,...,<apkN>
          * @hide
          */
+        @Readable
         public static final String UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST =
                 "updatable_driver_production_allowlist";
 
@@ -12570,6 +13482,7 @@
          * i.e. <lib1>:<lib2>:...:<libN>
          * @hide
          */
+        @Readable
         public static final String UPDATABLE_DRIVER_SPHAL_LIBRARIES =
                 "updatable_driver_sphal_libraries";
 
@@ -12578,6 +13491,7 @@
          * i.e. <layer1>:<layer2>:...:<layerN>
          * @hide
          */
+        @Readable
         public static final String GPU_DEBUG_LAYERS = "gpu_debug_layers";
 
         /**
@@ -12585,12 +13499,14 @@
          * i.e. <layer1>:<layer2>:...:<layerN>
          * @hide
          */
+        @Readable
         public static final String GPU_DEBUG_LAYERS_GLES = "gpu_debug_layers_gles";
 
         /**
          * Addition app for GPU layer discovery
          * @hide
          */
+        @Readable
         public static final String GPU_DEBUG_LAYER_APP = "gpu_debug_layer_app";
 
         /**
@@ -12600,6 +13516,7 @@
          * {@link android.os.Build.VERSION_CODES#N_MR1}.
          */
         @Deprecated
+        @Readable
         public static final String SHOW_PROCESSES = "show_processes";
 
         /**
@@ -12607,6 +13524,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String LOW_POWER_MODE = "low_power";
 
         /**
@@ -12615,6 +13533,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String LOW_POWER_MODE_STICKY = "low_power_sticky";
 
         /**
@@ -12624,6 +13543,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL =
                 "low_power_sticky_auto_disable_level";
 
@@ -12633,6 +13553,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED =
                 "low_power_sticky_auto_disable_enabled";
 
@@ -12646,6 +13567,7 @@
          * @see android.os.PowerManager#getPowerSaveModeTrigger()
          * @hide
          */
+        @Readable
         public static final String LOW_POWER_MODE_TRIGGER_LEVEL = "low_power_trigger_level";
 
         /**
@@ -12656,6 +13578,7 @@
          *  @hide
          */
         @TestApi
+        @Readable
         public static final String AUTOMATIC_POWER_SAVE_MODE = "automatic_power_save_mode";
 
         /**
@@ -12666,6 +13589,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD =
                 "dynamic_power_savings_disable_threshold";
 
@@ -12676,6 +13600,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String DYNAMIC_POWER_SAVINGS_ENABLED = "dynamic_power_savings_enabled";
 
         /**
@@ -12687,6 +13612,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String TIME_REMAINING_ESTIMATE_MILLIS =
                 "time_remaining_estimate_millis";
 
@@ -12700,6 +13626,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String TIME_REMAINING_ESTIMATE_BASED_ON_USAGE =
                 "time_remaining_estimate_based_on_usage";
 
@@ -12712,6 +13639,7 @@
          * @hide
          */
         @Deprecated
+        @Readable
         public static final String AVERAGE_TIME_TO_DISCHARGE = "average_time_to_discharge";
 
         /**
@@ -12723,6 +13651,7 @@
          * @deprecated No longer needed due to {@link PowerManager#getBatteryDischargePrediction}.
          */
         @Deprecated
+        @Readable
         public static final String BATTERY_ESTIMATES_LAST_UPDATE_TIME =
                 "battery_estimates_last_update_time";
 
@@ -12732,12 +13661,14 @@
          *
          * @hide
          */
+        @Readable
         public static final String LOW_POWER_MODE_TRIGGER_LEVEL_MAX = "low_power_trigger_level_max";
 
         /**
          * See com.android.settingslib.fuelgauge.BatterySaverUtils.
          * @hide
          */
+        @Readable
         public static final String LOW_POWER_MODE_SUGGESTION_PARAMS =
                 "low_power_mode_suggestion_params";
 
@@ -12746,6 +13677,7 @@
          * processes as soon as they are no longer needed.  If 0, the normal
          * extended lifetime is used.
          */
+        @Readable
         public static final String ALWAYS_FINISH_ACTIVITIES = "always_finish_activities";
 
         /**
@@ -12755,6 +13687,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String HIDE_ERROR_DIALOGS = "hide_error_dialogs";
 
         /**
@@ -12763,6 +13696,7 @@
          *      1 = enabled
          * @hide
          */
+        @Readable
         public static final String DOCK_AUDIO_MEDIA_ENABLED = "dock_audio_media_enabled";
 
         /**
@@ -12822,6 +13756,7 @@
          * ENCODED_SURROUND_OUTPUT_MANUAL
          * @hide
          */
+        @Readable
         public static final String ENCODED_SURROUND_OUTPUT = "encoded_surround_output";
 
         /**
@@ -12833,6 +13768,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS =
                 "encoded_surround_output_enabled_formats";
 
@@ -12840,36 +13776,42 @@
          * Persisted safe headphone volume management state by AudioService
          * @hide
          */
+        @Readable
         public static final String AUDIO_SAFE_VOLUME_STATE = "audio_safe_volume_state";
 
         /**
          * URL for tzinfo (time zone) updates
          * @hide
          */
+        @Readable
         public static final String TZINFO_UPDATE_CONTENT_URL = "tzinfo_content_url";
 
         /**
          * URL for tzinfo (time zone) update metadata
          * @hide
          */
+        @Readable
         public static final String TZINFO_UPDATE_METADATA_URL = "tzinfo_metadata_url";
 
         /**
          * URL for selinux (mandatory access control) updates
          * @hide
          */
+        @Readable
         public static final String SELINUX_UPDATE_CONTENT_URL = "selinux_content_url";
 
         /**
          * URL for selinux (mandatory access control) update metadata
          * @hide
          */
+        @Readable
         public static final String SELINUX_UPDATE_METADATA_URL = "selinux_metadata_url";
 
         /**
          * URL for sms short code updates
          * @hide
          */
+        @Readable
         public static final String SMS_SHORT_CODES_UPDATE_CONTENT_URL =
                 "sms_short_codes_content_url";
 
@@ -12877,6 +13819,7 @@
          * URL for sms short code update metadata
          * @hide
          */
+        @Readable
         public static final String SMS_SHORT_CODES_UPDATE_METADATA_URL =
                 "sms_short_codes_metadata_url";
 
@@ -12884,30 +13827,35 @@
          * URL for apn_db updates
          * @hide
          */
+        @Readable
         public static final String APN_DB_UPDATE_CONTENT_URL = "apn_db_content_url";
 
         /**
          * URL for apn_db update metadata
          * @hide
          */
+        @Readable
         public static final String APN_DB_UPDATE_METADATA_URL = "apn_db_metadata_url";
 
         /**
          * URL for cert pinlist updates
          * @hide
          */
+        @Readable
         public static final String CERT_PIN_UPDATE_CONTENT_URL = "cert_pin_content_url";
 
         /**
          * URL for cert pinlist updates
          * @hide
          */
+        @Readable
         public static final String CERT_PIN_UPDATE_METADATA_URL = "cert_pin_metadata_url";
 
         /**
          * URL for intent firewall updates
          * @hide
          */
+        @Readable
         public static final String INTENT_FIREWALL_UPDATE_CONTENT_URL =
                 "intent_firewall_content_url";
 
@@ -12915,6 +13863,7 @@
          * URL for intent firewall update metadata
          * @hide
          */
+        @Readable
         public static final String INTENT_FIREWALL_UPDATE_METADATA_URL =
                 "intent_firewall_metadata_url";
 
@@ -12922,18 +13871,21 @@
          * URL for lang id model updates
          * @hide
          */
+        @Readable
         public static final String LANG_ID_UPDATE_CONTENT_URL = "lang_id_content_url";
 
         /**
          * URL for lang id model update metadata
          * @hide
          */
+        @Readable
         public static final String LANG_ID_UPDATE_METADATA_URL = "lang_id_metadata_url";
 
         /**
          * URL for smart selection model updates
          * @hide
          */
+        @Readable
         public static final String SMART_SELECTION_UPDATE_CONTENT_URL =
                 "smart_selection_content_url";
 
@@ -12941,6 +13893,7 @@
          * URL for smart selection model update metadata
          * @hide
          */
+        @Readable
         public static final String SMART_SELECTION_UPDATE_METADATA_URL =
                 "smart_selection_metadata_url";
 
@@ -12948,6 +13901,7 @@
          * URL for conversation actions model updates
          * @hide
          */
+        @Readable
         public static final String CONVERSATION_ACTIONS_UPDATE_CONTENT_URL =
                 "conversation_actions_content_url";
 
@@ -12955,6 +13909,7 @@
          * URL for conversation actions model update metadata
          * @hide
          */
+        @Readable
         public static final String CONVERSATION_ACTIONS_UPDATE_METADATA_URL =
                 "conversation_actions_metadata_url";
 
@@ -12962,12 +13917,14 @@
          * SELinux enforcement status. If 0, permissive; if 1, enforcing.
          * @hide
          */
+        @Readable
         public static final String SELINUX_STATUS = "selinux_status";
 
         /**
          * Developer setting to force RTL layout.
          * @hide
          */
+        @Readable
         public static final String DEVELOPMENT_FORCE_RTL = "debug.force_rtl";
 
         /**
@@ -12978,6 +13935,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String LOW_BATTERY_SOUND_TIMEOUT = "low_battery_sound_timeout";
 
         /**
@@ -12987,6 +13945,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String WIFI_BOUNCE_DELAY_OVERRIDE_MS = "wifi_bounce_delay_override_ms";
 
         /**
@@ -12996,6 +13955,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String POLICY_CONTROL = "policy_control";
 
         /**
@@ -13003,6 +13963,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String EMULATE_DISPLAY_CUTOUT = "emulate_display_cutout";
 
         /** @hide */ public static final int EMULATE_DISPLAY_CUTOUT_OFF = 0;
@@ -13013,6 +13974,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BLOCKED_SLICES = "blocked_slices";
 
         /**
@@ -13022,6 +13984,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String ZEN_MODE = "zen_mode";
 
         /** @hide */
@@ -13061,6 +14024,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ZEN_MODE_RINGER_LEVEL = "zen_mode_ringer_level";
 
         /**
@@ -13069,6 +14033,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String ZEN_MODE_CONFIG_ETAG = "zen_mode_config_etag";
 
         /**
@@ -13098,6 +14063,7 @@
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        @Readable
         public static final String HEADS_UP_NOTIFICATIONS_ENABLED =
                 "heads_up_notifications_enabled";
 
@@ -13111,6 +14077,7 @@
         /**
          * The name of the device
          */
+        @Readable
         public static final String DEVICE_NAME = "device_name";
 
         /**
@@ -13119,6 +14086,7 @@
          * Type: int (0 for false, 1 for true)
          * @hide
          */
+        @Readable
         public static final String NETWORK_SCORING_PROVISIONED = "network_scoring_provisioned";
 
         /**
@@ -13130,6 +14098,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String REQUIRE_PASSWORD_TO_DECRYPT = "require_password_to_decrypt";
 
         /**
@@ -13143,6 +14112,7 @@
          * {@link android.provider.Telephony.SimInfo#COLUMN_ENHANCED_4G_MODE_ENABLED} instead.
          */
         @Deprecated
+        @Readable
         public static final String ENHANCED_4G_MODE_ENABLED =
                 Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED;
 
@@ -13155,6 +14125,7 @@
          * @deprecated Use {@link android.provider.Telephony.SimInfo#COLUMN_VT_IMS_ENABLED} instead.
          */
         @Deprecated
+        @Readable
         public static final String VT_IMS_ENABLED = Telephony.SimInfo.COLUMN_VT_IMS_ENABLED;
 
         /**
@@ -13167,6 +14138,7 @@
          * {@link android.provider.Telephony.SimInfo#COLUMN_WFC_IMS_ENABLED} instead.
          */
         @Deprecated
+        @Readable
         public static final String WFC_IMS_ENABLED = Telephony.SimInfo.COLUMN_WFC_IMS_ENABLED;
 
         /**
@@ -13178,6 +14150,7 @@
          * @deprecated Use {@link android.provider.Telephony.SimInfo#COLUMN_WFC_IMS_MODE} instead.
          */
         @Deprecated
+        @Readable
         public static final String WFC_IMS_MODE = Telephony.SimInfo.COLUMN_WFC_IMS_MODE;
 
         /**
@@ -13190,6 +14163,7 @@
          * instead.
          */
         @Deprecated
+        @Readable
         public static final String WFC_IMS_ROAMING_MODE =
                 Telephony.SimInfo.COLUMN_WFC_IMS_ROAMING_MODE;
 
@@ -13203,6 +14177,7 @@
          * instead
          */
         @Deprecated
+        @Readable
         public static final String WFC_IMS_ROAMING_ENABLED =
                 Telephony.SimInfo.COLUMN_WFC_IMS_ROAMING_ENABLED;
 
@@ -13213,6 +14188,7 @@
          * Type: int (0 for false, 1 for true)
          * @hide
          */
+        @Readable
         public static final String LTE_SERVICE_FORCED = "lte_service_forced";
 
 
@@ -13222,6 +14198,7 @@
          * See WindowManagerPolicy.WindowManagerFuncs
          * @hide
          */
+        @Readable
         public static final String LID_BEHAVIOR = "lid_behavior";
 
         /**
@@ -13230,6 +14207,7 @@
          * Type: int
          * @hide
          */
+        @Readable
         public static final String EPHEMERAL_COOKIE_MAX_SIZE_BYTES =
                 "ephemeral_cookie_max_size_bytes";
 
@@ -13241,6 +14219,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ENABLE_EPHEMERAL_FEATURE = "enable_ephemeral_feature";
 
         /**
@@ -13251,6 +14230,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String INSTANT_APP_DEXOPT_ENABLED = "instant_app_dexopt_enabled";
 
         /**
@@ -13259,6 +14239,7 @@
          * Type: long
          * @hide
          */
+        @Readable
         public static final String INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD =
                 "installed_instant_app_min_cache_period";
 
@@ -13268,6 +14249,7 @@
          * Type: long
          * @hide
          */
+        @Readable
         public static final String INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD =
                 "installed_instant_app_max_cache_period";
 
@@ -13277,6 +14259,7 @@
          * Type: long
          * @hide
          */
+        @Readable
         public static final String UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD =
                 "uninstalled_instant_app_min_cache_period";
 
@@ -13286,6 +14269,7 @@
          * Type: long
          * @hide
          */
+        @Readable
         public static final String UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD =
                 "uninstalled_instant_app_max_cache_period";
 
@@ -13295,6 +14279,7 @@
          * Type: long
          * @hide
          */
+        @Readable
         public static final String UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
                 "unused_static_shared_lib_min_cache_period";
 
@@ -13304,6 +14289,7 @@
          * Type: int
          * @hide
          */
+        @Readable
         public static final String ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED =
                 "allow_user_switching_when_system_user_locked";
 
@@ -13312,6 +14298,7 @@
          * <p>
          * Type: int
          */
+        @Readable
         public static final String BOOT_COUNT = "boot_count";
 
         /**
@@ -13322,6 +14309,7 @@
          * before the user restrictions are loaded.
          * @hide
          */
+        @Readable
         public static final String SAFE_BOOT_DISALLOWED = "safe_boot_disallowed";
 
         /**
@@ -13333,6 +14321,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String DEVICE_DEMO_MODE = "device_demo_mode";
 
         /**
@@ -13342,6 +14331,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String NETWORK_ACCESS_TIMEOUT_MS = "network_access_timeout_ms";
 
         /**
@@ -13352,6 +14342,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DATABASE_DOWNGRADE_REASON = "database_downgrade_reason";
 
         /**
@@ -13362,6 +14353,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String DATABASE_CREATION_BUILDID = "database_creation_buildid";
 
         /**
@@ -13370,6 +14362,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CONTACTS_DATABASE_WAL_ENABLED = "contacts_database_wal_enabled";
 
         /**
@@ -13377,6 +14370,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String LOCATION_SETTINGS_LINK_TO_PERMISSIONS_ENABLED =
                 "location_settings_link_to_permissions_enabled";
 
@@ -13387,6 +14381,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS =
                 "euicc_removing_invisible_profiles_timeout_millis";
 
@@ -13396,6 +14391,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String EUICC_FACTORY_RESET_TIMEOUT_MILLIS =
                 "euicc_factory_reset_timeout_millis";
 
@@ -13405,6 +14401,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String EUICC_SWITCH_SLOT_TIMEOUT_MILLIS =
                 "euicc_switch_slot_timeout_millis";
 
@@ -13414,6 +14411,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ENABLE_MULTI_SLOT_TIMEOUT_MILLIS =
                 "enable_multi_slot_timeout_millis";
 
@@ -13423,6 +14421,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String STORAGE_SETTINGS_CLOBBER_THRESHOLD =
                 "storage_settings_clobber_threshold";
 
@@ -13432,6 +14431,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String OVERRIDE_SETTINGS_PROVIDER_RESTORE_ANY_VERSION =
                 "override_settings_provider_restore_any_version";
         /**
@@ -13442,6 +14442,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String CHAINED_BATTERY_ATTRIBUTION_ENABLED =
                 "chained_battery_attribution_enabled";
 
@@ -13454,6 +14455,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ENABLE_ADB_INCREMENTAL_INSTALL_DEFAULT =
                 "enable_adb_incremental_install_default";
 
@@ -13471,6 +14473,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES =
                 "autofill_compat_mode_allowed_packages";
 
@@ -13484,6 +14487,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String AUTOFILL_LOGGING_LEVEL = "autofill_logging_level";
 
         /**
@@ -13491,6 +14495,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String AUTOFILL_MAX_PARTITIONS_SIZE = "autofill_max_partitions_size";
 
         /**
@@ -13499,6 +14504,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String AUTOFILL_MAX_VISIBLE_DATASETS = "autofill_max_visible_datasets";
 
         /**
@@ -13507,6 +14513,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String HIDDEN_API_BLACKLIST_EXEMPTIONS =
                 "hidden_api_blacklist_exemptions";
 
@@ -13519,14 +14526,16 @@
          * @hide
          */
         @TestApi
+        @Readable
         public static final String HIDDEN_API_POLICY = "hidden_api_policy";
 
-         /**
+        /**
          * Flag for forcing {@link com.android.server.compat.OverrideValidatorImpl}
          * to consider this a non-debuggable build.
          *
          * @hide
          */
+        @Readable
         public static final String FORCE_NON_DEBUGGABLE_FINAL_BUILD_FOR_COMPAT =
                 "force_non_debuggable_final_build_for_compat";
 
@@ -13536,6 +14545,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SIGNED_CONFIG_VERSION = "signed_config_version";
 
         /**
@@ -13544,6 +14554,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT =
                 "sound_trigger_detection_service_op_timeout";
 
@@ -13553,6 +14564,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY =
                 "max_sound_trigger_detection_service_ops_per_day";
 
@@ -13560,6 +14572,7 @@
          * Indicates whether aware is available in the current location.
          * @hide
          */
+        @Readable
         public static final String AWARE_ALLOWED = "aware_allowed";
 
         /**
@@ -13568,6 +14581,7 @@
          * Used by PhoneWindowManager.
          * @hide
          */
+        @Readable
         public static final String POWER_BUTTON_LONG_PRESS =
                 "power_button_long_press";
 
@@ -13577,6 +14591,7 @@
          * Used by PhoneWindowManager.
          * @hide
          */
+        @Readable
         public static final String POWER_BUTTON_VERY_LONG_PRESS =
                 "power_button_very_long_press";
 
@@ -13602,7 +14617,8 @@
                     CONTENT_URI,
                     CALL_METHOD_GET_GLOBAL,
                     CALL_METHOD_PUT_GLOBAL,
-                    sProviderHolder);
+                    sProviderHolder,
+                    Global.class);
 
         // Certain settings have been moved from global to the per-user secure namespace
         @UnsupportedAppUsage
@@ -13631,6 +14647,11 @@
             sNameValueCache.clearGenerationTrackerForTest();
         }
 
+        /** @hide */
+        public static void getPublicSettings(Set<String> allKeys, Set<String> readableKeys) {
+            getPublicSettingsForClass(Global.class, allKeys, readableKeys);
+        }
+
         /**
          * Look up a name in the database.
          * @param resolver to access the database with
@@ -14040,6 +15061,7 @@
           * Subscription Id to be used for voice call on a multi sim device.
           * @hide
           */
+        @Readable
         public static final String MULTI_SIM_VOICE_CALL_SUBSCRIPTION = "multi_sim_voice_call";
 
         /**
@@ -14048,18 +15070,21 @@
           * @hide
           */
         @UnsupportedAppUsage
+        @Readable
         public static final String MULTI_SIM_VOICE_PROMPT = "multi_sim_voice_prompt";
 
         /**
           * Subscription Id to be used for data call on a multi sim device.
           * @hide
           */
+        @Readable
         public static final String MULTI_SIM_DATA_CALL_SUBSCRIPTION = "multi_sim_data_call";
 
         /**
           * Subscription Id to be used for SMS on a multi sim device.
           * @hide
           */
+        @Readable
         public static final String MULTI_SIM_SMS_SUBSCRIPTION = "multi_sim_sms";
 
         /**
@@ -14067,6 +15092,7 @@
           * The value 1 - enable, 0 - disable
           * @hide
           */
+        @Readable
         public static final String MULTI_SIM_SMS_PROMPT = "multi_sim_sms_prompt";
 
         /** User preferred subscriptions setting.
@@ -14076,6 +15102,7 @@
           * @hide
          */
         @UnsupportedAppUsage
+        @Readable
         public static final String[] MULTI_SIM_USER_PREFERRED_SUBS = {"user_preferred_sub1",
                 "user_preferred_sub2","user_preferred_sub3"};
 
@@ -14083,6 +15110,7 @@
          * Which subscription is enabled for a physical slot.
          * @hide
          */
+        @Readable
         public static final String ENABLED_SUBSCRIPTION_FOR_SLOT = "enabled_subscription_for_slot";
 
         /**
@@ -14090,6 +15118,7 @@
          * The value 1 - enable, 0 - disable
          * @hide
          */
+        @Readable
         public static final String MODEM_STACK_ENABLED_FOR_SLOT = "modem_stack_enabled_for_slot";
 
         /**
@@ -14097,6 +15126,7 @@
          * The value 1 - enable, 0 - disable
          * @hide
          */
+        @Readable
         public static final String NEW_CONTACT_AGGREGATOR = "new_contact_aggregator";
 
         /**
@@ -14106,12 +15136,14 @@
          * @removed
          */
         @Deprecated
+        @Readable
         public static final String CONTACT_METADATA_SYNC = "contact_metadata_sync";
 
         /**
          * Whether to enable contacts metadata syncing or not
          * The value 1 - enable, 0 - disable
          */
+        @Readable
         public static final String CONTACT_METADATA_SYNC_ENABLED = "contact_metadata_sync_enabled";
 
         /**
@@ -14119,6 +15151,7 @@
          * The value 1 - enable, 0 - disable
          * @hide
          */
+        @Readable
         public static final String ENABLE_CELLULAR_ON_BOOT = "enable_cellular_on_boot";
 
         /**
@@ -14127,6 +15160,7 @@
          * Should be a float, and includes updates only.
          * @hide
          */
+        @Readable
         public static final String MAX_NOTIFICATION_ENQUEUE_RATE = "max_notification_enqueue_rate";
 
         /**
@@ -14135,6 +15169,7 @@
          * The value 1 - enable, 0 - disable
          * @hide
          */
+        @Readable
         public static final String SHOW_NOTIFICATION_CHANNEL_WARNINGS =
                 "show_notification_channel_warnings";
 
@@ -14142,6 +15177,7 @@
          * Whether cell is enabled/disabled
          * @hide
          */
+        @Readable
         public static final String CELL_ON = "cell_on";
 
         /**
@@ -14170,30 +15206,35 @@
          * Whether to show the high temperature warning notification.
          * @hide
          */
+        @Readable
         public static final String SHOW_TEMPERATURE_WARNING = "show_temperature_warning";
 
         /**
          * Whether to show the usb high temperature alarm notification.
          * @hide
          */
+        @Readable
         public static final String SHOW_USB_TEMPERATURE_ALARM = "show_usb_temperature_alarm";
 
         /**
          * Temperature at which the high temperature warning notification should be shown.
          * @hide
          */
+        @Readable
         public static final String WARNING_TEMPERATURE = "warning_temperature";
 
         /**
          * Whether the diskstats logging task is enabled/disabled.
          * @hide
          */
+        @Readable
         public static final String ENABLE_DISKSTATS_LOGGING = "enable_diskstats_logging";
 
         /**
          * Whether the cache quota calculation task is enabled/disabled.
          * @hide
          */
+        @Readable
         public static final String ENABLE_CACHE_QUOTA_CALCULATION =
                 "enable_cache_quota_calculation";
 
@@ -14201,6 +15242,7 @@
          * Whether the Deletion Helper no threshold toggle is available.
          * @hide
          */
+        @Readable
         public static final String ENABLE_DELETION_HELPER_NO_THRESHOLD_TOGGLE =
                 "enable_deletion_helper_no_threshold_toggle";
 
@@ -14221,6 +15263,7 @@
          * Options will be used in order up to the maximum allowed by the UI.
          * @hide
          */
+        @Readable
         public static final String NOTIFICATION_SNOOZE_OPTIONS =
                 "notification_snooze_options";
 
@@ -14232,6 +15275,7 @@
          * The value 1 - enable, 0 - disable
          * @hide
          */
+        @Readable
         public static final String NOTIFICATION_FEEDBACK_ENABLED = "notification_feedback_enabled";
 
         /**
@@ -14243,6 +15287,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT =
                 "blocking_helper_dismiss_to_view_ratio";
 
@@ -14254,6 +15299,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BLOCKING_HELPER_STREAK_LIMIT = "blocking_helper_streak_limit";
 
         /**
@@ -14281,6 +15327,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String SQLITE_COMPATIBILITY_WAL_FLAGS =
                 "sqlite_compatibility_wal_flags";
 
@@ -14290,6 +15337,7 @@
          * 1 = yes
          * @hide
          */
+        @Readable
         public static final String ENABLE_GNSS_RAW_MEAS_FULL_TRACKING =
                 "enable_gnss_raw_meas_full_tracking";
 
@@ -14301,6 +15349,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String INSTALL_CARRIER_APP_NOTIFICATION_PERSISTENT =
                 "install_carrier_app_notification_persistent";
 
@@ -14312,6 +15361,7 @@
          * @hide
          */
         @SystemApi
+        @Readable
         public static final String INSTALL_CARRIER_APP_NOTIFICATION_SLEEP_MILLIS =
                 "install_carrier_app_notification_sleep_millis";
 
@@ -14321,6 +15371,7 @@
          * everything else is unspecified.
          * @hide
          */
+        @Readable
         public static final String ZRAM_ENABLED =
                 "zram_enabled";
 
@@ -14330,6 +15381,7 @@
          * "device_default" will let the system decide whether to enable the freezer or not
          * @hide
          */
+        @Readable
         public static final String CACHED_APPS_FREEZER_ENABLED = "cached_apps_freezer";
 
         /**
@@ -14352,6 +15404,7 @@
          * @see com.android.systemui.statusbar.policy.SmartReplyConstants
          * @hide
          */
+        @Readable
         public static final String SMART_REPLIES_IN_NOTIFICATIONS_FLAGS =
                 "smart_replies_in_notifications_flags";
 
@@ -14368,6 +15421,7 @@
          * </pre>
          * @hide
          */
+        @Readable
         public static final String SMART_SUGGESTIONS_IN_NOTIFICATIONS_FLAGS =
                 "smart_suggestions_in_notifications_flags";
 
@@ -14377,6 +15431,7 @@
          * @hide
          */
         @TestApi
+        @Readable
         @SuppressLint("NoSettingsProvider")
         public static final String SHOW_FIRST_CRASH_DIALOG = "show_first_crash_dialog";
 
@@ -14384,6 +15439,7 @@
          * If nonzero, crash dialogs will show an option to restart the app.
          * @hide
          */
+        @Readable
         public static final String SHOW_RESTART_IN_CRASH_DIALOG = "show_restart_in_crash_dialog";
 
         /**
@@ -14391,6 +15447,7 @@
          * this app.
          * @hide
          */
+        @Readable
         public static final String SHOW_MUTE_IN_CRASH_DIALOG = "show_mute_in_crash_dialog";
 
 
@@ -14446,6 +15503,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BACKUP_AGENT_TIMEOUT_PARAMETERS =
                 "backup_agent_timeout_parameters";
 
@@ -14460,6 +15518,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String GNSS_SATELLITE_BLOCKLIST = "gnss_satellite_blocklist";
 
         /**
@@ -14471,6 +15530,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String GNSS_HAL_LOCATION_REQUEST_DURATION_MILLIS =
                 "gnss_hal_location_request_duration_millis";
 
@@ -14487,6 +15547,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BINDER_CALLS_STATS = "binder_calls_stats";
 
         /**
@@ -14500,6 +15561,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String LOOPER_STATS = "looper_stats";
 
         /**
@@ -14514,6 +15576,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String KERNEL_CPU_THREAD_READER = "kernel_cpu_thread_reader";
 
         /**
@@ -14521,6 +15584,7 @@
          * reboot. The value "1" enables native flags health check; otherwise it's disabled.
          * @hide
          */
+        @Readable
         public static final String NATIVE_FLAGS_HEALTH_CHECK_ENABLED =
                 "native_flags_health_check_enabled";
 
@@ -14530,6 +15594,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String APPOP_HISTORY_MODE = "mode";
 
         /**
@@ -14539,6 +15604,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String APPOP_HISTORY_BASE_INTERVAL_MILLIS = "baseIntervalMillis";
 
         /**
@@ -14547,6 +15613,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String APPOP_HISTORY_INTERVAL_MULTIPLIER = "intervalMultiplier";
 
         /**
@@ -14568,6 +15635,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String APPOP_HISTORY_PARAMETERS =
                 "appop_history_parameters";
 
@@ -14585,6 +15653,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String AUTO_REVOKE_PARAMETERS =
                 "auto_revoke_parameters";
 
@@ -14596,6 +15665,7 @@
          * @see com.android.internal.os.BatteryStatsImpl.Constants.KEY_BATTERY_CHARGED_DELAY_MS
          * @hide
          */
+        @Readable
         public static final String BATTERY_CHARGING_STATE_UPDATE_DELAY =
                 "battery_charging_state_update_delay";
 
@@ -14604,6 +15674,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String TEXT_CLASSIFIER_ACTION_MODEL_PARAMS =
                 "text_classifier_action_model_params";
 
@@ -14617,6 +15688,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE =
                 "power_button_suppression_delay_after_gesture_wake";
 
@@ -14625,6 +15697,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String ADVANCED_BATTERY_USAGE_AMOUNT = "advanced_battery_usage_amount";
 
         /**
@@ -14639,6 +15712,7 @@
          * 2: always on - All 5G NSA tracking indications are on whether the screen is on or off.
          * @hide
          */
+        @Readable
         public static final String NR_NSA_TRACKING_SCREEN_OFF_MODE =
                 "nr_nsa_tracking_screen_off_mode";
 
@@ -14649,6 +15723,7 @@
          * 1: Enabled
          * @hide
          */
+        @Readable
         public static final String SHOW_PEOPLE_SPACE = "show_people_space";
 
         /**
@@ -14659,6 +15734,7 @@
          * 2: All conversations
          * @hide
          */
+        @Readable
         public static final String PEOPLE_SPACE_CONVERSATION_TYPE =
                 "people_space_conversation_type";
 
@@ -14669,6 +15745,7 @@
          * 1: Enabled
          * @hide
          */
+        @Readable
         public static final String SHOW_NEW_NOTIF_DISMISS = "show_new_notif_dismiss";
 
         /**
@@ -14683,6 +15760,7 @@
          * 1: Enabled (All apps will receive the new rules)
          * @hide
          */
+        @Readable
         public static final String BACKPORT_S_NOTIF_RULES = "backport_s_notif_rules";
 
         /**
@@ -14697,6 +15775,7 @@
          * <p>See {@link android.app.Notification.DevFlags} for more details.
          * @hide
          */
+        @Readable
         public static final String FULLY_CUSTOM_VIEW_NOTIF_DECORATION =
                 "fully_custom_view_notif_decoration";
 
@@ -14710,6 +15789,7 @@
          * <p>See {@link android.app.Notification.DevFlags} for more details.
          * @hide
          */
+        @Readable
         public static final String DECORATED_CUSTOM_VIEW_NOTIF_DECORATION =
                 "decorated_custom_view_notif_decoration";
 
@@ -14726,6 +15806,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BLOCK_UNTRUSTED_TOUCHES_MODE = "block_untrusted_touches";
 
         /**
@@ -14751,6 +15832,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH =
                 "maximum_obscuring_opacity_for_touch";
 
@@ -14763,6 +15845,7 @@
          * 1: enabled
          * @hide
          */
+        @Readable
         public static final String RESTRICTED_NETWORKING_MODE = "restricted_networking_mode";
     }
 
@@ -14784,7 +15867,8 @@
                 CALL_METHOD_PUT_CONFIG,
                 CALL_METHOD_LIST_CONFIG,
                 CALL_METHOD_SET_ALL_CONFIG,
-                sProviderHolder);
+                sProviderHolder,
+                Config.class);
 
         /**
          * Look up a name in the database.
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 56d98e7..acc77b5 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1675,7 +1675,8 @@
         requestLayout();
 
         // See comment for View.sForceLayoutWhenInsetsChanged
-        if (View.sForceLayoutWhenInsetsChanged && mView != null) {
+        if (View.sForceLayoutWhenInsetsChanged && mView != null
+                && mWindowAttributes.softInputMode == SOFT_INPUT_ADJUST_RESIZE) {
             forceLayout(mView);
         }
 
diff --git a/core/proto/android/content/package_item_info.proto b/core/proto/android/content/package_item_info.proto
index bb39ea8..5c6116a 100644
--- a/core/proto/android/content/package_item_info.proto
+++ b/core/proto/android/content/package_item_info.proto
@@ -114,4 +114,5 @@
         optional bool native_heap_zero_init = 21;
     }
     optional Detail detail = 17;
+    repeated string overlay_paths = 18;
 }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 827bf7b..cc7251a 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -5447,6 +5447,11 @@
     <permission android:name="android.permission.MANAGE_TOAST_RATE_LIMITING"
                 android:protectionLevel="signature" />
 
+    <!-- Allows managing the Game Mode
+     @hide Used internally. -->
+    <permission android:name="android.permission.MANAGE_GAME_MODE"
+                android:protectionLevel="signature" />
+
     <!-- Attribution for Geofencing service. -->
     <attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/>
     <!-- Attribution for Country Detector. -->
diff --git a/core/res/res/values/colors_device_defaults.xml b/core/res/res/values/colors_device_defaults.xml
index c8cccc4..f723426 100644
--- a/core/res/res/values/colors_device_defaults.xml
+++ b/core/res/res/values/colors_device_defaults.xml
@@ -48,6 +48,8 @@
     <color name="text_color_secondary_device_default_dark">@color/system_main_200</color>
     <color name="text_color_tertiary_device_default_light">@color/system_main_500</color>
     <color name="text_color_tertiary_device_default_dark">@color/system_main_400</color>
+    <color name="foreground_device_default_light">@color/text_color_primary_device_default_light</color>
+    <color name="foreground_device_default_dark">@color/text_color_primary_device_default_dark</color>
 
     <!-- Error color -->
     <color name="error_color_device_default_dark">@color/error_color_material_dark</color>
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index ee17f6f..ce4ee87 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -222,6 +222,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+        <item name="colorForeground">@color/foreground_device_default_dark</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_light</item>
     </style>
 
     <style name="Theme.DeviceDefault" parent="Theme.DeviceDefaultBase" />
@@ -236,6 +238,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+        <item name="colorForeground">@color/foreground_device_default_dark</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -267,6 +271,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+        <item name="colorForeground">@color/foreground_device_default_dark</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -300,6 +306,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+        <item name="colorForeground">@color/foreground_device_default_dark</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -332,6 +340,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+        <item name="colorForeground">@color/foreground_device_default_dark</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -381,6 +391,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+        <item name="colorForeground">@color/foreground_device_default_dark</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -405,6 +417,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+        <item name="colorForeground">@color/foreground_device_default_dark</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -435,6 +449,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+        <item name="colorForeground">@color/foreground_device_default_dark</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -466,6 +482,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+        <item name="colorForeground">@color/foreground_device_default_dark</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -513,6 +531,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+        <item name="colorForeground">@color/foreground_device_default_dark</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -545,6 +565,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+        <item name="colorForeground">@color/foreground_device_default_dark</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -575,6 +597,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+        <item name="colorForeground">@color/foreground_device_default_dark</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -607,6 +631,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+        <item name="colorForeground">@color/foreground_device_default_dark</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -638,6 +664,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+        <item name="colorForeground">@color/foreground_device_default_dark</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -669,6 +697,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+        <item name="colorForeground">@color/foreground_device_default_dark</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -700,6 +730,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -731,6 +763,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -766,6 +800,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+        <item name="colorForeground">@color/foreground_device_default_dark</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_light</item>
 
         <!-- Text styles -->
         <item name="textAppearanceButton">@style/TextAppearance.DeviceDefault.Widget.Button</item>
@@ -798,6 +834,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+        <item name="colorForeground">@color/foreground_device_default_dark</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -827,6 +865,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+        <item name="colorForeground">@color/foreground_device_default_dark</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1012,6 +1052,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
         <item name="colorPopupBackground">?attr/colorBackgroundFloating</item>
         <item name="panelColorBackground">?attr/colorBackgroundFloating</item>
     </style>
@@ -1027,6 +1069,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1057,6 +1101,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1088,6 +1134,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1121,6 +1169,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1153,6 +1203,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1204,6 +1256,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
@@ -1227,6 +1281,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1260,6 +1316,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1294,6 +1352,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1329,6 +1389,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
     </style>
 
     <!-- Variant of Theme.DeviceDefault.Dialog.NoActionBar that has a fixed size. -->
@@ -1346,6 +1408,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
     </style>
 
     <!-- DeviceDefault light theme for a window that will be displayed either full-screen on smaller
@@ -1362,6 +1426,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1397,6 +1463,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1430,6 +1498,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1462,6 +1532,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1493,6 +1565,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1524,6 +1598,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1553,6 +1629,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1672,6 +1750,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+        <item name="colorForeground">@color/foreground_device_default_dark</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1702,6 +1782,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="alertDialogTheme">@style/Theme.DeviceDefault.Light.Dialog.Alert</item>
@@ -1742,6 +1824,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1775,6 +1859,8 @@
         <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
         <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
         <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+        <item name="colorForeground">@color/foreground_device_default_light</item>
+        <item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
diff --git a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
index 45adf83..46dbe0f 100644
--- a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
+++ b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
@@ -90,12 +90,12 @@
     @SmallTest
     public void testMultipleCallsWithIdenticalParametersCacheReference() {
         Resources resources = mResourcesManager.getResources(
-                null, APP_ONE_RES_DIR, null, null, null, null, null,
+                null, APP_ONE_RES_DIR, null, null, null, null, null, null,
                 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
         assertNotNull(resources);
 
         Resources newResources = mResourcesManager.getResources(
-                null, APP_ONE_RES_DIR, null, null, null, null, null,
+                null, APP_ONE_RES_DIR, null, null, null, null, null, null,
                 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
         assertNotNull(newResources);
         assertSame(resources, newResources);
@@ -104,14 +104,14 @@
     @SmallTest
     public void testMultipleCallsWithDifferentParametersReturnDifferentReferences() {
         Resources resources = mResourcesManager.getResources(
-                null, APP_ONE_RES_DIR, null, null, null, null, null,
+                null, APP_ONE_RES_DIR, null, null, null, null, null, null,
                 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
         assertNotNull(resources);
 
         Configuration overrideConfig = new Configuration();
         overrideConfig.smallestScreenWidthDp = 200;
         Resources newResources = mResourcesManager.getResources(
-                null, APP_ONE_RES_DIR, null, null, null, null, overrideConfig,
+                null, APP_ONE_RES_DIR, null, null, null, null, null, overrideConfig,
                 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
         assertNotNull(newResources);
         assertNotSame(resources, newResources);
@@ -120,12 +120,12 @@
     @SmallTest
     public void testAddingASplitCreatesANewImpl() {
         Resources resources1 = mResourcesManager.getResources(
-                null, APP_ONE_RES_DIR, null, null, null, null, null,
+                null, APP_ONE_RES_DIR, null, null, null, null, null, null,
                 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
         assertNotNull(resources1);
 
         Resources resources2 = mResourcesManager.getResources(
-                null, APP_ONE_RES_DIR, new String[] { APP_ONE_RES_SPLIT_DIR }, null, null,
+                null, APP_ONE_RES_DIR, new String[] { APP_ONE_RES_SPLIT_DIR }, null, null, null,
                 null, null, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null,
                 null);
         assertNotNull(resources2);
@@ -137,12 +137,12 @@
     @SmallTest
     public void testUpdateConfigurationUpdatesAllAssetManagers() {
         Resources resources1 = mResourcesManager.getResources(
-                null, APP_ONE_RES_DIR, null, null, null, null, null,
+                null, APP_ONE_RES_DIR, null, null, null, null, null, null,
                 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
         assertNotNull(resources1);
 
         Resources resources2 = mResourcesManager.getResources(
-                null, APP_TWO_RES_DIR, null, null, null, null, null,
+                null, APP_TWO_RES_DIR, null, null, null, null, null, null,
                 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
         assertNotNull(resources2);
 
@@ -150,7 +150,7 @@
         final Configuration overrideConfig = new Configuration();
         overrideConfig.orientation = Configuration.ORIENTATION_LANDSCAPE;
         Resources resources3 = mResourcesManager.getResources(
-                activity, APP_ONE_RES_DIR, null, null, null, null,
+                activity, APP_ONE_RES_DIR, null, null, null, null, null,
                 overrideConfig, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
         assertNotNull(resources3);
 
@@ -183,13 +183,13 @@
     public void testTwoActivitiesWithIdenticalParametersShareImpl() {
         Binder activity1 = new Binder();
         Resources resources1 = mResourcesManager.getResources(
-                activity1, APP_ONE_RES_DIR, null, null, null, null, null,
+                activity1, APP_ONE_RES_DIR, null, null, null, null, null, null,
                 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
         assertNotNull(resources1);
 
         Binder activity2 = new Binder();
         Resources resources2 = mResourcesManager.getResources(
-                activity2, APP_ONE_RES_DIR, null, null, null, null, null,
+                activity2, APP_ONE_RES_DIR, null, null, null, null, null, null,
                 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
         assertNotNull(resources1);
 
@@ -204,7 +204,7 @@
     public void testThemesGetUpdatedWithNewImpl() {
         Binder activity1 = new Binder();
         Resources resources1 = mResourcesManager.createBaseTokenResources(
-                activity1, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
+                activity1, APP_ONE_RES_DIR, null, null, null, null, Display.DEFAULT_DISPLAY, null,
                 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
         assertNotNull(resources1);
 
@@ -237,15 +237,15 @@
         Configuration config1 = new Configuration();
         config1.densityDpi = 280;
         Resources resources1 = mResourcesManager.createBaseTokenResources(
-                activity1, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, config1,
-                CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
+                activity1, APP_ONE_RES_DIR, null, null, null, null, Display.DEFAULT_DISPLAY,
+                config1, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
         assertNotNull(resources1);
 
         // Create a Resources based on the Activity.
         Configuration config2 = new Configuration();
         config2.screenLayout |= Configuration.SCREENLAYOUT_ROUND_YES;
         Resources resources2 = mResourcesManager.getResources(
-                activity1, APP_ONE_RES_DIR, null, null, null, null, config2,
+                activity1, APP_ONE_RES_DIR, null, null, null, null, null, config2,
                 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
         assertNotNull(resources2);
 
@@ -286,8 +286,8 @@
         final Configuration overrideConfig = new Configuration();
         overrideConfig.densityDpi = originalOverrideDensity;
         final Resources resources = mResourcesManager.createBaseTokenResources(
-                token, APP_ONE_RES_DIR, null /* splitResDirs */, null /* overlayDirs */,
-                null /* libDirs */, Display.DEFAULT_DISPLAY, overrideConfig,
+                token, APP_ONE_RES_DIR, null /* splitResDirs */, null /* legacyOverlayDirs */,
+                null /* overlayDirs */,null /* libDirs */, Display.DEFAULT_DISPLAY, overrideConfig,
                 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null /* classLoader */,
                 null /* loaders */);
 
@@ -315,12 +315,12 @@
 
         // Create a base token resources that are based on the default display.
         Resources activityResources = mResourcesManager.createBaseTokenResources(
-                activity, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
+                activity, APP_ONE_RES_DIR, null, null, null,null, Display.DEFAULT_DISPLAY, null,
                 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
         // Create another resources that explicitly override the display of the base token above
         // and set it to DEFAULT_DISPLAY.
         Resources defaultDisplayResources = mResourcesManager.getResources(
-                activity, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
+                activity, APP_ONE_RES_DIR, null, null, null, null, Display.DEFAULT_DISPLAY, null,
                 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
 
         assertEquals(mDisplayMetricsMap.get(Display.DEFAULT_DISPLAY).widthPixels,
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index ca2ada9..b14ade9 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -54,7 +54,7 @@
 }
 
 static inline SkScalar isIntegerAligned(SkScalar x) {
-    return fabsf(roundf(x) - x) <= NON_ZERO_EPSILON;
+    return MathUtils::isZero(roundf(x) - x);
 }
 
 // Disable filtering when there is no scaling in screen coordinates and the corners have the same
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
index 34df5dd..471a7f7 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.cpp
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -34,7 +34,7 @@
 }
 
 static inline SkScalar isIntegerAligned(SkScalar x) {
-    return fabsf(roundf(x) - x) <= NON_ZERO_EPSILON;
+    return MathUtils::isZero(roundf(x) - x);
 }
 
 // Disable filtering when there is no scaling in screen coordinates and the corners have the same
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
index 3b8caeb..7cfccb5 100644
--- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
@@ -52,7 +52,7 @@
         RenderNodeDrawable* childNode = mChildren[drawIndex];
         SkASSERT(childNode);
         const float casterZ = childNode->getNodeProperties().getZ();
-        if (casterZ >= -NON_ZERO_EPSILON) {  // draw only children with negative Z
+        if (casterZ >= -MathUtils::NON_ZERO_EPSILON) {  // draw only children with negative Z
             return;
         }
         SkAutoCanvasRestore acr(canvas, true);
@@ -86,7 +86,7 @@
 
     const size_t endIndex = zChildren.size();
     while (drawIndex < endIndex  // draw only children with positive Z
-           && zChildren[drawIndex]->getNodeProperties().getZ() <= NON_ZERO_EPSILON)
+           && zChildren[drawIndex]->getNodeProperties().getZ() <= MathUtils::NON_ZERO_EPSILON)
         drawIndex++;
     size_t shadowIndex = drawIndex;
 
diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp
index 85924c5..d998e50 100644
--- a/libs/hwui/renderthread/CacheManager.cpp
+++ b/libs/hwui/renderthread/CacheManager.cpp
@@ -101,7 +101,8 @@
         return;
     }
 
-    mGrContext->flushAndSubmit();
+    // flush and submit all work to the gpu and wait for it to finish
+    mGrContext->flushAndSubmit(/*syncCpu=*/true);
 
     switch (mode) {
         case TrimMemoryMode::Complete:
@@ -119,11 +120,6 @@
             SkGraphics::SetFontCacheLimit(mMaxCpuFontCacheBytes);
             break;
     }
-
-    // We must sync the cpu to make sure deletions of resources still queued up on the GPU actually
-    // happen.
-    mGrContext->flush({});
-    mGrContext->submit(true);
 }
 
 void CacheManager::trimStaleResources() {
diff --git a/libs/hwui/utils/MathUtils.h b/libs/hwui/utils/MathUtils.h
index 62bf39c..1d3f9d7 100644
--- a/libs/hwui/utils/MathUtils.h
+++ b/libs/hwui/utils/MathUtils.h
@@ -22,11 +22,11 @@
 namespace android {
 namespace uirenderer {
 
-#define NON_ZERO_EPSILON (0.001f)
-#define ALPHA_EPSILON (0.001f)
-
 class MathUtils {
 public:
+    static constexpr float NON_ZERO_EPSILON = 0.001f;
+    static constexpr float ALPHA_EPSILON = 0.001f;
+
     /**
      * Check for floats that are close enough to zero.
      */
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index c7790fd..a1fd7ee 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -297,6 +297,24 @@
         Settings.System.getCloneFromParentOnValueSettings(sSystemCloneFromParentOnDependency);
     }
 
+    private static final Set<String> sAllSecureSettings = new ArraySet<>();
+    private static final Set<String> sReadableSecureSettings = new ArraySet<>();
+    static {
+        Settings.Secure.getPublicSettings(sAllSecureSettings, sReadableSecureSettings);
+    }
+
+    private static final Set<String> sAllSystemSettings = new ArraySet<>();
+    private static final Set<String> sReadableSystemSettings = new ArraySet<>();
+    static {
+        Settings.System.getPublicSettings(sAllSystemSettings, sReadableSystemSettings);
+    }
+
+    private static final Set<String> sAllGlobalSettings = new ArraySet<>();
+    private static final Set<String> sReadableGlobalSettings = new ArraySet<>();
+    static {
+        Settings.Global.getPublicSettings(sAllGlobalSettings, sReadableGlobalSettings);
+    }
+
     private final Object mLock = new Object();
 
     @GuardedBy("mLock")
@@ -1919,6 +1937,7 @@
         if (UserHandle.getAppId(Binder.getCallingUid()) < Process.FIRST_APPLICATION_UID) {
             return;
         }
+        checkReadableAnnotation(settingsType, settingName);
         ApplicationInfo ai = getCallingApplicationInfoOrThrow();
         if (!ai.isInstantApp()) {
             return;
@@ -1932,6 +1951,41 @@
         }
     }
 
+    /**
+     * Check if the target settings key is readable. Reject if the caller app is trying to access a
+     * settings key defined in the Settings.Secure, Settings.System or Settings.Global and is not
+     * annotated as @Readable.
+     * Notice that a key string that is not defined in any of the Settings.* classes will still be
+     * regarded as readable.
+     */
+    private void checkReadableAnnotation(int settingsType, String settingName) {
+        final Set<String> allFields;
+        final Set<String> readableFields;
+        switch (settingsType) {
+            case SETTINGS_TYPE_GLOBAL:
+                allFields = sAllGlobalSettings;
+                readableFields = sReadableGlobalSettings;
+                break;
+            case SETTINGS_TYPE_SYSTEM:
+                allFields = sAllSystemSettings;
+                readableFields = sReadableSystemSettings;
+                break;
+            case SETTINGS_TYPE_SECURE:
+                allFields = sAllSecureSettings;
+                readableFields = sReadableSecureSettings;
+                break;
+            default:
+                throw new IllegalArgumentException("Invalid settings type: " + settingsType);
+        }
+
+        if (allFields.contains(settingName) && !readableFields.contains(settingName)) {
+            throw new SecurityException(
+                    "Settings key: <" + settingName + "> is not readable. From S+, new public "
+                            + "settings keys need to be annotated with @Readable unless they are "
+                            + "annotated with @hide.");
+        }
+    }
+
     private ApplicationInfo getCallingApplicationInfoOrThrow() {
         // We always use the callingUid for this lookup. This means that if hypothetically an
         // app was installed in user A with cross user and in user B as an Instant App
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index 862076b..187ae58 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -43,14 +43,17 @@
             android:accessibilityLiveRegion="polite"/>
 
         <com.android.systemui.statusbar.phone.KeyguardIndicationTextView
-            android:id="@+id/keyguard_indication_enterprise_disclosure"
-            android:layout_width="match_parent"
+            android:id="@+id/keyguard_indication_text_bottom"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:gravity="center"
+            android:minHeight="48dp"
+            android:layout_gravity="center_horizontal"
+            android:layout_centerHorizontal="true"
             android:paddingStart="@dimen/keyguard_indication_text_padding"
             android:paddingEnd="@dimen/keyguard_indication_text_padding"
             android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"
-            android:alpha=".54"
+            android:alpha=".8"
             android:visibility="gone"/>
 
     </LinearLayout>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index afa98b5..5bb46a8 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -199,6 +199,9 @@
     <!-- The amount the content shifts upwards when transforming into the shelf -->
     <dimen name="shelf_transform_content_shift">32dp</dimen>
 
+    <!-- The y translation for keyguard indication text animation for rotating text in/out -->
+    <dimen name="keyguard_indication_y_translation">24dp</dimen>
+
     <!-- The padding on the bottom of the notifications on the keyguard -->
     <dimen name="keyguard_indication_bottom_padding">12sp</dimen>
 
@@ -1157,7 +1160,7 @@
     <dimen name="logout_button_layout_height">32dp</dimen>
     <dimen name="logout_button_padding_horizontal">16dp</dimen>
     <dimen name="logout_button_margin_bottom">12dp</dimen>
-    <dimen name="logout_button_corner_radius">2dp</dimen>
+    <dimen name="logout_button_corner_radius">4dp</dimen>
 
     <!--  Blur radius on status bar window and power menu  -->
     <dimen name="min_window_blur_radius">1px</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 589a39c..abcf4e8 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2253,6 +2253,12 @@
     <!-- Accessibility description indicating the currently selected tile's position. Only used for tiles that are currently in use [CHAR LIMIT=NONE] -->
     <string name="accessibility_qs_edit_position">Position <xliff:g id="position" example="5">%1$d</xliff:g></string>
 
+    <!-- Accessibility announcement after a tile has been added [CHAR LIMIT=NONE] -->
+    <string name="accessibility_qs_edit_tile_added">Tile added</string>
+
+    <!-- Accessibility announcement after a tile has been added [CHAR LIMIT=NONE] -->
+    <string name="accessibility_qs_edit_tile_removed">Tile removed</string>
+
     <!-- Accessibility label for window when QS editing is happening [CHAR LIMIT=NONE] -->
     <string name="accessibility_desc_quick_settings_edit">Quick settings editor.</string>
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 97aa26f..fea152a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -56,8 +56,10 @@
     private final IActivityManager mIActivityManager;
 
     private TextView mLogoutView;
+    private boolean mCanShowLogout = true; // by default, try to show the logout button here
     private KeyguardClockSwitch mClockView;
     private TextView mOwnerInfo;
+    private boolean mCanShowOwnerInfo = true; // by default, try to show the owner information here
     private KeyguardSliceView mKeyguardSlice;
     private View mNotificationIcons;
     private Runnable mPendingMarqueeStart;
@@ -114,6 +116,25 @@
         if (mOwnerInfo != null) mOwnerInfo.setSelected(enabled);
     }
 
+    void setCanShowOwnerInfo(boolean canShowOwnerInfo) {
+        mCanShowOwnerInfo = canShowOwnerInfo;
+        mOwnerInfo = findViewById(R.id.owner_info);
+        if (mOwnerInfo != null) {
+            if (mCanShowOwnerInfo) {
+                mOwnerInfo.setVisibility(VISIBLE);
+                updateOwnerInfo();
+            } else {
+                mOwnerInfo.setVisibility(GONE);
+                mOwnerInfo = null;
+            }
+        }
+    }
+
+    void setCanShowLogout(boolean canShowLogout) {
+        mCanShowLogout = canShowLogout;
+        updateLogoutView();
+    }
+
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
@@ -128,7 +149,10 @@
         if (KeyguardClockAccessibilityDelegate.isNeeded(mContext)) {
             mClockView.setAccessibilityDelegate(new KeyguardClockAccessibilityDelegate(mContext));
         }
-        mOwnerInfo = findViewById(R.id.owner_info);
+        if (mCanShowOwnerInfo) {
+            mOwnerInfo = findViewById(R.id.owner_info);
+        }
+
         mKeyguardSlice = findViewById(R.id.keyguard_status_area);
         mTextColor = mClockView.getCurrentTextColor();
 
@@ -189,7 +213,7 @@
         if (mLogoutView == null) {
             return;
         }
-        mLogoutView.setVisibility(shouldShowLogout() ? VISIBLE : GONE);
+        mLogoutView.setVisibility(mCanShowLogout && shouldShowLogout() ? VISIBLE : GONE);
         // Logout button will stay in language of user 0 if we don't set that manually.
         mLogoutView.setText(mContext.getResources().getString(
                 com.android.internal.R.string.global_action_logout));
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index 973b493..a5f364d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -134,7 +134,7 @@
     }
 
     /**
-     * Get the height of the logout button.
+     * Get the height of the owner information view.
      */
     public int getOwnerInfoHeight() {
         return mView.getOwnerInfoHeight();
@@ -335,9 +335,13 @@
                 // of the top of the view
                 mKeyguardSliceViewController.updateTopMargin(
                         mKeyguardClockSwitchController.getClockTextTopPadding());
+                mView.setCanShowOwnerInfo(false);
+                mView.setCanShowLogout(false);
             } else {
                 // reset margin
                 mKeyguardSliceViewController.updateTopMargin(0);
+                mView.setCanShowOwnerInfo(true);
+                mView.setCanShowLogout(false);
             }
             updateAodIcons();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java
new file mode 100644
index 0000000..3a06f7a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.res.ColorStateList;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+
+/**
+ * Data class containing display information (message, icon, styling) for indication to show at
+ * the bottom of the keyguard.
+ *
+ * See {@link com.android.systemui.statusbar.phone.KeyguardBottomAreaView}.
+ */
+public class KeyguardIndication {
+    @NonNull
+    private final CharSequence mMessage;
+    @NonNull
+    private final ColorStateList mTextColor;
+    @Nullable
+    private final Drawable mIcon;
+    @Nullable
+    private final View.OnClickListener mOnClickListener;
+    @Nullable
+    private final Drawable mBackground;
+
+    private KeyguardIndication(
+            CharSequence message,
+            ColorStateList textColor,
+            Drawable icon,
+            View.OnClickListener onClickListener,
+            Drawable background) {
+        mMessage = message;
+        mTextColor = textColor;
+        mIcon = icon;
+        mOnClickListener = onClickListener;
+        mBackground = background;
+    }
+
+    /**
+     * Message to display
+     */
+    public @NonNull CharSequence getMessage() {
+        return mMessage;
+    }
+
+    /**
+     * TextColor to display the message.
+     */
+    public @NonNull ColorStateList getTextColor() {
+        return mTextColor;
+    }
+
+    /**
+     * Icon to display.
+     */
+    public @Nullable Drawable getIcon() {
+        return mIcon;
+    }
+
+    /**
+     * Click listener for messsage.
+     */
+    public @Nullable View.OnClickListener getClickListener() {
+        return mOnClickListener;
+    }
+
+    /**
+     * Background for textView.
+     */
+    public @Nullable Drawable getBackground() {
+        return mBackground;
+    }
+
+    /**
+     * KeyguardIndication Builder
+     */
+    public static class Builder {
+        private CharSequence mMessage;
+        private Drawable mIcon;
+        private View.OnClickListener mOnClickListener;
+        private ColorStateList mTextColor;
+        private Drawable mBackground;
+
+        public Builder() { }
+
+        /**
+         * Required field. Message to display.
+         */
+        public Builder setMessage(@NonNull CharSequence message) {
+            this.mMessage = message;
+            return this;
+        }
+
+        /**
+         * Required field. Text color to use to display the message.
+         */
+        public Builder setTextColor(@NonNull ColorStateList textColor) {
+            this.mTextColor = textColor;
+            return this;
+        }
+
+        /**
+         * Optional. Icon to show next to the text. Icon location changes based on language
+         * display direction. For LTR, icon shows to the left of the message. For RTL, icon shows
+         * to the right of the message.
+         */
+        public Builder setIcon(Drawable icon) {
+            this.mIcon = icon;
+            return this;
+        }
+
+        /**
+         * Optional. Set a click listener on the message.
+         */
+        public Builder setClickListener(View.OnClickListener onClickListener) {
+            this.mOnClickListener = onClickListener;
+            return this;
+        }
+
+        /**
+         * Optional. Set a custom background on the TextView.
+         */
+        public Builder setBackground(Drawable background) {
+            this.mBackground = background;
+            return this;
+        }
+
+        /**
+         * Build the KeyguardIndication.
+         */
+        public KeyguardIndication build() {
+            if (mMessage == null) throw new IllegalStateException("message must be set");
+            if (mTextColor == null) throw new IllegalStateException("text color must be set");
+            return new KeyguardIndication(
+                    mMessage, mTextColor, mIcon, mOnClickListener, mBackground);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
new file mode 100644
index 0000000..d0070d8d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard;
+
+import android.annotation.Nullable;
+import android.content.res.ColorStateList;
+import android.graphics.Color;
+import android.text.TextUtils;
+import android.view.View;
+
+import androidx.annotation.IntDef;
+
+import com.android.settingslib.Utils;
+import com.android.systemui.Dumpable;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
+import com.android.systemui.util.ViewController;
+import com.android.systemui.util.concurrency.DelayableExecutor;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Rotates through messages to show on the keyguard bottom area on the lock screen
+ * NOTE: This controller should not be used on AoD to avoid waking up the AP too often.
+ */
+public class KeyguardIndicationRotateTextViewController extends
+        ViewController<KeyguardIndicationTextView> implements Dumpable {
+    public static String TAG = "KgIndicationRotatingCtrl";
+    private static final long DEFAULT_INDICATION_SHOW_LENGTH = 3500; // milliseconds
+
+    private final StatusBarStateController mStatusBarStateController;
+    private final float mMaxAlpha;
+    private final ColorStateList mInitialTextColorState;
+
+    // Stores @IndicationType => KeyguardIndication messages
+    private final Map<Integer, KeyguardIndication> mIndicationMessages = new HashMap<>();
+
+    // Executor that will show the next message after a delay
+    private final DelayableExecutor mExecutor;
+    @Nullable private ShowNextIndication mShowNextIndicationRunnable;
+
+    // List of indication types to show. The next indication to show is always at index 0
+    private final List<Integer> mIndicationQueue = new LinkedList<>();
+    private @IndicationType int mCurrIndicationType = INDICATION_TYPE_NONE;
+
+    private boolean mIsDozing;
+
+    public KeyguardIndicationRotateTextViewController(
+            KeyguardIndicationTextView view,
+            @Main DelayableExecutor executor,
+            StatusBarStateController statusBarStateController,
+            int lockScreenMode
+    ) {
+        super(view);
+        mMaxAlpha = view.getAlpha();
+        mExecutor = executor;
+        mInitialTextColorState = mView != null
+                ? mView.getTextColors() : ColorStateList.valueOf(Color.WHITE);
+        mStatusBarStateController = statusBarStateController;
+        mView.setLockScreenMode(lockScreenMode);
+        init();
+    }
+
+    @Override
+    protected void onViewAttached() {
+        mStatusBarStateController.addCallback(mStatusBarStateListener);
+    }
+
+    @Override
+    protected void onViewDetached() {
+        mStatusBarStateController.removeCallback(mStatusBarStateListener);
+        cancelScheduledIndication();
+    }
+
+    /**
+     * Update the indication type with the given String.
+     * @param type of indication
+     * @param newIndication message to associate with this indication type
+     * @param showImmediately if true: shows this indication message immediately. Else, the text
+     *                        associated with this type is updated and will show when its turn in
+     *                        the IndicationQueue comes around.
+     */
+    public void updateIndication(@IndicationType int type, KeyguardIndication newIndication,
+            boolean showImmediately) {
+        final boolean hasPreviousIndication = mIndicationMessages.get(type) != null;
+        final boolean hasNewIndication = newIndication != null
+                && !TextUtils.isEmpty(newIndication.getMessage());
+        if (!hasNewIndication) {
+            mIndicationMessages.remove(type);
+            mIndicationQueue.removeIf(x -> x == type);
+        } else {
+            if (!hasPreviousIndication) {
+                mIndicationQueue.add(type);
+            }
+
+            mIndicationMessages.put(type, newIndication);
+        }
+
+        if (mIsDozing) {
+            return;
+        }
+
+        final boolean showNow = showImmediately
+                || mCurrIndicationType == INDICATION_TYPE_NONE
+                || mCurrIndicationType == type;
+        if (hasNewIndication) {
+            if (showNow) {
+                showIndication(type);
+            } else if (!isNextIndicationScheduled()) {
+                scheduleShowNextIndication();
+            }
+            return;
+        }
+
+        if (mCurrIndicationType == type
+                && !hasNewIndication
+                && showImmediately) {
+            if (mShowNextIndicationRunnable != null) {
+                mShowNextIndicationRunnable.runImmediately();
+            } else {
+                showIndication(INDICATION_TYPE_NONE);
+            }
+        }
+    }
+
+    /**
+     * Stop showing the following indication type.
+     *
+     * If the current indication is of this type, immediately stops showing the message.
+     */
+    public void hideIndication(@IndicationType int type) {
+        updateIndication(type, null, true);
+    }
+
+    /**
+     * Show a transient message.
+     * Transient messages:
+     * - show immediately
+     * - will continue to be in the rotation of messages shown until hideTransient is called.
+     * - can be presented with an "error" color if isError is true
+     */
+    public void showTransient(CharSequence newIndication, boolean isError) {
+        updateIndication(INDICATION_TYPE_TRANSIENT,
+                new KeyguardIndication.Builder()
+                        .setMessage(newIndication)
+                        .setTextColor(isError
+                                ? Utils.getColorError(getContext())
+                                : mInitialTextColorState)
+                        .build(),
+                /* showImmediately */true);
+    }
+
+    /**
+     * Hide a transient message immediately.
+     */
+    public void hideTransient() {
+        hideIndication(INDICATION_TYPE_TRANSIENT);
+    }
+
+    /**
+     * @return true if there are available indications to show
+     */
+    public boolean hasIndications() {
+        return mIndicationMessages.keySet().size() > 0;
+    }
+
+    /**
+     * Immediately show the passed indication type and schedule the next indication to show.
+     * Will re-add this indication to be re-shown after all other indications have been
+     * rotated through.
+     */
+    private void showIndication(@IndicationType int type) {
+        cancelScheduledIndication();
+
+        mCurrIndicationType = type;
+        mIndicationQueue.removeIf(x -> x == type);
+        if (mCurrIndicationType == INDICATION_TYPE_NONE) {
+            mView.setVisibility(View.GONE);
+        } else {
+            mView.setVisibility(View.VISIBLE);
+            mIndicationQueue.add(type); // re-add to show later
+        }
+
+        // pass the style update to be run right before our new indication is shown:
+        mView.switchIndication(mIndicationMessages.get(type));
+
+        // only schedule next indication if there's more than just this indication in the queue
+        if (mCurrIndicationType != INDICATION_TYPE_NONE && mIndicationQueue.size() > 1) {
+            scheduleShowNextIndication();
+        }
+    }
+
+    protected boolean isNextIndicationScheduled() {
+        return mShowNextIndicationRunnable != null;
+    }
+
+    private void scheduleShowNextIndication() {
+        cancelScheduledIndication();
+        mShowNextIndicationRunnable = new ShowNextIndication(DEFAULT_INDICATION_SHOW_LENGTH);
+    }
+
+    private void cancelScheduledIndication() {
+        if (mShowNextIndicationRunnable != null) {
+            mShowNextIndicationRunnable.cancelDelayedExecution();
+            mShowNextIndicationRunnable = null;
+        }
+    }
+
+    private StatusBarStateController.StateListener mStatusBarStateListener =
+            new StatusBarStateController.StateListener() {
+                @Override
+                public void onDozeAmountChanged(float linear, float eased) {
+                    mView.setAlpha((1 - linear) * mMaxAlpha);
+                }
+
+                @Override
+                public void onDozingChanged(boolean isDozing) {
+                    if (isDozing == mIsDozing) return;
+                    mIsDozing = isDozing;
+                    if (mIsDozing) {
+                        showIndication(INDICATION_TYPE_NONE);
+                    } else if (mIndicationQueue.size() > 0) {
+                        showIndication(mIndicationQueue.remove(0));
+                    }
+                }
+            };
+
+    /**
+     * Shows the next indication in the IndicationQueue after an optional delay.
+     * This wrapper has the ability to cancel itself (remove runnable from DelayableExecutor) or
+     * immediately run itself (which also removes itself from the DelayableExecutor).
+     */
+    class ShowNextIndication {
+        private final Runnable mShowIndicationRunnable;
+        private Runnable mCancelDelayedRunnable;
+
+        ShowNextIndication(long delay) {
+            mShowIndicationRunnable = () -> {
+                int type = mIndicationQueue.size() == 0
+                        ? INDICATION_TYPE_NONE : mIndicationQueue.remove(0);
+                showIndication(type);
+            };
+            mCancelDelayedRunnable = mExecutor.executeDelayed(mShowIndicationRunnable, delay);
+        }
+
+        public void runImmediately() {
+            cancelDelayedExecution();
+            mShowIndicationRunnable.run();
+        }
+
+        public void cancelDelayedExecution() {
+            if (mCancelDelayedRunnable != null) {
+                mCancelDelayedRunnable.run();
+                mCancelDelayedRunnable = null;
+            }
+        }
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("KeyguardIndicationRotatingTextViewController:");
+        pw.println("    currentMessage=" + mView.getText());
+        pw.println("    dozing:" + mIsDozing);
+        pw.println("    queue:" + mIndicationQueue.toString());
+        pw.println("    showNextIndicationRunnable:" + mShowNextIndicationRunnable);
+
+        if (hasIndications()) {
+            pw.println("    All messages:");
+            for (int type : mIndicationMessages.keySet()) {
+                pw.println("        type=" + type + " message=" + mIndicationMessages.get(type));
+            }
+        }
+    }
+
+    private static final int INDICATION_TYPE_NONE = -1;
+    public static final int INDICATION_TYPE_OWNER_INFO = 0;
+    public static final int INDICATION_TYPE_DISCLOSURE = 1;
+    public static final int INDICATION_TYPE_LOGOUT = 2;
+    public static final int INDICATION_TYPE_BATTERY = 3;
+    public static final int INDICATION_TYPE_ALIGNMENT = 4;
+    public static final int INDICATION_TYPE_TRANSIENT = 5;
+    public static final int INDICATION_TYPE_TRUST = 6;
+    public static final int INDICATION_TYPE_RESTING = 7;
+    public static final int INDICATION_TYPE_USER_LOCKED = 8;
+    public static final int INDICATION_TYPE_NOW_PLAYING = 9;
+    public static final int INDICATION_TYPE_REVERSE_CHARGING = 10;
+
+    @IntDef({
+            INDICATION_TYPE_NONE,
+            INDICATION_TYPE_DISCLOSURE,
+            INDICATION_TYPE_OWNER_INFO,
+            INDICATION_TYPE_LOGOUT,
+            INDICATION_TYPE_BATTERY,
+            INDICATION_TYPE_ALIGNMENT,
+            INDICATION_TYPE_TRANSIENT,
+            INDICATION_TYPE_TRUST,
+            INDICATION_TYPE_RESTING,
+            INDICATION_TYPE_USER_LOCKED,
+            INDICATION_TYPE_NOW_PLAYING,
+            INDICATION_TYPE_REVERSE_CHARGING,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface IndicationType{}
+}
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
index 3f79be8..680a617 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
@@ -41,13 +41,12 @@
  * @param context A context to create the dialog
  * @param list list of elements to show in the dialog. The elements will show in the same order they
  *             appear in the list
- * @param activityStarter a callback to start an activity for a given permission group name (as
- *                        given by [PrivacyType.permGroupName])
+ * @param activityStarter a callback to start an activity for a given package name and user id
  */
 class PrivacyDialog(
     context: Context,
     private val list: List<PrivacyElement>,
-    activityStarter: (String) -> Unit
+    activityStarter: (String, Int) -> Unit
 ) : SystemUIDialog(context, R.style.ScreenRecord) {
 
     private val dismissListeners = mutableListOf<WeakReference<OnDialogDismissed>>()
@@ -129,7 +128,7 @@
         } ?: firstLine
         newView.requireViewById<TextView>(R.id.text).text = finalText
         newView.apply {
-            tag = element.type.permGroupName
+            setTag(element)
             setOnClickListener(clickListener)
         }
         return newView
@@ -152,12 +151,17 @@
     }
 
     private val clickListener = View.OnClickListener { v ->
-        v.tag?.let { activityStarter(it as String) }
+        v.tag?.let {
+            val element = it as PrivacyElement
+            activityStarter(element.packageName, element.userId)
+        }
     }
 
     /** */
     data class PrivacyElement(
         val type: PrivacyType,
+        val packageName: String,
+        val userId: Int,
         val applicationName: CharSequence,
         val attribution: CharSequence?,
         val lastActiveTimestamp: Long,
@@ -169,6 +173,8 @@
 
         init {
             builder.append("type=${type.logName}")
+            builder.append(", packageName=$packageName")
+            builder.append(", userId=$userId")
             builder.append(", appName=$applicationName")
             if (attribution != null) {
                 builder.append(", attribution=$attribution")
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogController.kt
index 8b6c04f..03c1843 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogController.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogController.kt
@@ -43,7 +43,7 @@
     override fun makeDialog(
         context: Context,
         list: List<PrivacyDialog.PrivacyElement>,
-        starter: (String) -> Unit
+        starter: (String, Int) -> Unit
     ): PrivacyDialog {
         return PrivacyDialog(context, list, starter)
     }
@@ -107,10 +107,11 @@
     }
 
     @MainThread
-    private fun startActivity(permGroupName: String) {
-        val intent = Intent(Intent.ACTION_MANAGE_PERMISSION_APPS)
-        intent.putExtra(Intent.EXTRA_PERMISSION_GROUP_NAME, permGroupName)
-        privacyLogger.logStartSettingsActivityFromDialog(permGroupName)
+    private fun startActivity(packageName: String, userId: Int) {
+        val intent = Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS)
+        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName)
+        intent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
+        privacyLogger.logStartSettingsActivityFromDialog(packageName, userId)
         if (!keyguardStateController.isUnlocked) {
             // If we are locked, hide the dialog so the user can unlock
             dialog?.hide()
@@ -159,6 +160,8 @@
                         }
                         PrivacyDialog.PrivacyElement(
                                 t,
+                                it.packageName,
+                                UserHandle.getUserId(it.uid),
                                 appName,
                                 it.attribution,
                                 it.lastAccess,
@@ -257,7 +260,7 @@
         fun makeDialog(
             context: Context,
             list: List<PrivacyDialog.PrivacyElement>,
-            starter: (String) -> Unit
+            starter: (String, Int) -> Unit
         ): PrivacyDialog
     }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/logging/PrivacyLogger.kt b/packages/SystemUI/src/com/android/systemui/privacy/logging/PrivacyLogger.kt
index 8059475..ebf6ae9 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/logging/PrivacyLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/logging/PrivacyLogger.kt
@@ -121,11 +121,12 @@
         })
     }
 
-    fun logStartSettingsActivityFromDialog(permGroupName: String) {
+    fun logStartSettingsActivityFromDialog(packageName: String, userId: Int) {
         log(LogLevel.INFO, {
-            str1 = permGroupName
+            str1 = packageName
+            int1 = userId
         }, {
-            "Start settings activity from dialog for perm group: $str1"
+            "Start settings activity from dialog for packageName=$str1, userId=$int1 "
         })
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index 507048c..21464fd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -441,15 +441,17 @@
         return position > mEditIndex;
     }
 
-    private void addFromPosition(int position) {
-        if (!canAddFromPosition(position)) return;
+    private boolean addFromPosition(int position) {
+        if (!canAddFromPosition(position)) return false;
         move(position, mEditIndex);
+        return true;
     }
 
-    private void removeFromPosition(int position) {
-        if (!canRemoveFromPosition(position)) return;
+    private boolean removeFromPosition(int position) {
+        if (!canRemoveFromPosition(position)) return false;
         TileInfo info = mTiles.get(position);
         move(position, info.isSystem ? mEditIndex : mTileDividerIndex);
+        return true;
     }
 
     public SpanSizeLookup getSizeLookup() {
@@ -578,11 +580,17 @@
         }
 
         private void add() {
-            addFromPosition(getLayoutPosition());
+            if (addFromPosition(getLayoutPosition())) {
+                itemView.announceForAccessibility(
+                        itemView.getContext().getText(R.string.accessibility_qs_edit_tile_added));
+            }
         }
 
         private void remove() {
-            removeFromPosition(getLayoutPosition());
+            if (removeFromPosition(getLayoutPosition())) {
+                itemView.announceForAccessibility(
+                        itemView.getContext().getText(R.string.accessibility_qs_edit_tile_removed));
+            }
         }
 
         boolean isCurrentTile() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index c816784..c70a93b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -16,10 +16,24 @@
 
 package com.android.systemui.statusbar;
 
+import static android.view.View.GONE;
+import static android.view.View.VISIBLE;
+
+import static com.android.keyguard.KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1;
 import static com.android.systemui.DejankUtils.whitelistIpcs;
+import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_ALIGNMENT;
+import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY;
+import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_DISCLOSURE;
+import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_LOGOUT;
+import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_OWNER_INFO;
+import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_RESTING;
+import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_TRUST;
+import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_USER_LOCKED;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
+import android.app.ActivityManager;
+import android.app.IActivityManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -47,6 +61,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IBatteryStats;
+import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.widget.ViewClippingUtil;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
@@ -56,13 +71,16 @@
 import com.android.systemui.R;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dock.DockManager;
+import com.android.systemui.keyguard.KeyguardIndication;
+import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
 import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
 import com.android.systemui.statusbar.phone.LockscreenLockIconController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.concurrency.DelayableExecutor;
 import com.android.systemui.util.wakelock.SettableWakeLock;
 import com.android.systemui.util.wakelock.WakeLock;
 
@@ -76,8 +94,7 @@
  * Controls the indications and error messages shown on the Keyguard
  */
 @SysUISingleton
-public class KeyguardIndicationController implements StateListener,
-        KeyguardStateController.Callback {
+public class KeyguardIndicationController implements KeyguardStateController.Callback {
 
     private static final String TAG = "KeyguardIndication";
     private static final boolean DEBUG_CHARGING_SPEED = false;
@@ -94,14 +111,17 @@
     private final StatusBarStateController mStatusBarStateController;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private ViewGroup mIndicationArea;
-    private KeyguardIndicationTextView mTextView;
-    private KeyguardIndicationTextView mDisclosure;
+    private KeyguardIndicationTextView mTopIndicationView;
     private final IBatteryStats mBatteryInfo;
     private final SettableWakeLock mWakeLock;
     private final DockManager mDockManager;
     private final DevicePolicyManager mDevicePolicyManager;
     private final UserManager mUserManager;
+    private final @Main DelayableExecutor mExecutor;
+    private final LockPatternUtils mLockPatternUtils;
+    private final IActivityManager mIActivityManager;
 
+    protected KeyguardIndicationRotateTextViewController mRotateTextViewController;
     private BroadcastReceiver mBroadcastReceiver;
     private LockscreenLockIconController mLockIconController;
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@@ -110,7 +130,7 @@
     private String mAlignmentIndication;
     private CharSequence mTransientIndication;
     private boolean mTransientTextIsError;
-    private ColorStateList mInitialTextColorState;
+    protected ColorStateList mInitialTextColorState;
     private boolean mVisible;
     private boolean mHideTransientMessageOnScreenOff;
 
@@ -124,8 +144,8 @@
     private int mBatteryLevel;
     private boolean mBatteryPresent = true;
     private long mChargingTimeRemaining;
-    private float mDisclosureMaxAlpha;
     private String mMessageToShowOnScreenOn;
+    protected int mLockScreenMode;
 
     private KeyguardUpdateMonitorCallback mUpdateMonitorCallback;
 
@@ -151,7 +171,8 @@
             BroadcastDispatcher broadcastDispatcher,
             DevicePolicyManager devicePolicyManager,
             IBatteryStats iBatteryStats,
-            UserManager userManager) {
+            UserManager userManager,
+            @Main DelayableExecutor executor) {
         mContext = context;
         mBroadcastDispatcher = broadcastDispatcher;
         mDevicePolicyManager = devicePolicyManager;
@@ -165,23 +186,29 @@
                 wakeLockBuilder.setTag("Doze:KeyguardIndication").build(), TAG);
         mBatteryInfo = iBatteryStats;
         mUserManager = userManager;
+        mExecutor = executor;
+        mLockPatternUtils = new LockPatternUtils(context);
+        mIActivityManager = ActivityManager.getService();
 
         mKeyguardUpdateMonitor.registerCallback(getKeyguardCallback());
         mKeyguardUpdateMonitor.registerCallback(mTickReceiver);
-        mStatusBarStateController.addCallback(this);
+        mStatusBarStateController.addCallback(mStatusBarStateListener);
         mKeyguardStateController.addCallback(this);
     }
 
     public void setIndicationArea(ViewGroup indicationArea) {
         mIndicationArea = indicationArea;
-        mTextView = indicationArea.findViewById(R.id.keyguard_indication_text);
-        mInitialTextColorState = mTextView != null ?
-                mTextView.getTextColors() : ColorStateList.valueOf(Color.WHITE);
-        mDisclosure = indicationArea.findViewById(R.id.keyguard_indication_enterprise_disclosure);
-        mDisclosureMaxAlpha = mDisclosure.getAlpha();
+        mTopIndicationView = indicationArea.findViewById(R.id.keyguard_indication_text);
+        mInitialTextColorState = mTopIndicationView != null
+                ? mTopIndicationView.getTextColors() : ColorStateList.valueOf(Color.WHITE);
+        mRotateTextViewController = new KeyguardIndicationRotateTextViewController(
+                indicationArea.findViewById(R.id.keyguard_indication_text_bottom),
+                mExecutor,
+                mStatusBarStateController,
+                mLockScreenMode);
         updateIndication(false /* animate */);
         updateDisclosure();
-
+        updateOwnerInfo();
         if (mBroadcastReceiver == null) {
             // Update the disclosure proactively to avoid IPC on the critical path.
             mBroadcastReceiver = new BroadcastReceiver() {
@@ -233,19 +260,196 @@
         return mUpdateMonitorCallback;
     }
 
+    /**
+     * Doesn't include owner information or disclosure which get triggered separately.
+     */
+    private void updateIndications(boolean animate, int userId) {
+        updateBattery(animate);
+        updateUserLocked(userId);
+        updateTransient();
+        updateTrust(userId, getTrustGrantedIndication(), getTrustManagedIndication());
+        updateAlignment();
+        updateResting();
+    }
+
     private void updateDisclosure() {
-        // NOTE: Because this uses IPC, avoid calling updateDisclosure() on a critical path.
         if (whitelistIpcs(this::isOrganizationOwnedDevice)) {
-            CharSequence organizationName = getOrganizationOwnedDeviceOrganizationName();
-            if (organizationName != null) {
-                mDisclosure.switchIndication(mContext.getResources().getString(
-                        R.string.do_disclosure_with_name, organizationName));
-            } else {
-                mDisclosure.switchIndication(R.string.do_disclosure_generic);
-            }
-            mDisclosure.setVisibility(View.VISIBLE);
+            final CharSequence organizationName = getOrganizationOwnedDeviceOrganizationName();
+            final CharSequence disclosure =  organizationName != null
+                    ? mContext.getResources().getString(R.string.do_disclosure_with_name,
+                    organizationName)
+                    : mContext.getResources().getText(R.string.do_disclosure_generic);
+            mRotateTextViewController.updateIndication(
+                    INDICATION_TYPE_DISCLOSURE,
+                    new KeyguardIndication.Builder()
+                            .setMessage(disclosure)
+                            .setTextColor(mInitialTextColorState)
+                            .build(),
+                    /* updateImmediately */ false);
         } else {
-            mDisclosure.setVisibility(View.GONE);
+            mRotateTextViewController.hideIndication(INDICATION_TYPE_DISCLOSURE);
+        }
+
+        if (isKeyguardLayoutEnabled()) {
+            updateIndication(false); // resting indication may need to update
+        }
+    }
+
+    private void updateBattery(boolean animate) {
+        if (mPowerPluggedIn || mEnableBatteryDefender) {
+            String powerIndication = computePowerIndication();
+            if (DEBUG_CHARGING_SPEED) {
+                powerIndication += ",  " + (mChargingWattage / 1000) + " mW";
+            }
+
+            mRotateTextViewController.updateIndication(
+                    INDICATION_TYPE_BATTERY,
+                    new KeyguardIndication.Builder()
+                            .setMessage(powerIndication)
+                            .setTextColor(mInitialTextColorState)
+                            .build(),
+                    animate);
+        } else {
+            // don't show the charging information if device isn't plugged in
+            mRotateTextViewController.hideIndication(INDICATION_TYPE_BATTERY);
+        }
+    }
+
+    private void updateUserLocked(int userId) {
+        if (!mKeyguardUpdateMonitor.isUserUnlocked(userId)) {
+            mRotateTextViewController.updateIndication(
+                    INDICATION_TYPE_USER_LOCKED,
+                    new KeyguardIndication.Builder()
+                            .setMessage(mContext.getResources().getText(
+                                    com.android.internal.R.string.lockscreen_storage_locked))
+                            .setTextColor(mInitialTextColorState)
+                            .build(),
+                    false);
+        } else {
+            mRotateTextViewController.hideIndication(INDICATION_TYPE_USER_LOCKED);
+        }
+    }
+
+    private void updateTransient() {
+        if (!TextUtils.isEmpty(mTransientIndication)) {
+            mRotateTextViewController.showTransient(mTransientIndication,
+                    mTransientTextIsError);
+        } else {
+            mRotateTextViewController.hideTransient();
+        }
+    }
+
+    private void updateTrust(int userId, CharSequence trustGrantedIndication,
+            CharSequence trustManagedIndication) {
+        if (!TextUtils.isEmpty(trustGrantedIndication)
+                && mKeyguardUpdateMonitor.getUserHasTrust(userId)) {
+            mRotateTextViewController.updateIndication(
+                    INDICATION_TYPE_TRUST,
+                    new KeyguardIndication.Builder()
+                            .setMessage(trustGrantedIndication)
+                            .setTextColor(mInitialTextColorState)
+                            .build(),
+                    false);
+        } else if (!TextUtils.isEmpty(trustManagedIndication)
+                && mKeyguardUpdateMonitor.getUserTrustIsManaged(userId)
+                && !mKeyguardUpdateMonitor.getUserHasTrust(userId)) {
+            mRotateTextViewController.updateIndication(
+                    INDICATION_TYPE_TRUST,
+                    new KeyguardIndication.Builder()
+                            .setMessage(trustManagedIndication)
+                            .setTextColor(mInitialTextColorState)
+                            .build(),
+                    false);
+        } else {
+            mRotateTextViewController.hideIndication(INDICATION_TYPE_TRUST);
+        }
+    }
+
+    private void updateAlignment() {
+        if (!TextUtils.isEmpty(mAlignmentIndication)) {
+            mRotateTextViewController.updateIndication(
+                    INDICATION_TYPE_ALIGNMENT,
+                    new KeyguardIndication.Builder()
+                            .setMessage(mAlignmentIndication)
+                            .setTextColor(Utils.getColorError(mContext))
+                            .build(),
+                    true);
+        } else {
+            mRotateTextViewController.hideIndication(INDICATION_TYPE_ALIGNMENT);
+        }
+    }
+
+    private void updateResting() {
+        if (mRestingIndication != null
+                && !mRotateTextViewController.hasIndications()) {
+            mRotateTextViewController.updateIndication(
+                    INDICATION_TYPE_RESTING,
+                    new KeyguardIndication.Builder()
+                            .setMessage(mRestingIndication)
+                            .setTextColor(mInitialTextColorState)
+                            .build(),
+                    false);
+        } else {
+            mRotateTextViewController.hideIndication(INDICATION_TYPE_RESTING);
+        }
+    }
+
+    protected boolean isKeyguardLayoutEnabled() {
+        return mLockScreenMode == LOCK_SCREEN_MODE_LAYOUT_1;
+    }
+
+    private void updateLogoutView() {
+        if (!isKeyguardLayoutEnabled()) {
+            return;
+        }
+        final boolean shouldShowLogout = mKeyguardUpdateMonitor.isLogoutEnabled()
+                && KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM;
+        String logoutString = shouldShowLogout ? mContext.getResources().getString(
+                    com.android.internal.R.string.global_action_logout) : null;
+        mRotateTextViewController.updateIndication(
+                INDICATION_TYPE_LOGOUT,
+                new KeyguardIndication.Builder()
+                        .setMessage(logoutString)
+                        .setTextColor(mInitialTextColorState)
+                        .setBackground(mContext.getDrawable(
+                                com.android.systemui.R.drawable.logout_button_background))
+                        .setClickListener((view) -> {
+                            int currentUserId = KeyguardUpdateMonitor.getCurrentUser();
+                            try {
+                                mIActivityManager.switchUser(UserHandle.USER_SYSTEM);
+                                mIActivityManager.stopUser(currentUserId, true /* force */, null);
+                            } catch (RemoteException re) {
+                                Log.e(TAG, "Failed to logout user", re);
+                            }
+                        })
+                .build(),
+                false);
+        updateIndication(false); // resting indication may need to update
+    }
+
+    private void updateOwnerInfo() {
+        if (!isKeyguardLayoutEnabled()) {
+            return;
+        }
+        String info = mLockPatternUtils.getDeviceOwnerInfo();
+        if (info == null) {
+            // Use the current user owner information if enabled.
+            final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled(
+                    KeyguardUpdateMonitor.getCurrentUser());
+            if (ownerInfoEnabled) {
+                info = mLockPatternUtils.getOwnerInfo(KeyguardUpdateMonitor.getCurrentUser());
+            }
+        }
+        if (info != null) {
+            mRotateTextViewController.updateIndication(
+                    INDICATION_TYPE_OWNER_INFO,
+                    new KeyguardIndication.Builder()
+                            .setMessage(info)
+                            .setTextColor(mInitialTextColorState)
+                            .build(),
+                    false);
+        } else {
+            updateIndication(false); // resting indication may need to update
         }
     }
 
@@ -281,9 +485,10 @@
         return UserHandle.USER_NULL;
     }
 
-    public void setVisible(boolean visible) {
+    @VisibleForTesting
+    protected void setVisible(boolean visible) {
         mVisible = visible;
-        mIndicationArea.setVisibility(visible ? View.VISIBLE : View.GONE);
+        mIndicationArea.setVisibility(visible ? VISIBLE : GONE);
         if (visible) {
             // If this is called after an error message was already shown, we should not clear it.
             // Otherwise the error message won't be shown
@@ -382,6 +587,7 @@
             mTransientIndication = null;
             mHideTransientMessageOnScreenOff = false;
             mHandler.removeMessages(MSG_HIDE_TRANSIENT);
+            mRotateTextViewController.hideTransient();
             updateIndication(false);
         }
     }
@@ -396,98 +602,109 @@
         }
 
         // A few places might need to hide the indication, so always start by making it visible
-        mIndicationArea.setVisibility(View.VISIBLE);
+        mIndicationArea.setVisibility(VISIBLE);
 
         // Walk down a precedence-ordered list of what indication
         // should be shown based on user or device state
+        // AoD
         if (mDozing) {
+            mTopIndicationView.setVisibility(VISIBLE);
             // When dozing we ignore any text color and use white instead, because
             // colors can be hard to read in low brightness.
-            mTextView.setTextColor(Color.WHITE);
+            mTopIndicationView.setTextColor(Color.WHITE);
             if (!TextUtils.isEmpty(mTransientIndication)) {
-                mTextView.switchIndication(mTransientIndication);
+                mTopIndicationView.switchIndication(mTransientIndication, null);
             } else if (!mBatteryPresent) {
                 // If there is no battery detected, hide the indication and bail
-                mIndicationArea.setVisibility(View.GONE);
+                mIndicationArea.setVisibility(GONE);
             } else if (!TextUtils.isEmpty(mAlignmentIndication)) {
-                mTextView.switchIndication(mAlignmentIndication);
-                mTextView.setTextColor(mContext.getColor(R.color.misalignment_text_color));
+                mTopIndicationView.switchIndication(mAlignmentIndication, null);
+                mTopIndicationView.setTextColor(mContext.getColor(R.color.misalignment_text_color));
             } else if (mPowerPluggedIn || mEnableBatteryDefender) {
                 String indication = computePowerIndication();
                 if (animate) {
-                    animateText(mTextView, indication);
+                    animateText(mTopIndicationView, indication);
                 } else {
-                    mTextView.switchIndication(indication);
+                    mTopIndicationView.switchIndication(indication, null);
                 }
             } else {
                 String percentage = NumberFormat.getPercentInstance()
                         .format(mBatteryLevel / 100f);
-                mTextView.switchIndication(percentage);
+                mTopIndicationView.switchIndication(percentage, null);
             }
             return;
         }
 
-        int userId = KeyguardUpdateMonitor.getCurrentUser();
-        String trustGrantedIndication = getTrustGrantedIndication();
-        String trustManagedIndication = getTrustManagedIndication();
-
-        String powerIndication = null;
-        if (mPowerPluggedIn || mEnableBatteryDefender) {
-            powerIndication = computePowerIndication();
-        }
-
+        // LOCK SCREEN
         // Some cases here might need to hide the indication (if the battery is not present)
-        boolean hideIndication = false;
-        boolean isError = false;
-        if (!mKeyguardUpdateMonitor.isUserUnlocked(userId)) {
-            mTextView.switchIndication(com.android.internal.R.string.lockscreen_storage_locked);
-        } else if (!TextUtils.isEmpty(mTransientIndication)) {
-            if (powerIndication != null && !mTransientIndication.equals(powerIndication)) {
-                String indication = mContext.getResources().getString(
-                                R.string.keyguard_indication_trust_unlocked_plugged_in,
-                                mTransientIndication, powerIndication);
-                mTextView.switchIndication(indication);
-                hideIndication = !mBatteryPresent;
-            } else {
-                mTextView.switchIndication(mTransientIndication);
-            }
-            isError = mTransientTextIsError;
-        } else if (!TextUtils.isEmpty(trustGrantedIndication)
-                && mKeyguardUpdateMonitor.getUserHasTrust(userId)) {
-            if (powerIndication != null) {
-                String indication = mContext.getResources().getString(
-                                R.string.keyguard_indication_trust_unlocked_plugged_in,
-                                trustGrantedIndication, powerIndication);
-                mTextView.switchIndication(indication);
-                hideIndication = !mBatteryPresent;
-            } else {
-                mTextView.switchIndication(trustGrantedIndication);
-            }
-        } else if (!TextUtils.isEmpty(mAlignmentIndication)) {
-            mTextView.switchIndication(mAlignmentIndication);
-            isError = true;
-            hideIndication = !mBatteryPresent;
-        } else if (mPowerPluggedIn || mEnableBatteryDefender) {
-            if (DEBUG_CHARGING_SPEED) {
-                powerIndication += ",  " + (mChargingWattage / 1000) + " mW";
-            }
-            if (animate) {
-                animateText(mTextView, powerIndication);
-            } else {
-                mTextView.switchIndication(powerIndication);
-            }
-            hideIndication = !mBatteryPresent;
-        } else if (!TextUtils.isEmpty(trustManagedIndication)
-                && mKeyguardUpdateMonitor.getUserTrustIsManaged(userId)
-                && !mKeyguardUpdateMonitor.getUserHasTrust(userId)) {
-            mTextView.switchIndication(trustManagedIndication);
+        int userId = KeyguardUpdateMonitor.getCurrentUser();
+
+        if (mLockScreenMode == LOCK_SCREEN_MODE_LAYOUT_1) {
+            mTopIndicationView.setVisibility(GONE);
+            updateIndications(animate, userId);
         } else {
-            mTextView.switchIndication(mRestingIndication);
-        }
-        mTextView.setTextColor(isError ? Utils.getColorError(mContext)
-                : mInitialTextColorState);
-        if (hideIndication) {
-            mIndicationArea.setVisibility(View.GONE);
+            boolean hideIndication = false;
+            boolean isError = false;
+            String trustGrantedIndication = getTrustGrantedIndication();
+            String trustManagedIndication = getTrustManagedIndication();
+            String powerIndication = null;
+
+            if (mPowerPluggedIn || mEnableBatteryDefender) {
+                powerIndication = computePowerIndication();
+            }
+            if (!mKeyguardUpdateMonitor.isUserUnlocked(userId)) {
+                mTopIndicationView.switchIndication(
+                        com.android.internal.R.string.lockscreen_storage_locked);
+            } else if (!TextUtils.isEmpty(mTransientIndication)) {
+                if (powerIndication != null && !mTransientIndication.equals(powerIndication)) {
+                    String indication = mContext.getResources().getString(
+                            R.string.keyguard_indication_trust_unlocked_plugged_in,
+                            mTransientIndication, powerIndication);
+                    mTopIndicationView.switchIndication(indication, null);
+                    hideIndication = !mBatteryPresent;
+                } else {
+                    mTopIndicationView.switchIndication(mTransientIndication, null);
+                }
+                isError = mTransientTextIsError;
+            } else if (!TextUtils.isEmpty(trustGrantedIndication)
+                    && mKeyguardUpdateMonitor.getUserHasTrust(userId)) {
+                if (powerIndication != null) {
+                    String indication = mContext.getResources().getString(
+                            R.string.keyguard_indication_trust_unlocked_plugged_in,
+                            trustGrantedIndication, powerIndication);
+                    mTopIndicationView.switchIndication(indication, null);
+                    hideIndication = !mBatteryPresent;
+                } else {
+                    mTopIndicationView.switchIndication(trustGrantedIndication, null);
+                }
+            } else if (!TextUtils.isEmpty(mAlignmentIndication)) {
+                mTopIndicationView.switchIndication(mAlignmentIndication, null);
+                isError = true;
+                hideIndication = !mBatteryPresent;
+            } else if (mPowerPluggedIn || mEnableBatteryDefender) {
+                if (DEBUG_CHARGING_SPEED) {
+                    powerIndication += ",  " + (mChargingWattage / 1000) + " mW";
+                }
+                if (animate) {
+                    animateText(mTopIndicationView, powerIndication);
+                } else {
+                    mTopIndicationView.switchIndication(powerIndication, null);
+                }
+                hideIndication = !mBatteryPresent;
+            } else if (!TextUtils.isEmpty(trustManagedIndication)
+                    && mKeyguardUpdateMonitor.getUserTrustIsManaged(userId)
+                    && !mKeyguardUpdateMonitor.getUserHasTrust(userId)) {
+                mTopIndicationView.switchIndication(trustManagedIndication, null);
+            } else {
+                mTopIndicationView.switchIndication(mRestingIndication, null);
+            }
+
+            mTopIndicationView.setTextColor(
+                    isError ? Utils.getColorError(mContext) : mInitialTextColorState);
+
+            if (hideIndication) {
+                mIndicationArea.setVisibility(GONE);
+            }
         }
     }
 
@@ -510,7 +727,7 @@
 
                     @Override
                     public void onAnimationStart(Animator animation) {
-                        textView.switchIndication(indication);
+                        textView.switchIndication(indication, null);
                     }
 
                     @Override
@@ -634,18 +851,6 @@
         }
     }
 
-    public void setDozing(boolean dozing) {
-        if (mDozing == dozing) {
-            return;
-        }
-        mDozing = dozing;
-        if (mHideTransientMessageOnScreenOff && mDozing) {
-            hideTransientIndication();
-        } else {
-            updateIndication(false);
-        }
-    }
-
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("KeyguardIndicationController:");
         pw.println("  mTransientTextIsError: " + mTransientTextIsError);
@@ -659,23 +864,10 @@
         pw.println("  mDozing: " + mDozing);
         pw.println("  mBatteryLevel: " + mBatteryLevel);
         pw.println("  mBatteryPresent: " + mBatteryPresent);
-        pw.println("  mTextView.getText(): " + (mTextView == null ? null : mTextView.getText()));
+        pw.println("  mTextView.getText(): " + (
+                mTopIndicationView == null ? null : mTopIndicationView.getText()));
         pw.println("  computePowerIndication(): " + computePowerIndication());
-    }
-
-    @Override
-    public void onStateChanged(int newState) {
-        // don't care
-    }
-
-    @Override
-    public void onDozingChanged(boolean isDozing) {
-        setDozing(isDozing);
-    }
-
-    @Override
-    public void onDozeAmountChanged(float linear, float eased) {
-        mDisclosure.setAlpha((1 - linear) * mDisclosureMaxAlpha);
+        mRotateTextViewController.dump(fd, pw, args);
     }
 
     @Override
@@ -687,6 +879,11 @@
         public static final int HIDE_DELAY_MS = 5000;
 
         @Override
+        public void onLockScreenModeChanged(int mode) {
+            mLockScreenMode = mode;
+        }
+
+        @Override
         public void onRefreshBatteryInfo(BatteryStatus status) {
             boolean isChargingOrFull = status.status == BatteryManager.BATTERY_STATUS_CHARGING
                     || status.status == BatteryManager.BATTERY_STATUS_FULL;
@@ -845,6 +1042,7 @@
         @Override
         public void onUserSwitchComplete(int userId) {
             if (mVisible) {
+                updateOwnerInfo();
                 updateIndication(false);
             }
         }
@@ -857,11 +1055,39 @@
         }
 
         @Override
+        public void onLogoutEnabledChanged() {
+            if (mVisible) {
+                updateLogoutView();
+            }
+        }
+
+        @Override
         public void onRequireUnlockForNfc() {
             showTransientIndication(mContext.getString(R.string.require_unlock_for_nfc),
                     false /* isError */, false /* hideOnScreenOff */);
             hideTransientIndicationDelayed(HIDE_DELAY_MS);
         }
-
     }
+
+    private StatusBarStateController.StateListener mStatusBarStateListener =
+            new StatusBarStateController.StateListener() {
+        @Override
+        public void onStateChanged(int newState) {
+            setVisible(newState == StatusBarState.KEYGUARD);
+        }
+
+        @Override
+        public void onDozingChanged(boolean dozing) {
+            if (mDozing == dozing) {
+                return;
+            }
+            mDozing = dozing;
+
+            if (mHideTransientMessageOnScreenOff && mDozing) {
+                hideTransientIndication();
+            } else {
+                updateIndication(false);
+            }
+        }
+    };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index dd1419f..2ce0a87 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -131,8 +131,8 @@
     private KeyguardAffordanceView mLeftAffordanceView;
     private ImageView mAltLeftButton;
     private ViewGroup mIndicationArea;
-    private TextView mEnterpriseDisclosure;
     private TextView mIndicationText;
+    private TextView mIndicationTextBottom;
     private ViewGroup mPreviewContainer;
     private ViewGroup mOverlayContainer;
 
@@ -251,9 +251,8 @@
         mLeftAffordanceView = findViewById(R.id.left_button);
         mAltLeftButton = findViewById(R.id.alt_left_button);
         mIndicationArea = findViewById(R.id.keyguard_indication_area);
-        mEnterpriseDisclosure = findViewById(
-                R.id.keyguard_indication_enterprise_disclosure);
         mIndicationText = findViewById(R.id.keyguard_indication_text);
+        mIndicationTextBottom = findViewById(R.id.keyguard_indication_text_bottom);
         mIndicationBottomMargin = getResources().getDimensionPixelSize(
                 R.dimen.keyguard_indication_margin_bottom);
         mBurnInYOffset = getResources().getDimensionPixelSize(
@@ -330,7 +329,7 @@
         }
 
         // Respect font size setting.
-        mEnterpriseDisclosure.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+        mIndicationTextBottom.setTextSize(TypedValue.COMPLEX_UNIT_PX,
                 getResources().getDimensionPixelSize(
                         com.android.internal.R.dimen.text_size_small_material));
         mIndicationText.setTextSize(TypedValue.COMPLEX_UNIT_PX,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
index 30c951a..8970a9a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
@@ -16,11 +16,15 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static com.android.keyguard.KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.content.Context;
+import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.Drawable;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.View;
@@ -28,6 +32,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.Interpolators;
+import com.android.systemui.keyguard.KeyguardIndication;
 
 import java.util.LinkedList;
 
@@ -35,13 +40,15 @@
  * A view to show hints on Keyguard ("Swipe up to unlock", "Tap again to open").
  */
 public class KeyguardIndicationTextView extends TextView {
-
     private static final int FADE_OUT_MILLIS = 200;
     private static final int FADE_IN_MILLIS = 250;
     private static final long MSG_DURATION_MILLIS = 600;
     private long mNextAnimationTime = 0;
     private boolean mAnimationsEnabled = true;
     private LinkedList<CharSequence> mMessages = new LinkedList<>();
+    private LinkedList<KeyguardIndication> mKeyguardIndicationInfo = new LinkedList<>();
+
+    private boolean mUseNewAnimations = false;
 
     public KeyguardIndicationTextView(Context context) {
         super(context);
@@ -60,12 +67,33 @@
         super(context, attrs, defStyleAttr, defStyleRes);
     }
 
+    public void setLockScreenMode(int lockScreenMode) {
+        mUseNewAnimations = lockScreenMode == LOCK_SCREEN_MODE_LAYOUT_1;
+    }
+
+    /**
+     * Changes the text with an animation and makes sure a single indication is shown long enough.
+     */
+    public void switchIndication(int textResId) {
+        switchIndication(getResources().getText(textResId), null);
+    }
+
+    /**
+     * Changes the text with an animation and makes sure a single indication is shown long enough.
+     *
+     * @param indication The text to show.
+     */
+    public void switchIndication(KeyguardIndication indication) {
+        switchIndication(indication == null ? null : indication.getMessage(), indication);
+    }
+
     /**
      * Changes the text with an animation and makes sure a single indication is shown long enough.
      *
      * @param text The text to show.
+     * @param indication optional display information for the text
      */
-    public void switchIndication(CharSequence text) {
+    public void switchIndication(CharSequence text, KeyguardIndication indication) {
         if (text == null) text = "";
 
         CharSequence lastPendingMessage = mMessages.peekLast();
@@ -74,55 +102,119 @@
             return;
         }
         mMessages.add(text);
+        mKeyguardIndicationInfo.add(indication);
 
-        Animator fadeOut = ObjectAnimator.ofFloat(this, View.ALPHA, 0f);
-        fadeOut.setDuration(getFadeOutMillis());
-        fadeOut.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
-
-        final CharSequence nextText = text;
-        fadeOut.addListener(new AnimatorListenerAdapter() {
-                public void onAnimationEnd(Animator animator) {
-                    setText(mMessages.poll());
-                }
-            });
-
+        final boolean hasIcon = indication != null && indication.getIcon() != null;
         final AnimatorSet animSet = new AnimatorSet();
-        final AnimatorSet.Builder animSetBuilder = animSet.play(fadeOut);
+        final AnimatorSet.Builder animSetBuilder = animSet.play(getOutAnimator());
 
         // Make sure each animation is visible for a minimum amount of time, while not worrying
         // about fading in blank text
         long timeInMillis = System.currentTimeMillis();
         long delay = Math.max(0, mNextAnimationTime - timeInMillis);
-        setNextAnimationTime(timeInMillis + delay + getFadeOutMillis());
+        setNextAnimationTime(timeInMillis + delay + getFadeOutDuration());
 
-        if (!text.equals("")) {
+        if (!text.equals("") || hasIcon) {
             setNextAnimationTime(mNextAnimationTime + MSG_DURATION_MILLIS);
-
-            ObjectAnimator fadeIn = ObjectAnimator.ofFloat(this, View.ALPHA, 1f);
-            fadeIn.setDuration(getFadeInMillis());
-            fadeIn.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
-            animSetBuilder.before(fadeIn);
+            animSetBuilder.before(getInAnimator());
         }
 
         animSet.setStartDelay(delay);
         animSet.start();
     }
 
+    private AnimatorSet getOutAnimator() {
+        AnimatorSet animatorSet = new AnimatorSet();
+        Animator fadeOut = ObjectAnimator.ofFloat(this, View.ALPHA, 0f);
+        fadeOut.setDuration(getFadeOutDuration());
+        fadeOut.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
+        fadeOut.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animator) {
+                KeyguardIndication info = mKeyguardIndicationInfo.poll();
+                if (info != null) {
+                    setTextColor(info.getTextColor());
+                    setOnClickListener(info.getClickListener());
+                    final Drawable icon = info.getIcon();
+                    if (icon != null) {
+                        icon.setTint(getCurrentTextColor());
+                        if (icon instanceof AnimatedVectorDrawable) {
+                            ((AnimatedVectorDrawable) icon).start();
+                        }
+                    }
+                    setCompoundDrawablesRelativeWithIntrinsicBounds(icon, null, null, null);
+                }
+                setText(mMessages.poll());
+            }
+        });
+
+        if (mUseNewAnimations) {
+            Animator yTranslate =
+                    ObjectAnimator.ofFloat(this, View.TRANSLATION_Y, 0, -getYTranslationPixels());
+            yTranslate.setDuration(getFadeOutDuration());
+            fadeOut.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
+            animatorSet.playTogether(fadeOut, yTranslate);
+        } else {
+            animatorSet.play(fadeOut);
+        }
+
+        return animatorSet;
+    }
+
+    private AnimatorSet getInAnimator() {
+        AnimatorSet animatorSet = new AnimatorSet();
+        ObjectAnimator fadeIn = ObjectAnimator.ofFloat(this, View.ALPHA, 1f);
+        fadeIn.setStartDelay(getFadeInDelay());
+        fadeIn.setDuration(getFadeInDuration());
+        fadeIn.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
+
+        if (mUseNewAnimations) {
+            Animator yTranslate =
+                    ObjectAnimator.ofFloat(this, View.TRANSLATION_Y, getYTranslationPixels(), 0);
+            yTranslate.setDuration(getYInDuration());
+            yTranslate.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationCancel(Animator animation) {
+                    setTranslationY(0);
+                }
+            });
+            animatorSet.playTogether(yTranslate, fadeIn);
+        } else {
+            animatorSet.play(fadeIn);
+        }
+
+        return animatorSet;
+    }
+
     @VisibleForTesting
     public void setAnimationsEnabled(boolean enabled) {
         mAnimationsEnabled = enabled;
     }
 
-    private long getFadeInMillis() {
-        if (mAnimationsEnabled) return FADE_IN_MILLIS;
+    private long getFadeInDelay() {
+        if (!mAnimationsEnabled) return 0L;
+        if (mUseNewAnimations) return 150L;
         return 0L;
     }
 
-    private long getFadeOutMillis() {
-        if (mAnimationsEnabled) return FADE_OUT_MILLIS;
+    private long getFadeInDuration() {
+        if (!mAnimationsEnabled) return 0L;
+        if (mUseNewAnimations) return 317L;
+        return FADE_IN_MILLIS;
+    }
+
+    private long getYInDuration() {
+        if (!mAnimationsEnabled) return 0L;
+        if (mUseNewAnimations) return 600L;
         return 0L;
     }
 
+    private long getFadeOutDuration() {
+        if (!mAnimationsEnabled) return 0L;
+        if (mUseNewAnimations) return 167L;
+        return FADE_OUT_MILLIS;
+    }
+
     private void setNextAnimationTime(long time) {
         if (mAnimationsEnabled) {
             mNextAnimationTime = time;
@@ -131,10 +223,8 @@
         }
     }
 
-    /**
-     * See {@link #switchIndication}.
-     */
-    public void switchIndication(int textResId) {
-        switchIndication(getResources().getText(textResId));
+    private int getYTranslationPixels() {
+        return mContext.getResources().getDimensionPixelSize(
+                com.android.systemui.R.dimen.keyguard_indication_y_translation);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 061f2a8..1e19bee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1146,8 +1146,6 @@
             mLockscreenWallpaper = mLockscreenWallpaperLazy.get();
         }
 
-        mKeyguardIndicationController.setIndicationArea(
-                mNotificationShadeWindowView.findViewById(R.id.keyguard_indication_area));
         mNotificationPanelViewController.setKeyguardIndicationController(
                 mKeyguardIndicationController);
 
@@ -3625,26 +3623,19 @@
         mNavigationBarController.touchAutoDim(mDisplayId);
         Trace.beginSection("StatusBar#updateKeyguardState");
         if (mState == StatusBarState.KEYGUARD) {
-            mKeyguardIndicationController.setVisible(true);
             if (mKeyguardUserSwitcher != null) {
                 mKeyguardUserSwitcher.setKeyguard(true,
                         mStatusBarStateController.fromShadeLocked());
             }
             if (mStatusBarView != null) mStatusBarView.removePendingHideExpandedRunnables();
-            if (mAmbientIndicationContainer != null) {
-                mAmbientIndicationContainer.setVisibility(View.VISIBLE);
-            }
         } else {
-            mKeyguardIndicationController.setVisible(false);
             if (mKeyguardUserSwitcher != null) {
                 mKeyguardUserSwitcher.setKeyguard(false,
                         mStatusBarStateController.goingToFullShade() ||
                                 mState == StatusBarState.SHADE_LOCKED ||
                                 mStatusBarStateController.fromShadeLocked());
             }
-            if (mAmbientIndicationContainer != null) {
-                mAmbientIndicationContainer.setVisibility(View.INVISIBLE);
-            }
+
         }
         updateDozingState();
         checkBarModes();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java
new file mode 100644
index 0000000..b6729ad
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard;
+
+
+import static com.android.keyguard.KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1;
+import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY;
+import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_DISCLOSURE;
+import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_OWNER_INFO;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.res.ColorStateList;
+import android.graphics.Color;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.View;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
+import com.android.systemui.util.concurrency.DelayableExecutor;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+@SmallTest
+public class KeyguardIndicationRotateTextViewControllerTest extends SysuiTestCase {
+
+    private static final String TEST_MESSAGE = "test message";
+    private static final String TEST_MESSAGE_2 = "test message 2";
+
+    @Mock
+    private DelayableExecutor mExecutor;
+    @Mock
+    private KeyguardIndicationTextView mView;
+    @Mock
+    private StatusBarStateController mStatusBarStateController;
+    @Captor
+    private ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateListenerCaptor;
+
+    private KeyguardIndicationRotateTextViewController mController;
+    private StatusBarStateController.StateListener mStatusBarStateListener;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        when(mView.getTextColors()).thenReturn(ColorStateList.valueOf(Color.WHITE));
+        mController = new KeyguardIndicationRotateTextViewController(mView, mExecutor,
+                mStatusBarStateController, LOCK_SCREEN_MODE_LAYOUT_1);
+        mController.onViewAttached();
+
+        verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
+        mStatusBarStateListener = mStatusBarStateListenerCaptor.getValue();
+    }
+
+    @Test
+    public void testInitialState_noIndication() {
+        assertFalse(mController.hasIndications());
+    }
+
+    @Test
+    public void testShowOneIndication() {
+        // WHEN we add our first indication
+        final KeyguardIndication indication = createIndication();
+        mController.updateIndication(
+                INDICATION_TYPE_DISCLOSURE, indication, false);
+
+        // THEN
+        // - we see controller has an indication
+        // - the indication shows immediately since it's the only one
+        // - no next indication is scheduled since there's only one indication
+        assertTrue(mController.hasIndications());
+        verify(mView).switchIndication(indication);
+        verify(mExecutor, never()).executeDelayed(any(), anyLong());
+    }
+
+    @Test
+    public void testShowTwoRotatingMessages() {
+        // GIVEN we already have an indication message
+        mController.updateIndication(
+                INDICATION_TYPE_OWNER_INFO, createIndication(), false);
+        reset(mView);
+
+        // WHEN we have a new indication type to display
+        final KeyguardIndication indication2 = createIndication();
+        mController.updateIndication(
+                INDICATION_TYPE_DISCLOSURE, indication2, false);
+
+        // THEN
+        // - we don't immediately see the new message until the delay
+        // - next indication is scheduled
+        verify(mView, never()).switchIndication(indication2);
+        verify(mExecutor).executeDelayed(any(), anyLong());
+    }
+
+    @Test
+    public void testUpdateCurrentMessage() {
+        // GIVEN we already have an indication message
+        mController.updateIndication(
+                INDICATION_TYPE_DISCLOSURE, createIndication(), false);
+        reset(mView);
+
+        // WHEN we have a new message for this indication type to display
+        final KeyguardIndication indication2 = createIndication();
+        mController.updateIndication(
+                INDICATION_TYPE_DISCLOSURE, indication2, false);
+
+        // THEN
+        // - new indication is updated immediately
+        // - we don't schedule to show anything later
+        verify(mView).switchIndication(indication2);
+        verify(mExecutor, never()).executeDelayed(any(), anyLong());
+    }
+
+    @Test
+    public void testUpdateRotatingMessageForUndisplayedIndication() {
+        // GIVEN we already have two indication messages
+        mController.updateIndication(
+                INDICATION_TYPE_OWNER_INFO, createIndication(), false);
+        mController.updateIndication(
+                INDICATION_TYPE_DISCLOSURE, createIndication(), false);
+        reset(mView);
+        reset(mExecutor);
+
+        // WHEN we have a new message for an undisplayed indication type
+        final KeyguardIndication indication3 = createIndication();
+        mController.updateIndication(
+                INDICATION_TYPE_DISCLOSURE, indication3, false);
+
+        // THEN
+        // - we don't immediately update
+        // - we don't schedule to show anything new
+        verify(mView, never()).switchIndication(indication3);
+        verify(mExecutor, never()).executeDelayed(any(), anyLong());
+    }
+
+    @Test
+    public void testUpdateImmediately() {
+        // GIVEN we already have three indication messages
+        mController.updateIndication(
+                INDICATION_TYPE_OWNER_INFO, createIndication(), false);
+        mController.updateIndication(
+                INDICATION_TYPE_DISCLOSURE, createIndication(), false);
+        mController.updateIndication(
+                INDICATION_TYPE_BATTERY, createIndication(), false);
+        reset(mView);
+        reset(mExecutor);
+
+        // WHEN we have a new message for a currently shown type that we want to show immediately
+        final KeyguardIndication indication4 = createIndication();
+        mController.updateIndication(
+                INDICATION_TYPE_BATTERY, indication4, true);
+
+        // THEN
+        // - we immediately update
+        // - we schedule a new delayable to show the next message later
+        verify(mView).switchIndication(indication4);
+        verify(mExecutor).executeDelayed(any(), anyLong());
+
+        // WHEN an already existing type is updated to show immediately
+        reset(mView);
+        reset(mExecutor);
+        final KeyguardIndication indication5 = createIndication();
+        mController.updateIndication(
+                INDICATION_TYPE_DISCLOSURE, indication5, true);
+
+        // THEN
+        // - we immediately update
+        // - we schedule a new delayable to show the next message later
+        verify(mView).switchIndication(indication5);
+        verify(mExecutor).executeDelayed(any(), anyLong());
+    }
+
+    @Test
+    public void testTransientIndication() {
+        // GIVEN we already have two indication messages
+        mController.updateIndication(
+                INDICATION_TYPE_OWNER_INFO, createIndication(), false);
+        mController.updateIndication(
+                INDICATION_TYPE_DISCLOSURE, createIndication(), false);
+        reset(mView);
+        reset(mExecutor);
+
+        // WHEN we have a transient message
+        mController.showTransient(TEST_MESSAGE_2, false);
+
+        // THEN
+        // - we immediately update
+        // - we schedule a new delayable to show the next message later
+        verify(mView).switchIndication(any(KeyguardIndication.class));
+        verify(mExecutor).executeDelayed(any(), anyLong());
+    }
+
+    @Test
+    public void testHideIndicationOneMessage() {
+        // GIVEN we have one indication message
+        mController.updateIndication(
+                INDICATION_TYPE_OWNER_INFO, createIndication(), false);
+
+        // WHEN we hide the current indication type
+        mController.hideIndication(INDICATION_TYPE_OWNER_INFO);
+
+        // THEN we immediately update the text to show no text
+        verify(mView).switchIndication(null);
+    }
+
+    @Test
+    public void testHideIndicationTwoMessages() {
+        // GIVEN we have two indication messages
+        final KeyguardIndication indication1 = createIndication();
+        final KeyguardIndication indication2 = createIndication();
+        mController.updateIndication(
+                INDICATION_TYPE_OWNER_INFO, indication1, false);
+        mController.updateIndication(
+                INDICATION_TYPE_DISCLOSURE, indication2, false);
+        assertTrue(mController.isNextIndicationScheduled());
+
+        // WHEN we hide the current indication type
+        mController.hideIndication(INDICATION_TYPE_OWNER_INFO);
+
+        // THEN we show the next indication and there's no scheduled next indication
+        verify(mView).switchIndication(indication2);
+        assertFalse(mController.isNextIndicationScheduled());
+    }
+
+    @Test
+    public void testStartDozing() {
+        // WHEN the device is dozing
+        mStatusBarStateListener.onDozingChanged(true);
+
+        // THEN the view is GONE
+        verify(mView).setVisibility(View.GONE);
+    }
+
+    @Test
+    public void testStoppedDozing() {
+        // GIVEN we're dozing & we have an indication message
+        mStatusBarStateListener.onDozingChanged(true);
+        final KeyguardIndication indication = createIndication();
+        mController.updateIndication(
+                INDICATION_TYPE_DISCLOSURE, indication, false);
+        reset(mView);
+        reset(mExecutor);
+
+        // WHEN the device is no longer dozing
+        mStatusBarStateListener.onDozingChanged(false);
+
+        // THEN show the next message
+        verify(mView).switchIndication(indication);
+    }
+
+    @Test
+    public void testIsDozing() {
+        // GIVEN the device is dozing
+        mStatusBarStateListener.onDozingChanged(true);
+        reset(mView);
+
+        // WHEN an indication is updated
+        final KeyguardIndication indication = createIndication();
+        mController.updateIndication(
+                INDICATION_TYPE_DISCLOSURE, indication, false);
+
+        // THEN no message is shown since we're dozing
+        verify(mView, never()).switchIndication(any());
+    }
+
+    private KeyguardIndication createIndication() {
+        return new KeyguardIndication.Builder()
+                .setMessage(TEST_MESSAGE)
+                .setTextColor(ColorStateList.valueOf(Color.WHITE))
+                .build();
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt
index f86b465..072f7b8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt
@@ -100,12 +100,12 @@
 
     private val dialogProvider = object : PrivacyDialogController.DialogProvider {
         var list: List<PrivacyDialog.PrivacyElement>? = null
-        var starter: ((String) -> Unit)? = null
+        var starter: ((String, Int) -> Unit)? = null
 
         override fun makeDialog(
             context: Context,
             list: List<PrivacyDialog.PrivacyElement>,
-            starter: (String) -> Unit
+            starter: (String, Int) -> Unit
         ): PrivacyDialog {
             this.list = list
             this.starter = starter
@@ -210,7 +210,7 @@
     fun testSingleElementInList() {
         val usage = createMockPermGroupUsage(
                 packageName = TEST_PACKAGE_NAME,
-                uid = generateUidForUser(0),
+                uid = generateUidForUser(USER_ID),
                 permGroupName = PERM_CAMERA,
                 lastAccess = 5L,
                 isActive = true,
@@ -224,6 +224,8 @@
 
         val expected = PrivacyDialog.PrivacyElement(
                 type = PrivacyType.TYPE_CAMERA,
+                packageName = TEST_PACKAGE_NAME,
+                userId = USER_ID,
                 applicationName = TEST_PACKAGE_NAME,
                 attribution = TEST_ATTRIBUTION,
                 lastActiveTimestamp = 5L,
@@ -459,13 +461,28 @@
         controller.showDialog(context)
         exhaustExecutors()
 
-        dialogProvider.starter?.invoke(PERM_MICROPHONE)
+        dialogProvider.starter?.invoke(TEST_PACKAGE_NAME, USER_ID)
         verify(activityStarter)
                 .startActivity(capture(intentCaptor), eq(true), any<ActivityStarter.Callback>())
 
-        assertThat(intentCaptor.value.action).isEqualTo(Intent.ACTION_MANAGE_PERMISSION_APPS)
-        assertThat(intentCaptor.value.getStringExtra(Intent.EXTRA_PERMISSION_GROUP_NAME))
-                .isEqualTo(PERM_MICROPHONE)
+        assertThat(intentCaptor.value.action).isEqualTo(Intent.ACTION_MANAGE_APP_PERMISSIONS)
+        assertThat(intentCaptor.value.getStringExtra(Intent.EXTRA_PACKAGE_NAME))
+                .isEqualTo(TEST_PACKAGE_NAME)
+        assertThat(intentCaptor.value.getParcelableExtra(Intent.EXTRA_USER) as? UserHandle)
+                .isEqualTo(UserHandle.of(USER_ID))
+    }
+
+    @Test
+    fun testStartActivityCorrectIntent_enterpriseUser() {
+        controller.showDialog(context)
+        exhaustExecutors()
+
+        dialogProvider.starter?.invoke(TEST_PACKAGE_NAME, ENT_USER_ID)
+        verify(activityStarter)
+                .startActivity(capture(intentCaptor), eq(true), any<ActivityStarter.Callback>())
+
+        assertThat(intentCaptor.value.getParcelableExtra(Intent.EXTRA_USER) as? UserHandle)
+                .isEqualTo(UserHandle.of(ENT_USER_ID))
     }
 
     @Test
@@ -473,7 +490,7 @@
         controller.showDialog(context)
         exhaustExecutors()
 
-        dialogProvider.starter?.invoke(PERM_MICROPHONE)
+        dialogProvider.starter?.invoke(TEST_PACKAGE_NAME, USER_ID)
         verify(activityStarter).startActivity(any(), eq(true), capture(activityStartedCaptor))
 
         activityStartedCaptor.value.onActivityStarted(ActivityManager.START_DELIVERED_TO_TOP)
@@ -486,7 +503,7 @@
         controller.showDialog(context)
         exhaustExecutors()
 
-        dialogProvider.starter?.invoke(PERM_MICROPHONE)
+        dialogProvider.starter?.invoke(TEST_PACKAGE_NAME, USER_ID)
         verify(activityStarter).startActivity(any(), eq(true), capture(activityStartedCaptor))
 
         activityStartedCaptor.value.onActivityStarted(ActivityManager.START_ABORTED)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
index eb5dd4e..28b44d9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
@@ -40,8 +40,13 @@
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 class PrivacyDialogTest : SysuiTestCase() {
 
+    companion object {
+        private const val TEST_PACKAGE_NAME = "test_pkg"
+        private const val TEST_USER_ID = 0
+    }
+
     @Mock
-    private lateinit var starter: (String) -> Unit
+    private lateinit var starter: (String, Int) -> Unit
 
     private lateinit var dialog: PrivacyDialog
 
@@ -58,10 +63,12 @@
     }
 
     @Test
-    fun testStarterCalledWithCorrectPermGroupName() {
+    fun testStarterCalledWithCorrectParams() {
         val list = listOf(
                 PrivacyDialog.PrivacyElement(
                         PrivacyType.TYPE_MICROPHONE,
+                        TEST_PACKAGE_NAME,
+                        TEST_USER_ID,
                         "App",
                         null,
                         0L,
@@ -73,7 +80,7 @@
         dialog = PrivacyDialog(context, list, starter)
         dialog.show()
         dialog.requireViewById<View>(R.id.privacy_item).callOnClick()
-        verify(starter).invoke(PrivacyType.TYPE_MICROPHONE.permGroupName)
+        verify(starter).invoke(TEST_PACKAGE_NAME, TEST_USER_ID)
     }
 
     @Test
@@ -104,6 +111,8 @@
         val list = listOf(
                 PrivacyDialog.PrivacyElement(
                         PrivacyType.TYPE_CAMERA,
+                        TEST_PACKAGE_NAME,
+                        TEST_USER_ID,
                         "App",
                         null,
                         0L,
@@ -113,6 +122,8 @@
                 ),
                 PrivacyDialog.PrivacyElement(
                         PrivacyType.TYPE_MICROPHONE,
+                        TEST_PACKAGE_NAME,
+                        TEST_USER_ID,
                         "App",
                         null,
                         0L,
@@ -130,6 +141,8 @@
     fun testUsingText() {
         val element = PrivacyDialog.PrivacyElement(
                 PrivacyType.TYPE_CAMERA,
+                TEST_PACKAGE_NAME,
+                TEST_USER_ID,
                 "App",
                 null,
                 0L,
@@ -154,6 +167,8 @@
     fun testRecentText() {
         val element = PrivacyDialog.PrivacyElement(
                 PrivacyType.TYPE_MICROPHONE,
+                TEST_PACKAGE_NAME,
+                TEST_USER_ID,
                 "App",
                 null,
                 0L,
@@ -178,6 +193,8 @@
     fun testEnterprise() {
         val element = PrivacyDialog.PrivacyElement(
                 PrivacyType.TYPE_MICROPHONE,
+                TEST_PACKAGE_NAME,
+                TEST_USER_ID,
                 "App",
                 null,
                 0L,
@@ -198,6 +215,8 @@
     fun testPhoneCall() {
         val element = PrivacyDialog.PrivacyElement(
                 PrivacyType.TYPE_MICROPHONE,
+                TEST_PACKAGE_NAME,
+                TEST_USER_ID,
                 "App",
                 null,
                 0L,
@@ -218,6 +237,8 @@
     fun testAttribution() {
         val element = PrivacyDialog.PrivacyElement(
                 PrivacyType.TYPE_MICROPHONE,
+                TEST_PACKAGE_NAME,
+                TEST_USER_ID,
                 "App",
                 "attribution",
                 0L,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index 2c96535..0cae6742 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -18,6 +18,8 @@
 
 import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
 
+import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_DISCLOSURE;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertFalse;
@@ -27,13 +29,11 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.Instrumentation;
@@ -51,7 +51,6 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.UserManager;
-import android.view.View;
 import android.view.ViewGroup;
 
 import androidx.test.InstrumentationRegistry;
@@ -60,18 +59,21 @@
 
 import com.android.internal.app.IBatteryStats;
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.settingslib.Utils;
 import com.android.settingslib.fuelgauge.BatteryStatus;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dock.DockManager;
+import com.android.systemui.keyguard.KeyguardIndication;
+import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
 import com.android.systemui.statusbar.phone.LockIcon;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
 import com.android.systemui.util.wakelock.WakeLockFake;
 
 import org.junit.After;
@@ -93,6 +95,7 @@
     private static final String ORGANIZATION_NAME = "organization";
 
     private String mDisclosureWithOrganization;
+    private String mDisclosureGeneric;
 
     @Mock
     private DevicePolicyManager mDevicePolicyManager;
@@ -101,7 +104,7 @@
     @Mock
     private KeyguardStateController mKeyguardStateController;
     @Mock
-    private KeyguardIndicationTextView mDisclosure;
+    private KeyguardIndicationTextView mIndicationAreaBottom;
     @Mock
     private BroadcastDispatcher mBroadcastDispatcher;
     @Mock
@@ -118,8 +121,20 @@
     private IBatteryStats mIBatteryStats;
     @Mock
     private DockManager mDockManager;
+    @Mock
+    private KeyguardIndicationRotateTextViewController mRotateTextViewController;
     @Captor
     private ArgumentCaptor<DockManager.AlignmentStateListener> mAlignmentListener;
+    @Captor
+    private ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateListenerCaptor;
+    @Captor
+    private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
+    @Captor
+    private ArgumentCaptor<KeyguardIndication> mKeyguardIndicationCaptor;
+    private StatusBarStateController.StateListener mStatusBarStateListener;
+    private BroadcastReceiver mBroadcastReceiver;
+    private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
+
     private KeyguardIndicationTextView mTextView;
 
     private KeyguardIndicationController mController;
@@ -140,15 +155,15 @@
         mContext.addMockSystemService(Context.FINGERPRINT_SERVICE, mock(FingerprintManager.class));
         mDisclosureWithOrganization = mContext.getString(R.string.do_disclosure_with_name,
                 ORGANIZATION_NAME);
+        mDisclosureGeneric = mContext.getString(R.string.do_disclosure_generic);
 
         when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
         when(mKeyguardUpdateMonitor.isScreenOn()).thenReturn(true);
         when(mKeyguardUpdateMonitor.isUserUnlocked(anyInt())).thenReturn(true);
 
-        when(mIndicationArea.findViewById(R.id.keyguard_indication_enterprise_disclosure))
-                .thenReturn(mDisclosure);
+        when(mIndicationArea.findViewById(R.id.keyguard_indication_text_bottom))
+                .thenReturn(mIndicationAreaBottom);
         when(mIndicationArea.findViewById(R.id.keyguard_indication_text)).thenReturn(mTextView);
-        when(mDisclosure.getAlpha()).thenReturn(1f);
 
         mWakeLock = new WakeLockFake();
         mWakeLockBuilder = new WakeLockFake.Builder(mContext);
@@ -168,11 +183,15 @@
         mController = new KeyguardIndicationController(mContext, mWakeLockBuilder,
                 mKeyguardStateController, mStatusBarStateController, mKeyguardUpdateMonitor,
                 mDockManager, mBroadcastDispatcher, mDevicePolicyManager, mIBatteryStats,
-                mUserManager);
+                mUserManager, mExecutor);
         mController.setIndicationArea(mIndicationArea);
+        verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
+        mStatusBarStateListener = mStatusBarStateListenerCaptor.getValue();
+        verify(mBroadcastDispatcher).registerReceiver(mBroadcastReceiverCaptor.capture(), any());
+        mBroadcastReceiver = mBroadcastReceiverCaptor.getValue();
+        mController.mRotateTextViewController = mRotateTextViewController;
         mController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
         clearInvocations(mIBatteryStats);
-        verify(mDisclosure).getAlpha();
     }
 
     @Test
@@ -223,7 +242,7 @@
             createController();
             verify(mDockManager).addAlignmentStateListener(mAlignmentListener.capture());
             mController.setVisible(true);
-            mController.setDozing(true);
+            mStatusBarStateListener.onDozingChanged(true);
 
             mAlignmentListener.getValue().onAlignmentStateChanged(DockManager.ALIGN_STATE_POOR);
         });
@@ -241,7 +260,7 @@
             createController();
             verify(mDockManager).addAlignmentStateListener(mAlignmentListener.capture());
             mController.setVisible(true);
-            mController.setDozing(true);
+            mStatusBarStateListener.onDozingChanged(true);
 
             mAlignmentListener.getValue().onAlignmentStateChanged(DockManager.ALIGN_STATE_TERRIBLE);
         });
@@ -255,136 +274,108 @@
 
     @Test
     public void disclosure_unmanaged() {
+        createController();
         when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false);
         when(mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()).thenReturn(false);
-        createController();
+        sendUpdateDisclosureBroadcast();
 
-        verify(mDisclosure).setVisibility(View.GONE);
-        verifyNoMoreInteractions(mDisclosure);
+        verify(mRotateTextViewController).hideIndication(INDICATION_TYPE_DISCLOSURE);
+        verify(mRotateTextViewController, never()).updateIndication(eq(INDICATION_TYPE_DISCLOSURE),
+                any(), anyBoolean());
     }
 
     @Test
-    public void disclosure_deviceOwner_noOwnerName() {
+    public void disclosure_deviceOwner_noOrganizationName() {
+        createController();
         when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
         when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null);
-        createController();
+        sendUpdateDisclosureBroadcast();
 
-        verify(mDisclosure).setVisibility(View.VISIBLE);
-        verify(mDisclosure).switchIndication(R.string.do_disclosure_generic);
-        verifyNoMoreInteractions(mDisclosure);
+        verify(mRotateTextViewController).updateIndication(eq(INDICATION_TYPE_DISCLOSURE),
+                mKeyguardIndicationCaptor.capture(), eq(false));
+        assertThat(mKeyguardIndicationCaptor.getValue().getMessage())
+                .isEqualTo(mDisclosureGeneric);
     }
 
     @Test
-    public void disclosure_orgOwnedDeviceWithManagedProfile_noOwnerName() {
+    public void disclosure_orgOwnedDeviceWithManagedProfile_noOrganizationName() {
+        createController();
         when(mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()).thenReturn(true);
         when(mUserManager.getProfiles(anyInt())).thenReturn(Collections.singletonList(
                 new UserInfo(10, /* name */ null, /* flags */ FLAG_MANAGED_PROFILE)));
         when(mDevicePolicyManager.getOrganizationNameForUser(eq(10))).thenReturn(null);
-        createController();
+        sendUpdateDisclosureBroadcast();
 
-        verify(mDisclosure).setVisibility(View.VISIBLE);
-        verify(mDisclosure).switchIndication(R.string.do_disclosure_generic);
-        verifyNoMoreInteractions(mDisclosure);
+        verify(mRotateTextViewController).updateIndication(eq(INDICATION_TYPE_DISCLOSURE),
+                mKeyguardIndicationCaptor.capture(), eq(false));
+        assertThat(mKeyguardIndicationCaptor.getValue().getMessage())
+                .isEqualTo(mDisclosureGeneric);
     }
 
     @Test
-    public void disclosure_hiddenWhenDozing() {
-        when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
-        when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null);
+    public void disclosure_deviceOwner_withOrganizationName() {
         createController();
-
-        mController.setVisible(true);
-        mController.onDozeAmountChanged(1, 1);
-        mController.setDozing(true);
-
-        verify(mDisclosure).setVisibility(View.VISIBLE);
-        verify(mDisclosure).setAlpha(0f);
-        verify(mDisclosure).switchIndication(R.string.do_disclosure_generic);
-        verifyNoMoreInteractions(mDisclosure);
-    }
-
-    @Test
-    public void disclosure_visibleWhenDozing() {
-        when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
-        when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null);
-        createController();
-
-        mController.setVisible(true);
-        mController.onDozeAmountChanged(0, 0);
-        mController.setDozing(false);
-
-        verify(mDisclosure).setVisibility(View.VISIBLE);
-        verify(mDisclosure).setAlpha(1f);
-        verify(mDisclosure).switchIndication(R.string.do_disclosure_generic);
-        verifyNoMoreInteractions(mDisclosure);
-    }
-
-    @Test
-    public void disclosure_deviceOwner_withOwnerName() {
         when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
         when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(ORGANIZATION_NAME);
-        createController();
+        sendUpdateDisclosureBroadcast();
 
-        verify(mDisclosure).setVisibility(View.VISIBLE);
-        verify(mDisclosure).switchIndication(mDisclosureWithOrganization);
-        verifyNoMoreInteractions(mDisclosure);
+        verify(mRotateTextViewController).updateIndication(eq(INDICATION_TYPE_DISCLOSURE),
+                mKeyguardIndicationCaptor.capture(), eq(false));
+        assertThat(mKeyguardIndicationCaptor.getValue().getMessage())
+                .isEqualTo(mDisclosureWithOrganization);
     }
 
     @Test
-    public void disclosure_orgOwnedDeviceWithManagedProfile_withOwnerName() {
+    public void disclosure_orgOwnedDeviceWithManagedProfile_withOrganizationName() {
+        createController();
         when(mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()).thenReturn(true);
         when(mUserManager.getProfiles(anyInt())).thenReturn(Collections.singletonList(
                 new UserInfo(10, /* name */ null, FLAG_MANAGED_PROFILE)));
         when(mDevicePolicyManager.getOrganizationNameForUser(eq(10))).thenReturn(ORGANIZATION_NAME);
-        createController();
+        sendUpdateDisclosureBroadcast();
 
-        verify(mDisclosure).setVisibility(View.VISIBLE);
-        verify(mDisclosure).switchIndication(mDisclosureWithOrganization);
-        verifyNoMoreInteractions(mDisclosure);
+        verify(mRotateTextViewController).updateIndication(eq(INDICATION_TYPE_DISCLOSURE),
+                mKeyguardIndicationCaptor.capture(), eq(false));
+        assertThat(mKeyguardIndicationCaptor.getValue().getMessage())
+                .isEqualTo(mDisclosureWithOrganization);
     }
 
     @Test
     public void disclosure_updateOnTheFly() {
-        ArgumentCaptor<BroadcastReceiver> receiver = ArgumentCaptor.forClass(
-                BroadcastReceiver.class);
-        doNothing().when(mBroadcastDispatcher).registerReceiver(receiver.capture(), any());
-
         when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false);
         createController();
 
-        final KeyguardUpdateMonitorCallback monitor = mController.getKeyguardCallback();
-        reset(mDisclosure);
-
         when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
         when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null);
-        receiver.getValue().onReceive(mContext, new Intent());
+        sendUpdateDisclosureBroadcast();
 
-        verify(mDisclosure).setVisibility(View.VISIBLE);
-        verify(mDisclosure).switchIndication(R.string.do_disclosure_generic);
-        verifyNoMoreInteractions(mDisclosure);
-        reset(mDisclosure);
+        verify(mRotateTextViewController).updateIndication(eq(INDICATION_TYPE_DISCLOSURE),
+                mKeyguardIndicationCaptor.capture(), eq(false));
+        assertThat(mKeyguardIndicationCaptor.getValue().getMessage())
+                .isEqualTo(mDisclosureGeneric);
+        reset(mRotateTextViewController);
 
         when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
         when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(ORGANIZATION_NAME);
-        receiver.getValue().onReceive(mContext, new Intent());
+        sendUpdateDisclosureBroadcast();
 
-        verify(mDisclosure).setVisibility(View.VISIBLE);
-        verify(mDisclosure).switchIndication(mDisclosureWithOrganization);
-        verifyNoMoreInteractions(mDisclosure);
-        reset(mDisclosure);
+        verify(mRotateTextViewController).updateIndication(eq(INDICATION_TYPE_DISCLOSURE),
+                mKeyguardIndicationCaptor.capture(), eq(false));
+        assertThat(mKeyguardIndicationCaptor.getValue().getMessage())
+                .isEqualTo(mDisclosureWithOrganization);
+        reset(mRotateTextViewController);
 
         when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false);
-        receiver.getValue().onReceive(mContext, new Intent());
+        sendUpdateDisclosureBroadcast();
 
-        verify(mDisclosure).setVisibility(View.GONE);
-        verifyNoMoreInteractions(mDisclosure);
+        verify(mRotateTextViewController).hideIndication(INDICATION_TYPE_DISCLOSURE);
     }
 
     @Test
     public void transientIndication_holdsWakeLock_whenDozing() {
         createController();
 
-        mController.setDozing(true);
+        mStatusBarStateListener.onDozingChanged(true);
         mController.showTransientIndication("Test");
 
         assertTrue(mWakeLock.isHeld());
@@ -394,7 +385,7 @@
     public void transientIndication_releasesWakeLock_afterHiding() {
         createController();
 
-        mController.setDozing(true);
+        mStatusBarStateListener.onDozingChanged(true);
         mController.showTransientIndication("Test");
         mController.hideTransientIndication();
 
@@ -406,7 +397,7 @@
         mInstrumentation.runOnMainSync(() -> {
             createController();
 
-            mController.setDozing(true);
+            mStatusBarStateListener.onDozingChanged(true);
             mController.showTransientIndication("Test");
             mController.hideTransientIndicationDelayed(0);
         });
@@ -425,7 +416,7 @@
 
         mController.setVisible(true);
         mController.showTransientIndication("Test");
-        mController.setDozing(true);
+        mStatusBarStateListener.onDozingChanged(true);
 
         assertThat(mTextView.getText()).isEqualTo("Test");
         assertThat(mTextView.getCurrentTextColor()).isEqualTo(Color.WHITE);
@@ -442,7 +433,7 @@
                 KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED, message,
                 BiometricSourceType.FACE);
         assertThat(mTextView.getText()).isEqualTo(message);
-        mController.setDozing(true);
+        mStatusBarStateListener.onDozingChanged(true);
 
         assertThat(mTextView.getText()).isNotEqualTo(message);
     }
@@ -457,7 +448,7 @@
                 "A message", BiometricSourceType.FACE);
 
         assertThat(mTextView.getText()).isEqualTo(message);
-        mController.setDozing(true);
+        mStatusBarStateListener.onDozingChanged(true);
 
         assertThat(mTextView.getText()).isNotEqualTo(message);
     }
@@ -528,8 +519,8 @@
     public void setDozing_noIBatteryCalls() throws RemoteException {
         createController();
         mController.setVisible(true);
-        mController.setDozing(true);
-        mController.setDozing(false);
+        mStatusBarStateListener.onDozingChanged(true);
+        mStatusBarStateListener.onDozingChanged(false);
         verify(mIBatteryStats, never()).computeChargeTimeRemaining();
     }
 
@@ -537,7 +528,6 @@
     public void updateMonitor_listener() {
         createController();
         verify(mKeyguardStateController).addCallback(eq(mController));
-        verify(mStatusBarStateController).addCallback(eq(mController));
         verify(mKeyguardUpdateMonitor, times(2)).registerCallback(any());
     }
 
@@ -612,10 +602,14 @@
                 0 /* maxChargingWattage */, true /* present */);
 
         mController.getKeyguardCallback().onRefreshBatteryInfo(status);
-        mController.setDozing(true);
+        mStatusBarStateListener.onDozingChanged(true);
         mController.setVisible(true);
 
         String percentage = NumberFormat.getPercentInstance().format(90 / 100f);
         assertThat(mTextView.getText()).isEqualTo(percentage);
     }
+
+    private void sendUpdateDisclosureBroadcast() {
+        mBroadcastReceiver.onReceive(mContext, new Intent());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java
index 0e77504..6068f0d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextViewTest.java
@@ -51,21 +51,21 @@
 
     @Test
     public void switchIndication_null_hideIndication() {
-        mKeyguardIndicationTextView.switchIndication(null /* text */);
+        mKeyguardIndicationTextView.switchIndication(null /* text */, null);
 
         assertThat(mKeyguardIndicationTextView.getText()).isEqualTo("");
     }
 
     @Test
     public void switchIndication_emptyText_hideIndication() {
-        mKeyguardIndicationTextView.switchIndication("" /* text */);
+        mKeyguardIndicationTextView.switchIndication("" /* text */, null);
 
         assertThat(mKeyguardIndicationTextView.getText()).isEqualTo("");
     }
 
     @Test
     public void switchIndication_newText_updateProperly() {
-        mKeyguardIndicationTextView.switchIndication("test_indication" /* text */);
+        mKeyguardIndicationTextView.switchIndication("test_indication" /* text */, null);
 
         assertThat(mKeyguardIndicationTextView.getVisibility()).isEqualTo(View.VISIBLE);
         assertThat(mKeyguardIndicationTextView.getText()).isEqualTo("test_indication");
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 37d2cdc..96cfe02 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -103,7 +103,7 @@
         "android.hardware.gnss-V1-java",
         "android.hardware.power-V1-java",
         "android.hardware.power-V1.0-java",
-        "android.hardware.vibrator-V1-java",
+        "android.hardware.vibrator-V2-java",
         "android.net.ipsec.ike.stubs.module_lib",
         "app-compat-annotations",
         "framework-tethering.stubs.module_lib",
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index 6886cde..737a9e4 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -30,6 +30,7 @@
 import android.content.pm.PackageManager.ComponentInfoFlags;
 import android.content.pm.PackageManager.PackageInfoFlags;
 import android.content.pm.PackageManager.ResolveInfoFlags;
+import android.content.pm.overlay.OverlayPaths;
 import android.content.pm.parsing.component.ParsedMainComponent;
 import android.os.Bundle;
 import android.os.Handler;
@@ -49,8 +50,8 @@
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 
@@ -535,17 +536,17 @@
      * Set which overlay to use for a package.
      * @param userId The user for which to update the overlays.
      * @param targetPackageName The package name of the package for which to update the overlays.
-     * @param overlayPackageNames The complete list of overlay packages that should be enabled for
-     *                            the target. Previously enabled overlays not specified in the list
-     *                            will be disabled. Pass in null or an empty list to disable
-     *                            all overlays. The order of the items is significant if several
-     *                            overlays modify the same resource.
+     * @param overlayPaths  The complete list of overlay paths that should be enabled for
+     *                      the target. Previously enabled overlays not specified in the list
+     *                      will be disabled. Pass in null or empty paths to disable all overlays.
+     *                      The order of the items is significant if several overlays modify the
+     *                      same resource.
      * @param outUpdatedPackageNames An output list that contains the package names of packages
      *                               affected by the update of enabled overlays.
      * @return true if all packages names were known by the package manager, false otherwise
      */
     public abstract boolean setEnabledOverlayPackages(int userId, String targetPackageName,
-            List<String> overlayPackageNames, Collection<String> outUpdatedPackageNames);
+            @Nullable OverlayPaths overlayPaths, Set<String> outUpdatedPackageNames);
 
     /**
      * Resolves an activity intent, allowing instant apps to be resolved.
diff --git a/services/core/java/com/android/server/VibratorManagerService.java b/services/core/java/com/android/server/VibratorManagerService.java
index 6a816af..e7e5d67 100644
--- a/services/core/java/com/android/server/VibratorManagerService.java
+++ b/services/core/java/com/android/server/VibratorManagerService.java
@@ -111,6 +111,7 @@
     private final AppOpsManager mAppOps;
     private final NativeWrapper mNativeWrapper;
     private final VibratorManagerRecords mVibratorManagerRecords;
+    private final long mCapabilities;
     private final int[] mVibratorIds;
     private final SparseArray<VibratorController> mVibrators;
     private final VibrationCallbacks mVibrationCallbacks = new VibrationCallbacks();
@@ -127,18 +128,28 @@
     private VibrationScaler mVibrationScaler;
     private InputDeviceDelegate mInputDeviceDelegate;
 
-    static native long nativeInit();
+    static native long nativeInit(OnSyncedVibrationCompleteListener listener);
 
     static native long nativeGetFinalizer();
 
+    static native long nativeGetCapabilities(long nativeServicePtr);
+
     static native int[] nativeGetVibratorIds(long nativeServicePtr);
 
+    static native boolean nativePrepareSynced(long nativeServicePtr, int[] vibratorIds);
+
+    static native boolean nativeTriggerSynced(long nativeServicePtr, long vibrationId);
+
+    static native void nativeCancelSynced(long nativeServicePtr);
+
     @VisibleForTesting
     VibratorManagerService(Context context, Injector injector) {
         mContext = context;
         mHandler = injector.createHandler(Looper.myLooper());
+
+        VibrationCompleteListener listener = new VibrationCompleteListener(this);
         mNativeWrapper = injector.getNativeWrapper();
-        mNativeWrapper.init();
+        mNativeWrapper.init(listener);
 
         int dumpLimit = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_previousVibrationsDumpLimit);
@@ -153,6 +164,7 @@
         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*vibrator*");
         mWakeLock.setReferenceCounted(true);
 
+        mCapabilities = mNativeWrapper.getCapabilities();
         int[] vibratorIds = mNativeWrapper.getVibratorIds();
         if (vibratorIds == null) {
             mVibratorIds = new int[0];
@@ -161,11 +173,17 @@
             // Keep original vibrator id order, which might be meaningful.
             mVibratorIds = vibratorIds;
             mVibrators = new SparseArray<>(mVibratorIds.length);
-            VibrationCompleteListener listener = new VibrationCompleteListener(this);
             for (int vibratorId : vibratorIds) {
                 mVibrators.put(vibratorId, injector.createVibratorController(vibratorId, listener));
             }
         }
+
+        // Reset the hardware to a default state, in case this is a runtime restart instead of a
+        // fresh boot.
+        mNativeWrapper.cancelSynced();
+        for (int i = 0; i < mVibrators.size(); i++) {
+            mVibrators.valueAt(i).off();
+        }
     }
 
     /** Finish initialization at boot phase {@link SystemService#PHASE_SYSTEM_SERVICES_READY}. */
@@ -502,6 +520,17 @@
         }
     }
 
+    private void onSyncedVibrationComplete(long vibrationId) {
+        synchronized (mLock) {
+            if (mCurrentVibration != null && mCurrentVibration.getVibration().id == vibrationId) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Synced vibration " + vibrationId + " complete, notifying thread");
+                }
+                mCurrentVibration.syncedVibrationComplete();
+            }
+        }
+    }
+
     private void onVibrationComplete(int vibratorId, long vibrationId) {
         synchronized (mLock) {
             if (mCurrentVibration != null && mCurrentVibration.getVibration().id == vibrationId) {
@@ -839,13 +868,22 @@
     private final class VibrationCallbacks implements VibrationThread.VibrationCallbacks {
 
         @Override
-        public void prepareSyncedVibration(int requiredCapabilities, int[] vibratorIds) {
-            // TODO(b/167946816): call IVibratorManager to prepare
+        public boolean prepareSyncedVibration(long requiredCapabilities, int[] vibratorIds) {
+            if ((mCapabilities & requiredCapabilities) != requiredCapabilities) {
+                // This sync step requires capabilities this device doesn't have, skipping sync...
+                return false;
+            }
+            return mNativeWrapper.prepareSynced(vibratorIds);
         }
 
         @Override
-        public void triggerSyncedVibration(long vibrationId) {
-            // TODO(b/167946816): call IVibratorManager to trigger
+        public boolean triggerSyncedVibration(long vibrationId) {
+            return mNativeWrapper.triggerSynced(vibrationId);
+        }
+
+        @Override
+        public void cancelSyncedVibration() {
+            mNativeWrapper.cancelSynced();
         }
 
         @Override
@@ -868,12 +906,19 @@
         }
     }
 
+    /** Listener for synced vibration completion callbacks from native. */
+    @VisibleForTesting
+    public interface OnSyncedVibrationCompleteListener {
+
+        /** Callback triggered when synced vibration is complete. */
+        void onComplete(long vibrationId);
+    }
+
     /**
-     * Implementation of {@link VibratorController.OnVibrationCompleteListener} with a weak
-     * reference to this service.
+     * Implementation of listeners to native vibrators with a weak reference to this service.
      */
     private static final class VibrationCompleteListener implements
-            VibratorController.OnVibrationCompleteListener {
+            VibratorController.OnVibrationCompleteListener, OnSyncedVibrationCompleteListener {
         private WeakReference<VibratorManagerService> mServiceRef;
 
         VibrationCompleteListener(VibratorManagerService service) {
@@ -881,6 +926,14 @@
         }
 
         @Override
+        public void onComplete(long vibrationId) {
+            VibratorManagerService service = mServiceRef.get();
+            if (service != null) {
+                service.onSyncedVibrationComplete(vibrationId);
+            }
+        }
+
+        @Override
         public void onComplete(int vibratorId, long vibrationId) {
             VibratorManagerService service = mServiceRef.get();
             if (service != null) {
@@ -952,9 +1005,9 @@
         private long mNativeServicePtr = 0;
 
         /** Returns native pointer to newly created controller and connects with HAL service. */
-        public void init() {
-            mNativeServicePtr = VibratorManagerService.nativeInit();
-            long finalizerPtr = VibratorManagerService.nativeGetFinalizer();
+        public void init(OnSyncedVibrationCompleteListener listener) {
+            mNativeServicePtr = nativeInit(listener);
+            long finalizerPtr = nativeGetFinalizer();
 
             if (finalizerPtr != 0) {
                 NativeAllocationRegistry registry =
@@ -964,9 +1017,29 @@
             }
         }
 
+        /** Returns manager capabilities. */
+        public long getCapabilities() {
+            return nativeGetCapabilities(mNativeServicePtr);
+        }
+
         /** Returns vibrator ids. */
         public int[] getVibratorIds() {
-            return VibratorManagerService.nativeGetVibratorIds(mNativeServicePtr);
+            return nativeGetVibratorIds(mNativeServicePtr);
+        }
+
+        /** Prepare vibrators for triggering vibrations in sync. */
+        public boolean prepareSynced(@NonNull int[] vibratorIds) {
+            return nativePrepareSynced(mNativeServicePtr, vibratorIds);
+        }
+
+        /** Trigger prepared synced vibration. */
+        public boolean triggerSynced(long vibrationId) {
+            return nativeTriggerSynced(mNativeServicePtr, vibrationId);
+        }
+
+        /** Cancel prepared synced vibration. */
+        public void cancelSynced() {
+            nativeCancelSynced(mNativeServicePtr);
         }
     }
 
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 026eb63..2ac365d 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -119,11 +119,17 @@
     private final class VibrationCallbacks implements VibrationThread.VibrationCallbacks {
 
         @Override
-        public void prepareSyncedVibration(int requiredCapabilities, int[] vibratorIds) {
+        public boolean prepareSyncedVibration(long requiredCapabilities, int[] vibratorIds) {
+            return false;
         }
 
         @Override
-        public void triggerSyncedVibration(long vibrationId) {
+        public boolean triggerSyncedVibration(long vibrationId) {
+            return false;
+        }
+
+        @Override
+        public void cancelSyncedVibration() {
         }
 
         @Override
diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java
index 3acad49..76c3467 100644
--- a/services/core/java/com/android/server/app/GameManagerService.java
+++ b/services/core/java/com/android/server/app/GameManagerService.java
@@ -16,17 +16,23 @@
 
 package com.android.server.app;
 
+import android.Manifest;
 import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.app.ActivityManager;
 import android.app.GameManager;
 import android.app.GameManager.GameMode;
 import android.app.IGameManagerService;
 import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Binder;
 import android.os.Environment;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Process;
 import android.util.ArrayMap;
+import android.util.Log;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
@@ -81,6 +87,14 @@
             switch (msg.what) {
                 case WRITE_SETTINGS: {
                     final int userId = (int) msg.obj;
+                    if (userId < 0) {
+                        Slog.wtf(TAG, "Attempt to write settings for invalid user: " + userId);
+                        synchronized (mLock) {
+                            removeMessages(WRITE_SETTINGS, msg.obj);
+                        }
+                        break;
+                    }
+
                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
                     synchronized (mLock) {
                         removeMessages(WRITE_SETTINGS, msg.obj);
@@ -94,6 +108,15 @@
                 }
                 case REMOVE_SETTINGS: {
                     final int userId = (int) msg.obj;
+                    if (userId < 0) {
+                        Slog.wtf(TAG, "Attempt to write settings for invalid user: " + userId);
+                        synchronized (mLock) {
+                            removeMessages(WRITE_SETTINGS, msg.obj);
+                            removeMessages(REMOVE_SETTINGS, msg.obj);
+                        }
+                        break;
+                    }
+
                     synchronized (mLock) {
                         // Since the user was removed, ignore previous write message
                         // and do write here.
@@ -146,9 +169,23 @@
         }
     }
 
-    //TODO(b/178111358) Add proper permission check and multi-user handling
+    private boolean hasPermission(String permission) {
+        return mContext.checkCallingOrSelfPermission(permission)
+                == PackageManager.PERMISSION_GRANTED;
+    }
+
     @Override
+    @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
     public @GameMode int getGameMode(String packageName, int userId) {
+        if (!hasPermission(Manifest.permission.MANAGE_GAME_MODE)) {
+            Log.w(TAG, String.format("Caller or self does not have permission.MANAGE_GAME_MODE"));
+            return GameManager.GAME_MODE_UNSUPPORTED;
+        }
+
+        userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
+                Binder.getCallingUid(), userId, false, true, "getGameMode",
+                "com.android.server.app.GameManagerService");
+
         synchronized (mLock) {
             if (!mSettings.containsKey(userId)) {
                 return GameManager.GAME_MODE_UNSUPPORTED;
@@ -158,9 +195,18 @@
         }
     }
 
-    //TODO(b/178111358) Add proper permission check and multi-user handling
     @Override
+    @RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
     public void setGameMode(String packageName, @GameMode int gameMode, int userId) {
+        if (!hasPermission(Manifest.permission.MANAGE_GAME_MODE)) {
+            Log.w(TAG, String.format("Caller or self does not have permission.MANAGE_GAME_MODE"));
+            return;
+        }
+
+        userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
+                Binder.getCallingUid(), userId, false, true, "setGameMode",
+                "com.android.server.app.GameManagerService");
+
         synchronized (mLock) {
             if (!mSettings.containsKey(userId)) {
                 return;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index f7f1865..4c3dfbf 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -378,7 +378,9 @@
     static final String[] DEFAULT_ALLOWED_ADJUSTMENTS = new String[] {
             Adjustment.KEY_CONTEXTUAL_ACTIONS,
             Adjustment.KEY_TEXT_REPLIES,
-            Adjustment.KEY_NOT_CONVERSATION};
+            Adjustment.KEY_NOT_CONVERSATION,
+            Adjustment.KEY_IMPORTANCE,
+            Adjustment.KEY_RANKING_SCORE};
 
     static final String[] NON_BLOCKABLE_DEFAULT_ROLES = new String[] {
             RoleManager.ROLE_DIALER,
@@ -9048,7 +9050,8 @@
     public class NotificationAssistants extends ManagedServices {
         static final String TAG_ENABLED_NOTIFICATION_ASSISTANTS = "enabled_assistants";
 
-        private static final String TAG_ALLOWED_ADJUSTMENT_TYPES = "q_allowed_adjustments";
+        private static final String TAG_ALLOWED_ADJUSTMENT_TYPES_OLD = "q_allowed_adjustments";
+        private static final String TAG_ALLOWED_ADJUSTMENT_TYPES = "s_allowed_adjustments";
         private static final String ATT_TYPES = "types";
 
         private final Object mLock = new Object();
@@ -9150,13 +9153,19 @@
 
         @Override
         protected void readExtraTag(String tag, TypedXmlPullParser parser) throws IOException {
-            if (TAG_ALLOWED_ADJUSTMENT_TYPES.equals(tag)) {
+            if (TAG_ALLOWED_ADJUSTMENT_TYPES_OLD.equals(tag)
+                    || TAG_ALLOWED_ADJUSTMENT_TYPES.equals(tag)) {
                 final String types = XmlUtils.readStringAttribute(parser, ATT_TYPES);
                 synchronized (mLock) {
                     mAllowedAdjustments.clear();
                     if (!TextUtils.isEmpty(types)) {
                         mAllowedAdjustments.addAll(Arrays.asList(types.split(",")));
                     }
+                    if (TAG_ALLOWED_ADJUSTMENT_TYPES_OLD.equals(tag)) {
+                        if (DEBUG) Slog.d(TAG, "Migrate allowed adjustments.");
+                        mAllowedAdjustments.addAll(
+                                Arrays.asList(DEFAULT_ALLOWED_ADJUSTMENTS));
+                    }
                 }
             }
         }
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 50fb176..fd2fb1f 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -50,6 +50,7 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.UserInfo;
+import android.content.pm.overlay.OverlayPaths;
 import android.content.res.ApkAssets;
 import android.net.Uri;
 import android.os.Binder;
@@ -1376,18 +1377,18 @@
                 targetPackageNames = pm.getTargetPackageNames(userId);
             }
 
-            final Map<String, List<String>> pendingChanges =
+            final Map<String, OverlayPaths> pendingChanges =
                     new ArrayMap<>(targetPackageNames.size());
             synchronized (mLock) {
-                final List<String> frameworkOverlays =
-                        mImpl.getEnabledOverlayPackageNames("android", userId);
+                final OverlayPaths frameworkOverlays =
+                        mImpl.getEnabledOverlayPaths("android", userId);
                 for (final String targetPackageName : targetPackageNames) {
-                    List<String> list = new ArrayList<>();
+                    final OverlayPaths.Builder list = new OverlayPaths.Builder();
                     if (!"android".equals(targetPackageName)) {
                         list.addAll(frameworkOverlays);
                     }
-                    list.addAll(mImpl.getEnabledOverlayPackageNames(targetPackageName, userId));
-                    pendingChanges.put(targetPackageName, list);
+                    list.addAll(mImpl.getEnabledOverlayPaths(targetPackageName, userId));
+                    pendingChanges.put(targetPackageName, list.build());
                 }
             }
 
@@ -1395,7 +1396,7 @@
             for (final String targetPackageName : targetPackageNames) {
                 if (DEBUG) {
                     Slog.d(TAG, "-> Updating overlay: target=" + targetPackageName + " overlays=["
-                            + TextUtils.join(",", pendingChanges.get(targetPackageName))
+                            + pendingChanges.get(targetPackageName)
                             + "] userId=" + userId);
                 }
 
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index e60411bb..c547c36 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -31,6 +31,7 @@
 import android.content.om.OverlayInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
+import android.content.pm.overlay.OverlayPaths;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -697,19 +698,20 @@
         removeIdmapIfPossible(oi);
     }
 
-    List<String> getEnabledOverlayPackageNames(@NonNull final String targetPackageName,
+    OverlayPaths getEnabledOverlayPaths(@NonNull final String targetPackageName,
             final int userId) {
         final List<OverlayInfo> overlays = mSettings.getOverlaysForTarget(targetPackageName,
                 userId);
-        final List<String> paths = new ArrayList<>(overlays.size());
+        final OverlayPaths.Builder paths = new OverlayPaths.Builder();
         final int n = overlays.size();
         for (int i = 0; i < n; i++) {
             final OverlayInfo oi = overlays.get(i);
-            if (oi.isEnabled()) {
-                paths.add(oi.packageName);
+            if (!oi.isEnabled()) {
+                continue;
             }
+            paths.addApkPath(oi.baseCodePath);
         }
-        return paths;
+        return paths.build();
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 965f68b..b725c96 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -193,6 +193,7 @@
 import android.content.pm.IntentFilterVerificationInfo;
 import android.content.pm.KeySet;
 import android.content.pm.ModuleInfo;
+import android.content.pm.overlay.OverlayPaths;
 import android.content.pm.PackageChangeEvent;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageInfoLite;
@@ -234,6 +235,7 @@
 import android.content.pm.dex.ArtManager;
 import android.content.pm.dex.DexMetadataHelper;
 import android.content.pm.dex.IArtManager;
+import android.content.pm.overlay.OverlayPaths;
 import android.content.pm.parsing.ApkLiteParseUtils;
 import android.content.pm.parsing.PackageLite;
 import android.content.pm.parsing.ParsingPackageUtils;
@@ -5938,6 +5940,21 @@
         }
     }
 
+    // Link watchables to the class
+    private void registerObserver() {
+        mPackages.registerObserver(mWatcher);
+        mSharedLibraries.registerObserver(mWatcher);
+        mStaticLibsByDeclaringPackage.registerObserver(mWatcher);
+        mInstrumentation.registerObserver(mWatcher);
+        mWebInstantAppsDisabled.registerObserver(mWatcher);
+        mAppsFilter.registerObserver(mWatcher);
+        mInstantAppRegistry.registerObserver(mWatcher);
+        mSettings.registerObserver(mWatcher);
+        // If neither "build" attribute is true then this may be a mockito test, and verification
+        // can fail as a false positive.
+        Watchable.verifyWatchedAttributes(this, mWatcher, !(mIsEngBuild || mIsUserDebugBuild));
+    }
+
     /**
      * A extremely minimal constructor designed to start up a PackageManagerService instance for
      * testing.
@@ -6021,15 +6038,7 @@
         sSnapshotCorked = true;
         mLiveComputer = createLiveComputer();
         mSnapshotComputer = mLiveComputer;
-
-        // Link up the watchers
-        mPackages.registerObserver(mWatcher);
-        mSharedLibraries.registerObserver(mWatcher);
-        mStaticLibsByDeclaringPackage.registerObserver(mWatcher);
-        mInstrumentation.registerObserver(mWatcher);
-        mWebInstantAppsDisabled.registerObserver(mWatcher);
-        mAppsFilter.registerObserver(mWatcher);
-        Watchable.verifyWatchedAttributes(this, mWatcher);
+        registerObserver();
 
         mPackages.putAll(testParams.packages);
         mEnableFreeCacheV2 = testParams.enableFreeCacheV2;
@@ -6183,15 +6192,6 @@
         mDomainVerificationManager = injector.getDomainVerificationManagerInternal();
         mDomainVerificationManager.setConnection(mDomainVerificationConnection);
 
-        // Link up the watchers
-        mPackages.registerObserver(mWatcher);
-        mSharedLibraries.registerObserver(mWatcher);
-        mStaticLibsByDeclaringPackage.registerObserver(mWatcher);
-        mInstrumentation.registerObserver(mWatcher);
-        mWebInstantAppsDisabled.registerObserver(mWatcher);
-        mAppsFilter.registerObserver(mWatcher);
-        Watchable.verifyWatchedAttributes(this, mWatcher);
-
         // Create the computer as soon as the state objects have been installed.  The
         // cached computer is the same as the live computer until the end of the
         // constructor, at which time the invalidation method updates it.  The cache is
@@ -6200,6 +6200,7 @@
         sSnapshotCorked = true;
         mLiveComputer = createLiveComputer();
         mSnapshotComputer = mLiveComputer;
+        registerObserver();
 
         // CHECKSTYLE:OFF IndentationCheck
         synchronized (mInstallLock) {
@@ -18119,11 +18120,8 @@
                             if (libPs == null) {
                                 continue;
                             }
-                            final String[] overlayPaths = libPs.getOverlayPaths(currentUserId);
-                            if (overlayPaths != null) {
-                                ps.setOverlayPathsForLibrary(sharedLib.getName(),
-                                        Arrays.asList(overlayPaths), currentUserId);
-                            }
+                            ps.setOverlayPathsForLibrary(sharedLib.getName(),
+                                    libPs.getOverlayPaths(currentUserId), currentUserId);
                         }
                     }
                 }
@@ -26614,34 +26612,19 @@
 
         @Override
         public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
-                @Nullable List<String> overlayPackageNames,
-                @NonNull Collection<String> outUpdatedPackageNames) {
+                @Nullable OverlayPaths overlayPaths,
+                @NonNull Set<String> outUpdatedPackageNames) {
+            boolean modified = false;
             synchronized (mLock) {
                 final AndroidPackage targetPkg = mPackages.get(targetPackageName);
                 if (targetPackageName == null || targetPkg == null) {
                     Slog.e(TAG, "failed to find package " + targetPackageName);
                     return false;
                 }
-                ArrayList<String> overlayPaths = null;
-                if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
-                    final int N = overlayPackageNames.size();
-                    overlayPaths = new ArrayList<>(N);
-                    for (int i = 0; i < N; i++) {
-                        final String packageName = overlayPackageNames.get(i);
-                        final AndroidPackage pkg = mPackages.get(packageName);
-                        if (pkg == null) {
-                            Slog.e(TAG, "failed to find package " + packageName);
-                            return false;
-                        }
-                        overlayPaths.add(pkg.getBaseApkPath());
-                    }
-                }
 
-                ArraySet<String> updatedPackageNames = null;
                 if (targetPkg.getLibraryNames() != null) {
                     // Set the overlay paths for dependencies of the shared library.
-                    updatedPackageNames = new ArraySet<>();
-                    for (String libName : targetPkg.getLibraryNames()) {
+                    for (final String libName : targetPkg.getLibraryNames()) {
                         final SharedLibraryInfo info = getSharedLibraryInfoLPr(libName,
                                 SharedLibraryInfo.VERSION_UNDEFINED);
                         if (info == null) {
@@ -26652,28 +26635,30 @@
                         if (dependents == null) {
                             continue;
                         }
-                        for (VersionedPackage dependent : dependents) {
+                        for (final VersionedPackage dependent : dependents) {
                             final PackageSetting ps = mSettings.getPackageLPr(
                                     dependent.getPackageName());
                             if (ps == null) {
                                 continue;
                             }
-                            ps.setOverlayPathsForLibrary(libName, overlayPaths, userId);
-                            updatedPackageNames.add(dependent.getPackageName());
+                            if (ps.setOverlayPathsForLibrary(libName, overlayPaths, userId)) {
+                                outUpdatedPackageNames.add(dependent.getPackageName());
+                                modified = true;
+                            }
                         }
                     }
                 }
 
                 final PackageSetting ps = mSettings.getPackageLPr(targetPackageName);
-                ps.setOverlayPaths(overlayPaths, userId);
-
-                outUpdatedPackageNames.add(targetPackageName);
-                if (updatedPackageNames != null) {
-                    outUpdatedPackageNames.addAll(updatedPackageNames);
+                if (ps.setOverlayPaths(overlayPaths, userId)) {
+                    outUpdatedPackageNames.add(targetPackageName);
+                    modified = true;
                 }
             }
 
-            invalidatePackageInfoCache();
+            if (modified) {
+                invalidatePackageInfoCache();
+            }
             return true;
         }
 
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index 3a14283..5364cbf 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -31,6 +31,7 @@
 import android.content.pm.PackageUserState;
 import android.content.pm.Signature;
 import android.content.pm.SuspendDialogInfo;
+import android.content.pm.overlay.OverlayPaths;
 import android.os.PersistableBundle;
 import android.os.incremental.IncrementalManager;
 import android.service.pm.PackageProto;
@@ -44,7 +45,6 @@
 
 import java.io.File;
 import java.util.Arrays;
-import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
@@ -327,21 +327,20 @@
         modifyUserState(userId).uninstallReason = uninstallReason;
     }
 
-    void setOverlayPaths(List<String> overlayPaths, int userId) {
-        modifyUserState(userId).setOverlayPaths(overlayPaths == null ? null :
-            overlayPaths.toArray(new String[overlayPaths.size()]));
+    boolean setOverlayPaths(OverlayPaths overlayPaths, int userId) {
+        return modifyUserState(userId).setOverlayPaths(overlayPaths);
     }
 
-    String[] getOverlayPaths(int userId) {
+    OverlayPaths getOverlayPaths(int userId) {
         return readUserState(userId).getOverlayPaths();
     }
 
-    void setOverlayPathsForLibrary(String libName, List<String> overlayPaths, int userId) {
-        modifyUserState(userId).setSharedLibraryOverlayPaths(libName,
-                overlayPaths == null ? null : overlayPaths.toArray(new String[0]));
+    boolean setOverlayPathsForLibrary(String libName, OverlayPaths overlayPaths,
+            int userId) {
+        return modifyUserState(userId).setSharedLibraryOverlayPaths(libName, overlayPaths);
     }
 
-    Map<String, String[]> getOverlayPathsForLibrary(int userId) {
+    Map<String, OverlayPaths> getOverlayPathsForLibrary(int userId) {
         return readUserState(userId).getSharedLibraryOverlayPaths();
     }
 
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index fb033e6..e73486a 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -40,6 +40,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ComponentInfo;
 import android.content.pm.IntentFilterVerificationInfo;
+import android.content.pm.overlay.OverlayPaths;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.PackageUserState;
@@ -49,6 +50,7 @@
 import android.content.pm.SuspendDialogInfo;
 import android.content.pm.UserInfo;
 import android.content.pm.VerifierDeviceIdentity;
+import android.content.pm.overlay.OverlayPaths;
 import android.content.pm.parsing.PackageInfoWithoutStateUtils;
 import android.content.pm.parsing.component.ParsedComponent;
 import android.content.pm.parsing.component.ParsedIntentInfo;
@@ -105,9 +107,6 @@
 import com.android.server.LocalServices;
 import com.android.server.backup.PreferredActivityBackupHelper;
 import com.android.server.pm.Installer.InstallerException;
-import com.android.server.pm.verify.domain.DomainVerificationLegacySettings;
-import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
-import com.android.server.pm.verify.domain.DomainVerificationPersistence;
 import com.android.server.pm.parsing.PackageInfoUtils;
 import com.android.server.pm.parsing.pkg.AndroidPackage;
 import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
@@ -115,6 +114,9 @@
 import com.android.server.pm.permission.LegacyPermissionSettings;
 import com.android.server.pm.permission.LegacyPermissionState;
 import com.android.server.pm.permission.LegacyPermissionState.PermissionState;
+import com.android.server.pm.verify.domain.DomainVerificationLegacySettings;
+import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
+import com.android.server.pm.verify.domain.DomainVerificationPersistence;
 import com.android.server.utils.Snappable;
 import com.android.server.utils.TimingsTraceAndSlog;
 import com.android.server.utils.Watchable;
@@ -487,7 +489,7 @@
     // App-link priority tracking, per-user
     @NonNull
     @Watched
-    final WatchedSparseIntArray mNextAppLinkGeneration = new WatchedSparseIntArray();
+    private final WatchedSparseIntArray mNextAppLinkGeneration = new WatchedSparseIntArray();
 
     final StringBuilder mReadMessages = new StringBuilder();
 
@@ -552,6 +554,7 @@
         mAppIds.registerObserver(mObserver);
         mOtherAppIds.registerObserver(mObserver);
         mRenamedPackages.registerObserver(mObserver);
+        mNextAppLinkGeneration.registerObserver(mObserver);
         mDefaultBrowserApp.registerObserver(mObserver);
 
         Watchable.verifyWatchedAttributes(this, mObserver);
@@ -602,6 +605,7 @@
         mAppIds.registerObserver(mObserver);
         mOtherAppIds.registerObserver(mObserver);
         mRenamedPackages.registerObserver(mObserver);
+        mNextAppLinkGeneration.registerObserver(mObserver);
         mDefaultBrowserApp.registerObserver(mObserver);
 
         Watchable.verifyWatchedAttributes(this, mObserver);
@@ -649,6 +653,7 @@
         mPastSignatures.addAll(r.mPastSignatures);
         mKeySetRefs.putAll(r.mKeySetRefs);
         mRenamedPackages.snapshot(r.mRenamedPackages);
+        mNextAppLinkGeneration.snapshot(r.mNextAppLinkGeneration);
         mDefaultBrowserApp.snapshot(r.mDefaultBrowserApp);
         // mReadMessages
         mPendingPackages.addAll(r.mPendingPackages);
@@ -4686,26 +4691,58 @@
                 }
             }
 
-            String[] overlayPaths = ps.getOverlayPaths(user.id);
-            if (overlayPaths != null && overlayPaths.length > 0) {
-                pw.print(prefix); pw.println("    overlay paths:");
-                for (String path : overlayPaths) {
-                    pw.print(prefix); pw.print("      "); pw.println(path);
+            final OverlayPaths overlayPaths = ps.getOverlayPaths(user.id);
+            if (overlayPaths != null) {
+                if (!overlayPaths.getOverlayPaths().isEmpty()) {
+                    pw.print(prefix);
+                    pw.println("    overlay paths:");
+                    for (String path : overlayPaths.getOverlayPaths()) {
+                        pw.print(prefix);
+                        pw.print("      ");
+                        pw.println(path);
+                    }
+                }
+                if (!overlayPaths.getResourceDirs().isEmpty()) {
+                    pw.print(prefix);
+                    pw.println("    legacy overlay paths:");
+                    for (String path : overlayPaths.getResourceDirs()) {
+                        pw.print(prefix);
+                        pw.print("      ");
+                        pw.println(path);
+                    }
                 }
             }
 
-            Map<String, String[]> sharedLibraryOverlayPaths =
+            final Map<String, OverlayPaths> sharedLibraryOverlayPaths =
                     ps.getOverlayPathsForLibrary(user.id);
             if (sharedLibraryOverlayPaths != null) {
-                for (Map.Entry<String, String[]> libOverlayPaths :
+                for (Map.Entry<String, OverlayPaths> libOverlayPaths :
                         sharedLibraryOverlayPaths.entrySet()) {
-                    if (libOverlayPaths.getValue() == null) {
+                    final OverlayPaths paths = libOverlayPaths.getValue();
+                    if (paths == null) {
                         continue;
                     }
-                    pw.print(prefix); pw.print("    ");
-                    pw.print(libOverlayPaths.getKey()); pw.println(" overlay paths:");
-                    for (String path : libOverlayPaths.getValue()) {
-                        pw.print(prefix); pw.print("      "); pw.println(path);
+                    if (!paths.getOverlayPaths().isEmpty()) {
+                        pw.print(prefix);
+                        pw.println("    ");
+                        pw.print(libOverlayPaths.getKey());
+                        pw.println(" overlay paths:");
+                        for (String path : paths.getOverlayPaths()) {
+                            pw.print(prefix);
+                            pw.print("        ");
+                            pw.println(path);
+                        }
+                    }
+                    if (!paths.getResourceDirs().isEmpty()) {
+                        pw.print(prefix);
+                        pw.println("      ");
+                        pw.print(libOverlayPaths.getKey());
+                        pw.println(" legacy overlay paths:");
+                        for (String path : paths.getResourceDirs()) {
+                            pw.print(prefix);
+                            pw.print("      ");
+                            pw.println(path);
+                        }
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/utils/Watchable.java b/services/core/java/com/android/server/utils/Watchable.java
index f936693..44a7459 100644
--- a/services/core/java/com/android/server/utils/Watchable.java
+++ b/services/core/java/com/android/server/utils/Watchable.java
@@ -19,8 +19,8 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.Build;
+import android.util.Log;
 
-import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 
 /**
@@ -61,40 +61,54 @@
     public void dispatchChange(@Nullable Watchable what);
 
     /**
-     * Return true if the field is tagged with @Watched
-     */
-    private static boolean isWatched(Field f) {
-        for (Annotation a : f.getDeclaredAnnotations()) {
-            if (a.annotationType().equals(Watched.class)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
      * Verify that all @Watched {@link Watchable} attributes are being watched by this
      * class.  This requires reflection and only runs in engineering or user debug
      * builds.
+     * @param base The object that contains watched attributes.
+     * @param observer The {@link Watcher} that should be watching these attributes.
+     * @param logOnly If true then log errors; if false then throw an RuntimeExecption on error.
      */
-    static void verifyWatchedAttributes(Object base, Watcher observer) {
-        if (Build.IS_ENG || Build.IS_USERDEBUG) {
-            for (Field f : base.getClass().getDeclaredFields()) {
+    static void verifyWatchedAttributes(Object base, Watcher observer, boolean logOnly) {
+        if (!(Build.IS_ENG || Build.IS_USERDEBUG)) {
+            return;
+        }
+        for (Field f : base.getClass().getDeclaredFields()) {
+            if (f.getAnnotation(Watched.class) != null) {
+                final String fn = base.getClass().getName() + "." + f.getName();
                 try {
-                    final boolean flagged = isWatched(f);
+                    f.setAccessible(true);
                     final Object o = f.get(base);
-                    final boolean watchable = o instanceof Watchable;
-                    if (flagged && watchable) {
-                        Watchable attr = (Watchable) f.get(base);
+                    if (o instanceof Watchable) {
+                        Watchable attr = (Watchable) (o);
                         if (attr != null && !attr.isRegisteredObserver(observer)) {
-                            throw new RuntimeException(f.getName() + " missing an observer");
+                            if (logOnly) {
+                                Log.e("Watchable", fn + " missing an observer");
+                            } else {
+                                throw new RuntimeException("Watchable " + fn
+                                                           + " missing an observer");
+                            }
                         }
                     }
                 } catch (IllegalAccessException e) {
                     // The field is protected; ignore it.  Other exceptions that may be thrown by
                     // Field.get() are allowed to roll up.
+                    if (logOnly) {
+                        Log.e("Watchable", fn + " not visible");
+                    } else {
+                        throw new RuntimeException("Watchable " + fn + " not visible");
+                    }
                 }
             }
         }
     }
+
+    /**
+     * Verify that all @Watched {@link Watchable} attributes are being watched by this
+     * class.  This calls verifyWatchedAttributes() with logOnly set to false.
+     * @param base The object that contains watched attributes.
+     * @param observer The {@link Watcher} that should be watching these attributes.
+     */
+    static void verifyWatchedAttributes(Object base, Watcher observer) {
+        verifyWatchedAttributes(base, observer, false);
+    }
 }
diff --git a/services/core/java/com/android/server/vibrator/VibrationThread.java b/services/core/java/com/android/server/vibrator/VibrationThread.java
index 4f2fc86..bee66637 100644
--- a/services/core/java/com/android/server/vibrator/VibrationThread.java
+++ b/services/core/java/com/android/server/vibrator/VibrationThread.java
@@ -17,6 +17,7 @@
 package com.android.server.vibrator;
 
 import android.annotation.Nullable;
+import android.hardware.vibrator.IVibratorManager;
 import android.os.CombinedVibrationEffect;
 import android.os.IBinder;
 import android.os.PowerManager;
@@ -65,10 +66,13 @@
          *                             IVibratorManager.CAP_MIXED_TRIGGER_*.
          * @param vibratorIds          The id of the vibrators to be prepared.
          */
-        void prepareSyncedVibration(int requiredCapabilities, int[] vibratorIds);
+        boolean prepareSyncedVibration(long requiredCapabilities, int[] vibratorIds);
 
         /** Callback triggered after synchronized vibrations were prepared. */
-        void triggerSyncedVibration(long vibrationId);
+        boolean triggerSyncedVibration(long vibrationId);
+
+        /** Callback triggered to cancel a prepared synced vibration. */
+        void cancelSyncedVibration();
 
         /** Callback triggered when vibration thread is complete. */
         void onVibrationEnded(long vibrationId, Vibration.Status status);
@@ -146,6 +150,20 @@
         }
     }
 
+    /** Notify current vibration that a synced step has completed. */
+    public void syncedVibrationComplete() {
+        synchronized (mLock) {
+            if (DEBUG) {
+                Slog.d(TAG, "Synced vibration complete reported by vibrator manager");
+            }
+            if (mCurrentVibrateStep != null) {
+                for (int i = 0; i < mVibrators.size(); i++) {
+                    mCurrentVibrateStep.vibratorComplete(mVibrators.keyAt(i));
+                }
+            }
+        }
+    }
+
     /** Notify current vibration that a step has completed on given vibrator. */
     public void vibratorComplete(int vibratorId) {
         synchronized (mLock) {
@@ -530,7 +548,7 @@
     /** Represent a synchronized vibration step on multiple vibrators. */
     private final class SyncedVibrateStep implements VibrateStep {
         private final SparseArray<VibrationEffect> mEffects;
-        private final int mRequiredCapabilities;
+        private final long mRequiredCapabilities;
         private final int[] mVibratorIds;
 
         @GuardedBy("mLock")
@@ -539,8 +557,7 @@
         SyncedVibrateStep(SparseArray<VibrationEffect> effects) {
             mEffects = effects;
             mActiveVibratorCounter = mEffects.size();
-            // TODO(b/159207608): Calculate required capabilities for syncing this step.
-            mRequiredCapabilities = 0;
+            mRequiredCapabilities = calculateRequiredSyncCapabilities(effects);
             mVibratorIds = new int[effects.size()];
             for (int i = 0; i < effects.size(); i++) {
                 mVibratorIds[i] = effects.keyAt(i);
@@ -574,18 +591,21 @@
         @Override
         public Vibration.Status play() {
             Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "SyncedVibrateStep");
-            long timeout = -1;
+            long duration = -1;
             try {
                 if (DEBUG) {
                     Slog.d(TAG, "SyncedVibrateStep starting...");
                 }
                 final PriorityQueue<AmplitudeStep> nextSteps = new PriorityQueue<>(mEffects.size());
                 long startTime = SystemClock.uptimeMillis();
-                mCallbacks.prepareSyncedVibration(mRequiredCapabilities, mVibratorIds);
-                timeout = startVibrating(startTime, nextSteps);
-                mCallbacks.triggerSyncedVibration(mVibration.id);
-                noteVibratorOn(timeout);
+                duration = startVibratingSynced(startTime, nextSteps);
 
+                if (duration <= 0) {
+                    // Vibrate step failed, vibrator could not be turned on for this step.
+                    return Vibration.Status.IGNORED;
+                }
+
+                noteVibratorOn(duration);
                 while (!nextSteps.isEmpty()) {
                     AmplitudeStep step = nextSteps.poll();
                     if (!waitUntil(step.startTime)) {
@@ -607,7 +627,7 @@
                 synchronized (mLock) {
                     // All OneShot and Waveform effects have finished. Just wait for the other
                     // effects to end via native callbacks before finishing this synced step.
-                    final long wakeUpTime = startTime + timeout + CALLBACKS_EXTRA_TIMEOUT;
+                    final long wakeUpTime = startTime + duration + CALLBACKS_EXTRA_TIMEOUT;
                     if (mActiveVibratorCounter <= 0 || waitForVibrationComplete(this, wakeUpTime)) {
                         return Vibration.Status.FINISHED;
                     }
@@ -617,7 +637,7 @@
                     return mForceStop ? Vibration.Status.CANCELLED : Vibration.Status.FINISHED;
                 }
             } finally {
-                if (timeout > 0) {
+                if (duration > 0) {
                     noteVibratorOff();
                 }
                 if (DEBUG) {
@@ -628,14 +648,48 @@
         }
 
         /**
+         * Starts playing effects on designated vibrators, in sync.
+         *
+         * @return A positive duration, in millis, to wait for the completion of this effect.
+         * Non-positive values indicate the vibrator has ignored this effect. Repeating waveform
+         * returns the duration of a single run to be used as timeout for callbacks.
+         */
+        private long startVibratingSynced(long startTime, PriorityQueue<AmplitudeStep> nextSteps) {
+            // This synchronization of vibrators should be executed one at a time, even if we are
+            // vibrating different sets of vibrators in parallel. The manager can only prepareSynced
+            // one set of vibrators at a time.
+            synchronized (mLock) {
+                boolean hasPrepared = false;
+                boolean hasTriggered = false;
+                try {
+                    hasPrepared = mCallbacks.prepareSyncedVibration(mRequiredCapabilities,
+                            mVibratorIds);
+                    long timeout = startVibrating(startTime, nextSteps);
+
+                    // Check if preparation was successful, otherwise devices area already vibrating
+                    if (hasPrepared) {
+                        hasTriggered = mCallbacks.triggerSyncedVibration(mVibration.id);
+                    }
+                    return timeout;
+                } finally {
+                    if (hasPrepared && !hasTriggered) {
+                        mCallbacks.cancelSyncedVibration();
+                        return 0;
+                    }
+                }
+            }
+        }
+
+        /**
          * Starts playing effects on designated vibrators.
          *
          * <p>This includes the {@link VibrationEffect.OneShot} and {@link VibrationEffect.Waveform}
          * effects, that should start in sync with all other effects in this step. The waveforms are
          * controlled by {@link AmplitudeStep} added to the {@code nextSteps} queue.
          *
-         * @return A duration, in millis, to wait for the completion of all vibrations. This ignores
-         * any repeating waveform duration and returns the duration of a single run.
+         * @return A positive duration, in millis, to wait for the completion of this effect.
+         * Non-positive values indicate the vibrator has ignored this effect. Repeating waveform
+         * returns the duration of a single run to be used as timeout for callbacks.
          */
         private long startVibrating(long startTime, PriorityQueue<AmplitudeStep> nextSteps) {
             long maxDuration = 0;
@@ -651,9 +705,9 @@
         /**
          * Play a single effect on a single vibrator.
          *
-         * @return A duration, in millis, to wait for the completion of this effect. This ignores
-         * any repeating waveform duration and returns the duration of a single run to be used as
-         * timeout for callbacks.
+         * @return A positive duration, in millis, to wait for the completion of this effect.
+         * Non-positive values indicate the vibrator has ignored this effect. Repeating waveform
+         * returns the duration of a single run to be used as timeout for callbacks.
          */
         private long startVibrating(VibratorController controller, VibrationEffect effect,
                 long startTime, PriorityQueue<AmplitudeStep> nextSteps) {
@@ -698,6 +752,49 @@
                 }
             }
         }
+
+        /**
+         * Return all capabilities required from the {@link IVibratorManager} to prepare and
+         * trigger all given effects in sync.
+         *
+         * @return {@link IVibratorManager#CAP_SYNC} together with all required
+         * IVibratorManager.CAP_PREPARE_* and IVibratorManager.CAP_MIXED_TRIGGER_* capabilities.
+         */
+        private long calculateRequiredSyncCapabilities(SparseArray<VibrationEffect> effects) {
+            long prepareCap = 0;
+            for (int i = 0; i < effects.size(); i++) {
+                VibrationEffect effect = effects.valueAt(i);
+                if (effect instanceof VibrationEffect.OneShot
+                        || effect instanceof VibrationEffect.Waveform) {
+                    prepareCap |= IVibratorManager.CAP_PREPARE_ON;
+                } else if (effect instanceof VibrationEffect.Prebaked) {
+                    prepareCap |= IVibratorManager.CAP_PREPARE_PERFORM;
+                } else if (effect instanceof VibrationEffect.Composed) {
+                    prepareCap |= IVibratorManager.CAP_PREPARE_COMPOSE;
+                }
+            }
+            int triggerCap = 0;
+            if (requireMixedTriggerCapability(prepareCap, IVibratorManager.CAP_PREPARE_ON)) {
+                triggerCap |= IVibratorManager.CAP_MIXED_TRIGGER_ON;
+            }
+            if (requireMixedTriggerCapability(prepareCap, IVibratorManager.CAP_PREPARE_PERFORM)) {
+                triggerCap |= IVibratorManager.CAP_MIXED_TRIGGER_PERFORM;
+            }
+            if (requireMixedTriggerCapability(prepareCap, IVibratorManager.CAP_PREPARE_COMPOSE)) {
+                triggerCap |= IVibratorManager.CAP_MIXED_TRIGGER_COMPOSE;
+            }
+            return IVibratorManager.CAP_SYNC | prepareCap | triggerCap;
+        }
+
+        /**
+         * Return true if {@code prepareCapabilities} contains this {@code capability} mixed with
+         * different ones, requiring a mixed trigger capability from the vibrator manager for
+         * syncing all effects.
+         */
+        private boolean requireMixedTriggerCapability(long prepareCapabilities, long capability) {
+            return (prepareCapabilities & capability) != 0
+                    && (prepareCapabilities & ~capability) != 0;
+        }
     }
 
     /** Represent a step to set amplitude on a single vibrator. */
@@ -794,12 +891,12 @@
                 // Waveform has ended, no more steps to run.
                 return null;
             }
-            long nextWakeUpTime = startTime + waveform.getTimings()[currentIndex];
+            long nextStartTime = startTime + waveform.getTimings()[currentIndex];
             int nextIndex = currentIndex + 1;
             if (nextIndex >= waveform.getTimings().length) {
                 nextIndex = waveform.getRepeatIndex();
             }
-            return new AmplitudeStep(vibratorId, waveform, nextIndex, nextWakeUpTime,
+            return new AmplitudeStep(vibratorId, waveform, nextIndex, nextStartTime,
                     nextVibratorStopTime());
         }
 
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 61fe023..5460e36 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -2086,6 +2086,7 @@
                 pi.getResDir(),
                 null /* splitResDirs */,
                 pi.getOverlayDirs(),
+                pi.getOverlayPaths(),
                 pi.getApplicationInfo().sharedLibraryFiles,
                 mDisplayContent.getDisplayId(),
                 null /* overrideConfig */,
diff --git a/services/core/jni/com_android_server_VibratorManagerService.cpp b/services/core/jni/com_android_server_VibratorManagerService.cpp
index 71de9bd..5dbb71a 100644
--- a/services/core/jni/com_android_server_VibratorManagerService.cpp
+++ b/services/core/jni/com_android_server_VibratorManagerService.cpp
@@ -24,27 +24,47 @@
 #include <utils/Log.h>
 #include <utils/misc.h>
 
-#include <vibratorservice/VibratorManagerHalWrapper.h>
+#include <vibratorservice/VibratorManagerHalController.h>
 
 #include "com_android_server_VibratorManagerService.h"
 
 namespace android {
 
+static JavaVM* sJvm = nullptr;
+static jmethodID sMethodIdOnComplete;
 static std::mutex gManagerMutex;
-static vibrator::ManagerHalWrapper* gManager GUARDED_BY(gManagerMutex) = nullptr;
+static vibrator::ManagerHalController* gManager GUARDED_BY(gManagerMutex) = nullptr;
 
 class NativeVibratorManagerService {
 public:
-    NativeVibratorManagerService() : mHal(std::make_unique<vibrator::LegacyManagerHalWrapper>()) {}
-    ~NativeVibratorManagerService() = default;
+    NativeVibratorManagerService(JNIEnv* env, jobject callbackListener)
+          : mHal(std::make_unique<vibrator::ManagerHalController>()),
+            mCallbackListener(env->NewGlobalRef(callbackListener)) {
+        LOG_ALWAYS_FATAL_IF(mHal == nullptr, "Unable to find reference to vibrator manager hal");
+        LOG_ALWAYS_FATAL_IF(mCallbackListener == nullptr,
+                            "Unable to create global reference to vibration callback handler");
+    }
 
-    vibrator::ManagerHalWrapper* hal() const { return mHal.get(); }
+    ~NativeVibratorManagerService() {
+        auto jniEnv = GetOrAttachJNIEnvironment(sJvm);
+        jniEnv->DeleteGlobalRef(mCallbackListener);
+    }
+
+    vibrator::ManagerHalController* hal() const { return mHal.get(); }
+
+    std::function<void()> createCallback(jlong vibrationId) {
+        return [vibrationId, this]() {
+            auto jniEnv = GetOrAttachJNIEnvironment(sJvm);
+            jniEnv->CallVoidMethod(mCallbackListener, sMethodIdOnComplete, vibrationId);
+        };
+    }
 
 private:
-    const std::unique_ptr<vibrator::ManagerHalWrapper> mHal;
+    const std::unique_ptr<vibrator::ManagerHalController> mHal;
+    const jobject mCallbackListener;
 };
 
-vibrator::ManagerHalWrapper* android_server_VibratorManagerService_getManager() {
+vibrator::ManagerHalController* android_server_VibratorManagerService_getManager() {
     std::lock_guard<std::mutex> lock(gManagerMutex);
     return gManager;
 }
@@ -58,9 +78,9 @@
     }
 }
 
-static jlong nativeInit(JNIEnv* /* env */, jclass /* clazz */) {
+static jlong nativeInit(JNIEnv* env, jclass /* clazz */, jobject callbackListener) {
     std::unique_ptr<NativeVibratorManagerService> service =
-            std::make_unique<NativeVibratorManagerService>();
+            std::make_unique<NativeVibratorManagerService>(env, callbackListener);
     {
         std::lock_guard<std::mutex> lock(gManagerMutex);
         gManager = service->hal();
@@ -72,6 +92,17 @@
     return static_cast<jlong>(reinterpret_cast<uintptr_t>(&destroyNativeService));
 }
 
+static jlong nativeGetCapabilities(JNIEnv* env, jclass /* clazz */, jlong servicePtr) {
+    NativeVibratorManagerService* service =
+            reinterpret_cast<NativeVibratorManagerService*>(servicePtr);
+    if (service == nullptr) {
+        ALOGE("nativeGetCapabilities failed because native service was not initialized");
+        return 0;
+    }
+    auto result = service->hal()->getCapabilities();
+    return result.isOk() ? static_cast<jlong>(result.value()) : 0;
+}
+
 static jintArray nativeGetVibratorIds(JNIEnv* env, jclass /* clazz */, jlong servicePtr) {
     NativeVibratorManagerService* service =
             reinterpret_cast<NativeVibratorManagerService*>(servicePtr);
@@ -89,13 +120,61 @@
     return ids;
 }
 
+static jboolean nativePrepareSynced(JNIEnv* env, jclass /* clazz */, jlong servicePtr,
+                                    jintArray vibratorIds) {
+    NativeVibratorManagerService* service =
+            reinterpret_cast<NativeVibratorManagerService*>(servicePtr);
+    if (service == nullptr) {
+        ALOGE("nativePrepareSynced failed because native service was not initialized");
+        return JNI_FALSE;
+    }
+    jsize size = env->GetArrayLength(vibratorIds);
+    std::vector<int32_t> ids(size);
+    env->GetIntArrayRegion(vibratorIds, 0, size, reinterpret_cast<jint*>(ids.data()));
+    return service->hal()->prepareSynced(ids).isOk() ? JNI_TRUE : JNI_FALSE;
+}
+
+static jboolean nativeTriggerSynced(JNIEnv* env, jclass /* clazz */, jlong servicePtr,
+                                    jlong vibrationId) {
+    NativeVibratorManagerService* service =
+            reinterpret_cast<NativeVibratorManagerService*>(servicePtr);
+    if (service == nullptr) {
+        ALOGE("nativeTriggerSynced failed because native service was not initialized");
+        return JNI_FALSE;
+    }
+    auto callback = service->createCallback(vibrationId);
+    return service->hal()->triggerSynced(callback).isOk() ? JNI_TRUE : JNI_FALSE;
+}
+
+static void nativeCancelSynced(JNIEnv* env, jclass /* clazz */, jlong servicePtr) {
+    NativeVibratorManagerService* service =
+            reinterpret_cast<NativeVibratorManagerService*>(servicePtr);
+    if (service == nullptr) {
+        ALOGE("nativeCancelSynced failed because native service was not initialized");
+        return;
+    }
+    service->hal()->cancelSynced();
+}
+
 static const JNINativeMethod method_table[] = {
-        {"nativeInit", "()J", (void*)nativeInit},
+        {"nativeInit",
+         "(Lcom/android/server/VibratorManagerService$OnSyncedVibrationCompleteListener;)J",
+         (void*)nativeInit},
         {"nativeGetFinalizer", "()J", (void*)nativeGetFinalizer},
+        {"nativeGetCapabilities", "(J)J", (void*)nativeGetCapabilities},
         {"nativeGetVibratorIds", "(J)[I", (void*)nativeGetVibratorIds},
+        {"nativePrepareSynced", "(J[I)Z", (void*)nativePrepareSynced},
+        {"nativeTriggerSynced", "(JJ)Z", (void*)nativeTriggerSynced},
+        {"nativeCancelSynced", "(J)V", (void*)nativeCancelSynced},
 };
 
-int register_android_server_VibratorManagerService(JNIEnv* env) {
+int register_android_server_VibratorManagerService(JavaVM* jvm, JNIEnv* env) {
+    sJvm = jvm;
+    auto listenerClassName =
+            "com/android/server/VibratorManagerService$OnSyncedVibrationCompleteListener";
+    jclass listenerClass = FindClassOrDie(env, listenerClassName);
+    sMethodIdOnComplete = GetMethodIDOrDie(env, listenerClass, "onComplete", "(J)V");
+
     return jniRegisterNativeMethods(env, "com/android/server/VibratorManagerService", method_table,
                                     NELEM(method_table));
 }
diff --git a/services/core/jni/com_android_server_VibratorManagerService.h b/services/core/jni/com_android_server_VibratorManagerService.h
index 3f2a322..22950c5 100644
--- a/services/core/jni/com_android_server_VibratorManagerService.h
+++ b/services/core/jni/com_android_server_VibratorManagerService.h
@@ -17,11 +17,11 @@
 #ifndef _ANDROID_SERVER_VIBRATOR_MANAGER_SERVICE_H
 #define _ANDROID_SERVER_VIBRATOR_MANAGER_SERVICE_H
 
-#include <vibratorservice/VibratorManagerHalWrapper.h>
+#include <vibratorservice/VibratorManagerHalController.h>
 
 namespace android {
 
-extern vibrator::ManagerHalWrapper* android_server_VibratorManagerService_getManager();
+extern vibrator::ManagerHalController* android_server_VibratorManagerService_getManager();
 
 } // namespace android
 
diff --git a/services/core/jni/com_android_server_vibrator_VibratorController.cpp b/services/core/jni/com_android_server_vibrator_VibratorController.cpp
index 7ed3748..4e47984 100644
--- a/services/core/jni/com_android_server_vibrator_VibratorController.cpp
+++ b/services/core/jni/com_android_server_vibrator_VibratorController.cpp
@@ -77,7 +77,7 @@
     if (vibratorId < 0) {
         return std::move(std::make_unique<vibrator::HalController>());
     }
-    vibrator::ManagerHalWrapper* manager = android_server_VibratorManagerService_getManager();
+    vibrator::ManagerHalController* manager = android_server_VibratorManagerService_getManager();
     if (manager == nullptr) {
         return nullptr;
     }
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index c5394f3..34f6048 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -39,7 +39,7 @@
 int register_android_server_UsbHostManager(JNIEnv* env);
 int register_android_server_vr_VrManagerService(JNIEnv* env);
 int register_android_server_vibrator_VibratorController(JavaVM* vm, JNIEnv* env);
-int register_android_server_VibratorManagerService(JNIEnv* env);
+int register_android_server_VibratorManagerService(JavaVM* vm, JNIEnv* env);
 int register_android_server_location_GnssLocationProvider(JNIEnv* env);
 int register_android_server_devicepolicy_CryptoTestHelper(JNIEnv*);
 int register_android_server_tv_TvUinputBridge(JNIEnv* env);
@@ -90,7 +90,7 @@
     register_android_server_UsbHostManager(env);
     register_android_server_vr_VrManagerService(env);
     register_android_server_vibrator_VibratorController(vm, env);
-    register_android_server_VibratorManagerService(env);
+    register_android_server_VibratorManagerService(vm, env);
     register_android_server_SystemServer(env);
     register_android_server_location_GnssLocationProvider(env);
     register_android_server_devicepolicy_CryptoTestHelper(env);
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 7a0cb8e..31e2b64 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -61,7 +61,7 @@
     libs: [
         "android.hardware.power-V1-java",
         "android.hardware.tv.cec-V1.0-java",
-        "android.hardware.vibrator-V1-java",
+        "android.hardware.vibrator-V2-java",
         "android.hidl.manager-V1.0-java",
         "android.test.mock",
         "android.test.base",
diff --git a/services/tests/servicestests/src/com/android/server/VibratorManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/VibratorManagerServiceTest.java
index f7b2492..f0d7006 100644
--- a/services/tests/servicestests/src/com/android/server/VibratorManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/VibratorManagerServiceTest.java
@@ -24,6 +24,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeastOnce;
@@ -32,6 +33,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -44,6 +46,7 @@
 import android.hardware.input.IInputManager;
 import android.hardware.input.InputManager;
 import android.hardware.vibrator.IVibrator;
+import android.hardware.vibrator.IVibratorManager;
 import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.os.CombinedVibrationEffect;
@@ -204,7 +207,7 @@
     public void createService_initializesNativeManagerServiceAndVibrators() {
         mockVibrators(1, 2);
         createService();
-        verify(mNativeWrapperMock).init();
+        verify(mNativeWrapperMock).init(any());
         assertTrue(mVibratorProviders.get(1).isInitialized());
         assertTrue(mVibratorProviders.get(2).isInitialized());
     }
@@ -557,8 +560,6 @@
     @Test
     public void vibrate_withNativeCallbackTriggered_finishesVibration() throws Exception {
         mockVibrators(1);
-        mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS,
-                IVibrator.CAP_AMPLITUDE_CONTROL);
         mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
         VibratorManagerService service = createService();
         // The native callback will be dispatched manually in this test.
@@ -577,6 +578,139 @@
         assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS));
     }
 
+    @Test
+    public void vibrate_withTriggerCallback_finishesVibration() throws Exception {
+        mockCapabilities(IVibratorManager.CAP_SYNC, IVibratorManager.CAP_PREPARE_COMPOSE);
+        mockVibrators(1, 2);
+        mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
+        mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
+        VibratorManagerService service = createService();
+        // The native callback will be dispatched manually in this test.
+        mTestLooper.stopAutoDispatchAndIgnoreExceptions();
+
+        ArgumentCaptor<VibratorManagerService.OnSyncedVibrationCompleteListener> listenerCaptor =
+                ArgumentCaptor.forClass(
+                        VibratorManagerService.OnSyncedVibrationCompleteListener.class);
+        verify(mNativeWrapperMock).init(listenerCaptor.capture());
+
+        // Mock trigger callback on registered listener.
+        when(mNativeWrapperMock.prepareSynced(eq(new int[]{1, 2}))).thenReturn(true);
+        when(mNativeWrapperMock.triggerSynced(anyLong())).then(answer -> {
+            listenerCaptor.getValue().onComplete(answer.getArgument(0));
+            return true;
+        });
+
+        VibrationEffect composed = VibrationEffect.startComposition()
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 100)
+                .compose();
+        CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(composed);
+
+        // Wait for vibration to start, it should finish right away with trigger callback.
+        vibrate(service, effect, ALARM_ATTRS);
+
+        // VibrationThread will start this vibration async, so wait until callback is triggered.
+        assertTrue(waitUntil(s -> !listenerCaptor.getAllValues().isEmpty(), service,
+                TEST_TIMEOUT_MILLIS));
+
+        verify(mNativeWrapperMock).prepareSynced(eq(new int[]{1, 2}));
+        verify(mNativeWrapperMock).triggerSynced(anyLong());
+        assertEquals(Arrays.asList(composed), mVibratorProviders.get(1).getEffects());
+        assertEquals(Arrays.asList(composed), mVibratorProviders.get(2).getEffects());
+    }
+
+    @Test
+    public void vibrate_withMultipleVibratorsAndCapabilities_prepareAndTriggerCalled()
+            throws Exception {
+        mockCapabilities(IVibratorManager.CAP_SYNC, IVibratorManager.CAP_PREPARE_PERFORM,
+                IVibratorManager.CAP_PREPARE_COMPOSE, IVibratorManager.CAP_MIXED_TRIGGER_PERFORM,
+                IVibratorManager.CAP_MIXED_TRIGGER_COMPOSE);
+        mockVibrators(1, 2);
+        when(mNativeWrapperMock.prepareSynced(eq(new int[]{1, 2}))).thenReturn(true);
+        when(mNativeWrapperMock.triggerSynced(anyLong())).thenReturn(true);
+        FakeVibratorControllerProvider fakeVibrator1 = mVibratorProviders.get(1);
+        fakeVibrator1.setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+        mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
+        VibratorManagerService service = createService();
+
+        CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+                .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+                .addVibrator(2, VibrationEffect.startComposition()
+                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
+                        .compose())
+                .combine();
+        vibrate(service, effect, ALARM_ATTRS);
+        assertTrue(waitUntil(s -> !fakeVibrator1.getEffects().isEmpty(), service,
+                TEST_TIMEOUT_MILLIS));
+
+        verify(mNativeWrapperMock).prepareSynced(eq(new int[]{1, 2}));
+        verify(mNativeWrapperMock).triggerSynced(anyLong());
+        verify(mNativeWrapperMock).cancelSynced(); // Trigger on service creation only.
+    }
+
+    @Test
+    public void vibrate_withMultipleVibratorsWithoutCapabilities_skipPrepareAndTrigger()
+            throws Exception {
+        // Missing CAP_MIXED_TRIGGER_ON and CAP_MIXED_TRIGGER_PERFORM.
+        mockCapabilities(IVibratorManager.CAP_SYNC, IVibratorManager.CAP_PREPARE_ON,
+                IVibratorManager.CAP_PREPARE_PERFORM);
+        mockVibrators(1, 2);
+        FakeVibratorControllerProvider fakeVibrator1 = mVibratorProviders.get(1);
+        fakeVibrator1.setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+        VibratorManagerService service = createService();
+
+        CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+                .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+                .addVibrator(2, VibrationEffect.createOneShot(10, 100))
+                .combine();
+        vibrate(service, effect, ALARM_ATTRS);
+        assertTrue(waitUntil(s -> !fakeVibrator1.getEffects().isEmpty(), service,
+                TEST_TIMEOUT_MILLIS));
+
+        verify(mNativeWrapperMock, never()).prepareSynced(any());
+        verify(mNativeWrapperMock, never()).triggerSynced(anyLong());
+        verify(mNativeWrapperMock).cancelSynced(); // Trigger on service creation only.
+    }
+
+    @Test
+    public void vibrate_withMultipleVibratorsPrepareFailed_skipTrigger() throws Exception {
+        mockCapabilities(IVibratorManager.CAP_SYNC, IVibratorManager.CAP_PREPARE_ON);
+        mockVibrators(1, 2);
+        when(mNativeWrapperMock.prepareSynced(any())).thenReturn(false);
+        VibratorManagerService service = createService();
+
+        CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+                .addVibrator(1, VibrationEffect.createOneShot(10, 50))
+                .addVibrator(2, VibrationEffect.createOneShot(10, 100))
+                .combine();
+        vibrate(service, effect, ALARM_ATTRS);
+        assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getEffects().isEmpty(), service,
+                TEST_TIMEOUT_MILLIS));
+
+        verify(mNativeWrapperMock).prepareSynced(eq(new int[]{1, 2}));
+        verify(mNativeWrapperMock, never()).triggerSynced(anyLong());
+        verify(mNativeWrapperMock).cancelSynced(); // Trigger on service creation only.
+    }
+
+    @Test
+    public void vibrate_withMultipleVibratorsTriggerFailed_cancelPreparedSynced() throws Exception {
+        mockCapabilities(IVibratorManager.CAP_SYNC, IVibratorManager.CAP_PREPARE_ON);
+        mockVibrators(1, 2);
+        when(mNativeWrapperMock.prepareSynced(eq(new int[]{1, 2}))).thenReturn(true);
+        when(mNativeWrapperMock.triggerSynced(anyLong())).thenReturn(false);
+        VibratorManagerService service = createService();
+
+        CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+                .addVibrator(1, VibrationEffect.createOneShot(10, 50))
+                .addVibrator(2, VibrationEffect.createOneShot(10, 100))
+                .combine();
+        vibrate(service, effect, ALARM_ATTRS);
+        assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getEffects().isEmpty(), service,
+                TEST_TIMEOUT_MILLIS));
+
+        verify(mNativeWrapperMock).prepareSynced(eq(new int[]{1, 2}));
+        verify(mNativeWrapperMock).triggerSynced(anyLong());
+        verify(mNativeWrapperMock, times(2)).cancelSynced(); // Trigger on service creation too.
+    }
 
     @Test
     public void vibrate_withIntensitySettings_appliesSettingsToScaleVibrations() throws Exception {
@@ -682,6 +816,11 @@
         assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS));
     }
 
+    private void mockCapabilities(long... capabilities) {
+        when(mNativeWrapperMock.getCapabilities()).thenReturn(
+                Arrays.stream(capabilities).reduce(0, (a, b) -> a | b));
+    }
+
     private void mockVibrators(int... vibratorIds) {
         for (int vibratorId : vibratorIds) {
             mVibratorProviders.put(vibratorId,
diff --git a/services/tests/servicestests/src/com/android/server/app/GameManagerServiceTests.java b/services/tests/servicestests/src/com/android/server/app/GameManagerServiceTests.java
index caa46da..d039a9d 100644
--- a/services/tests/servicestests/src/com/android/server/app/GameManagerServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/app/GameManagerServiceTests.java
@@ -18,14 +18,23 @@
 
 import static org.junit.Assert.assertEquals;
 
+import android.Manifest;
 import android.app.GameManager;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.pm.PackageManager;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+import java.util.HashMap;
+import java.util.function.Supplier;
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
@@ -37,15 +46,88 @@
     private static final int USER_ID_1 = 1001;
     private static final int USER_ID_2 = 1002;
 
+    // Stolen from ConnectivityServiceTest.MockContext
+    class MockContext extends ContextWrapper {
+        private static final String TAG = "MockContext";
+
+        // Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant
+        private final HashMap<String, Integer> mMockedPermissions = new HashMap<>();
+
+        MockContext(Context base) {
+            super(base);
+        }
+
+        /**
+         * Mock checks for the specified permission, and have them behave as per {@code granted}.
+         *
+         * <p>Passing null reverts to default behavior, which does a real permission check on the
+         * test package.
+         * @param granted One of {@link PackageManager#PERMISSION_GRANTED} or
+         *                {@link PackageManager#PERMISSION_DENIED}.
+         */
+        public void setPermission(String permission, Integer granted) {
+            mMockedPermissions.put(permission, granted);
+        }
+
+        private int checkMockedPermission(String permission, Supplier<Integer> ifAbsent) {
+            final Integer granted = mMockedPermissions.get(permission);
+            return granted != null ? granted : ifAbsent.get();
+        }
+
+        @Override
+        public int checkPermission(String permission, int pid, int uid) {
+            return checkMockedPermission(
+                    permission, () -> super.checkPermission(permission, pid, uid));
+        }
+
+        @Override
+        public int checkCallingOrSelfPermission(String permission) {
+            return checkMockedPermission(
+                    permission, () -> super.checkCallingOrSelfPermission(permission));
+        }
+
+        @Override
+        public void enforceCallingOrSelfPermission(String permission, String message) {
+            final Integer granted = mMockedPermissions.get(permission);
+            if (granted == null) {
+                super.enforceCallingOrSelfPermission(permission, message);
+                return;
+            }
+
+            if (!granted.equals(PackageManager.PERMISSION_GRANTED)) {
+                throw new SecurityException("[Test] permission denied: " + permission);
+            }
+        }
+    }
+
+    @Mock
+    private MockContext mMockContext;
+
+    @Before
+    public void setUp() throws Exception {
+        mMockContext = new MockContext(InstrumentationRegistry.getContext());
+    }
+
+    private void mockModifyGameModeGranted() {
+        mMockContext.setPermission(Manifest.permission.MANAGE_GAME_MODE,
+                PackageManager.PERMISSION_GRANTED);
+    }
+
+    private void mockModifyGameModeDenied() {
+        mMockContext.setPermission(Manifest.permission.MANAGE_GAME_MODE,
+                PackageManager.PERMISSION_DENIED);
+    }
+
     /**
      * By default game mode is not supported.
      */
     @Test
     public void testGameModeDefaultValue() {
-        GameManagerService gameManagerService =
-                new GameManagerService(InstrumentationRegistry.getContext());
+        GameManagerService gameManagerService = new GameManagerService(mMockContext);
         gameManagerService.onUserStarting(USER_ID_1);
 
+        mockModifyGameModeGranted();
+
         assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
                 gameManagerService.getGameMode(PACKAGE_NAME_0, USER_ID_1));
     }
@@ -55,10 +137,11 @@
      */
     @Test
     public void testDefaultValueForNonexistentUser() {
-        GameManagerService gameManagerService =
-                new GameManagerService(InstrumentationRegistry.getContext());
+        GameManagerService gameManagerService = new GameManagerService(mMockContext);
         gameManagerService.onUserStarting(USER_ID_1);
 
+        mockModifyGameModeGranted();
+
         gameManagerService.setGameMode(PACKAGE_NAME_1, GameManager.GAME_MODE_STANDARD, USER_ID_2);
         assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
                 gameManagerService.getGameMode(PACKAGE_NAME_1, USER_ID_2));
@@ -69,10 +152,11 @@
      */
     @Test
     public void testGameMode() {
-        GameManagerService gameManagerService =
-                new GameManagerService(InstrumentationRegistry.getContext());
+        GameManagerService gameManagerService =  new GameManagerService(mMockContext);
         gameManagerService.onUserStarting(USER_ID_1);
 
+        mockModifyGameModeGranted();
+
         assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
                 gameManagerService.getGameMode(PACKAGE_NAME_1, USER_ID_1));
         gameManagerService.setGameMode(PACKAGE_NAME_1, GameManager.GAME_MODE_STANDARD, USER_ID_1);
@@ -83,4 +167,48 @@
         assertEquals(GameManager.GAME_MODE_PERFORMANCE,
                 gameManagerService.getGameMode(PACKAGE_NAME_1, USER_ID_1));
     }
+
+    /**
+     * Test permission.MANAGE_GAME_MODE is checked
+     */
+    @Test
+    public void testGetGameModePermissionDenied() {
+        GameManagerService gameManagerService =  new GameManagerService(mMockContext);
+        gameManagerService.onUserStarting(USER_ID_1);
+
+        // Update the game mode so we can read back something valid.
+        mockModifyGameModeGranted();
+        gameManagerService.setGameMode(PACKAGE_NAME_1, GameManager.GAME_MODE_STANDARD, USER_ID_1);
+        assertEquals(GameManager.GAME_MODE_STANDARD,
+                gameManagerService.getGameMode(PACKAGE_NAME_1, USER_ID_1));
+
+        // Deny permission.MANAGE_GAME_MODE and verify we get back GameManager.GAME_MODE_UNSUPPORTED
+        mockModifyGameModeDenied();
+        assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
+                gameManagerService.getGameMode(PACKAGE_NAME_1, USER_ID_1));
+    }
+
+    /**
+     * Test permission.MANAGE_GAME_MODE is checked
+     */
+    @Test
+    public void testSetGameModePermissionDenied() {
+        GameManagerService gameManagerService =  new GameManagerService(mMockContext);
+        gameManagerService.onUserStarting(USER_ID_1);
+
+        // Update the game mode so we can read back something valid.
+        mockModifyGameModeGranted();
+        gameManagerService.setGameMode(PACKAGE_NAME_1, GameManager.GAME_MODE_STANDARD, USER_ID_1);
+        assertEquals(GameManager.GAME_MODE_STANDARD,
+                gameManagerService.getGameMode(PACKAGE_NAME_1, USER_ID_1));
+
+        // Deny permission.MANAGE_GAME_MODE and verify the game mode is not updated.
+        mockModifyGameModeDenied();
+        gameManagerService.setGameMode(PACKAGE_NAME_1, GameManager.GAME_MODE_PERFORMANCE,
+                USER_ID_1);
+
+        mockModifyGameModeGranted();
+        assertEquals(GameManager.GAME_MODE_STANDARD,
+                gameManagerService.getGameMode(PACKAGE_NAME_1, USER_ID_1));
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
index e6a238a..ba60111 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -814,6 +814,7 @@
         assertArrayEquals(a.splitSourceDirs, that.splitSourceDirs);
         assertArrayEquals(a.splitPublicSourceDirs, that.splitPublicSourceDirs);
         assertArrayEquals(a.resourceDirs, that.resourceDirs);
+        assertArrayEquals(a.overlayPaths, that.overlayPaths);
         assertEquals(a.seInfo, that.seInfo);
         assertArrayEquals(a.sharedLibraryFiles, that.sharedLibraryFiles);
         assertEquals(a.dataDir, that.dataDir);
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
index 938e4cc..7297622 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
@@ -21,11 +21,14 @@
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
 
 import android.content.pm.PackageManager;
 import android.content.pm.PackageUserState;
 import android.content.pm.SuspendDialogInfo;
+import android.content.pm.overlay.OverlayPaths;
 import android.os.PersistableBundle;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -346,4 +349,40 @@
         assertLastPackageUsageSet(
                 testState6, PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT - 1, 60L);
     }
+
+    @Test
+    public void testOverlayPaths() {
+        final PackageUserState testState = new PackageUserState();
+        assertFalse(testState.setOverlayPaths(null));
+        assertFalse(testState.setOverlayPaths(new OverlayPaths.Builder().build()));
+
+        assertTrue(testState.setOverlayPaths(new OverlayPaths.Builder()
+                .addApkPath("/path/to/some.apk").build()));
+        assertFalse(testState.setOverlayPaths(new OverlayPaths.Builder()
+                .addApkPath("/path/to/some.apk").build()));
+
+        assertTrue(testState.setOverlayPaths(new OverlayPaths.Builder().build()));
+        assertFalse(testState.setOverlayPaths(null));
+    }
+    @Test
+    public void testSharedLibOverlayPaths() {
+        final PackageUserState testState = new PackageUserState();
+        final String LIB_ONE = "lib1";
+        final String LIB_TW0 = "lib2";
+        assertFalse(testState.setSharedLibraryOverlayPaths(LIB_ONE, null));
+        assertFalse(testState.setSharedLibraryOverlayPaths(LIB_ONE,
+                new OverlayPaths.Builder().build()));
+
+        assertTrue(testState.setSharedLibraryOverlayPaths(LIB_ONE, new OverlayPaths.Builder()
+                .addApkPath("/path/to/some.apk").build()));
+        assertFalse(testState.setSharedLibraryOverlayPaths(LIB_ONE, new OverlayPaths.Builder()
+                .addApkPath("/path/to/some.apk").build()));
+        assertTrue(testState.setSharedLibraryOverlayPaths(LIB_TW0, new OverlayPaths.Builder()
+                .addApkPath("/path/to/some.apk").build()));
+
+        assertTrue(testState.setSharedLibraryOverlayPaths(LIB_ONE,
+                new OverlayPaths.Builder().build()));
+        assertFalse(testState.setSharedLibraryOverlayPaths(LIB_ONE, null));
+    }
+
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt b/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt
index 61252c4..ff0aec7 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt
+++ b/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt
@@ -248,6 +248,7 @@
             .ignored("Deferred pre-R, but assigned immediately in R")}
             requiresSmallestWidthDp=${this.requiresSmallestWidthDp}
             resourceDirs=${this.resourceDirs?.contentToString()}
+            overlayPaths=${this.overlayPaths?.contentToString()}
             roundIconRes=${this.roundIconRes}
             scanPublicSourceDir=${this.scanPublicSourceDir
             .ignored("Deferred pre-R, but assigned immediately in R")}
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
index 7d20879..3ff8e76 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
@@ -27,8 +28,10 @@
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.hardware.vibrator.IVibrator;
+import android.hardware.vibrator.IVibratorManager;
 import android.os.CombinedVibrationEffect;
 import android.os.IBinder;
 import android.os.PowerManager;
@@ -388,6 +391,20 @@
     }
 
     @Test
+    public void vibrate_singleVibrator_skipsSyncedCallbacks() {
+        mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+
+        long vibrationId = 1;
+        waitForCompletion(startThreadAndDispatcher(vibrationId++,
+                VibrationEffect.createOneShot(10, 100)));
+
+        verify(mThreadCallbacks).onVibrationEnded(anyLong(), eq(Vibration.Status.FINISHED));
+        verify(mThreadCallbacks, never()).prepareSyncedVibration(anyLong(), any());
+        verify(mThreadCallbacks, never()).triggerSyncedVibration(anyLong());
+        verify(mThreadCallbacks, never()).cancelSyncedVibration();
+    }
+
+    @Test
     public void vibrate_multipleExistingAndMissingVibrators_vibratesOnlyExistingOnes()
             throws Exception {
         mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_TICK);
@@ -484,8 +501,7 @@
     }
 
     @Test
-    public void vibrate_multipleSequential_runsVibrationInOrderWithDelays()
-            throws Exception {
+    public void vibrate_multipleSequential_runsVibrationInOrderWithDelays() throws Exception {
         mockVibrators(1, 2, 3);
         mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
         mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
@@ -529,6 +545,126 @@
     }
 
     @Test
+    public void vibrate_multipleSyncedCallbackTriggered_finishSteps() throws Exception {
+        int[] vibratorIds = new int[]{1, 2};
+        long vibrationId = 1;
+        mockVibrators(vibratorIds);
+        mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
+        mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
+        when(mThreadCallbacks.prepareSyncedVibration(anyLong(), eq(vibratorIds))).thenReturn(true);
+        when(mThreadCallbacks.triggerSyncedVibration(eq(vibrationId))).thenReturn(true);
+
+        VibrationEffect composed = VibrationEffect.startComposition()
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 100)
+                .compose();
+        CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(composed);
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+
+        assertTrue(waitUntil(t -> !mVibratorProviders.get(1).getEffects().isEmpty()
+                && !mVibratorProviders.get(2).getEffects().isEmpty(), thread, TEST_TIMEOUT_MILLIS));
+        thread.syncedVibrationComplete();
+        waitForCompletion(thread);
+
+        long expectedCap = IVibratorManager.CAP_SYNC | IVibratorManager.CAP_PREPARE_COMPOSE;
+        verify(mThreadCallbacks).prepareSyncedVibration(eq(expectedCap), eq(vibratorIds));
+        verify(mThreadCallbacks).triggerSyncedVibration(eq(vibrationId));
+        verify(mThreadCallbacks, never()).cancelSyncedVibration();
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.FINISHED));
+
+        assertEquals(Arrays.asList(composed), mVibratorProviders.get(1).getEffects());
+        assertEquals(Arrays.asList(composed), mVibratorProviders.get(2).getEffects());
+    }
+
+    @Test
+    public void vibrate_multipleSynced_callsPrepareAndTriggerCallbacks() {
+        int[] vibratorIds = new int[]{1, 2, 3, 4};
+        mockVibrators(vibratorIds);
+        mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+        mVibratorProviders.get(4).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
+        when(mThreadCallbacks.prepareSyncedVibration(anyLong(), any())).thenReturn(true);
+        when(mThreadCallbacks.triggerSyncedVibration(anyLong())).thenReturn(true);
+
+        long vibrationId = 1;
+        VibrationEffect composed = VibrationEffect.startComposition()
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
+                .compose();
+        CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+                .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+                .addVibrator(2, VibrationEffect.createOneShot(10, 100))
+                .addVibrator(3, VibrationEffect.createWaveform(new long[]{10}, new int[]{100}, -1))
+                .addVibrator(4, composed)
+                .combine();
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion(thread);
+
+        long expectedCap = IVibratorManager.CAP_SYNC
+                | IVibratorManager.CAP_PREPARE_ON
+                | IVibratorManager.CAP_PREPARE_PERFORM
+                | IVibratorManager.CAP_PREPARE_COMPOSE
+                | IVibratorManager.CAP_MIXED_TRIGGER_ON
+                | IVibratorManager.CAP_MIXED_TRIGGER_PERFORM
+                | IVibratorManager.CAP_MIXED_TRIGGER_COMPOSE;
+        verify(mThreadCallbacks).prepareSyncedVibration(eq(expectedCap), eq(vibratorIds));
+        verify(mThreadCallbacks).triggerSyncedVibration(eq(vibrationId));
+        verify(mThreadCallbacks, never()).cancelSyncedVibration();
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.FINISHED));
+    }
+
+    @Test
+    public void vibrate_multipleSyncedPrepareFailed_skipTriggerStepAndVibrates() {
+        int[] vibratorIds = new int[]{1, 2};
+        mockVibrators(vibratorIds);
+        mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+        mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+        when(mThreadCallbacks.prepareSyncedVibration(anyLong(), any())).thenReturn(false);
+
+        long vibrationId = 1;
+        CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+                .addVibrator(1, VibrationEffect.createOneShot(10, 100))
+                .addVibrator(2, VibrationEffect.createWaveform(new long[]{5}, new int[]{200}, -1))
+                .combine();
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion(thread);
+
+        long expectedCap = IVibratorManager.CAP_SYNC | IVibratorManager.CAP_PREPARE_ON;
+        verify(mThreadCallbacks).prepareSyncedVibration(eq(expectedCap), eq(vibratorIds));
+        verify(mThreadCallbacks, never()).triggerSyncedVibration(eq(vibrationId));
+        verify(mThreadCallbacks, never()).cancelSyncedVibration();
+
+        assertEquals(Arrays.asList(expectedOneShot(10)), mVibratorProviders.get(1).getEffects());
+        assertEquals(Arrays.asList(100), mVibratorProviders.get(1).getAmplitudes());
+        assertEquals(Arrays.asList(expectedOneShot(5)), mVibratorProviders.get(2).getEffects());
+        assertEquals(Arrays.asList(200), mVibratorProviders.get(2).getAmplitudes());
+    }
+
+    @Test
+    public void vibrate_multipleSyncedTriggerFailed_cancelPreparedVibrationAndSkipSetAmplitude() {
+        int[] vibratorIds = new int[]{1, 2};
+        mockVibrators(vibratorIds);
+        mVibratorProviders.get(2).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+        when(mThreadCallbacks.prepareSyncedVibration(anyLong(), any())).thenReturn(true);
+        when(mThreadCallbacks.triggerSyncedVibration(anyLong())).thenReturn(false);
+
+        long vibrationId = 1;
+        CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+                .addVibrator(1, VibrationEffect.createOneShot(10, 100))
+                .addVibrator(2, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+                .combine();
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion(thread);
+
+        long expectedCap = IVibratorManager.CAP_SYNC
+                | IVibratorManager.CAP_PREPARE_ON
+                | IVibratorManager.CAP_PREPARE_PERFORM
+                | IVibratorManager.CAP_MIXED_TRIGGER_ON
+                | IVibratorManager.CAP_MIXED_TRIGGER_PERFORM;
+        verify(mThreadCallbacks).prepareSyncedVibration(eq(expectedCap), eq(vibratorIds));
+        verify(mThreadCallbacks).triggerSyncedVibration(eq(vibrationId));
+        verify(mThreadCallbacks).cancelSyncedVibration();
+        assertTrue(mVibratorProviders.get(1).getAmplitudes().isEmpty());
+    }
+
+    @Test
     public void vibrate_multipleWaveforms_playsWaveformsInParallel() throws Exception {
         mockVibrators(1, 2, 3);
         mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
@@ -623,6 +759,7 @@
 
         assertTrue(waitUntil(t -> t.getVibrators().get(2).isVibrating(), vibrationThread,
                 TEST_TIMEOUT_MILLIS));
+        assertTrue(vibrationThread.isAlive());
 
         // Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
         // fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
index b3116d9..17c9411 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
@@ -15,6 +15,9 @@
  */
 package com.android.server.notification;
 
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Matchers.any;
@@ -138,6 +141,30 @@
     }
 
     @Test
+    public void testXmlMigratingAllowedAdjustments() throws Exception {
+        // Old tag, need migration
+        String xml = "<q_allowed_adjustments types=\"adj_1\"/>";
+
+        TypedXmlPullParser parser = Xml.newFastPullParser();
+        parser.setInput(new BufferedInputStream(
+                new ByteArrayInputStream(xml.toString().getBytes())), null);
+        parser.nextTag();
+        mAssistants.readExtraTag("q_allowed_adjustments", parser);
+        assertTrue(mAssistants.isAdjustmentAllowed("adj_1"));
+        assertEquals(mNm.DEFAULT_ALLOWED_ADJUSTMENTS.length + 1,
+                mAssistants.getAllowedAssistantAdjustments().size());
+
+        // New TAG
+        xml = "<s_allowed_adjustments types=\"adj_2\"/>";
+        parser.setInput(new BufferedInputStream(
+                new ByteArrayInputStream(xml.toString().getBytes())), null);
+        parser.nextTag();
+        mAssistants.readExtraTag("s_allowed_adjustments", parser);
+        assertTrue(mAssistants.isAdjustmentAllowed("adj_2"));
+        assertEquals(1, mAssistants.getAllowedAssistantAdjustments().size());
+    }
+
+    @Test
     public void testSetPackageOrComponentEnabled_onlyOnePackage() throws Exception {
         ComponentName component1 = ComponentName.unflattenFromString("package/Component1");
         ComponentName component2 = ComponentName.unflattenFromString("package/Component2");
diff --git a/tools/hiddenapi/Android.bp b/tools/hiddenapi/Android.bp
deleted file mode 100644
index e0eb06cb..0000000
--- a/tools/hiddenapi/Android.bp
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-python_binary_host {
-	name: "merge_csv",
-	main: "merge_csv.py",
-	srcs: ["merge_csv.py"],
-	version: {
-		py2: {
-			enabled: false,
-		},
-		py3: {
-			enabled: true,
-			embedded_launcher: true
-		},
-	},
-}
diff --git a/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py
deleted file mode 100755
index 28ff606..0000000
--- a/tools/hiddenapi/generate_hiddenapi_lists.py
+++ /dev/null
@@ -1,383 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-"""Generate API lists for non-SDK API enforcement."""
-import argparse
-from collections import defaultdict, namedtuple
-import functools
-import os
-import re
-import sys
-
-# Names of flags recognized by the `hiddenapi` tool.
-FLAG_SDK = 'sdk'
-FLAG_UNSUPPORTED = 'unsupported'
-FLAG_BLOCKED = 'blocked'
-FLAG_MAX_TARGET_O = 'max-target-o'
-FLAG_MAX_TARGET_P = 'max-target-p'
-FLAG_MAX_TARGET_Q = 'max-target-q'
-FLAG_MAX_TARGET_R = 'max-target-r'
-FLAG_CORE_PLATFORM_API = 'core-platform-api'
-FLAG_PUBLIC_API = 'public-api'
-FLAG_SYSTEM_API = 'system-api'
-FLAG_TEST_API = 'test-api'
-
-# List of all known flags.
-FLAGS_API_LIST = [
-    FLAG_SDK,
-    FLAG_UNSUPPORTED,
-    FLAG_BLOCKED,
-    FLAG_MAX_TARGET_O,
-    FLAG_MAX_TARGET_P,
-    FLAG_MAX_TARGET_Q,
-    FLAG_MAX_TARGET_R,
-]
-ALL_FLAGS = FLAGS_API_LIST + [
-    FLAG_CORE_PLATFORM_API,
-    FLAG_PUBLIC_API,
-    FLAG_SYSTEM_API,
-    FLAG_TEST_API,
-]
-
-FLAGS_API_LIST_SET = set(FLAGS_API_LIST)
-ALL_FLAGS_SET = set(ALL_FLAGS)
-
-# Option specified after one of FLAGS_API_LIST to indicate that
-# only known and otherwise unassigned entries should be assign the
-# given flag.
-# For example, the max-target-P list is checked in as it was in P,
-# but signatures have changes since then. The flag instructs this
-# script to skip any entries which do not exist any more.
-FLAG_IGNORE_CONFLICTS = "ignore-conflicts"
-
-# Option specified after one of FLAGS_API_LIST to express that all
-# apis within a given set of packages should be assign the given flag.
-FLAG_PACKAGES = "packages"
-
-# Option specified after one of FLAGS_API_LIST to indicate an extra
-# tag that should be added to the matching APIs.
-FLAG_TAG = "tag"
-
-# Regex patterns of fields/methods used in serialization. These are
-# considered public API despite being hidden.
-SERIALIZATION_PATTERNS = [
-    r'readObject\(Ljava/io/ObjectInputStream;\)V',
-    r'readObjectNoData\(\)V',
-    r'readResolve\(\)Ljava/lang/Object;',
-    r'serialVersionUID:J',
-    r'serialPersistentFields:\[Ljava/io/ObjectStreamField;',
-    r'writeObject\(Ljava/io/ObjectOutputStream;\)V',
-    r'writeReplace\(\)Ljava/lang/Object;',
-]
-
-# Single regex used to match serialization API. It combines all the
-# SERIALIZATION_PATTERNS into a single regular expression.
-SERIALIZATION_REGEX = re.compile(r'.*->(' + '|'.join(SERIALIZATION_PATTERNS) + r')$')
-
-# Predicates to be used with filter_apis.
-HAS_NO_API_LIST_ASSIGNED = lambda api, flags: not FLAGS_API_LIST_SET.intersection(flags)
-IS_SERIALIZATION = lambda api, flags: SERIALIZATION_REGEX.match(api)
-
-
-class StoreOrderedOptions(argparse.Action):
-    """An argparse action that stores a number of option arguments in the order that
-    they were specified.
-    """
-    def __call__(self, parser, args, values, option_string = None):
-        items = getattr(args, self.dest, None)
-        if items is None:
-            items = []
-        items.append([option_string.lstrip('-'), values])
-        setattr(args, self.dest, items)
-
-def get_args():
-    """Parses command line arguments.
-
-    Returns:
-        Namespace: dictionary of parsed arguments
-    """
-    parser = argparse.ArgumentParser()
-    parser.add_argument('--output', required=True)
-    parser.add_argument('--csv', nargs='*', default=[], metavar='CSV_FILE',
-        help='CSV files to be merged into output')
-
-    for flag in ALL_FLAGS:
-        parser.add_argument('--' + flag, dest='ordered_flags', metavar='TXT_FILE',
-            action=StoreOrderedOptions, help='lists of entries with flag "' + flag + '"')
-    parser.add_argument('--' + FLAG_IGNORE_CONFLICTS, dest='ordered_flags', nargs=0,
-        action=StoreOrderedOptions, help='Indicates that only known and otherwise unassigned '
-        'entries should be assign the given flag. Must follow a list of entries and applies '
-        'to the preceding such list.')
-    parser.add_argument('--' + FLAG_PACKAGES, dest='ordered_flags', nargs=0,
-        action=StoreOrderedOptions, help='Indicates that the previous list of entries '
-        'is a list of packages. All members in those packages will be given the flag. '
-        'Must follow a list of entries and applies to the preceding such list.')
-    parser.add_argument('--' + FLAG_TAG, dest='ordered_flags', nargs=1,
-        action=StoreOrderedOptions, help='Adds an extra tag to the previous list of entries. '
-        'Must follow a list of entries and applies to the preceding such list.')
-
-    return parser.parse_args()
-
-
-def read_lines(filename):
-    """Reads entire file and return it as a list of lines.
-
-    Lines which begin with a hash are ignored.
-
-    Args:
-        filename (string): Path to the file to read from.
-
-    Returns:
-        Lines of the file as a list of string.
-    """
-    with open(filename, 'r') as f:
-        lines = f.readlines();
-    lines = filter(lambda line: not line.startswith('#'), lines)
-    lines = map(lambda line: line.strip(), lines)
-    return set(lines)
-
-
-def write_lines(filename, lines):
-    """Writes list of lines into a file, overwriting the file if it exists.
-
-    Args:
-        filename (string): Path to the file to be writting into.
-        lines (list): List of strings to write into the file.
-    """
-    lines = map(lambda line: line + '\n', lines)
-    with open(filename, 'w') as f:
-        f.writelines(lines)
-
-
-def extract_package(signature):
-    """Extracts the package from a signature.
-
-    Args:
-        signature (string): JNI signature of a method or field.
-
-    Returns:
-        The package name of the class containing the field/method.
-    """
-    full_class_name = signature.split(";->")[0]
-    # Example: Landroid/hardware/radio/V1_2/IRadio$Proxy
-    if (full_class_name[0] != "L"):
-        raise ValueError("Expected to start with 'L': %s" % full_class_name)
-    full_class_name = full_class_name[1:]
-    # If full_class_name doesn't contain '/', then package_name will be ''.
-    package_name = full_class_name.rpartition("/")[0]
-    return package_name.replace('/', '.')
-
-
-class FlagsDict:
-    def __init__(self):
-        self._dict_keyset = set()
-        self._dict = defaultdict(set)
-
-    def _check_entries_set(self, keys_subset, source):
-        assert isinstance(keys_subset, set)
-        assert keys_subset.issubset(self._dict_keyset), (
-            "Error: {} specifies signatures not present in code:\n"
-            "{}"
-            "Please visit go/hiddenapi for more information.").format(
-                source, "".join(map(lambda x: "  " + str(x) + "\n", keys_subset - self._dict_keyset)))
-
-    def _check_flags_set(self, flags_subset, source):
-        assert isinstance(flags_subset, set)
-        assert flags_subset.issubset(ALL_FLAGS_SET), (
-            "Error processing: {}\n"
-            "The following flags were not recognized: \n"
-            "{}\n"
-            "Please visit go/hiddenapi for more information.").format(
-                source, "\n".join(flags_subset - ALL_FLAGS_SET))
-
-    def filter_apis(self, filter_fn):
-        """Returns APIs which match a given predicate.
-
-        This is a helper function which allows to filter on both signatures (keys) and
-        flags (values). The built-in filter() invokes the lambda only with dict's keys.
-
-        Args:
-            filter_fn : Function which takes two arguments (signature/flags) and returns a boolean.
-
-        Returns:
-            A set of APIs which match the predicate.
-        """
-        return set(filter(lambda x: filter_fn(x, self._dict[x]), self._dict_keyset))
-
-    def get_valid_subset_of_unassigned_apis(self, api_subset):
-        """Sanitizes a key set input to only include keys which exist in the dictionary
-        and have not been assigned any API list flags.
-
-        Args:
-            entries_subset (set/list): Key set to be sanitized.
-
-        Returns:
-            Sanitized key set.
-        """
-        assert isinstance(api_subset, set)
-        return api_subset.intersection(self.filter_apis(HAS_NO_API_LIST_ASSIGNED))
-
-    def generate_csv(self):
-        """Constructs CSV entries from a dictionary.
-
-        Old versions of flags are used to generate the file.
-
-        Returns:
-            List of lines comprising a CSV file. See "parse_and_merge_csv" for format description.
-        """
-        lines = []
-        for api in self._dict:
-          flags = sorted(self._dict[api])
-          lines.append(",".join([api] + flags))
-        return sorted(lines)
-
-    def parse_and_merge_csv(self, csv_lines, source = "<unknown>"):
-        """Parses CSV entries and merges them into a given dictionary.
-
-        The expected CSV format is:
-            <api signature>,<flag1>,<flag2>,...,<flagN>
-
-        Args:
-            csv_lines (list of strings): Lines read from a CSV file.
-            source (string): Origin of `csv_lines`. Will be printed in error messages.
-
-        Throws:
-            AssertionError if parsed flags are invalid.
-        """
-        # Split CSV lines into arrays of values.
-        csv_values = [ line.split(',') for line in csv_lines ]
-
-        # Update the full set of API signatures.
-        self._dict_keyset.update([ csv[0] for csv in csv_values ])
-
-        # Check that all flags are known.
-        csv_flags = set()
-        for csv in csv_values:
-          csv_flags.update(csv[1:])
-        self._check_flags_set(csv_flags, source)
-
-        # Iterate over all CSV lines, find entry in dict and append flags to it.
-        for csv in csv_values:
-            flags = csv[1:]
-            if (FLAG_PUBLIC_API in flags) or (FLAG_SYSTEM_API in flags):
-                flags.append(FLAG_SDK)
-            self._dict[csv[0]].update(flags)
-
-    def assign_flag(self, flag, apis, source="<unknown>", tag = None):
-        """Assigns a flag to given subset of entries.
-
-        Args:
-            flag (string): One of ALL_FLAGS.
-            apis (set): Subset of APIs to receive the flag.
-            source (string): Origin of `entries_subset`. Will be printed in error messages.
-
-        Throws:
-            AssertionError if parsed API signatures of flags are invalid.
-        """
-        # Check that all APIs exist in the dict.
-        self._check_entries_set(apis, source)
-
-        # Check that the flag is known.
-        self._check_flags_set(set([ flag ]), source)
-
-        # Iterate over the API subset, find each entry in dict and assign the flag to it.
-        for api in apis:
-            self._dict[api].add(flag)
-            if tag:
-                self._dict[api].add(tag)
-
-
-FlagFile = namedtuple('FlagFile', ('flag', 'file', 'ignore_conflicts', 'packages', 'tag'))
-
-def parse_ordered_flags(ordered_flags):
-    r = []
-    currentflag, file, ignore_conflicts, packages, tag = None, None, False, False, None
-    for flag_value in ordered_flags:
-        flag, value = flag_value[0], flag_value[1]
-        if flag in ALL_FLAGS_SET:
-            if currentflag:
-                r.append(FlagFile(currentflag, file, ignore_conflicts, packages, tag))
-                ignore_conflicts, packages, tag = False, False, None
-            currentflag = flag
-            file = value
-        else:
-            if currentflag is None:
-                raise argparse.ArgumentError('--%s is only allowed after one of %s' % (
-                    flag, ' '.join(['--%s' % f for f in ALL_FLAGS_SET])))
-            if flag == FLAG_IGNORE_CONFLICTS:
-                ignore_conflicts = True
-            elif flag == FLAG_PACKAGES:
-                packages = True
-            elif flag == FLAG_TAG:
-                tag = value[0]
-
-
-    if currentflag:
-        r.append(FlagFile(currentflag, file, ignore_conflicts, packages, tag))
-    return r
-
-
-def main(argv):
-    # Parse arguments.
-    args = vars(get_args())
-    flagfiles = parse_ordered_flags(args['ordered_flags'])
-
-    # Initialize API->flags dictionary.
-    flags = FlagsDict()
-
-    # Merge input CSV files into the dictionary.
-    # Do this first because CSV files produced by parsing API stubs will
-    # contain the full set of APIs. Subsequent additions from text files
-    # will be able to detect invalid entries, and/or filter all as-yet
-    # unassigned entries.
-    for filename in args["csv"]:
-        flags.parse_and_merge_csv(read_lines(filename), filename)
-
-    # Combine inputs which do not require any particular order.
-    # (1) Assign serialization API to SDK.
-    flags.assign_flag(FLAG_SDK, flags.filter_apis(IS_SERIALIZATION))
-
-    # (2) Merge text files with a known flag into the dictionary.
-    for info in flagfiles:
-        if (not info.ignore_conflicts) and (not info.packages):
-            flags.assign_flag(info.flag, read_lines(info.file), info.file, info.tag)
-
-    # Merge text files where conflicts should be ignored.
-    # This will only assign the given flag if:
-    # (a) the entry exists, and
-    # (b) it has not been assigned any other flag.
-    # Because of (b), this must run after all strict assignments have been performed.
-    for info in flagfiles:
-        if info.ignore_conflicts:
-            valid_entries = flags.get_valid_subset_of_unassigned_apis(read_lines(info.file))
-            flags.assign_flag(info.flag, valid_entries, filename, info.tag)
-
-    # All members in the specified packages will be assigned the appropriate flag.
-    for info in flagfiles:
-        if info.packages:
-            packages_needing_list = set(read_lines(info.file))
-            should_add_signature_to_list = lambda sig,lists: extract_package(
-                sig) in packages_needing_list and not lists
-            valid_entries = flags.filter_apis(should_add_signature_to_list)
-            flags.assign_flag(info.flag, valid_entries, info.file, info.tag)
-
-    # Mark all remaining entries as blocked.
-    flags.assign_flag(FLAG_BLOCKED, flags.filter_apis(HAS_NO_API_LIST_ASSIGNED))
-
-    # Write output.
-    write_lines(args["output"], flags.generate_csv())
-
-if __name__ == "__main__":
-    main(sys.argv)
diff --git a/tools/hiddenapi/generate_hiddenapi_lists_test.py b/tools/hiddenapi/generate_hiddenapi_lists_test.py
deleted file mode 100755
index 82d117f..0000000
--- a/tools/hiddenapi/generate_hiddenapi_lists_test.py
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-"""Unit tests for Hidden API list generation."""
-import unittest
-from generate_hiddenapi_lists import *
-
-class TestHiddenapiListGeneration(unittest.TestCase):
-
-    def test_filter_apis(self):
-        # Initialize flags so that A and B are put on the whitelist and
-        # C, D, E are left unassigned. Try filtering for the unassigned ones.
-        flags = FlagsDict()
-        flags.parse_and_merge_csv(['A,' + FLAG_SDK, 'B,' + FLAG_SDK,
-                        'C', 'D', 'E'])
-        filter_set = flags.filter_apis(lambda api, flags: not flags)
-        self.assertTrue(isinstance(filter_set, set))
-        self.assertEqual(filter_set, set([ 'C', 'D', 'E' ]))
-
-    def test_get_valid_subset_of_unassigned_keys(self):
-        # Create flags where only A is unassigned.
-        flags = FlagsDict()
-        flags.parse_and_merge_csv(['A,' + FLAG_SDK, 'B', 'C'])
-        flags.assign_flag(FLAG_UNSUPPORTED, set(['C']))
-        self.assertEqual(flags.generate_csv(),
-            [ 'A,' + FLAG_SDK, 'B', 'C,' + FLAG_UNSUPPORTED ])
-
-        # Check three things:
-        # (1) B is selected as valid unassigned
-        # (2) A is not selected because it is assigned 'whitelist'
-        # (3) D is not selected because it is not a valid key
-        self.assertEqual(
-            flags.get_valid_subset_of_unassigned_apis(set(['A', 'B', 'D'])), set([ 'B' ]))
-
-    def test_parse_and_merge_csv(self):
-        flags = FlagsDict()
-
-        # Test empty CSV entry.
-        self.assertEqual(flags.generate_csv(), [])
-
-        # Test new additions.
-        flags.parse_and_merge_csv([
-            'A,' + FLAG_UNSUPPORTED,
-            'B,' + FLAG_BLOCKED + ',' + FLAG_MAX_TARGET_O,
-            'C,' + FLAG_SDK + ',' + FLAG_SYSTEM_API,
-            'D,' + FLAG_UNSUPPORTED + ',' + FLAG_TEST_API,
-            'E,' + FLAG_BLOCKED + ',' + FLAG_TEST_API,
-        ])
-        self.assertEqual(flags.generate_csv(), [
-            'A,' + FLAG_UNSUPPORTED,
-            'B,' + FLAG_BLOCKED + "," + FLAG_MAX_TARGET_O,
-            'C,' + FLAG_SYSTEM_API + ',' + FLAG_SDK,
-            'D,' + FLAG_UNSUPPORTED + ',' + FLAG_TEST_API,
-            'E,' + FLAG_BLOCKED + ',' + FLAG_TEST_API,
-        ])
-
-        # Test unknown flag.
-        with self.assertRaises(AssertionError):
-            flags.parse_and_merge_csv([ 'Z,foo' ])
-
-    def test_assign_flag(self):
-        flags = FlagsDict()
-        flags.parse_and_merge_csv(['A,' + FLAG_SDK, 'B'])
-
-        # Test new additions.
-        flags.assign_flag(FLAG_UNSUPPORTED, set([ 'A', 'B' ]))
-        self.assertEqual(flags.generate_csv(),
-            [ 'A,' + FLAG_UNSUPPORTED + "," + FLAG_SDK, 'B,' + FLAG_UNSUPPORTED ])
-
-        # Test invalid API signature.
-        with self.assertRaises(AssertionError):
-            flags.assign_flag(FLAG_SDK, set([ 'C' ]))
-
-        # Test invalid flag.
-        with self.assertRaises(AssertionError):
-            flags.assign_flag('foo', set([ 'A' ]))
-
-    def test_extract_package(self):
-        signature = 'Lcom/foo/bar/Baz;->method1()Lcom/bar/Baz;'
-        expected_package = 'com.foo.bar'
-        self.assertEqual(extract_package(signature), expected_package)
-
-        signature = 'Lcom/foo1/bar/MyClass;->method2()V'
-        expected_package = 'com.foo1.bar'
-        self.assertEqual(extract_package(signature), expected_package)
-
-        signature = 'Lcom/foo_bar/baz/MyClass;->method3()V'
-        expected_package = 'com.foo_bar.baz'
-        self.assertEqual(extract_package(signature), expected_package)
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/tools/hiddenapi/merge_csv.py b/tools/hiddenapi/merge_csv.py
deleted file mode 100755
index 6a5b0e1..0000000
--- a/tools/hiddenapi/merge_csv.py
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-"""
-Merge multiple CSV files, possibly with different columns.
-"""
-
-import argparse
-import csv
-import io
-
-from zipfile import ZipFile
-
-args_parser = argparse.ArgumentParser(description='Merge given CSV files into a single one.')
-args_parser.add_argument('--header', help='Comma separated field names; '
-                                          'if missing determines the header from input files.')
-args_parser.add_argument('--zip_input', help='ZIP archive with all CSV files to merge.')
-args_parser.add_argument('--output', help='Output file for merged CSV.',
-                         default='-', type=argparse.FileType('w'))
-args_parser.add_argument('files', nargs=argparse.REMAINDER)
-args = args_parser.parse_args()
-
-
-def dict_reader(input):
-    return csv.DictReader(input, delimiter=',', quotechar='|')
-
-
-if args.zip_input and len(args.files) > 0:
-    raise ValueError('Expecting either a single ZIP with CSV files'
-                     ' or a list of CSV files as input; not both.')
-
-csv_readers = []
-if len(args.files) > 0:
-    for file in args.files:
-        csv_readers.append(dict_reader(open(file, 'r')))
-elif args.zip_input:
-    with ZipFile(args.zip_input) as zip:
-        for entry in zip.namelist():
-            if entry.endswith('.uau'):
-                csv_readers.append(dict_reader(io.TextIOWrapper(zip.open(entry, 'r'))))
-
-headers = set()
-if args.header:
-    fieldnames = args.header.split(',')
-else:
-    # Build union of all columns from source files:
-    for reader in csv_readers:
-        headers = headers.union(reader.fieldnames)
-    fieldnames = sorted(headers)
-
-# Concatenate all files to output:
-writer = csv.DictWriter(args.output, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL,
-                        dialect='unix', fieldnames=fieldnames)
-writer.writeheader()
-for reader in csv_readers:
-    for row in reader:
-        writer.writerow(row)