Merge "Make mapIntentToUri understand meta-data hookup"
diff --git a/api/current.txt b/api/current.txt
index 3bf3e04..c0223b7 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -16276,9 +16276,7 @@
     field public static final android.hardware.camera2.CaptureResult.Key<android.hardware.camera2.params.LensShadingMap> STATISTICS_LENS_SHADING_CORRECTION_MAP;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> STATISTICS_LENS_SHADING_MAP_MODE;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> STATISTICS_OIS_DATA_MODE;
-    field public static final android.hardware.camera2.CaptureResult.Key<long[]> STATISTICS_OIS_TIMESTAMPS;
-    field public static final android.hardware.camera2.CaptureResult.Key<float[]> STATISTICS_OIS_X_SHIFTS;
-    field public static final android.hardware.camera2.CaptureResult.Key<float[]> STATISTICS_OIS_Y_SHIFTS;
+    field public static final android.hardware.camera2.CaptureResult.Key<android.hardware.camera2.params.OisSample[]> STATISTICS_OIS_SAMPLES;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> STATISTICS_SCENE_FLICKER;
     field public static final android.hardware.camera2.CaptureResult.Key<android.hardware.camera2.params.TonemapCurve> TONEMAP_CURVE;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Float> TONEMAP_GAMMA;
@@ -16374,6 +16372,13 @@
     field public static final int METERING_WEIGHT_MIN = 0; // 0x0
   }
 
+  public final class OisSample {
+    ctor public OisSample(long, float, float);
+    method public long getTimestamp();
+    method public float getXshift();
+    method public float getYshift();
+  }
+
   public final class OutputConfiguration implements android.os.Parcelable {
     ctor public OutputConfiguration(android.view.Surface);
     ctor public OutputConfiguration(int, android.view.Surface);
@@ -24076,13 +24081,14 @@
     method public static final android.media.MediaPlayer2 create();
     method public abstract void deselectTrack(int);
     method public abstract android.media.DataSourceDesc editPlaylistItem(int, android.media.DataSourceDesc);
+    method public abstract android.media.AudioAttributes getAudioAttributes();
     method public abstract int getAudioSessionId();
     method public abstract android.media.DataSourceDesc getCurrentDataSource();
     method public abstract int getCurrentPlaylistItemIndex();
-    method public abstract int getCurrentPosition();
+    method public abstract long getCurrentPosition();
     method public abstract android.media.MediaPlayer2.DrmInfo getDrmInfo();
     method public abstract java.lang.String getDrmPropertyString(java.lang.String) throws android.media.MediaPlayer2.NoDrmSchemeException;
-    method public abstract int getDuration();
+    method public abstract long getDuration();
     method public abstract android.media.MediaDrm.KeyRequest getKeyRequest(byte[], byte[], java.lang.String, int, java.util.Map<java.lang.String, java.lang.String>) throws android.media.MediaPlayer2.NoDrmSchemeException;
     method public abstract int getLoopingMode();
     method public abstract android.os.PersistableBundle getMetrics();
@@ -24168,8 +24174,8 @@
 
   public static abstract class MediaPlayer2.DrmEventCallback {
     ctor public MediaPlayer2.DrmEventCallback();
-    method public void onDrmInfo(android.media.MediaPlayer2, android.media.MediaPlayer2.DrmInfo);
-    method public void onDrmPrepared(android.media.MediaPlayer2, int);
+    method public void onDrmInfo(android.media.MediaPlayer2, long, android.media.MediaPlayer2.DrmInfo);
+    method public void onDrmPrepared(android.media.MediaPlayer2, long, int);
   }
 
   public static abstract class MediaPlayer2.DrmInfo {
@@ -24207,7 +24213,7 @@
   }
 
   public static abstract interface MediaPlayer2.OnDrmConfigHelper {
-    method public abstract void onDrmConfig(android.media.MediaPlayer2);
+    method public abstract void onDrmConfig(android.media.MediaPlayer2, long);
   }
 
   public static abstract class MediaPlayer2.ProvisioningNetworkErrorException extends android.media.MediaDrmException {
@@ -38433,7 +38439,6 @@
     method public boolean isRandomizedEncryptionRequired();
     method public boolean isStrongBoxBacked();
     method public boolean isTrustedUserPresenceRequired();
-    method public boolean isUnlockedDeviceRequired();
     method public boolean isUserAuthenticationRequired();
     method public boolean isUserAuthenticationValidWhileOnBody();
     method public boolean isUserConfirmationRequired();
@@ -38461,7 +38466,6 @@
     method public android.security.keystore.KeyGenParameterSpec.Builder setRandomizedEncryptionRequired(boolean);
     method public android.security.keystore.KeyGenParameterSpec.Builder setSignaturePaddings(java.lang.String...);
     method public android.security.keystore.KeyGenParameterSpec.Builder setTrustedUserPresenceRequired(boolean);
-    method public android.security.keystore.KeyGenParameterSpec.Builder setUnlockedDeviceRequired(boolean);
     method public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationRequired(boolean);
     method public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationValidWhileOnBody(boolean);
     method public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationValidityDurationSeconds(int);
@@ -38553,8 +38557,6 @@
     method public boolean isDigestsSpecified();
     method public boolean isInvalidatedByBiometricEnrollment();
     method public boolean isRandomizedEncryptionRequired();
-    method public boolean isTrustedUserPresenceRequired();
-    method public boolean isUnlockedDeviceRequired();
     method public boolean isUserAuthenticationRequired();
     method public boolean isUserAuthenticationValidWhileOnBody();
     method public boolean isUserConfirmationRequired();
@@ -38573,8 +38575,6 @@
     method public android.security.keystore.KeyProtection.Builder setKeyValidityStart(java.util.Date);
     method public android.security.keystore.KeyProtection.Builder setRandomizedEncryptionRequired(boolean);
     method public android.security.keystore.KeyProtection.Builder setSignaturePaddings(java.lang.String...);
-    method public android.security.keystore.KeyProtection.Builder setTrustedUserPresenceRequired(boolean);
-    method public android.security.keystore.KeyProtection.Builder setUnlockedDeviceRequired(boolean);
     method public android.security.keystore.KeyProtection.Builder setUserAuthenticationRequired(boolean);
     method public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidWhileOnBody(boolean);
     method public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidityDurationSeconds(int);
@@ -47622,6 +47622,7 @@
     method public void setAlpha(float);
     method public void setAnimation(android.view.animation.Animation);
     method public void setAutofillHints(java.lang.String...);
+    method public void setAutofillId(android.view.autofill.AutofillId);
     method public void setBackground(android.graphics.drawable.Drawable);
     method public void setBackgroundColor(int);
     method public deprecated void setBackgroundDrawable(android.graphics.drawable.Drawable);
@@ -49785,6 +49786,7 @@
     method public android.content.ComponentName getAutofillServiceComponentName();
     method public java.util.List<java.lang.String> getAvailableFieldClassificationAlgorithms();
     method public java.lang.String getDefaultFieldClassificationAlgorithm();
+    method public android.view.autofill.AutofillId getNextAutofillId();
     method public android.service.autofill.UserData getUserData();
     method public java.lang.String getUserDataId();
     method public boolean hasEnabledAutofillServices();
diff --git a/api/system-current.txt b/api/system-current.txt
index 1235591..d24a313 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4292,6 +4292,7 @@
   }
 
   public class RecoveryController {
+    method public android.security.keystore.recovery.RecoverySession createRecoverySession();
     method public byte[] generateAndStoreKey(java.lang.String, byte[]) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.LockScreenRequiredException;
     method public java.util.List<java.lang.String> getAliases(java.lang.String) throws android.security.keystore.recovery.InternalRecoveryServiceException;
     method public static android.security.keystore.recovery.RecoveryController getInstance(android.content.Context);
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.cpp b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
index babe0fc..c40eb81 100644
--- a/cmds/statsd/src/anomaly/AnomalyTracker.cpp
+++ b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
@@ -233,11 +233,19 @@
 void AnomalyTracker::informSubscribers(const MetricDimensionKey& key) {
     VLOG("informSubscribers called.");
     if (mSubscriptions.empty()) {
-        ALOGE("Attempt to call with no subscribers.");
+        // The config just wanted to log the anomaly. That's fine.
+        VLOG("No Subscriptions were associated with the alert.");
         return;
     }
 
     for (const Subscription& subscription : mSubscriptions) {
+        if (subscription.probability_of_informing() < 1
+                && ((float)rand() / RAND_MAX) >= subscription.probability_of_informing()) {
+            // Note that due to float imprecision, 0.0 and 1.0 might not truly mean never/always.
+            // The config writer was advised to use -0.1 and 1.1 for never/always.
+            ALOGI("Fate decided that a subscriber would not be informed.");
+            continue;
+        }
         switch (subscription.subscriber_information_case()) {
             case Subscription::SubscriberInformationCase::kIncidentdDetails:
                 if (!GenerateIncidentReport(subscription.incidentd_details(), mAlert, mConfigKey)) {
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index 8750275..a313854 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -307,6 +307,8 @@
     PerfettoDetails perfetto_details = 5;
     BroadcastSubscriberDetails broadcast_subscriber_details = 6;
   }
+
+  optional float probability_of_informing = 7 [default = 1.1];
 }
 
 message StatsdConfig {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index ccbf21b..3ebe89f 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1400,6 +1400,7 @@
      *
      * {@hide}
      */
+    @Override
     public int getNextAutofillId() {
         if (mLastAutofillId == Integer.MAX_VALUE - 1) {
             mLastAutofillId = View.LAST_APP_AUTOFILL_ID;
@@ -1411,6 +1412,14 @@
     }
 
     /**
+     * @hide
+     */
+    @Override
+    public AutofillId autofillClientGetNextAutofillId() {
+        return new AutofillId(getNextAutofillId());
+    }
+
+    /**
      * Check whether this activity is running as part of a voice interaction with the user.
      * If true, it should perform its interaction with the user through the
      * {@link VoiceInteractor} returned by {@link #getVoiceInteractor}.
@@ -7624,6 +7633,19 @@
 
     /** @hide */
     @Override
+    public final void autofillClientDispatchUnhandledKey(@NonNull View anchor,
+            @NonNull KeyEvent keyEvent) {
+        ViewRootImpl rootImpl = anchor.getViewRootImpl();
+        if (rootImpl != null) {
+            // dont care if anchorView is current focus, for example a custom view may only receive
+            // touchEvent, not focusable but can still trigger autofill window. The Key handling
+            // might be inside parent of the custom view.
+            rootImpl.dispatchKeyFromAutofill(keyEvent);
+        }
+    }
+
+    /** @hide */
+    @Override
     public final boolean autofillClientRequestHideFillUi() {
         if (mAutofillPopupWindow == null) {
             return false;
@@ -7739,7 +7761,7 @@
 
     /** @hide */
     @Override
-    public final boolean autofillIsCompatibilityModeEnabled() {
+    public final boolean autofillClientIsCompatibilityModeEnabled() {
         return isAutofillCompatibilityEnabled();
     }
 
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index d36a794..d1c957b 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -18,6 +18,7 @@
 
 import android.app.IBackupAgent;
 import android.app.QueuedWork;
+import android.app.backup.FullBackup.BackupScheme.PathWithRequiredFlags;
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.pm.ApplicationInfo;
@@ -343,8 +344,8 @@
             return;
         }
 
-        Map<String, Set<String>> manifestIncludeMap;
-        ArraySet<String> manifestExcludeSet;
+        Map<String, Set<PathWithRequiredFlags>> manifestIncludeMap;
+        ArraySet<PathWithRequiredFlags> manifestExcludeSet;
         try {
             manifestIncludeMap =
                     backupScheme.maybeParseAndGetCanonicalIncludePaths();
@@ -514,14 +515,13 @@
     /**
      * Check whether the xml yielded any <include/> tag for the provided <code>domainToken</code>.
      * If so, perform a {@link #fullBackupFileTree} which backs up the file or recurses if the path
-     * is a directory.
+     * is a directory, but only if all the required flags of the include rule are satisfied by
+     * the transport.
      */
     private void applyXmlFiltersAndDoFullBackupForDomain(String packageName, String domainToken,
-                                                         Map<String, Set<String>> includeMap,
-                                                         ArraySet<String> filterSet,
-                                                         ArraySet<String> traversalExcludeSet,
-                                                         FullBackupDataOutput data)
-            throws IOException {
+            Map<String, Set<PathWithRequiredFlags>> includeMap,
+            ArraySet<PathWithRequiredFlags> filterSet, ArraySet<String> traversalExcludeSet,
+            FullBackupDataOutput data) throws IOException {
         if (includeMap == null || includeMap.size() == 0) {
             // Do entire sub-tree for the provided token.
             fullBackupFileTree(packageName, domainToken,
@@ -530,13 +530,22 @@
         } else if (includeMap.get(domainToken) != null) {
             // This will be null if the xml parsing didn't yield any rules for
             // this domain (there may still be rules for other domains).
-            for (String includeFile : includeMap.get(domainToken)) {
-                fullBackupFileTree(packageName, domainToken, includeFile, filterSet,
-                        traversalExcludeSet, data);
+            for (PathWithRequiredFlags includeFile : includeMap.get(domainToken)) {
+                if (areIncludeRequiredTransportFlagsSatisfied(includeFile.getRequiredFlags(),
+                        data.getTransportFlags())) {
+                    fullBackupFileTree(packageName, domainToken, includeFile.getPath(), filterSet,
+                            traversalExcludeSet, data);
+                }
             }
         }
     }
 
+    private boolean areIncludeRequiredTransportFlagsSatisfied(int includeFlags,
+            int transportFlags) {
+        // all bits that are set in includeFlags must also be set in transportFlags
+        return (transportFlags & includeFlags) == includeFlags;
+    }
+
     /**
      * Write an entire file as part of a full-backup operation.  The file's contents
      * will be delivered to the backup destination along with the metadata necessary
@@ -683,7 +692,7 @@
      * @hide
      */
     protected final void fullBackupFileTree(String packageName, String domain, String startingPath,
-                                            ArraySet<String> manifestExcludes,
+                                            ArraySet<PathWithRequiredFlags> manifestExcludes,
                                             ArraySet<String> systemExcludes,
             FullBackupDataOutput output) {
         // Pull out the domain and set it aside to use when making the tarball.
@@ -714,7 +723,8 @@
                     filePath = file.getCanonicalPath();
 
                     // prune this subtree?
-                    if (manifestExcludes != null && manifestExcludes.contains(filePath)) {
+                    if (manifestExcludes != null
+                            && manifestExcludesContainFilePath(manifestExcludes, filePath)) {
                         continue;
                     }
                     if (systemExcludes != null && systemExcludes.contains(filePath)) {
@@ -750,6 +760,17 @@
         }
     }
 
+    private boolean manifestExcludesContainFilePath(
+        ArraySet<PathWithRequiredFlags> manifestExcludes, String filePath) {
+        for (PathWithRequiredFlags exclude : manifestExcludes) {
+            String excludePath = exclude.getPath();
+            if (excludePath != null && excludePath.equals(filePath)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Handle the data delivered via the given file descriptor during a full restore
      * operation.  The agent is given the path to the file's original location as well
@@ -796,8 +817,8 @@
             return false;
         }
 
-        Map<String, Set<String>> includes = null;
-        ArraySet<String> excludes = null;
+        Map<String, Set<PathWithRequiredFlags>> includes = null;
+        ArraySet<PathWithRequiredFlags> excludes = null;
         final String destinationCanonicalPath = destination.getCanonicalPath();
         try {
             includes = bs.maybeParseAndGetCanonicalIncludePaths();
@@ -826,7 +847,7 @@
             // Rather than figure out the <include/> domain based on the path (a lot of code, and
             // it's a small list), we'll go through and look for it.
             boolean explicitlyIncluded = false;
-            for (Set<String> domainIncludes : includes.values()) {
+            for (Set<PathWithRequiredFlags> domainIncludes : includes.values()) {
                 explicitlyIncluded |= isFileSpecifiedInPathList(destination, domainIncludes);
                 if (explicitlyIncluded) {
                     break;
@@ -849,9 +870,10 @@
      * @return True if the provided file is either directly in the provided list, or the provided
      * file is within a directory in the list.
      */
-    private boolean isFileSpecifiedInPathList(File file, Collection<String> canonicalPathList)
-            throws IOException {
-        for (String canonicalPath : canonicalPathList) {
+    private boolean isFileSpecifiedInPathList(File file,
+            Collection<PathWithRequiredFlags> canonicalPathList) throws IOException {
+        for (PathWithRequiredFlags canonical : canonicalPathList) {
+            String canonicalPath = canonical.getPath();
             File fileFromList = new File(canonicalPath);
             if (fileFromList.isDirectory()) {
                 if (file.isDirectory()) {
diff --git a/core/java/android/app/backup/FullBackup.java b/core/java/android/app/backup/FullBackup.java
index a5dd5bd..fb1c2d0 100644
--- a/core/java/android/app/backup/FullBackup.java
+++ b/core/java/android/app/backup/FullBackup.java
@@ -82,6 +82,9 @@
     public static final String FULL_RESTORE_INTENT_ACTION = "fullrest";
     public static final String CONF_TOKEN_INTENT_EXTRA = "conftoken";
 
+    public static final String FLAG_REQUIRED_CLIENT_SIDE_ENCRYPTION = "clientSideEncryption";
+    public static final String FLAG_REQUIRED_DEVICE_TO_DEVICE_TRANSFER = "deviceToDeviceTransfer";
+
     /**
      * @hide
      */
@@ -224,6 +227,9 @@
 
         private final File EXTERNAL_DIR;
 
+        private final static String TAG_INCLUDE = "include";
+        private final static String TAG_EXCLUDE = "exclude";
+
         final int mFullBackupContent;
         final PackageManager mPackageManager;
         final StorageManager mStorageManager;
@@ -303,15 +309,45 @@
         }
 
         /**
-        * A map of domain -> list of canonical file names in that domain that are to be included.
-        * We keep track of the domain so that we can go through the file system in order later on.
-        */
-        Map<String, Set<String>> mIncludes;
-        /**e
-         * List that will be populated with the canonical names of each file or directory that is
-         * to be excluded.
+         * Represents a path attribute specified in an <include /> rule along with optional
+         * transport flags required from the transport to include file(s) under that path as
+         * specified by requiredFlags attribute. If optional requiredFlags attribute is not
+         * provided, default requiredFlags to 0.
+         * Note: since our parsing codepaths were the same for <include /> and <exclude /> tags,
+         * this structure is also used for <exclude /> tags to preserve that, however you can expect
+         * the getRequiredFlags() to always return 0 for exclude rules.
          */
-        ArraySet<String> mExcludes;
+        public static class PathWithRequiredFlags {
+            private final String mPath;
+            private final int mRequiredFlags;
+
+            public PathWithRequiredFlags(String path, int requiredFlags) {
+                mPath = path;
+                mRequiredFlags = requiredFlags;
+            }
+
+            public String getPath() {
+                return mPath;
+            }
+
+            public int getRequiredFlags() {
+                return mRequiredFlags;
+            }
+        }
+
+        /**
+         * A map of domain -> set of pairs (canonical file; required transport flags) in that
+         * domain that are to be included if the transport has decared the required flags.
+         * We keep track of the domain so that we can go through the file system in order later on.
+         */
+        Map<String, Set<PathWithRequiredFlags>> mIncludes;
+
+        /**
+         * Set that will be populated with pairs (canonical file; requiredFlags=0) for each file or
+         * directory that is to be excluded. Note that for excludes, the requiredFlags attribute is
+         * ignored and the value should be always set to 0.
+         */
+        ArraySet<PathWithRequiredFlags> mExcludes;
 
         BackupScheme(Context context) {
             mFullBackupContent = context.getApplicationInfo().fullBackupContent;
@@ -356,13 +392,14 @@
         }
 
         /**
-         * @return A mapping of domain -> canonical paths within that domain. Each of these paths
-         * specifies a file that the client has explicitly included in their backup set. If this
-         * map is empty we will back up the entire data directory (including managed external
-         * storage).
+         * @return A mapping of domain -> set of pairs (canonical file; required transport flags)
+         * in that domain that are to be included if the transport has decared the required flags.
+         * Each of these paths specifies a file that the client has explicitly included in their
+         * backup set. If this map is empty we will back up the entire data directory (including
+         * managed external storage).
          */
-        public synchronized Map<String, Set<String>> maybeParseAndGetCanonicalIncludePaths()
-                throws IOException, XmlPullParserException {
+        public synchronized Map<String, Set<PathWithRequiredFlags>>
+                maybeParseAndGetCanonicalIncludePaths() throws IOException, XmlPullParserException {
             if (mIncludes == null) {
                 maybeParseBackupSchemeLocked();
             }
@@ -370,9 +407,10 @@
         }
 
         /**
-         * @return A set of canonical paths that are to be excluded from the backup/restore set.
+         * @return A set of (canonical paths; requiredFlags=0) that are to be excluded from the
+         * backup/restore set.
          */
-        public synchronized ArraySet<String> maybeParseAndGetCanonicalExcludePaths()
+        public synchronized ArraySet<PathWithRequiredFlags> maybeParseAndGetCanonicalExcludePaths()
                 throws IOException, XmlPullParserException {
             if (mExcludes == null) {
                 maybeParseBackupSchemeLocked();
@@ -382,8 +420,8 @@
 
         private void maybeParseBackupSchemeLocked() throws IOException, XmlPullParserException {
             // This not being null is how we know that we've tried to parse the xml already.
-            mIncludes = new ArrayMap<String, Set<String>>();
-            mExcludes = new ArraySet<String>();
+            mIncludes = new ArrayMap<String, Set<PathWithRequiredFlags>>();
+            mExcludes = new ArraySet<PathWithRequiredFlags>();
 
             if (mFullBackupContent == 0) {
                 // android:fullBackupContent="true" which means that we'll do everything.
@@ -415,8 +453,8 @@
 
         @VisibleForTesting
         public void parseBackupSchemeFromXmlLocked(XmlPullParser parser,
-                                                   Set<String> excludes,
-                                                   Map<String, Set<String>> includes)
+                                                   Set<PathWithRequiredFlags> excludes,
+                                                   Map<String, Set<PathWithRequiredFlags>> includes)
                 throws IOException, XmlPullParserException {
             int event = parser.getEventType(); // START_DOCUMENT
             while (event != XmlPullParser.START_TAG) {
@@ -441,8 +479,7 @@
                     case XmlPullParser.START_TAG:
                         validateInnerTagContents(parser);
                         final String domainFromXml = parser.getAttributeValue(null, "domain");
-                        final File domainDirectory =
-                                getDirectoryForCriteriaDomain(domainFromXml);
+                        final File domainDirectory = getDirectoryForCriteriaDomain(domainFromXml);
                         if (domainDirectory == null) {
                             if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
                                 Log.v(TAG_XML_PARSER, "...parsing \"" + parser.getName() + "\": "
@@ -457,12 +494,23 @@
                             break;
                         }
 
-                        Set<String> activeSet = parseCurrentTagForDomain(
+                        int requiredFlags = 0; // no transport flags are required by default
+                        if (TAG_INCLUDE.equals(parser.getName())) {
+                            // requiredFlags are only supported for <include /> tag, for <exclude />
+                            // we should always leave them as the default = 0
+                            requiredFlags = getRequiredFlagsFromString(
+                                    parser.getAttributeValue(null, "requireFlags"));
+                        }
+
+                        // retrieve the include/exclude set we'll be adding this rule to
+                        Set<PathWithRequiredFlags> activeSet = parseCurrentTagForDomain(
                                 parser, excludes, includes, domainFromXml);
-                        activeSet.add(canonicalFile.getCanonicalPath());
+                        activeSet.add(new PathWithRequiredFlags(canonicalFile.getCanonicalPath(),
+                                requiredFlags));
                         if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
                             Log.v(TAG_XML_PARSER, "...parsed " + canonicalFile.getCanonicalPath()
-                                    + " for domain \"" + domainFromXml + "\"");
+                                    + " for domain \"" + domainFromXml + "\", requiredFlags + \""
+                                    + requiredFlags + "\"");
                         }
 
                         // Special case journal files (not dirs) for sqlite database. frowny-face.
@@ -472,14 +520,16 @@
                         if ("database".equals(domainFromXml) && !canonicalFile.isDirectory()) {
                             final String canonicalJournalPath =
                                     canonicalFile.getCanonicalPath() + "-journal";
-                            activeSet.add(canonicalJournalPath);
+                            activeSet.add(new PathWithRequiredFlags(canonicalJournalPath,
+                                    requiredFlags));
                             if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
                                 Log.v(TAG_XML_PARSER, "...automatically generated "
                                         + canonicalJournalPath + ". Ignore if nonexistent.");
                             }
                             final String canonicalWalPath =
                                     canonicalFile.getCanonicalPath() + "-wal";
-                            activeSet.add(canonicalWalPath);
+                            activeSet.add(new PathWithRequiredFlags(canonicalWalPath,
+                                    requiredFlags));
                             if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
                                 Log.v(TAG_XML_PARSER, "...automatically generated "
                                         + canonicalWalPath + ". Ignore if nonexistent.");
@@ -491,7 +541,8 @@
                             !canonicalFile.getCanonicalPath().endsWith(".xml")) {
                             final String canonicalXmlPath =
                                     canonicalFile.getCanonicalPath() + ".xml";
-                            activeSet.add(canonicalXmlPath);
+                            activeSet.add(new PathWithRequiredFlags(canonicalXmlPath,
+                                    requiredFlags));
                             if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
                                 Log.v(TAG_XML_PARSER, "...automatically generated "
                                         + canonicalXmlPath + ". Ignore if nonexistent.");
@@ -508,10 +559,12 @@
                     Log.v(TAG_XML_PARSER, "  ...nothing specified (This means the entirety of app"
                             + " data minus excludes)");
                 } else {
-                    for (Map.Entry<String, Set<String>> entry : includes.entrySet()) {
+                    for (Map.Entry<String, Set<PathWithRequiredFlags>> entry
+                            : includes.entrySet()) {
                         Log.v(TAG_XML_PARSER, "  domain=" + entry.getKey());
-                        for (String includeData : entry.getValue()) {
-                            Log.v(TAG_XML_PARSER, "  " + includeData);
+                        for (PathWithRequiredFlags includeData : entry.getValue()) {
+                            Log.v(TAG_XML_PARSER, " path: " + includeData.getPath()
+                                    + " requiredFlags: " + includeData.getRequiredFlags());
                         }
                     }
                 }
@@ -520,8 +573,9 @@
                 if (excludes.isEmpty()) {
                     Log.v(TAG_XML_PARSER, "  ...nothing to exclude.");
                 } else {
-                    for (String excludeData : excludes) {
-                        Log.v(TAG_XML_PARSER, "  " + excludeData);
+                    for (PathWithRequiredFlags excludeData : excludes) {
+                        Log.v(TAG_XML_PARSER, " path: " + excludeData.getPath()
+                                + " requiredFlags: " + excludeData.getRequiredFlags());
                     }
                 }
 
@@ -531,20 +585,41 @@
             }
         }
 
-        private Set<String> parseCurrentTagForDomain(XmlPullParser parser,
-                                                     Set<String> excludes,
-                                                     Map<String, Set<String>> includes,
-                                                     String domain)
+        private int getRequiredFlagsFromString(String requiredFlags) {
+            int flags = 0;
+            if (requiredFlags == null || requiredFlags.length() == 0) {
+                // requiredFlags attribute was missing or empty in <include /> tag
+                return flags;
+            }
+            String[] flagsStr = requiredFlags.split("\\|");
+            for (String f : flagsStr) {
+                switch (f) {
+                    case FLAG_REQUIRED_CLIENT_SIDE_ENCRYPTION:
+                        flags |= BackupAgent.FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED;
+                        break;
+                    case FLAG_REQUIRED_DEVICE_TO_DEVICE_TRANSFER:
+                        flags |= BackupAgent.FLAG_DEVICE_TO_DEVICE_TRANSFER;
+                        break;
+                    default:
+                        Log.w(TAG, "Unrecognized requiredFlag provided, value: \"" + f + "\"");
+                }
+            }
+            return flags;
+        }
+
+        private Set<PathWithRequiredFlags> parseCurrentTagForDomain(XmlPullParser parser,
+                Set<PathWithRequiredFlags> excludes,
+                Map<String, Set<PathWithRequiredFlags>> includes, String domain)
                 throws XmlPullParserException {
-            if ("include".equals(parser.getName())) {
+            if (TAG_INCLUDE.equals(parser.getName())) {
                 final String domainToken = getTokenForXmlDomain(domain);
-                Set<String> includeSet = includes.get(domainToken);
+                Set<PathWithRequiredFlags> includeSet = includes.get(domainToken);
                 if (includeSet == null) {
-                    includeSet = new ArraySet<String>();
+                    includeSet = new ArraySet<PathWithRequiredFlags>();
                     includes.put(domainToken, includeSet);
                 }
                 return includeSet;
-            } else if ("exclude".equals(parser.getName())) {
+            } else if (TAG_EXCLUDE.equals(parser.getName())) {
                 return excludes;
             } else {
                 // Unrecognised tag => hard failure.
@@ -589,8 +664,8 @@
         /**
          *
          * @param domain Directory where the specified file should exist. Not null.
-         * @param filePathFromXml parsed from xml. Not sanitised before calling this function so may be
-         *                        null.
+         * @param filePathFromXml parsed from xml. Not sanitised before calling this function so may
+         *                        be null.
          * @return The canonical path of the file specified or null if no such file exists.
          */
         private File extractCanonicalFile(File domain, String filePathFromXml) {
@@ -650,15 +725,27 @@
          * Let's be strict about the type of xml the client can write. If we see anything untoward,
          * throw an XmlPullParserException.
          */
-        private void validateInnerTagContents(XmlPullParser parser)
-                throws XmlPullParserException {
-            if (parser.getAttributeCount() > 2) {
-                throw new XmlPullParserException("At most 2 tag attributes allowed for \""
-                        + parser.getName() + "\" tag (\"domain\" & \"path\".");
+        private void validateInnerTagContents(XmlPullParser parser) throws XmlPullParserException {
+            if (parser == null) {
+                return;
             }
-            if (!"include".equals(parser.getName()) && !"exclude".equals(parser.getName())) {
-                throw new XmlPullParserException("A valid tag is one of \"<include/>\" or" +
-                        " \"<exclude/>. You provided \"" + parser.getName() + "\"");
+            switch (parser.getName()) {
+                case TAG_INCLUDE:
+                    if (parser.getAttributeCount() > 3) {
+                        throw new XmlPullParserException("At most 3 tag attributes allowed for "
+                                + "\"include\" tag (\"domain\" & \"path\""
+                                + " & optional \"requiredFlags\").");
+                    }
+                    break;
+                case TAG_EXCLUDE:
+                    if (parser.getAttributeCount() > 2) {
+                        throw new XmlPullParserException("At most 2 tag attributes allowed for "
+                                + "\"exclude\" tag (\"domain\" & \"path\".");
+                    }
+                    break;
+                default:
+                    throw new XmlPullParserException("A valid tag is one of \"<include/>\" or" +
+                            " \"<exclude/>. You provided \"" + parser.getName() + "\"");
             }
         }
     }
diff --git a/core/java/android/app/slice/ISliceManager.aidl b/core/java/android/app/slice/ISliceManager.aidl
index 38d9025..20ec75a 100644
--- a/core/java/android/app/slice/ISliceManager.aidl
+++ b/core/java/android/app/slice/ISliceManager.aidl
@@ -16,17 +16,13 @@
 
 package android.app.slice;
 
-import android.app.slice.ISliceListener;
 import android.app.slice.SliceSpec;
 import android.net.Uri;
 
 /** @hide */
 interface ISliceManager {
-    void addSliceListener(in Uri uri, String pkg, in ISliceListener listener,
-            in SliceSpec[] specs);
-    void removeSliceListener(in Uri uri, String pkg, in ISliceListener listener);
-    void pinSlice(String pkg, in Uri uri, in SliceSpec[] specs);
-    void unpinSlice(String pkg, in Uri uri);
+    void pinSlice(String pkg, in Uri uri, in SliceSpec[] specs, in IBinder token);
+    void unpinSlice(String pkg, in Uri uri, in IBinder token);
     boolean hasSliceAccess(String pkg);
     SliceSpec[] getPinnedSpecs(in Uri uri, String pkg);
     int checkSlicePermission(in Uri uri, String pkg, int pid, int uid);
diff --git a/core/java/android/app/slice/SliceManager.java b/core/java/android/app/slice/SliceManager.java
index 15ff03a..ae1d8d7 100644
--- a/core/java/android/app/slice/SliceManager.java
+++ b/core/java/android/app/slice/SliceManager.java
@@ -27,8 +27,10 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.ServiceManager.ServiceNotFoundException;
@@ -74,6 +76,7 @@
     private final Context mContext;
     private final ArrayMap<Pair<Uri, SliceCallback>, ISliceListener> mListenerLookup =
             new ArrayMap<>();
+    private final IBinder mToken = new Binder();
 
     /**
      * Permission denied.
@@ -106,7 +109,6 @@
     @Deprecated
     public void registerSliceCallback(@NonNull Uri uri, @NonNull SliceCallback callback,
             @NonNull List<SliceSpec> specs) {
-        registerSliceCallback(uri, specs, mContext.getMainExecutor(), callback);
     }
 
     /**
@@ -115,7 +117,6 @@
     @Deprecated
     public void registerSliceCallback(@NonNull Uri uri, @NonNull SliceCallback callback,
             @NonNull List<SliceSpec> specs, Executor executor) {
-        registerSliceCallback(uri, specs, executor, callback);
     }
 
     /**
@@ -133,7 +134,6 @@
      */
     public void registerSliceCallback(@NonNull Uri uri, @NonNull List<SliceSpec> specs,
             @NonNull SliceCallback callback) {
-        registerSliceCallback(uri, specs, mContext.getMainExecutor(), callback);
     }
 
     /**
@@ -151,32 +151,7 @@
      */
     public void registerSliceCallback(@NonNull Uri uri, @NonNull List<SliceSpec> specs,
             @NonNull @CallbackExecutor Executor executor, @NonNull SliceCallback callback) {
-        try {
-            mService.addSliceListener(uri, mContext.getPackageName(),
-                    getListener(uri, callback, new ISliceListener.Stub() {
-                        @Override
-                        public void onSliceUpdated(Slice s) throws RemoteException {
-                            executor.execute(() -> callback.onSliceUpdated(s));
-                        }
-                    }), specs.toArray(new SliceSpec[specs.size()]));
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
 
-    private ISliceListener getListener(Uri uri, SliceCallback callback,
-            ISliceListener listener) {
-        Pair<Uri, SliceCallback> key = new Pair<>(uri, callback);
-        if (mListenerLookup.containsKey(key)) {
-            try {
-                mService.removeSliceListener(uri, mContext.getPackageName(),
-                        mListenerLookup.get(key));
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
-            }
-        }
-        mListenerLookup.put(key, listener);
-        return listener;
     }
 
     /**
@@ -190,12 +165,7 @@
      * @see #registerSliceCallback
      */
     public void unregisterSliceCallback(@NonNull Uri uri, @NonNull SliceCallback callback) {
-        try {
-            mService.removeSliceListener(uri, mContext.getPackageName(),
-                    mListenerLookup.remove(new Pair<>(uri, callback)));
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+
     }
 
     /**
@@ -216,7 +186,7 @@
     public void pinSlice(@NonNull Uri uri, @NonNull List<SliceSpec> specs) {
         try {
             mService.pinSlice(mContext.getPackageName(), uri,
-                    specs.toArray(new SliceSpec[specs.size()]));
+                    specs.toArray(new SliceSpec[specs.size()]), mToken);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -238,7 +208,7 @@
      */
     public void unpinSlice(@NonNull Uri uri) {
         try {
-            mService.unpinSlice(mContext.getPackageName(), uri);
+            mService.unpinSlice(mContext.getPackageName(), uri, mToken);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/usage/AppStandbyInfo.java b/core/java/android/app/usage/AppStandbyInfo.java
new file mode 100644
index 0000000..51fe0e2
--- /dev/null
+++ b/core/java/android/app/usage/AppStandbyInfo.java
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+package android.app.usage;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A pair of {package, bucket} to denote the app standby bucket for a given package.
+ * Used as a vehicle of data across the binder IPC.
+ * @hide
+ */
+public final class AppStandbyInfo implements Parcelable {
+
+    public String mPackageName;
+    public @UsageStatsManager.StandbyBuckets int mStandbyBucket;
+
+    private AppStandbyInfo(Parcel in) {
+        mPackageName = in.readString();
+        mStandbyBucket = in.readInt();
+    }
+
+    public AppStandbyInfo(String packageName, int bucket) {
+        mPackageName = packageName;
+        mStandbyBucket = bucket;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mPackageName);
+        dest.writeInt(mStandbyBucket);
+    }
+
+    public static final Creator<AppStandbyInfo> CREATOR = new Creator<AppStandbyInfo>() {
+        @Override
+        public AppStandbyInfo createFromParcel(Parcel source) {
+            return new AppStandbyInfo(source);
+        }
+
+        @Override
+        public AppStandbyInfo[] newArray(int size) {
+            return new AppStandbyInfo[size];
+        }
+    };
+}
diff --git a/core/java/android/app/usage/IUsageStatsManager.aidl b/core/java/android/app/usage/IUsageStatsManager.aidl
index f089c127..e72b84d 100644
--- a/core/java/android/app/usage/IUsageStatsManager.aidl
+++ b/core/java/android/app/usage/IUsageStatsManager.aidl
@@ -40,6 +40,6 @@
             in String[] annotations, String action);
     int getAppStandbyBucket(String packageName, String callingPackage, int userId);
     void setAppStandbyBucket(String packageName, int bucket, int userId);
-    Map getAppStandbyBuckets(String callingPackage, int userId);
-    void setAppStandbyBuckets(in Map appBuckets, int userId);
+    ParceledListSlice getAppStandbyBuckets(String callingPackage, int userId);
+    void setAppStandbyBuckets(in ParceledListSlice appBuckets, int userId);
 }
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index cf35902..9a0bb1d 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -28,6 +28,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -388,8 +389,16 @@
     @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)
     public Map<String, Integer> getAppStandbyBuckets() {
         try {
-            return (Map<String, Integer>) mService.getAppStandbyBuckets(
+            final ParceledListSlice<AppStandbyInfo> slice = mService.getAppStandbyBuckets(
                     mContext.getOpPackageName(), mContext.getUserId());
+            final List<AppStandbyInfo> bucketList = slice.getList();
+            final ArrayMap<String, Integer> bucketMap = new ArrayMap<>();
+            final int n = bucketList.size();
+            for (int i = 0; i < n; i++) {
+                final AppStandbyInfo bucketInfo = bucketList.get(i);
+                bucketMap.put(bucketInfo.mPackageName, bucketInfo.mStandbyBucket);
+            }
+            return bucketMap;
         } catch (RemoteException e) {
         }
         return Collections.EMPTY_MAP;
@@ -404,8 +413,16 @@
     @SystemApi
     @RequiresPermission(android.Manifest.permission.CHANGE_APP_IDLE_STATE)
     public void setAppStandbyBuckets(Map<String, Integer> appBuckets) {
+        if (appBuckets == null) {
+            return;
+        }
+        final List<AppStandbyInfo> bucketInfoList = new ArrayList<>(appBuckets.size());
+        for (Map.Entry<String, Integer> bucketEntry : appBuckets.entrySet()) {
+            bucketInfoList.add(new AppStandbyInfo(bucketEntry.getKey(), bucketEntry.getValue()));
+        }
+        final ParceledListSlice<AppStandbyInfo> slice = new ParceledListSlice<>(bucketInfoList);
         try {
-            mService.setAppStandbyBuckets(appBuckets, mContext.getUserId());
+            mService.setAppStandbyBuckets(slice, mContext.getUserId());
         } catch (RemoteException e) {
         }
     }
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index e558b7e..52aefcc 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -2646,6 +2646,10 @@
 
     /**
      * <p>Include OIS data in the capture result.</p>
+     * <p>{@link CaptureResult#STATISTICS_OIS_SAMPLES android.statistics.oisSamples} provides OIS sample data in the
+     * output result metadata.</p>
+     *
+     * @see CaptureResult#STATISTICS_OIS_SAMPLES
      * @see CaptureRequest#STATISTICS_OIS_DATA_MODE
      */
     public static final int STATISTICS_OIS_DATA_MODE_ON = 1;
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index a1a14b9..ada7ebf 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -2784,9 +2784,6 @@
     /**
      * <p>A control for selecting whether OIS position information is included in output
      * result metadata.</p>
-     * <p>When set to ON,
-     * {@link CaptureResult#STATISTICS_OIS_TIMESTAMPS android.statistics.oisTimestamps}, android.statistics.oisShiftPixelX,
-     * and android.statistics.oisShiftPixelY provide OIS data in the output result metadata.</p>
      * <p><b>Possible values:</b>
      * <ul>
      *   <li>{@link #STATISTICS_OIS_DATA_MODE_OFF OFF}</li>
@@ -2795,8 +2792,6 @@
      * <p><b>Available values for this device:</b><br>
      * android.Statistics.info.availableOisDataModes</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
-     *
-     * @see CaptureResult#STATISTICS_OIS_TIMESTAMPS
      * @see #STATISTICS_OIS_DATA_MODE_OFF
      * @see #STATISTICS_OIS_DATA_MODE_ON
      */
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index c332d30..8c2f8c1 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -3911,9 +3911,6 @@
     /**
      * <p>A control for selecting whether OIS position information is included in output
      * result metadata.</p>
-     * <p>When set to ON,
-     * {@link CaptureResult#STATISTICS_OIS_TIMESTAMPS android.statistics.oisTimestamps}, android.statistics.oisShiftPixelX,
-     * and android.statistics.oisShiftPixelY provide OIS data in the output result metadata.</p>
      * <p><b>Possible values:</b>
      * <ul>
      *   <li>{@link #STATISTICS_OIS_DATA_MODE_OFF OFF}</li>
@@ -3922,8 +3919,6 @@
      * <p><b>Available values for this device:</b><br>
      * android.Statistics.info.availableOisDataModes</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
-     *
-     * @see CaptureResult#STATISTICS_OIS_TIMESTAMPS
      * @see #STATISTICS_OIS_DATA_MODE_OFF
      * @see #STATISTICS_OIS_DATA_MODE_ON
      */
@@ -3939,8 +3934,8 @@
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      *
      * @see CaptureResult#SENSOR_TIMESTAMP
+     * @hide
      */
-    @PublicKey
     public static final Key<long[]> STATISTICS_OIS_TIMESTAMPS =
             new Key<long[]>("android.statistics.oisTimestamps", long[].class);
 
@@ -3948,16 +3943,14 @@
      * <p>An array of shifts of OIS samples, in x direction.</p>
      * <p>The array contains the amount of shifts in x direction, in pixels, based on OIS samples.
      * A positive value is a shift from left to right in active array coordinate system. For
-     * example, if the optical center is (1000, 500) in active array coordinates, an shift of
+     * example, if the optical center is (1000, 500) in active array coordinates, a shift of
      * (3, 0) puts the new optical center at (1003, 500).</p>
      * <p>The number of shifts must match the number of timestamps in
-     * {@link CaptureResult#STATISTICS_OIS_TIMESTAMPS android.statistics.oisTimestamps}.</p>
+     * android.statistics.oisTimestamps.</p>
      * <p><b>Units</b>: Pixels in active array.</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
-     *
-     * @see CaptureResult#STATISTICS_OIS_TIMESTAMPS
+     * @hide
      */
-    @PublicKey
     public static final Key<float[]> STATISTICS_OIS_X_SHIFTS =
             new Key<float[]>("android.statistics.oisXShifts", float[].class);
 
@@ -3965,20 +3958,35 @@
      * <p>An array of shifts of OIS samples, in y direction.</p>
      * <p>The array contains the amount of shifts in y direction, in pixels, based on OIS samples.
      * A positive value is a shift from top to bottom in active array coordinate system. For
-     * example, if the optical center is (1000, 500) in active array coordinates, an shift of
+     * example, if the optical center is (1000, 500) in active array coordinates, a shift of
      * (0, 5) puts the new optical center at (1000, 505).</p>
      * <p>The number of shifts must match the number of timestamps in
-     * {@link CaptureResult#STATISTICS_OIS_TIMESTAMPS android.statistics.oisTimestamps}.</p>
+     * android.statistics.oisTimestamps.</p>
      * <p><b>Units</b>: Pixels in active array.</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
-     *
-     * @see CaptureResult#STATISTICS_OIS_TIMESTAMPS
+     * @hide
      */
-    @PublicKey
     public static final Key<float[]> STATISTICS_OIS_Y_SHIFTS =
             new Key<float[]>("android.statistics.oisYShifts", float[].class);
 
     /**
+     * <p>An array of OIS samples.</p>
+     * <p>Each OIS sample contains the timestamp and the amount of shifts in x and y direction,
+     * in pixels, of the OIS sample.</p>
+     * <p>A positive value for a shift in x direction is a shift from left to right in active array
+     * coordinate system. For example, if the optical center is (1000, 500) in active array
+     * coordinates, a shift of (3, 0) puts the new optical center at (1003, 500).</p>
+     * <p>A positive value for a shift in y direction is a shift from top to bottom in active array
+     * coordinate system. For example, if the optical center is (1000, 500) in active array
+     * coordinates, a shift of (0, 5) puts the new optical center at (1000, 505).</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     */
+    @PublicKey
+    @SyntheticKey
+    public static final Key<android.hardware.camera2.params.OisSample[]> STATISTICS_OIS_SAMPLES =
+            new Key<android.hardware.camera2.params.OisSample[]>("android.statistics.oisSamples", android.hardware.camera2.params.OisSample[].class);
+
+    /**
      * <p>Tonemapping / contrast / gamma curve for the blue
      * channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is
      * CONTRAST_CURVE.</p>
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index ebe2fa1..e4b1339 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -22,12 +22,12 @@
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.marshal.Marshaler;
 import android.hardware.camera2.marshal.MarshalQueryable;
 import android.hardware.camera2.marshal.MarshalRegistry;
+import android.hardware.camera2.marshal.Marshaler;
 import android.hardware.camera2.marshal.impl.MarshalQueryableArray;
-import android.hardware.camera2.marshal.impl.MarshalQueryableBoolean;
 import android.hardware.camera2.marshal.impl.MarshalQueryableBlackLevelPattern;
+import android.hardware.camera2.marshal.impl.MarshalQueryableBoolean;
 import android.hardware.camera2.marshal.impl.MarshalQueryableColorSpaceTransform;
 import android.hardware.camera2.marshal.impl.MarshalQueryableEnum;
 import android.hardware.camera2.marshal.impl.MarshalQueryableHighSpeedVideoConfiguration;
@@ -48,6 +48,7 @@
 import android.hardware.camera2.params.Face;
 import android.hardware.camera2.params.HighSpeedVideoConfiguration;
 import android.hardware.camera2.params.LensShadingMap;
+import android.hardware.camera2.params.OisSample;
 import android.hardware.camera2.params.ReprocessFormatsMap;
 import android.hardware.camera2.params.StreamConfiguration;
 import android.hardware.camera2.params.StreamConfigurationDuration;
@@ -56,8 +57,8 @@
 import android.hardware.camera2.utils.TypeReference;
 import android.location.Location;
 import android.location.LocationManager;
-import android.os.Parcelable;
 import android.os.Parcel;
+import android.os.Parcelable;
 import android.os.ServiceSpecificException;
 import android.util.Log;
 import android.util.Size;
@@ -614,6 +615,15 @@
                         return (T) metadata.getLensShadingMap();
                     }
                 });
+        sGetCommandMap.put(
+                CaptureResult.STATISTICS_OIS_SAMPLES.getNativeKey(),
+                        new GetCommand() {
+                    @Override
+                    @SuppressWarnings("unchecked")
+                    public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {
+                        return (T) metadata.getOisSamples();
+                    }
+                });
     }
 
     private int[] getAvailableFormats() {
@@ -962,6 +972,50 @@
         return tc;
     }
 
+    private OisSample[] getOisSamples() {
+        long[] timestamps = getBase(CaptureResult.STATISTICS_OIS_TIMESTAMPS);
+        float[] xShifts = getBase(CaptureResult.STATISTICS_OIS_X_SHIFTS);
+        float[] yShifts = getBase(CaptureResult.STATISTICS_OIS_Y_SHIFTS);
+
+        if (timestamps == null) {
+            if (xShifts != null) {
+                throw new AssertionError("timestamps is null but xShifts is not");
+            }
+
+            if (yShifts != null) {
+                throw new AssertionError("timestamps is null but yShifts is not");
+            }
+
+            return null;
+        }
+
+        if (xShifts == null) {
+            throw new AssertionError("timestamps is not null but xShifts is");
+        }
+
+        if (yShifts == null) {
+            throw new AssertionError("timestamps is not null but yShifts is");
+        }
+
+        if (xShifts.length != timestamps.length) {
+            throw new AssertionError(String.format(
+                    "timestamps has %d entries but xShifts has %d", timestamps.length,
+                    xShifts.length));
+        }
+
+        if (yShifts.length != timestamps.length) {
+            throw new AssertionError(String.format(
+                    "timestamps has %d entries but yShifts has %d", timestamps.length,
+                    yShifts.length));
+        }
+
+        OisSample[] samples = new OisSample[timestamps.length];
+        for (int i = 0; i < timestamps.length; i++) {
+            samples[i] = new OisSample(timestamps[i], xShifts[i], yShifts[i]);
+        }
+        return samples;
+    }
+
     private <T> void setBase(CameraCharacteristics.Key<T> key, T value) {
         setBase(key.getNativeKey(), value);
     }
diff --git a/core/java/android/hardware/camera2/params/OisSample.java b/core/java/android/hardware/camera2/params/OisSample.java
new file mode 100644
index 0000000..7ebaae3
--- /dev/null
+++ b/core/java/android/hardware/camera2/params/OisSample.java
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+package android.hardware.camera2.params;
+
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.utils.HashCodeHelpers;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * Immutable class to store an
+ * {@link CaptureResult#STATISTICS_OIS_SAMPLES optical image stabilization sample}.
+ */
+public final class OisSample {
+    /**
+     * Create a new {@link OisSample}.
+     *
+     * <p>{@link OisSample} contains the timestamp and the amount of shifts in x and y direction,
+     * in pixels, of the OIS sample.
+     *
+     * <p>A positive value for a shift in x direction is a shift from left to right in active array
+     * coordinate system. For example, if the optical center is {@code (1000, 500)} in active array
+     * coordinates, a shift of {@code (3, 0)} puts the new optical center at {@code (1003, 500)}.
+     * </p>
+     *
+     * <p>A positive value for a shift in y direction is a shift from top to bottom in active array
+     * coordinate system. For example, if the optical center is {@code (1000, 500)} in active array
+     * coordinates, a shift of {@code (0, 5)} puts the new optical center at {@code (1000, 505)}.
+     * </p>
+     *
+     * <p>xShift and yShift must be finite; NaN and infinity is not allowed.</p>
+     *
+     * @param timestamp timestamp of the OIS sample.
+     * @param xShift shift of the OIS sample in x direction.
+     * @param yShift shift of the OIS sample in y direction.
+     *
+     * @throws IllegalArgumentException if xShift or yShift is not finite
+     */
+    public OisSample(final long timestamp, final float xShift, final float yShift) {
+        mTimestampNs = timestamp;
+        mXShift = Preconditions.checkArgumentFinite(xShift, "xShift must be finite");
+        mYShift = Preconditions.checkArgumentFinite(yShift, "yShift must be finite");
+    }
+
+    /**
+     * Get the timestamp in nanoseconds.
+     *
+     *<p>The timestamps are in the same timebase as and comparable to
+     *{@link CaptureResult#SENSOR_TIMESTAMP android.sensor.timestamp}.</p>
+     *
+     * @return a long value (guaranteed to be finite)
+     */
+    public long getTimestamp() {
+        return mTimestampNs;
+    }
+
+    /**
+     * Get the shift in x direction.
+     *
+     * @return a floating point value (guaranteed to be finite)
+     */
+    public float getXshift() {
+        return mXShift;
+    }
+
+    /**
+     * Get the shift in y direction.
+     *
+     * @return a floating point value (guaranteed to be finite)
+     */
+    public float getYshift() {
+        return mYShift;
+    }
+
+    /**
+     * Check if this {@link OisSample} is equal to another {@link OisSample}.
+     *
+     * <p>Two samples are only equal if and only if each of the OIS information is equal.</p>
+     *
+     * @return {@code true} if the objects were equal, {@code false} otherwise
+     */
+    @Override
+    public boolean equals(final Object obj) {
+        if (obj == null) {
+            return false;
+        } else if (this == obj) {
+            return true;
+        } else if (obj instanceof OisSample) {
+            final OisSample other = (OisSample) obj;
+            return mTimestampNs == other.mTimestampNs
+                    && mXShift == other.mXShift
+                    && mYShift == other.mYShift;
+        }
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode() {
+        int timestampHash = HashCodeHelpers.hashCode(mTimestampNs);
+        return HashCodeHelpers.hashCode(mXShift, mYShift, timestampHash);
+    }
+
+    /**
+     * Return the OisSample as a string representation.
+     *
+     * <p> {@code "OisSample{timestamp:%l, shift_x:%f, shift_y:%f}"} represents the OIS sample's
+     * timestamp, shift in x direction, and shift in y direction.</p>
+     *
+     * @return string representation of {@link OisSample}
+     */
+    @Override
+    public String toString() {
+        return String.format("OisSample{timestamp:%d, shift_x:%f, shift_y:%f}", mTimestampNs,
+                mXShift, mYShift);
+    }
+
+    private final long mTimestampNs;
+    private final float mXShift;
+    private final float mYShift;
+}
diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl
index 90e3ffd..381cfb6 100644
--- a/core/java/android/net/INetworkStatsService.aidl
+++ b/core/java/android/net/INetworkStatsService.aidl
@@ -39,9 +39,6 @@
      */
     INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage);
 
-    /** Return network layer usage total for traffic that matches template. */
-    long getNetworkTotalBytes(in NetworkTemplate template, long start, long end);
-
     /** Return data layer snapshot of UID network usage. */
     NetworkStats getDataLayerSnapshotForUid(int uid);
     /** Return set of any ifaces associated with mobile networks since boot. */
@@ -50,17 +47,11 @@
     /** Increment data layer count of operations performed for UID and tag. */
     void incrementOperationCount(int uid, int tag, int operationCount);
 
-    /** Mark given UID as being in foreground for stats purposes. */
-    void setUidForeground(int uid, boolean uidForeground);
-
     /** Force update of ifaces. */
     void forceUpdateIfaces(in Network[] defaultNetworks);
     /** Force update of statistics. */
     void forceUpdate();
 
-    /** Advise persistance threshold; may be overridden internally. */
-    void advisePersistThreshold(long thresholdBytes);
-
     /** Registers a callback on data usage. */
     DataUsageRequest registerUsageCallback(String callingPackage,
             in DataUsageRequest request, in Messenger messenger, in IBinder binder);
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 01b2b39..16fb858 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -234,7 +234,7 @@
     public NetworkStats(long elapsedRealtime, int initialSize) {
         this.elapsedRealtime = elapsedRealtime;
         this.size = 0;
-        if (initialSize >= 0) {
+        if (initialSize > 0) {
             this.capacity = initialSize;
             this.iface = new String[initialSize];
             this.uid = new int[initialSize];
@@ -250,19 +250,7 @@
             this.operations = new long[initialSize];
         } else {
             // Special case for use by NetworkStatsFactory to start out *really* empty.
-            this.capacity = 0;
-            this.iface = EmptyArray.STRING;
-            this.uid = EmptyArray.INT;
-            this.set = EmptyArray.INT;
-            this.tag = EmptyArray.INT;
-            this.metered = EmptyArray.INT;
-            this.roaming = EmptyArray.INT;
-            this.defaultNetwork = EmptyArray.INT;
-            this.rxBytes = EmptyArray.LONG;
-            this.rxPackets = EmptyArray.LONG;
-            this.txBytes = EmptyArray.LONG;
-            this.txPackets = EmptyArray.LONG;
-            this.operations = EmptyArray.LONG;
+            clear();
         }
     }
 
@@ -314,6 +302,25 @@
         return clone;
     }
 
+    /**
+     * Clear all data stored in this object.
+     */
+    public void clear() {
+        this.capacity = 0;
+        this.iface = EmptyArray.STRING;
+        this.uid = EmptyArray.INT;
+        this.set = EmptyArray.INT;
+        this.tag = EmptyArray.INT;
+        this.metered = EmptyArray.INT;
+        this.roaming = EmptyArray.INT;
+        this.defaultNetwork = EmptyArray.INT;
+        this.rxBytes = EmptyArray.LONG;
+        this.rxPackets = EmptyArray.LONG;
+        this.txBytes = EmptyArray.LONG;
+        this.txPackets = EmptyArray.LONG;
+        this.operations = EmptyArray.LONG;
+    }
+
     @VisibleForTesting
     public NetworkStats addIfaceValues(
             String iface, long rxBytes, long rxPackets, long txBytes, long txPackets) {
diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java
index 433f941..a13ad65 100644
--- a/core/java/android/net/NetworkStatsHistory.java
+++ b/core/java/android/net/NetworkStatsHistory.java
@@ -39,6 +39,8 @@
 
 import com.android.internal.util.IndentingPrintWriter;
 
+import libcore.util.EmptyArray;
+
 import java.io.CharArrayWriter;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
@@ -459,6 +461,21 @@
     }
 
     /**
+     * Clear all data stored in this object.
+     */
+    public void clear() {
+        bucketStart = EmptyArray.LONG;
+        if (activeTime != null) activeTime = EmptyArray.LONG;
+        if (rxBytes != null) rxBytes = EmptyArray.LONG;
+        if (rxPackets != null) rxPackets = EmptyArray.LONG;
+        if (txBytes != null) txBytes = EmptyArray.LONG;
+        if (txPackets != null) txPackets = EmptyArray.LONG;
+        if (operations != null) operations = EmptyArray.LONG;
+        bucketCount = 0;
+        totalBytes = 0;
+    }
+
+    /**
      * Remove buckets older than requested cutoff.
      */
     @Deprecated
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index 8efd39a..74233fd 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -23,7 +23,6 @@
 import static android.net.ConnectivityManager.TYPE_WIFI;
 import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
 import static android.net.ConnectivityManager.TYPE_WIMAX;
-import static android.net.NetworkIdentity.COMBINE_SUBTYPE_ENABLED;
 import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
 import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
 import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
@@ -34,11 +33,6 @@
 import static android.net.NetworkStats.ROAMING_NO;
 import static android.net.NetworkStats.ROAMING_YES;
 import static android.net.wifi.WifiInfo.removeDoubleQuotes;
-import static android.telephony.TelephonyManager.NETWORK_CLASS_2_G;
-import static android.telephony.TelephonyManager.NETWORK_CLASS_3_G;
-import static android.telephony.TelephonyManager.NETWORK_CLASS_4_G;
-import static android.telephony.TelephonyManager.NETWORK_CLASS_UNKNOWN;
-import static android.telephony.TelephonyManager.getNetworkClass;
 
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -55,8 +49,8 @@
 import java.util.Objects;
 
 /**
- * Template definition used to generically match {@link NetworkIdentity},
- * usually when collecting statistics.
+ * Predicate used to match {@link NetworkIdentity}, usually when collecting
+ * statistics. (It should probably have been named {@code NetworkPredicate}.)
  *
  * @hide
  */
@@ -68,13 +62,7 @@
      */
     private static final int BACKUP_VERSION = 1;
 
-    public static final int MATCH_MOBILE_ALL = 1;
-    /** @deprecated don't use this any more */
-    @Deprecated
-    public static final int MATCH_MOBILE_3G_LOWER = 2;
-    /** @deprecated don't use this any more */
-    @Deprecated
-    public static final int MATCH_MOBILE_4G = 3;
+    public static final int MATCH_MOBILE = 1;
     public static final int MATCH_WIFI = 4;
     public static final int MATCH_ETHERNET = 5;
     public static final int MATCH_MOBILE_WILDCARD = 6;
@@ -84,9 +72,7 @@
 
     private static boolean isKnownMatchRule(final int rule) {
         switch (rule) {
-            case MATCH_MOBILE_ALL:
-            case MATCH_MOBILE_3G_LOWER:
-            case MATCH_MOBILE_4G:
+            case MATCH_MOBILE:
             case MATCH_WIFI:
             case MATCH_ETHERNET:
             case MATCH_MOBILE_WILDCARD:
@@ -111,25 +97,7 @@
      * the given IMSI.
      */
     public static NetworkTemplate buildTemplateMobileAll(String subscriberId) {
-        return new NetworkTemplate(MATCH_MOBILE_ALL, subscriberId, null);
-    }
-
-    /**
-     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
-     * the given IMSI that roughly meet a "3G" definition, or lower.
-     */
-    @Deprecated
-    public static NetworkTemplate buildTemplateMobile3gLower(String subscriberId) {
-        return new NetworkTemplate(MATCH_MOBILE_3G_LOWER, subscriberId, null);
-    }
-
-    /**
-     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
-     * the given IMSI that roughly meet a "4G" definition.
-     */
-    @Deprecated
-    public static NetworkTemplate buildTemplateMobile4g(String subscriberId) {
-        return new NetworkTemplate(MATCH_MOBILE_4G, subscriberId, null);
+        return new NetworkTemplate(MATCH_MOBILE, subscriberId, null);
     }
 
     /**
@@ -307,9 +275,7 @@
 
     public boolean isMatchRuleMobile() {
         switch (mMatchRule) {
-            case MATCH_MOBILE_3G_LOWER:
-            case MATCH_MOBILE_4G:
-            case MATCH_MOBILE_ALL:
+            case MATCH_MOBILE:
             case MATCH_MOBILE_WILDCARD:
                 return true;
             default:
@@ -348,12 +314,8 @@
         if (!matchesDefaultNetwork(ident)) return false;
 
         switch (mMatchRule) {
-            case MATCH_MOBILE_ALL:
+            case MATCH_MOBILE:
                 return matchesMobile(ident);
-            case MATCH_MOBILE_3G_LOWER:
-                return matchesMobile3gLower(ident);
-            case MATCH_MOBILE_4G:
-                return matchesMobile4g(ident);
             case MATCH_WIFI:
                 return matchesWifi(ident);
             case MATCH_ETHERNET:
@@ -410,43 +372,6 @@
     }
 
     /**
-     * Check if mobile network classified 3G or lower with matching IMSI.
-     */
-    @Deprecated
-    private boolean matchesMobile3gLower(NetworkIdentity ident) {
-        ensureSubtypeAvailable();
-        if (ident.mType == TYPE_WIMAX) {
-            return false;
-        } else if (matchesMobile(ident)) {
-            switch (getNetworkClass(ident.mSubType)) {
-                case NETWORK_CLASS_UNKNOWN:
-                case NETWORK_CLASS_2_G:
-                case NETWORK_CLASS_3_G:
-                    return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Check if mobile network classified 4G with matching IMSI.
-     */
-    @Deprecated
-    private boolean matchesMobile4g(NetworkIdentity ident) {
-        ensureSubtypeAvailable();
-        if (ident.mType == TYPE_WIMAX) {
-            // TODO: consider matching against WiMAX subscriber identity
-            return true;
-        } else if (matchesMobile(ident)) {
-            switch (getNetworkClass(ident.mSubType)) {
-                case NETWORK_CLASS_4_G:
-                    return true;
-            }
-        }
-        return false;
-    }
-
-    /**
      * Check if matches Wi-Fi network template.
      */
     private boolean matchesWifi(NetworkIdentity ident) {
@@ -506,12 +431,8 @@
 
     private static String getMatchRuleName(int matchRule) {
         switch (matchRule) {
-            case MATCH_MOBILE_3G_LOWER:
-                return "MOBILE_3G_LOWER";
-            case MATCH_MOBILE_4G:
-                return "MOBILE_4G";
-            case MATCH_MOBILE_ALL:
-                return "MOBILE_ALL";
+            case MATCH_MOBILE:
+                return "MOBILE";
             case MATCH_WIFI:
                 return "WIFI";
             case MATCH_ETHERNET:
@@ -529,13 +450,6 @@
         }
     }
 
-    private static void ensureSubtypeAvailable() {
-        if (COMBINE_SUBTYPE_ENABLED) {
-            throw new IllegalArgumentException(
-                    "Unable to enforce 3G_LOWER template on combined data.");
-        }
-    }
-
     /**
      * Examine the given template and normalize if it refers to a "merged"
      * mobile subscriber. We pick the "lowest" merged subscriber as the primary
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 68490ed..1ae0bc4 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8827,6 +8827,14 @@
         */
        public static final String NETWORK_SCORER_APP = "network_scorer_app";
 
+        /**
+         * Whether night display forced auto mode is available.
+         * 0 = unavailable, 1 = available.
+         * @hide
+         */
+        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
@@ -10314,6 +10322,16 @@
         public static final String SYS_VDSO = "sys_vdso";
 
         /**
+        * UidCpuPower global setting. This links the sys.uidcpupower system property.
+        * The following values are supported:
+        * 0 -> /proc/uid_cpupower/* are disabled
+        * 1 -> /proc/uid_cpupower/* are enabled
+        * Any other value defaults to enabled.
+        * @hide
+        */
+        public static final String SYS_UIDCPUPOWER = "sys_uidcpupower";
+
+        /**
          * An integer to reduce the FPS by this factor. Only for experiments. Need to reboot the
          * device for this setting to take full effect.
          *
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index f4dcce1..1d13335 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -75,7 +75,6 @@
     public static final int KM_TAG_ALLOW_WHILE_ON_BODY = KM_BOOL | 506;
     public static final int KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED = KM_BOOL | 507;
     public static final int KM_TAG_TRUSTED_CONFIRMATION_REQUIRED = KM_BOOL | 508;
-    public static final int KM_TAG_UNLOCKED_DEVICE_REQUIRED = KM_BOOL | 509;
 
     public static final int KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600;
     public static final int KM_TAG_APPLICATION_ID = KM_BYTES | 601;
@@ -217,7 +216,6 @@
     public static final int KM_ERROR_MISSING_MIN_MAC_LENGTH = -58;
     public static final int KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH = -59;
     public static final int KM_ERROR_CANNOT_ATTEST_IDS = -66;
-    public static final int KM_ERROR_DEVICE_LOCKED = -72;
     public static final int KM_ERROR_UNIMPLEMENTED = -100;
     public static final int KM_ERROR_VERSION_MISMATCH = -101;
     public static final int KM_ERROR_UNKNOWN_ERROR = -1000;
@@ -264,7 +262,6 @@
         sErrorCodeToString.put(KM_ERROR_INVALID_MAC_LENGTH,
                 "Invalid MAC or authentication tag length");
         sErrorCodeToString.put(KM_ERROR_CANNOT_ATTEST_IDS, "Unable to attest device ids");
-        sErrorCodeToString.put(KM_ERROR_DEVICE_LOCKED, "Device locked");
         sErrorCodeToString.put(KM_ERROR_UNIMPLEMENTED, "Not implemented");
         sErrorCodeToString.put(KM_ERROR_UNKNOWN_ERROR, "Unknown error");
     }
diff --git a/core/java/android/security/keystore/recovery/RecoveryController.java b/core/java/android/security/keystore/recovery/RecoveryController.java
index d57782c..fcca5af 100644
--- a/core/java/android/security/keystore/recovery/RecoveryController.java
+++ b/core/java/android/security/keystore/recovery/RecoveryController.java
@@ -552,6 +552,15 @@
         }
     }
 
+    /**
+     * Returns a new {@link RecoverySession}.
+     *
+     * <p>A recovery session is required to restore keys from a remote store.
+     */
+    public RecoverySession createRecoverySession() {
+        return RecoverySession.newInstance(this);
+    }
+
     InternalRecoveryServiceException wrapUnexpectedServiceSpecificException(
             ServiceSpecificException e) {
         if (e.errorCode == ERROR_SERVICE_INTERNAL_ERROR) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 3c76242..f61b652 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8144,7 +8144,12 @@
     }
 
     /**
-     * Gets the unique identifier of this view in the screen, for autofill purposes.
+     * Gets the unique, logical identifier of this view in the activity, for autofill purposes.
+     *
+     * <p>The autofill id is created on demand, unless it is explicitly set by
+     * {@link #setAutofillId(AutofillId)}.
+     *
+     * <p>See {@link #setAutofillId(AutofillId)} for more info.
      *
      * @return The View's autofill id.
      */
@@ -8158,6 +8163,61 @@
     }
 
     /**
+     * Sets the unique, logical identifier of this view in the activity, for autofill purposes.
+     *
+     * <p>The autofill id is created on demand, and this method should only be called when a view is
+     * reused after {@link #dispatchProvideAutofillStructure(ViewStructure, int)} is called, as
+     * that method creates a snapshot of the view that is passed along to the autofill service.
+     *
+     * <p>This method is typically used when view subtrees are recycled to represent different
+     * content* &mdash;in this case, the autofill id can be saved before the view content is swapped
+     * out, and restored later when it's swapped back in. For example:
+     *
+     * <pre>
+     * EditText reusableView = ...;
+     * ViewGroup parentView = ...;
+     * AutofillManager afm = ...;
+     *
+     * // Swap out the view and change its contents
+     * AutofillId oldId = reusableView.getAutofillId();
+     * CharSequence oldText = reusableView.getText();
+     * parentView.removeView(reusableView);
+     * AutofillId newId = afm.getNextAutofillId();
+     * reusableView.setText("New I am");
+     * reusableView.setAutofillId(newId);
+     * parentView.addView(reusableView);
+     *
+     * // Later, swap the old content back in
+     * parentView.removeView(reusableView);
+     * reusableView.setAutofillId(oldId);
+     * reusableView.setText(oldText);
+     * parentView.addView(reusableView);
+     * </pre>
+     *
+     * @param id an autofill ID that is unique in the {@link android.app.Activity} hosting the view,
+     * or {@code null} to reset it. Usually it's an id previously allocated to another view (and
+     * obtained through {@link #getAutofillId()}), or a new value obtained through
+     * {@link AutofillManager#getNextAutofillId()}.
+     *
+     * @throws IllegalStateException if the view is already {@link #isAttachedToWindow() attached to
+     * a window}.
+     *
+     * @throws IllegalArgumentException if the id is an autofill id associated with a virtual view.
+     */
+    public void setAutofillId(@Nullable AutofillId id) {
+        if (android.view.autofill.Helper.sVerbose) {
+            Log.v(VIEW_LOG_TAG, "setAutofill(): from " + mAutofillId + " to " + id);
+        }
+        if (isAttachedToWindow()) {
+            throw new IllegalStateException("Cannot set autofill id when view is attached");
+        }
+        if (id.isVirtual()) {
+            throw new IllegalStateException("Cannot set autofill id assigned to virtual views");
+        }
+        mAutofillId = id;
+    }
+
+    /**
      * Describes the autofill type of this view, so an
      * {@link android.service.autofill.AutofillService} can create the proper {@link AutofillValue}
      * when autofilling the view.
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 810864e..01d9265 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -3925,6 +3925,7 @@
     private final static int MSG_DISPATCH_APP_VISIBILITY = 8;
     private final static int MSG_DISPATCH_GET_NEW_SURFACE = 9;
     private final static int MSG_DISPATCH_KEY_FROM_IME = 11;
+    private final static int MSG_DISPATCH_KEY_FROM_AUTOFILL = 12;
     private final static int MSG_CHECK_FOCUS = 13;
     private final static int MSG_CLOSE_SYSTEM_DIALOGS = 14;
     private final static int MSG_DISPATCH_DRAG_EVENT = 15;
@@ -3966,6 +3967,8 @@
                     return "MSG_DISPATCH_GET_NEW_SURFACE";
                 case MSG_DISPATCH_KEY_FROM_IME:
                     return "MSG_DISPATCH_KEY_FROM_IME";
+                case MSG_DISPATCH_KEY_FROM_AUTOFILL:
+                    return "MSG_DISPATCH_KEY_FROM_AUTOFILL";
                 case MSG_CHECK_FOCUS:
                     return "MSG_CHECK_FOCUS";
                 case MSG_CLOSE_SYSTEM_DIALOGS:
@@ -4143,6 +4146,15 @@
                     }
                     enqueueInputEvent(event, null, QueuedInputEvent.FLAG_DELIVER_POST_IME, true);
                 } break;
+                case MSG_DISPATCH_KEY_FROM_AUTOFILL: {
+                    if (LOCAL_LOGV) {
+                        Log.v(TAG, "Dispatching key " + msg.obj + " from Autofill to " + mView);
+                    }
+                    KeyEvent event = (KeyEvent) msg.obj;
+                    // send InputEvent to pre IME, set FLAG_FROM_AUTOFILL so the InputEvent
+                    // wont be dropped as app window is not focus.
+                    enqueueInputEvent(event, null, QueuedInputEvent.FLAG_FROM_AUTOFILL, true);
+                } break;
                 case MSG_CHECK_FOCUS: {
                     InputMethodManager imm = InputMethodManager.peekInstance();
                     if (imm != null) {
@@ -4433,7 +4445,8 @@
                 Slog.w(mTag, "Dropping event due to root view being removed: " + q.mEvent);
                 return true;
             } else if ((!mAttachInfo.mHasWindowFocus
-                    && !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) || mStopped
+                    && !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)
+                    && (q.mFlags & QueuedInputEvent.FLAG_FROM_AUTOFILL) == 0) || mStopped
                     || (mIsAmbientMode && !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_BUTTON))
                     || (mPausedForTransition && !isBack(q.mEvent))) {
                 // This is a focus event and the window doesn't currently have input focus or
@@ -6805,6 +6818,7 @@
         public static final int FLAG_FINISHED_HANDLED = 1 << 3;
         public static final int FLAG_RESYNTHESIZED = 1 << 4;
         public static final int FLAG_UNHANDLED = 1 << 5;
+        public static final int FLAG_FROM_AUTOFILL = 1 << 6;
 
         public QueuedInputEvent mNext;
 
@@ -7262,6 +7276,12 @@
         mHandler.sendMessage(msg);
     }
 
+    public void dispatchKeyFromAutofill(KeyEvent event) {
+        Message msg = mHandler.obtainMessage(MSG_DISPATCH_KEY_FROM_AUTOFILL, event);
+        msg.setAsynchronous(true);
+        mHandler.sendMessage(msg);
+    }
+
     /**
      * Reinject unhandled {@link InputEvent}s in order to synthesize fallbacks events.
      *
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 7792fa6..a4261eb 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -46,6 +46,7 @@
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.Choreographer;
+import android.view.KeyEvent;
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
@@ -411,6 +412,13 @@
                 @Nullable Rect virtualBounds, IAutofillWindowPresenter presenter);
 
         /**
+         * Dispatch unhandled keyevent from Autofill window
+         * @param anchor The real view the UI needs to anchor to.
+         * @param keyEvent Unhandled KeyEvent from autofill window.
+         */
+        void autofillClientDispatchUnhandledKey(@NonNull View anchor, @NonNull KeyEvent keyEvent);
+
+        /**
          * Request hiding the autofill UI.
          *
          * @return Whether the UI was hidden.
@@ -490,7 +498,17 @@
         /**
           * @return Whether compatibility mode is enabled.
           */
-        boolean autofillIsCompatibilityModeEnabled();
+        boolean autofillClientIsCompatibilityModeEnabled();
+
+        /**
+         * Gets the next unique autofill ID.
+         *
+         * <p>Typically used to manage views whose content is recycled - see
+         * {@link View#setAutofillId(AutofillId)} for more info.
+         *
+         * @return An ID that is unique in the activity.
+         */
+        @Nullable AutofillId autofillClientGetNextAutofillId();
     }
 
     /**
@@ -773,7 +791,7 @@
     /** Returns AutofillCallback if need fire EVENT_INPUT_UNAVAILABLE */
     @GuardedBy("mLock")
     private AutofillCallback notifyViewEnteredLocked(@NonNull View view, int flags) {
-        final AutofillId id = getAutofillId(view);
+        final AutofillId id = view.getAutofillId();
         if (shouldIgnoreViewEnteredLocked(id, flags)) return null;
 
         AutofillCallback callback = null;
@@ -823,7 +841,7 @@
         if (mEnabled && isActiveLocked()) {
             // dont notify exited when Activity is already in background
             if (!isClientDisablingEnterExitEvent()) {
-                final AutofillId id = getAutofillId(view);
+                final AutofillId id = view.getAutofillId();
 
                 // Update focus on existing session.
                 updateSessionLocked(id, null, null, ACTION_VIEW_EXITED, 0);
@@ -866,6 +884,7 @@
             if (mEnabled && isActiveLocked()) {
                 final AutofillId id = virtual ? getAutofillId(view, virtualId)
                         : view.getAutofillId();
+                if (sVerbose) Log.v(TAG, "visibility changed for " + id + ": " + isVisible);
                 if (!isVisible && mFillableIds != null) {
                     if (mFillableIds.contains(id)) {
                         if (sDebug) Log.d(TAG, "Hidding UI when view " + id + " became invisible");
@@ -874,6 +893,8 @@
                 }
                 if (mTrackedViews != null) {
                     mTrackedViews.notifyViewVisibilityChangedLocked(id, isVisible);
+                } else if (sVerbose) {
+                    Log.v(TAG, "Ignoring visibility change on " + id + ": no tracked views");
                 }
             }
         }
@@ -1004,7 +1025,7 @@
             if (mLastAutofilledData == null) {
                 view.setAutofilled(false);
             } else {
-                id = getAutofillId(view);
+                id = view.getAutofillId();
                 if (mLastAutofilledData.containsKey(id)) {
                     value = view.getAutofillValue();
                     valueWasRead = true;
@@ -1029,7 +1050,7 @@
             }
 
             if (id == null) {
-                id = getAutofillId(view);
+                id = view.getAutofillId();
             }
 
             if (!valueWasRead) {
@@ -1429,8 +1450,27 @@
         }
     }
 
-    private static AutofillId getAutofillId(View view) {
-        return new AutofillId(view.getAutofillViewId());
+    /**
+     * Gets the next unique autofill ID for the activity context.
+     *
+     * <p>Typically used to manage views whose content is recycled - see
+     * {@link View#setAutofillId(AutofillId)} for more info.
+     *
+     * @return An ID that is unique in the activity, or {@code null} if autofill is not supported in
+     * the {@link Context} associated with this {@link AutofillManager}.
+     */
+    @Nullable
+    public AutofillId getNextAutofillId() {
+        final AutofillClient client = getClient();
+        if (client == null) return null;
+
+        final AutofillId id = client.autofillClientGetNextAutofillId();
+
+        if (id == null && sDebug) {
+            Log.d(TAG, "getNextAutofillId(): client " + client + " returned null");
+        }
+
+        return id;
     }
 
     private static AutofillId getAutofillId(View parent, int virtualId) {
@@ -1668,6 +1708,24 @@
         }
     }
 
+    private void dispatchUnhandledKey(int sessionId, AutofillId id, KeyEvent keyEvent) {
+        final View anchor = findView(id);
+        if (anchor == null) {
+            return;
+        }
+
+        AutofillCallback callback = null;
+        synchronized (mLock) {
+            if (mSessionId == sessionId) {
+                AutofillClient client = getClient();
+
+                if (client != null) {
+                    client.autofillClientDispatchUnhandledKey(anchor, keyEvent);
+                }
+            }
+        }
+    }
+
     /** @hide */
     public static final int SET_STATE_FLAG_ENABLED = 0x01;
     /** @hide */
@@ -1713,7 +1771,7 @@
                 if (mLastAutofilledData == null) {
                     mLastAutofilledData = new ParcelableMap(1);
                 }
-                mLastAutofilledData.put(getAutofillId(view), targetValue);
+                mLastAutofilledData.put(view.getAutofillId(), targetValue);
             }
             view.setAutofilled(true);
         }
@@ -2610,6 +2668,14 @@
         }
 
         @Override
+        public void dispatchUnhandledKey(int sessionId, AutofillId id, KeyEvent fullScreen) {
+            final AutofillManager afm = mAfm.get();
+            if (afm != null) {
+                afm.post(() -> afm.dispatchUnhandledKey(sessionId, id, fullScreen));
+            }
+        }
+
+        @Override
         public void startIntentSender(IntentSender intentSender, Intent intent) {
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
diff --git a/core/java/android/view/autofill/IAutoFillManagerClient.aidl b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
index 254c8a5..0ff7a0b 100644
--- a/core/java/android/view/autofill/IAutoFillManagerClient.aidl
+++ b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
@@ -25,6 +25,7 @@
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillValue;
 import android.view.autofill.IAutofillWindowPresenter;
+import android.view.KeyEvent;
 
 /**
  * Object running in the application process and responsible for autofilling it.
@@ -74,6 +75,13 @@
     void notifyNoFillUi(int sessionId, in AutofillId id, int sessionFinishedState);
 
     /**
+     * Dispatches unhandled keyevent from autofill ui. Autofill ui handles DPAD and ENTER events,
+     * other unhandled keyevents are dispatched to app's window to filter autofill result.
+     * Note this method is not called when autofill ui is in fullscreen mode (TV only).
+     */
+    void dispatchUnhandledKey(int sessionId, in AutofillId id, in KeyEvent keyEvent);
+
+    /**
      * Starts the provided intent sender.
      */
     void startIntentSender(in IntentSender intentSender, in Intent intent);
diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java
index 6427965..eb2af60 100644
--- a/core/java/android/widget/Magnifier.java
+++ b/core/java/android/widget/Magnifier.java
@@ -89,6 +89,9 @@
             NONEXISTENT_PREVIOUS_CONFIG_VALUE, NONEXISTENT_PREVIOUS_CONFIG_VALUE);
     // Rectangle defining the view surface area we pixel copy content from.
     private final Rect mPixelCopyRequestRect = new Rect();
+    // Lock to synchronize between the UI thread and the thread that handles pixel copy results.
+    // Only sync mWindow writes from UI thread with mWindow reads from sPixelCopyHandlerThread.
+    private final Object mLock = new Object();
 
     /**
      * Initializes a magnifier.
@@ -170,9 +173,12 @@
 
         if (xPosInView != mPrevPosInView.x || yPosInView != mPrevPosInView.y) {
             if (mWindow == null) {
-                mWindow = new InternalPopupWindow(mView.getContext(), mView.getDisplay(),
-                        getValidViewSurface(), mWindowWidth, mWindowHeight, mWindowElevation,
-                        Handler.getMain() /* draw the magnifier on the UI thread */, mCallback);
+                synchronized (mLock) {
+                    mWindow = new InternalPopupWindow(mView.getContext(), mView.getDisplay(),
+                            getValidViewSurface(), mWindowWidth, mWindowHeight, mWindowElevation,
+                            Handler.getMain() /* draw the magnifier on the UI thread */, mLock,
+                            mCallback);
+                }
             }
             performPixelCopy(startX, startY, true /* update window position */);
             mPrevPosInView.x = xPosInView;
@@ -200,8 +206,10 @@
      */
     public void dismiss() {
         if (mWindow != null) {
-            mWindow.destroy();
-            mWindow = null;
+            synchronized (mLock) {
+                mWindow.destroy();
+                mWindow = null;
+            }
         }
     }
 
@@ -281,19 +289,22 @@
                 clampedStartYInSurface + mBitmapHeight);
         final int windowCoordsX = mWindowCoords.x;
         final int windowCoordsY = mWindowCoords.y;
+        final InternalPopupWindow currentWindowInstance = mWindow;
 
         final Bitmap bitmap =
                 Bitmap.createBitmap(mBitmapWidth, mBitmapHeight, Bitmap.Config.ARGB_8888);
         PixelCopy.request(surface, mPixelCopyRequestRect, bitmap,
                 result -> {
-                    synchronized (mWindow.mLock) {
-                        if (mWindow != null) {
-                            if (updateWindowPosition) {
-                                // TODO: pull the position update outside #performPixelCopy
-                                mWindow.setContentPositionForNextDraw(windowCoordsX, windowCoordsY);
-                            }
-                            mWindow.updateContent(bitmap);
+                    synchronized (mLock) {
+                        if (mWindow != currentWindowInstance) {
+                            // The magnifier was dismissed (and maybe shown again) in the meantime.
+                            return;
                         }
+                        if (updateWindowPosition) {
+                            // TODO: pull the position update outside #performPixelCopy
+                            mWindow.setContentPositionForNextDraw(windowCoordsX, windowCoordsY);
+                        }
+                        mWindow.updateContent(bitmap);
                     }
                 },
                 sPixelCopyHandlerThread.getThreadHandler());
@@ -337,7 +348,7 @@
         // Members below describe the state of the magnifier. Reads/writes to them
         // have to be synchronized between the UI thread and the thread that handles
         // the pixel copy results. This is the purpose of mLock.
-        private final Object mLock = new Object();
+        private final Object mLock;
         // Whether a magnifier frame draw is currently pending in the UI thread queue.
         private boolean mFrameDrawScheduled;
         // The content bitmap.
@@ -353,8 +364,9 @@
         InternalPopupWindow(final Context context, final Display display,
                 final Surface parentSurface,
                 final int width, final int height, final float elevation,
-                final Handler handler, final Callback callback) {
+                final Handler handler, final Object lock, final Callback callback) {
             mDisplay = display;
+            mLock = lock;
             mCallback = callback;
 
             mContentWidth = width;
diff --git a/core/java/android/widget/VideoView2.java b/core/java/android/widget/VideoView2.java
index 69c1fb6..340be46 100644
--- a/core/java/android/widget/VideoView2.java
+++ b/core/java/android/widget/VideoView2.java
@@ -22,6 +22,7 @@
 import android.content.Context;
 import android.media.AudioAttributes;
 import android.media.AudioManager;
+import android.media.MediaMetadata2;
 import android.media.MediaPlayerInterface;
 import android.media.session.MediaController;
 import android.media.session.MediaSession;
@@ -168,6 +169,27 @@
         return mProvider.getMediaControlView2_impl();
     }
 
+    /**
+     * Sets MediaMetadata2 instance. It will replace the previously assigned MediaMetadata2 instance
+     * if any.
+     *
+     * @param metadata a MediaMetadata2 instance.
+     * @hide
+     */
+    public void setMediaMetadata(MediaMetadata2 metadata) {
+        mProvider.setMediaMetadata_impl(metadata);
+    }
+
+    /**
+     * Returns MediaMetadata2 instance which is retrieved from MediaPlayer2 inside VideoView2 by
+     * default or by {@link #setMediaMetadata} method.
+     * @hide
+     */
+    public MediaMetadata2 getMediaMetadata() {
+        // TODO: add to Javadoc whether this value can be null or not when integrating with
+        // MediaSession2.
+        return mProvider.getMediaMetadata_impl();
+    }
 
     /**
      * Returns MediaController instance which is connected with MediaSession that VideoView2 is
diff --git a/core/java/com/android/internal/app/ColorDisplayController.java b/core/java/com/android/internal/app/ColorDisplayController.java
index b8682a8..278d31a 100644
--- a/core/java/com/android/internal/app/ColorDisplayController.java
+++ b/core/java/com/android/internal/app/ColorDisplayController.java
@@ -22,6 +22,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.database.ContentObserver;
+import android.metrics.LogMaker;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Looper;
@@ -31,6 +32,8 @@
 import android.util.Slog;
 
 import com.android.internal.R;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -109,10 +112,10 @@
 
     private final Context mContext;
     private final int mUserId;
-
     private final ContentObserver mContentObserver;
 
     private Callback mCallback;
+    private MetricsLogger mMetricsLogger;
 
     public ColorDisplayController(@NonNull Context context) {
         this(context, ActivityManager.getCurrentUser());
@@ -209,6 +212,15 @@
     }
 
     /**
+     * Returns the current auto mode value, without validation, or {@code 1} if the auto mode has
+     * never been set.
+     */
+    public int getAutoModeRaw() {
+        return Secure.getIntForUser(mContext.getContentResolver(), Secure.NIGHT_DISPLAY_AUTO_MODE,
+                -1, mUserId);
+    }
+
+    /**
      * Sets the current auto mode value controlling when Night display will be automatically
      * activated. One of {@link #AUTO_MODE_DISABLED}, {@link #AUTO_MODE_CUSTOM}, or
      * {@link #AUTO_MODE_TWILIGHT}.
@@ -228,7 +240,12 @@
                     Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
                     null,
                     mUserId);
+            getMetricsLogger().write(new LogMaker(
+                    MetricsEvent.ACTION_NIGHT_DISPLAY_AUTO_MODE_CHANGED)
+                    .setType(MetricsEvent.TYPE_ACTION)
+                    .setSubtype(autoMode));
         }
+
         return Secure.putIntForUser(mContext.getContentResolver(),
                 Secure.NIGHT_DISPLAY_AUTO_MODE, autoMode, mUserId);
     }
@@ -263,6 +280,10 @@
         if (startTime == null) {
             throw new IllegalArgumentException("startTime cannot be null");
         }
+        getMetricsLogger().write(new LogMaker(
+                MetricsEvent.ACTION_NIGHT_DISPLAY_AUTO_MODE_CUSTOM_TIME_CHANGED)
+                .setType(MetricsEvent.TYPE_ACTION)
+                .setSubtype(0));
         return Secure.putIntForUser(mContext.getContentResolver(),
                 Secure.NIGHT_DISPLAY_CUSTOM_START_TIME, startTime.toSecondOfDay() * 1000, mUserId);
     }
@@ -297,6 +318,10 @@
         if (endTime == null) {
             throw new IllegalArgumentException("endTime cannot be null");
         }
+        getMetricsLogger().write(new LogMaker(
+                MetricsEvent.ACTION_NIGHT_DISPLAY_AUTO_MODE_CUSTOM_TIME_CHANGED)
+                .setType(MetricsEvent.TYPE_ACTION)
+                .setSubtype(1));
         return Secure.putIntForUser(mContext.getContentResolver(),
                 Secure.NIGHT_DISPLAY_CUSTOM_END_TIME, endTime.toSecondOfDay() * 1000, mUserId);
     }
@@ -450,6 +475,13 @@
         }
     }
 
+    private MetricsLogger getMetricsLogger() {
+        if (mMetricsLogger == null) {
+            mMetricsLogger = new MetricsLogger();
+        }
+        return mMetricsLogger;
+    }
+
     /**
      * Returns {@code true} if Night display is supported by the device.
      */
diff --git a/core/java/com/android/internal/util/IndentingPrintWriter.java b/core/java/com/android/internal/util/IndentingPrintWriter.java
index 696667c..e453866 100644
--- a/core/java/com/android/internal/util/IndentingPrintWriter.java
+++ b/core/java/com/android/internal/util/IndentingPrintWriter.java
@@ -57,26 +57,46 @@
         mWrapLength = wrapLength;
     }
 
-    public void increaseIndent() {
+    public IndentingPrintWriter setIndent(String indent) {
+        mIndentBuilder.setLength(0);
+        mIndentBuilder.append(indent);
+        mCurrentIndent = null;
+        return this;
+    }
+
+    public IndentingPrintWriter setIndent(int indent) {
+        mIndentBuilder.setLength(0);
+        for (int i = 0; i < indent; i++) {
+            increaseIndent();
+        }
+        return this;
+    }
+
+    public IndentingPrintWriter increaseIndent() {
         mIndentBuilder.append(mSingleIndent);
         mCurrentIndent = null;
+        return this;
     }
 
-    public void decreaseIndent() {
+    public IndentingPrintWriter decreaseIndent() {
         mIndentBuilder.delete(0, mSingleIndent.length());
         mCurrentIndent = null;
+        return this;
     }
 
-    public void printPair(String key, Object value) {
+    public IndentingPrintWriter printPair(String key, Object value) {
         print(key + "=" + String.valueOf(value) + " ");
+        return this;
     }
 
-    public void printPair(String key, Object[] value) {
+    public IndentingPrintWriter printPair(String key, Object[] value) {
         print(key + "=" + Arrays.toString(value) + " ");
+        return this;
     }
 
-    public void printHexPair(String key, int value) {
+    public IndentingPrintWriter printHexPair(String key, int value) {
         print(key + "=0x" + Integer.toHexString(value) + " ");
+        return this;
     }
 
     @Override
diff --git a/core/proto/android/server/jobscheduler.proto b/core/proto/android/server/jobscheduler.proto
index 304e63f..2d31c5a 100644
--- a/core/proto/android/server/jobscheduler.proto
+++ b/core/proto/android/server/jobscheduler.proto
@@ -201,6 +201,12 @@
     // be indices into this array, rather than the raw constants used by
     // AppIdleHistory.
     repeated int32 standby_beats = 20;
+    // The fraction of a job's running window that must pass before we
+    // consider running it when the network is congested.
+    optional double conn_congestion_delay_frac = 21;
+    // The fraction of a prefetch job's running window that must pass before
+    // we consider matching it against a metered network.
+    optional double conn_prefetch_relax_frac = 22;
 }
 
 message StateControllerProto {
diff --git a/core/res/res/drawable-watch/sym_def_app_icon.xml b/core/res/res/drawable-watch/sym_def_app_icon.xml
new file mode 100644
index 0000000..2720bfa
--- /dev/null
+++ b/core/res/res/drawable-watch/sym_def_app_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@color/accent_device_default_dark" />
+    <foreground android:drawable="@mipmap/sym_def_app_icon_foreground" />
+</adaptive-icon>
diff --git a/core/res/res/layout/autofill_dataset_picker.xml b/core/res/res/layout/autofill_dataset_picker.xml
index a88836e..ef19f87 100644
--- a/core/res/res/layout/autofill_dataset_picker.xml
+++ b/core/res/res/layout/autofill_dataset_picker.xml
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 
-<FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android"
+<view  xmlns:android="http://schemas.android.com/apk/res/android"
+    class="com.android.server.autofill.ui.FillUi$AutofillFrameLayout"
     android:id="@+id/autofill_dataset_picker"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
@@ -30,4 +31,4 @@
         android:visibility="gone">
     </ListView>
 
-</FrameLayout>
+</view>
diff --git a/core/res/res/mipmap-watch-anydpi/sym_def_app_icon_foreground.xml b/core/res/res/mipmap-watch-anydpi/sym_def_app_icon_foreground.xml
new file mode 100644
index 0000000..69c241c
--- /dev/null
+++ b/core/res/res/mipmap-watch-anydpi/sym_def_app_icon_foreground.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<inset
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:insetLeft="24dp"
+    android:insetRight="24dp"
+    android:insetTop="24dp"
+    android:insetBottom="24dp">
+    <vector
+        android:width="60dp"
+        android:height="60dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+        <path
+            android:fillColor="#FFFFFF"
+            android:pathData="M20,12c0,-2.6 -1.2,-4.8 -3.1,-6.3l-0.5,-2.8c-1.4,-0.7 -2.9,-1.1 -4.5,-1.1c-1.6,0 -3.1,0.4 -4.5,1.1L7,5.7C5.1,7.2 3.9,9.4 3.9,12c0,2.6 1.2,4.8 3.1,6.3l0.5,2.8c1.4,0.7 2.9,1.1 4.5,1.1c1.6,0 3.2,-0.4 4.5,-1.1l0.5,-2.8C18.8,16.8 20,14.6 20,12zM12,18c-3.3,0 -6,-2.7 -6,-6c0,-3.3 2.7,-6 6,-6s6,2.7 6,6C18,15.3 15.3,18 12,18z"/>
+        <path
+            android:fillColor="#FFFFFF"
+            android:pathData="M11.2,15.6h1.4v-4.3h-1.4V15.6zM11.2,9.8h1.4V8.4h-1.4V9.8z"/>
+    </vector>
+</inset>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 9d7432e..0b33211 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5905,6 +5905,9 @@
         <!-- Identifier of the image file. This attribute is mandatory.
              It must be an image file with multiple frames, e.g. gif or webp -->
         <attr name="src" />
+        <!-- Indicates if the drawable needs to be mirrored when its layout direction is
+             RTL (right-to-left). -->
+        <attr name="autoMirrored" />
     </declare-styleable>
 
     <!-- Drawable used to draw bitmaps. -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index f4be888..cadc3ff 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3772,31 +3772,23 @@
     <string name="extract_edit_menu_button">Edit</string>
 
     <!-- Notification title when data usage has exceeded warning threshold. [CHAR LIMIT=50] -->
-    <string name="data_usage_warning_title">Data usage alert</string>
+    <string name="data_usage_warning_title">Data warning</string>
     <!-- Notification body when data usage has exceeded warning threshold. [CHAR LIMIT=32] -->
-    <string name="data_usage_warning_body">Tap to view usage and settings.</string>
+    <string name="data_usage_warning_body">You've used <xliff:g id="app" example="3.8GB">%s</xliff:g> of data</string>
 
-    <!-- Notification title when 2G-3G data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
-    <string name="data_usage_3g_limit_title">2G-3G data limit reached</string>
-    <!-- Notification title when 4G data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
-    <string name="data_usage_4g_limit_title">4G data limit reached</string>
     <!-- Notification title when mobile data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=50] -->
     <string name="data_usage_mobile_limit_title">Mobile data limit reached</string>
     <!-- Notification title when Wi-Fi data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
     <string name="data_usage_wifi_limit_title">Wi-Fi data limit reached</string>
     <!-- Notification body when data usage has exceeded limit threshold, and has been disabled. -->
-    <string name="data_usage_limit_body">Data paused for rest of cycle</string>
+    <string name="data_usage_limit_body">Data paused for the rest of your cycle</string>
 
-    <!-- Notification title when 2G-3G data usage has exceeded limit threshold. [CHAR LIMIT=32] -->
-    <string name="data_usage_3g_limit_snoozed_title">2G-3G data limit exceeded</string>
-    <!-- Notification title when 4G data usage has exceeded limit threshold. [CHAR LIMIT=32] -->
-    <string name="data_usage_4g_limit_snoozed_title">4G data limit exceeded</string>
     <!-- Notification title when mobile data usage has exceeded limit threshold. [CHAR LIMIT=32] -->
-    <string name="data_usage_mobile_limit_snoozed_title">Mobile data limit exceeded</string>
+    <string name="data_usage_mobile_limit_snoozed_title">Over your mobile data limit</string>
     <!-- Notification title when Wi-Fi data usage has exceeded limit threshold. [CHAR LIMIT=32] -->
-    <string name="data_usage_wifi_limit_snoozed_title">Wi-Fi data limit exceeded</string>
+    <string name="data_usage_wifi_limit_snoozed_title">Over your Wi-Fi data limit</string>
     <!-- Notification body when data usage has exceeded limit threshold. -->
-    <string name="data_usage_limit_snoozed_body"><xliff:g id="size" example="3.8GB">%s</xliff:g> over specified limit.</string>
+    <string name="data_usage_limit_snoozed_body">You've gone <xliff:g id="size" example="3.8GB">%s</xliff:g> over your set limit</string>
 
     <!-- Notification title when background data usage is limited. [CHAR LIMIT=32] -->
     <string name="data_usage_restricted_title">Background data restricted</string>
@@ -3804,9 +3796,11 @@
     <string name="data_usage_restricted_body">Tap to remove restriction.</string>
 
     <!-- Notification title when there has been recent excessive data usage. [CHAR LIMIT=32] -->
-    <string name="data_usage_rapid_title">Large data usage</string>
+    <string name="data_usage_rapid_title">High mobile data usage</string>
     <!-- Notification body when there has been recent excessive data usage. [CHAR LIMIT=128] -->
-    <string name="data_usage_rapid_body">Your data usage over the last few days is larger than normal. Tap to view usage and settings.</string>
+    <string name="data_usage_rapid_body">Your apps have used more data than usual</string>
+    <!-- Notification body when there has been recent excessive data usage by a specific app. [CHAR LIMIT=128] -->
+    <string name="data_usage_rapid_app_body"><xliff:g id="app" example="Calculator">%s</xliff:g> has used more data than usual</string>
 
     <!-- SSL Certificate dialogs -->
     <!-- Title for an SSL Certificate dialog -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index fc4d4e7..a2af57e 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1971,10 +1971,6 @@
   <java-symbol type="string" name="config_wimaxServiceClassname" />
   <java-symbol type="string" name="config_wimaxServiceJarLocation" />
   <java-symbol type="string" name="config_wimaxStateTrackerClassname" />
-  <java-symbol type="string" name="data_usage_3g_limit_snoozed_title" />
-  <java-symbol type="string" name="data_usage_3g_limit_title" />
-  <java-symbol type="string" name="data_usage_4g_limit_snoozed_title" />
-  <java-symbol type="string" name="data_usage_4g_limit_title" />
   <java-symbol type="string" name="data_usage_limit_body" />
   <java-symbol type="string" name="data_usage_limit_snoozed_body" />
   <java-symbol type="string" name="data_usage_mobile_limit_snoozed_title" />
@@ -1987,6 +1983,7 @@
   <java-symbol type="string" name="data_usage_wifi_limit_title" />
   <java-symbol type="string" name="data_usage_rapid_title" />
   <java-symbol type="string" name="data_usage_rapid_body" />
+  <java-symbol type="string" name="data_usage_rapid_app_body" />
   <java-symbol type="string" name="default_wallpaper_component" />
   <java-symbol type="string" name="device_storage_monitor_notification_channel" />
   <java-symbol type="string" name="dlg_ok" />
diff --git a/core/tests/coretests/src/android/app/backup/FullBackupTest.java b/core/tests/coretests/src/android/app/backup/FullBackupTest.java
index bc6fc15..58ee7a7 100644
--- a/core/tests/coretests/src/android/app/backup/FullBackupTest.java
+++ b/core/tests/coretests/src/android/app/backup/FullBackupTest.java
@@ -19,6 +19,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import android.app.backup.FullBackup.BackupScheme.PathWithRequiredFlags;
 import android.content.Context;
 import android.support.test.filters.LargeTest;
 import android.test.AndroidTestCase;
@@ -43,8 +44,8 @@
     private XmlPullParser mXpp;
     private Context mContext;
 
-    Map<String, Set<String>> includeMap;
-    Set<String> excludesSet;
+    Map<String, Set<PathWithRequiredFlags>> includeMap;
+    Set<PathWithRequiredFlags> excludesSet;
 
     @Override
     public void setUp() throws Exception {
@@ -52,8 +53,8 @@
         mXpp = mFactory.newPullParser();
         mContext = getContext();
 
-        includeMap = new ArrayMap();
-        excludesSet = new ArraySet();
+        includeMap = new ArrayMap<>();
+        excludesSet = new ArraySet<>();
     }
 
     public void testparseBackupSchemeFromXml_onlyInclude() throws Exception {
@@ -68,11 +69,127 @@
         assertEquals("Excluding files when there was no <exclude/> tag.", 0, excludesSet.size());
         assertEquals("Unexpected number of <include/>s", 1, includeMap.size());
 
-        Set<String> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
+        Set<PathWithRequiredFlags> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
         assertEquals("Didn't find expected file domain include.", 1, fileDomainIncludes.size());
+        PathWithRequiredFlags include = fileDomainIncludes.iterator().next();
         assertEquals("Invalid path parsed for <include/>",
                 new File(mContext.getFilesDir(), "onlyInclude.txt").getCanonicalPath(),
-                fileDomainIncludes.iterator().next());
+                include.getPath());
+        assertEquals("Invalid requireFlags parsed for <include/>", 0, include.getRequiredFlags());
+    }
+
+    public void testparseBackupSchemeFromXml_onlyIncludeRequireEncryptionFlag() throws Exception {
+        mXpp.setInput(new StringReader(
+                "<full-backup-content>" +
+                        "<include path=\"onlyInclude.txt\" domain=\"file\""
+                        + " requireFlags=\"clientSideEncryption\"/>" +
+                "</full-backup-content>"));
+
+        FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext);
+        bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap);
+
+        assertEquals("Excluding files when there was no <exclude/> tag.", 0, excludesSet.size());
+        assertEquals("Unexpected number of <include/>s", 1, includeMap.size());
+
+        Set<PathWithRequiredFlags> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
+        assertEquals("Didn't find expected file domain include.", 1, fileDomainIncludes.size());
+        PathWithRequiredFlags include = fileDomainIncludes.iterator().next();
+        assertEquals("Invalid path parsed for <include/>",
+                new File(mContext.getFilesDir(), "onlyInclude.txt").getCanonicalPath(),
+                include.getPath());
+        assertEquals("Invalid requireFlags parsed for <include/>",
+                BackupAgent.FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED,
+                include.getRequiredFlags());
+    }
+
+    public void testparseBackupSchemeFromXml_onlyIncludeRequireD2DFlag() throws Exception {
+        mXpp.setInput(new StringReader(
+                "<full-backup-content>" +
+                        "<include path=\"onlyInclude.txt\" domain=\"file\""
+                        + " requireFlags=\"deviceToDeviceTransfer\"/>" +
+                "</full-backup-content>"));
+
+        FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext);
+        bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap);
+
+        assertEquals("Excluding files when there was no <exclude/> tag.", 0, excludesSet.size());
+        assertEquals("Unexpected number of <include/>s", 1, includeMap.size());
+
+        Set<PathWithRequiredFlags> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
+        assertEquals("Didn't find expected file domain include.", 1, fileDomainIncludes.size());
+        PathWithRequiredFlags include = fileDomainIncludes.iterator().next();
+        assertEquals("Invalid path parsed for <include/>",
+                new File(mContext.getFilesDir(), "onlyInclude.txt").getCanonicalPath(),
+                include.getPath());
+        assertEquals("Invalid requireFlags parsed for <include/>",
+                BackupAgent.FLAG_DEVICE_TO_DEVICE_TRANSFER,
+                include.getRequiredFlags());
+    }
+
+    public void testparseBackupSchemeFromXml_onlyIncludeRequireEncryptionAndD2DFlags()
+            throws Exception {
+        mXpp.setInput(new StringReader(
+                "<full-backup-content>" +
+                        "<include path=\"onlyInclude.txt\" domain=\"file\""
+                        + " requireFlags=\"clientSideEncryption|deviceToDeviceTransfer\"/>" +
+                "</full-backup-content>"));
+
+        FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext);
+        bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap);
+
+        assertEquals("Excluding files when there was no <exclude/> tag.", 0, excludesSet.size());
+        assertEquals("Unexpected number of <include/>s", 1, includeMap.size());
+
+        Set<PathWithRequiredFlags> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
+        assertEquals("Didn't find expected file domain include.", 1, fileDomainIncludes.size());
+        PathWithRequiredFlags include = fileDomainIncludes.iterator().next();
+        assertEquals("Invalid path parsed for <include/>",
+                new File(mContext.getFilesDir(), "onlyInclude.txt").getCanonicalPath(),
+                include.getPath());
+        assertEquals("Invalid requireFlags parsed for <include/>",
+                BackupAgent.FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED
+                        | BackupAgent.FLAG_DEVICE_TO_DEVICE_TRANSFER,
+                include.getRequiredFlags());
+    }
+
+    public void testparseBackupSchemeFromXml_onlyIncludeRequireD2DFlagAndIngoreGarbage()
+            throws Exception {
+        mXpp.setInput(new StringReader(
+                "<full-backup-content>" +
+                        "<include path=\"onlyInclude.txt\" domain=\"file\""
+                        + " requireFlags=\"deviceToDeviceTransfer|garbageFlag\"/>" +
+                "</full-backup-content>"));
+
+        FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext);
+        bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap);
+
+        assertEquals("Excluding files when there was no <exclude/> tag.", 0, excludesSet.size());
+        assertEquals("Unexpected number of <include/>s", 1, includeMap.size());
+
+        Set<PathWithRequiredFlags> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
+        assertEquals("Didn't find expected file domain include.", 1, fileDomainIncludes.size());
+        PathWithRequiredFlags include = fileDomainIncludes.iterator().next();
+        assertEquals("Invalid path parsed for <include/>",
+                new File(mContext.getFilesDir(), "onlyInclude.txt").getCanonicalPath(),
+                include.getPath());
+        assertEquals("Invalid requireFlags parsed for <include/>",
+                BackupAgent.FLAG_DEVICE_TO_DEVICE_TRANSFER,
+                include.getRequiredFlags());
+    }
+
+    public void testparseBackupSchemeFromXml_onlyExcludeRequireFlagsNotSupported()
+            throws Exception {
+        mXpp.setInput(new StringReader(
+                "<full-backup-content>" +
+                        "<exclude path=\"onlyExclude.txt\" domain=\"file\""
+                        + " requireFlags=\"deviceToDeviceTransfer\"/>" +
+                "</full-backup-content>"));
+
+        try {
+            FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext);
+            bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap);
+            fail("Having more than 3 attributes in exclude should throw an XmlPullParserException");
+        } catch (XmlPullParserException expected) {}
     }
 
     public void testparseBackupSchemeFromXml_onlyExclude() throws Exception {
@@ -88,7 +205,7 @@
         assertEquals("Unexpected number of <exclude/>s", 1, excludesSet.size());
         assertEquals("Invalid path parsed for <exclude/>",
                 new File(mContext.getFilesDir(), "onlyExclude.txt").getCanonicalPath(),
-                excludesSet.iterator().next());
+                excludesSet.iterator().next().getPath());
     }
 
     public void testparseBackupSchemeFromXml_includeAndExclude() throws Exception {
@@ -101,16 +218,16 @@
         FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext);
         bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap);
 
-        Set<String> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
+        Set<PathWithRequiredFlags> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
         assertEquals("Didn't find expected file domain include.", 1, fileDomainIncludes.size());
         assertEquals("Invalid path parsed for <include/>",
                 new File(mContext.getFilesDir(), "include.txt").getCanonicalPath(),
-                fileDomainIncludes.iterator().next());
+                fileDomainIncludes.iterator().next().getPath());
 
         assertEquals("Unexpected number of <exclude/>s", 1, excludesSet.size());
         assertEquals("Invalid path parsed for <exclude/>",
                 new File(mContext.getFilesDir(), "exclude.txt").getCanonicalPath(),
-                excludesSet.iterator().next());
+                excludesSet.iterator().next().getPath());
     }
 
     public void testparseBackupSchemeFromXml_lotsOfIncludesAndExcludes() throws Exception {
@@ -126,61 +243,74 @@
                         "<include path=\"include4.xml\" domain=\"sharedpref\"/>" +
                 "</full-backup-content>"));
 
-
         FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext);
         bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap);
 
-        Set<String> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
+        Set<PathWithRequiredFlags> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
         assertEquals("Didn't find expected file domain include.", 1, fileDomainIncludes.size());
         assertEquals("Invalid path parsed for <include/>",
                 new File(mContext.getFilesDir(), "include1.txt").getCanonicalPath(),
-                fileDomainIncludes.iterator().next());
+                fileDomainIncludes.iterator().next().getPath());
 
-        Set<String> databaseDomainIncludes = includeMap.get(FullBackup.DATABASE_TREE_TOKEN);
+        Set<PathWithRequiredFlags> databaseDomainIncludes =
+                includeMap.get(FullBackup.DATABASE_TREE_TOKEN);
+        Set<String> databaseDomainIncludesPaths = new ArraySet<>();
+        for (PathWithRequiredFlags databaseInclude : databaseDomainIncludes) {
+            databaseDomainIncludesPaths.add(databaseInclude.getPath());
+        }
         // Three expected here because of "-journal" and "-wal" files
         assertEquals("Didn't find expected database domain include.",
                 3, databaseDomainIncludes.size());
         assertTrue("Invalid path parsed for <include/>",
-                databaseDomainIncludes.contains(
+                databaseDomainIncludesPaths.contains(
                         new File(mContext.getDatabasePath("foo").getParentFile(), "include2.txt")
                                 .getCanonicalPath()));
         assertTrue("Invalid path parsed for <include/>",
-                databaseDomainIncludes.contains(
+                databaseDomainIncludesPaths.contains(
                         new File(
                                 mContext.getDatabasePath("foo").getParentFile(),
                                 "include2.txt-journal")
                                 .getCanonicalPath()));
         assertTrue("Invalid path parsed for <include/>",
-                databaseDomainIncludes.contains(
+                databaseDomainIncludesPaths.contains(
                         new File(
                                 mContext.getDatabasePath("foo").getParentFile(),
                                 "include2.txt-wal")
                                 .getCanonicalPath()));
 
-        List<String> sharedPrefDomainIncludes = new ArrayList<String>(
+        List<PathWithRequiredFlags> sharedPrefDomainIncludes = new ArrayList<PathWithRequiredFlags>(
                 includeMap.get(FullBackup.SHAREDPREFS_TREE_TOKEN));
-        Collections.sort(sharedPrefDomainIncludes);
+        ArrayList<String> sharedPrefDomainIncludesPaths = new ArrayList<>();
+        for (PathWithRequiredFlags sharedPrefInclude : sharedPrefDomainIncludes) {
+            sharedPrefDomainIncludesPaths.add(sharedPrefInclude.getPath());
+        }
+        // Sets are annoying to iterate over b/c order isn't enforced - convert to an array and
+        // sort lexicographically.
+        Collections.sort(sharedPrefDomainIncludesPaths);
 
         assertEquals("Didn't find expected sharedpref domain include.",
                 3, sharedPrefDomainIncludes.size());
         assertEquals("Invalid path parsed for <include/>",
                 new File(mContext.getSharedPrefsFile("foo").getParentFile(), "include3")
                         .getCanonicalPath(),
-                sharedPrefDomainIncludes.get(0));
+                sharedPrefDomainIncludesPaths.get(0));
         assertEquals("Invalid path parsed for <include/>",
                 new File(mContext.getSharedPrefsFile("foo").getParentFile(), "include3.xml")
                         .getCanonicalPath(),
-                sharedPrefDomainIncludes.get(1));
+                sharedPrefDomainIncludesPaths.get(1));
         assertEquals("Invalid path parsed for <include/>",
                 new File(mContext.getSharedPrefsFile("foo").getParentFile(), "include4.xml")
                         .getCanonicalPath(),
-                sharedPrefDomainIncludes.get(2));
+                sharedPrefDomainIncludesPaths.get(2));
 
 
         assertEquals("Unexpected number of <exclude/>s", 7, excludesSet.size());
         // Sets are annoying to iterate over b/c order isn't enforced - convert to an array and
         // sort lexicographically.
-        List<String> arrayedSet = new ArrayList<String>(excludesSet);
+        ArrayList<String> arrayedSet = new ArrayList<>();
+        for (PathWithRequiredFlags exclude : excludesSet) {
+            arrayedSet.add(exclude.getPath());
+        }
         Collections.sort(arrayedSet);
 
         assertEquals("Invalid path parsed for <exclude/>",
@@ -260,9 +390,10 @@
 
         assertEquals("Didn't throw away invalid \"..\" path.", 0, includeMap.size());
 
-        Set<String> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
+        Set<PathWithRequiredFlags> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
         assertNull("Didn't throw away invalid \"..\" path.", fileDomainIncludes);
     }
+
     public void testDoubleDotInPath_isIgnored() throws Exception {
         mXpp.setInput(new StringReader(
                 "<full-backup-content>" +
@@ -274,7 +405,7 @@
 
         assertEquals("Didn't throw away invalid \"..\" path.", 0, includeMap.size());
 
-        Set<String> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
+        Set<PathWithRequiredFlags> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
         assertNull("Didn't throw away invalid \"..\" path.", fileDomainIncludes);
     }
 
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 38e20a1..bba8c1a 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -305,6 +305,7 @@
                     Settings.Global.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS,
                     Settings.Global.NETWORK_WATCHLIST_ENABLED,
                     Settings.Global.NEW_CONTACT_AGGREGATOR,
+                    Settings.Global.NIGHT_DISPLAY_FORCED_AUTO_MODE_AVAILABLE,
                     Settings.Global.NITZ_UPDATE_DIFF,
                     Settings.Global.NITZ_UPDATE_SPACING,
                     Settings.Global.NOTIFICATION_SNOOZE_OPTIONS,
@@ -376,6 +377,7 @@
                     Settings.Global.SYS_STORAGE_THRESHOLD_MAX_BYTES,
                     Settings.Global.SYS_STORAGE_THRESHOLD_PERCENTAGE,
                     Settings.Global.SYS_VDSO,
+                    Settings.Global.SYS_UIDCPUPOWER,
                     Settings.Global.FPS_DEVISOR,
                     Settings.Global.TCP_DEFAULT_INIT_RWND,
                     Settings.Global.TETHER_DUN_APN,
diff --git a/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk b/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
index bd6d73d..d26425b 100644
--- a/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
+++ b/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
@@ -56,7 +56,7 @@
 LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_v1
 LOCAL_AAPT_FLAGS += --version-code 1 --version-name v1
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/app/v1/res
-LOCAL_MANIFEST_FILE := app/AndroidManifest.xml
+LOCAL_MANIFEST_FILE := app/v1/AndroidManifest.xml
 include $(BUILD_PACKAGE)
 
 include $(CLEAR_VARS)
@@ -67,7 +67,7 @@
 LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_v2
 LOCAL_AAPT_FLAGS += --version-code 2 --version-name v2
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/app/v2/res
-LOCAL_MANIFEST_FILE := app/AndroidManifest.xml
+LOCAL_MANIFEST_FILE := app/v2/AndroidManifest.xml
 include $(BUILD_PACKAGE)
 
 my_package_prefix :=
diff --git a/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/AndroidManifest.xml b/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v1/AndroidManifest.xml
similarity index 100%
rename from core/tests/overlaytests/host/test-apps/UpdateOverlay/app/AndroidManifest.xml
rename to core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v1/AndroidManifest.xml
diff --git a/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v2/AndroidManifest.xml b/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v2/AndroidManifest.xml
new file mode 100644
index 0000000..9ec7d06
--- /dev/null
+++ b/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v2/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.server.om.hosttest.app_overlay">
+    <overlay android:targetPackage="com.android.server.om.hosttest.update_overlay_test"
+        android:category="android.theme" />
+</manifest>
diff --git a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
index 598807d..796d008 100644
--- a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
@@ -72,11 +72,14 @@
             mAssetFd = afd;
         }
 
-        public  final long mNativePtr;
+        final long mNativePtr;
 
         // These just keep references so the native code can continue using them.
         private final InputStream mInputStream;
         private final AssetFileDescriptor mAssetFd;
+
+        int[] mThemeAttrs = null;
+        boolean mAutoMirrored = false;
     }
 
     private State mState;
@@ -99,7 +102,7 @@
      *  <p>By default, the loop count in the encoded data is respected.</p>
      */
     public void setLoopCount(int loopCount) {
-        if (mState == null) {
+        if (mState.mNativePtr == 0) {
             throw new IllegalStateException("called setLoopCount on empty AnimatedImageDrawable");
         }
         nSetLoopCount(mState.mNativePtr, loopCount);
@@ -109,7 +112,7 @@
      * Create an empty AnimatedImageDrawable.
      */
     public AnimatedImageDrawable() {
-        mState = null;
+        mState = new State(0, null, null);
     }
 
     @Override
@@ -123,6 +126,7 @@
 
     private void updateStateFromTypedArray(TypedArray a, int srcDensityOverride)
             throws XmlPullParserException {
+        State oldState = mState;
         final Resources r = a.getResources();
         final int srcResId = a.getResourceId(R.styleable.AnimatedImageDrawable_src, 0);
         if (srcResId != 0) {
@@ -172,6 +176,16 @@
             mIntrinsicWidth =  other.mIntrinsicWidth;
             mIntrinsicHeight = other.mIntrinsicHeight;
         }
+
+        mState.mThemeAttrs = a.extractThemeAttrs();
+        if (mState.mNativePtr == 0 && (mState.mThemeAttrs == null
+                || mState.mThemeAttrs[R.styleable.AnimatedImageDrawable_src] == 0)) {
+            throw new XmlPullParserException(a.getPositionDescription() +
+                    ": <animated-image> requires a valid 'src' attribute");
+        }
+
+        mState.mAutoMirrored = a.getBoolean(
+                R.styleable.AnimatedImageDrawable_autoMirrored, oldState.mAutoMirrored);
     }
 
     /**
@@ -225,7 +239,7 @@
 
     @Override
     public void draw(@NonNull Canvas canvas) {
-        if (mState == null) {
+        if (mState.mNativePtr == 0) {
             throw new IllegalStateException("called draw on empty AnimatedImageDrawable");
         }
 
@@ -256,7 +270,7 @@
                    + " 255! provided " + alpha);
         }
 
-        if (mState == null) {
+        if (mState.mNativePtr == 0) {
             throw new IllegalStateException("called setAlpha on empty AnimatedImageDrawable");
         }
 
@@ -266,7 +280,7 @@
 
     @Override
     public int getAlpha() {
-        if (mState == null) {
+        if (mState.mNativePtr == 0) {
             throw new IllegalStateException("called getAlpha on empty AnimatedImageDrawable");
         }
         return nGetAlpha(mState.mNativePtr);
@@ -274,7 +288,7 @@
 
     @Override
     public void setColorFilter(@Nullable ColorFilter colorFilter) {
-        if (mState == null) {
+        if (mState.mNativePtr == 0) {
             throw new IllegalStateException("called setColorFilter on empty AnimatedImageDrawable");
         }
 
@@ -298,11 +312,28 @@
     }
 
     @Override
+    public void setAutoMirrored(boolean mirrored) {
+        if (mState.mAutoMirrored != mirrored) {
+            mState.mAutoMirrored = mirrored;
+            invalidateSelf();
+        }
+    }
+
+    @Override
+    public final boolean isAutoMirrored() {
+        return mState.mAutoMirrored;
+    }
+
+    @Override
     public boolean setVisible(boolean visible, boolean restart) {
         if (!super.setVisible(visible, restart)) {
             return false;
         }
 
+        if (mState.mNativePtr == 0) {
+            throw new IllegalStateException("called setVisible on empty AnimatedImageDrawable");
+        }
+
         if (!visible) {
             nMarkInvisible(mState.mNativePtr);
         }
@@ -319,7 +350,7 @@
      */
     @Override
     public boolean isRunning() {
-        if (mState == null) {
+        if (mState.mNativePtr == 0) {
             throw new IllegalStateException("called isRunning on empty AnimatedImageDrawable");
         }
         return nIsRunning(mState.mNativePtr);
@@ -336,7 +367,7 @@
      */
     @Override
     public void start() {
-        if (mState == null) {
+        if (mState.mNativePtr == 0) {
             throw new IllegalStateException("called start on empty AnimatedImageDrawable");
         }
 
@@ -354,7 +385,7 @@
      */
     @Override
     public void stop() {
-        if (mState == null) {
+        if (mState.mNativePtr == 0) {
             throw new IllegalStateException("called stop on empty AnimatedImageDrawable");
         }
         if (nStop(mState.mNativePtr)) {
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index e2aba04..ded427e 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -545,9 +545,7 @@
         try {
             args = args != null ? args : new KeymasterArguments();
             entropy = entropy != null ? entropy : new byte[0];
-            OperationResult res = mBinder.begin(getToken(), alias, purpose, pruneable, args, entropy, uid);
-            // This result is -26 (KEY_USER_NOT_AUTHENTICATED) but why??
-            return res;
+            return mBinder.begin(getToken(), alias, purpose, pruneable, args, entropy, uid);
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
             return null;
@@ -565,8 +563,7 @@
         try {
             arguments = arguments != null ? arguments : new KeymasterArguments();
             input = input != null ? input : new byte[0];
-            OperationResult res = mBinder.update(token, arguments, input);
-            return res;
+            return mBinder.update(token, arguments, input);
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
             return null;
@@ -621,9 +618,9 @@
      * @return {@code KeyStore.NO_ERROR} on success, otherwise an error value corresponding to
      * a {@code KeymasterDefs.KM_ERROR_} value or {@code KeyStore} ResponseCode.
      */
-    public int addAuthToken(byte[] authToken, int userId) {
+    public int addAuthToken(byte[] authToken) {
         try {
-            return mBinder.addAuthToken(authToken, userId);
+            return mBinder.addAuthToken(authToken);
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
             return SYSTEM_ERROR;
@@ -835,14 +832,14 @@
     public InvalidKeyException getInvalidKeyException(
             String keystoreKeyAlias, int uid, KeyStoreException e) {
         switch (e.getErrorCode()) {
-            case LOCKED: // 2
+            case LOCKED:
                 return new UserNotAuthenticatedException();
-            case KeymasterDefs.KM_ERROR_KEY_EXPIRED: // -25
+            case KeymasterDefs.KM_ERROR_KEY_EXPIRED:
                 return new KeyExpiredException();
-            case KeymasterDefs.KM_ERROR_KEY_NOT_YET_VALID: // -2
+            case KeymasterDefs.KM_ERROR_KEY_NOT_YET_VALID:
                 return new KeyNotYetValidException();
-            case KeymasterDefs.KM_ERROR_KEY_USER_NOT_AUTHENTICATED: // -26
-            case OP_AUTH_NEEDED: // 15
+            case KeymasterDefs.KM_ERROR_KEY_USER_NOT_AUTHENTICATED:
+            case OP_AUTH_NEEDED:
             {
                 // We now need to determine whether the key/operation can become usable if user
                 // authentication is performed, or whether it can never become usable again.
@@ -882,7 +879,7 @@
                 // None of the key's SIDs can ever be authenticated
                 return new KeyPermanentlyInvalidatedException();
             }
-            case UNINITIALIZED: // 3
+            case UNINITIALIZED:
                 return new KeyPermanentlyInvalidatedException();
             default:
                 return new InvalidKeyException("Keystore operation failed", e);
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
index 419eb24..09b3b9b 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
@@ -243,7 +243,13 @@
                 // Check that user authentication related parameters are acceptable. This method
                 // will throw an IllegalStateException if there are issues (e.g., secure lock screen
                 // not set up).
-                KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), spec);
+                KeymasterUtils.addUserAuthArgs(new KeymasterArguments(),
+                        spec.isUserAuthenticationRequired(),
+                        spec.getUserAuthenticationValidityDurationSeconds(),
+                        spec.isUserAuthenticationValidWhileOnBody(),
+                        spec.isInvalidatedByBiometricEnrollment(),
+                        GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */,
+                        spec.isUserConfirmationRequired());
             } catch (IllegalStateException | IllegalArgumentException e) {
                 throw new InvalidAlgorithmParameterException(e);
             }
@@ -279,7 +285,16 @@
         args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockModes);
         args.addEnums(KeymasterDefs.KM_TAG_PADDING, mKeymasterPaddings);
         args.addEnums(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
-        KeymasterUtils.addUserAuthArgs(args, spec);
+        KeymasterUtils.addUserAuthArgs(args,
+                spec.isUserAuthenticationRequired(),
+                spec.getUserAuthenticationValidityDurationSeconds(),
+                spec.isUserAuthenticationValidWhileOnBody(),
+                spec.isInvalidatedByBiometricEnrollment(),
+                GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */,
+                spec.isUserConfirmationRequired());
+        if (spec.isTrustedUserPresenceRequired()) {
+            args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED);
+        }
         KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(
                 args,
                 mKeymasterAlgorithm,
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
index d68a33d..e33e3cd 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -344,7 +344,13 @@
                 // Check that user authentication related parameters are acceptable. This method
                 // will throw an IllegalStateException if there are issues (e.g., secure lock screen
                 // not set up).
-                KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), mSpec);
+                KeymasterUtils.addUserAuthArgs(new KeymasterArguments(),
+                        mSpec.isUserAuthenticationRequired(),
+                        mSpec.getUserAuthenticationValidityDurationSeconds(),
+                        mSpec.isUserAuthenticationValidWhileOnBody(),
+                        mSpec.isInvalidatedByBiometricEnrollment(),
+                        GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */,
+                        mSpec.isUserConfirmationRequired());
             } catch (IllegalArgumentException | IllegalStateException e) {
                 throw new InvalidAlgorithmParameterException(e);
             }
@@ -535,7 +541,13 @@
         args.addEnums(KeymasterDefs.KM_TAG_PADDING, mKeymasterSignaturePaddings);
         args.addEnums(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
 
-        KeymasterUtils.addUserAuthArgs(args, mSpec);
+        KeymasterUtils.addUserAuthArgs(args,
+                mSpec.isUserAuthenticationRequired(),
+                mSpec.getUserAuthenticationValidityDurationSeconds(),
+                mSpec.isUserAuthenticationValidWhileOnBody(),
+                mSpec.isInvalidatedByBiometricEnrollment(),
+                GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */,
+                mSpec.isUserConfirmationRequired());
         args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, mSpec.getKeyValidityStart());
         args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
                 mSpec.getKeyValidityForOriginationEnd());
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
index fc86ca0..05cc74a 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
@@ -497,7 +497,13 @@
                 importArgs.addEnums(KeymasterDefs.KM_TAG_PADDING, keymasterEncryptionPaddings);
                 importArgs.addEnums(KeymasterDefs.KM_TAG_PADDING,
                         KeyProperties.SignaturePadding.allToKeymaster(spec.getSignaturePaddings()));
-                KeymasterUtils.addUserAuthArgs(importArgs, spec);
+                KeymasterUtils.addUserAuthArgs(importArgs,
+                        spec.isUserAuthenticationRequired(),
+                        spec.getUserAuthenticationValidityDurationSeconds(),
+                        spec.isUserAuthenticationValidWhileOnBody(),
+                        spec.isInvalidatedByBiometricEnrollment(),
+                        spec.getBoundToSpecificSecureUserId(),
+                        spec.isUserConfirmationRequired());
                 importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME,
                         spec.getKeyValidityStart());
                 importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
@@ -694,7 +700,13 @@
             int[] keymasterPaddings = KeyProperties.EncryptionPadding.allToKeymaster(
                     params.getEncryptionPaddings());
             args.addEnums(KeymasterDefs.KM_TAG_PADDING, keymasterPaddings);
-            KeymasterUtils.addUserAuthArgs(args, params);
+            KeymasterUtils.addUserAuthArgs(args,
+                    params.isUserAuthenticationRequired(),
+                    params.getUserAuthenticationValidityDurationSeconds(),
+                    params.isUserAuthenticationValidWhileOnBody(),
+                    params.isInvalidatedByBiometricEnrollment(),
+                    params.getBoundToSpecificSecureUserId(),
+                    params.isUserConfirmationRequired());
             KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(
                     args,
                     keymasterAlgorithm,
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index d0814c6..da23c70 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -21,7 +21,6 @@
 import android.annotation.Nullable;
 import android.app.KeyguardManager;
 import android.hardware.fingerprint.FingerprintManager;
-import android.security.GateKeeper;
 import android.security.KeyStore;
 import android.text.TextUtils;
 
@@ -233,7 +232,7 @@
  * key = (SecretKey) keyStore.getKey("key2", null);
  * }</pre>
  */
-public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAuthArgs {
+public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
 
     private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake");
     private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1");
@@ -266,7 +265,6 @@
     private final boolean mInvalidatedByBiometricEnrollment;
     private final boolean mIsStrongBoxBacked;
     private final boolean mUserConfirmationRequired;
-    private final boolean mUnlockedDeviceRequired;
 
     /**
      * @hide should be built with Builder
@@ -297,8 +295,7 @@
             boolean userAuthenticationValidWhileOnBody,
             boolean invalidatedByBiometricEnrollment,
             boolean isStrongBoxBacked,
-            boolean userConfirmationRequired,
-            boolean unlockedDeviceRequired) {
+            boolean userConfirmationRequired) {
         if (TextUtils.isEmpty(keyStoreAlias)) {
             throw new IllegalArgumentException("keyStoreAlias must not be empty");
         }
@@ -347,7 +344,6 @@
         mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
         mIsStrongBoxBacked = isStrongBoxBacked;
         mUserConfirmationRequired = userConfirmationRequired;
-        mUnlockedDeviceRequired = unlockedDeviceRequired;
     }
 
     /**
@@ -673,22 +669,6 @@
     }
 
     /**
-     * Returns {@code true} if the key cannot be used unless the device screen is unlocked.
-     *
-     * @see Builder#SetUnlockedDeviceRequired(boolean)
-     */
-    public boolean isUnlockedDeviceRequired() {
-        return mUnlockedDeviceRequired;
-    }
-
-    /**
-     * @hide
-     */
-    public long getBoundToSpecificSecureUserId() {
-        return GateKeeper.INVALID_SECURE_USER_ID;
-    }
-
-    /**
      * Builder of {@link KeyGenParameterSpec} instances.
      */
     public final static class Builder {
@@ -719,7 +699,6 @@
         private boolean mInvalidatedByBiometricEnrollment = true;
         private boolean mIsStrongBoxBacked = false;
         private boolean mUserConfirmationRequired;
-        private boolean mUnlockedDeviceRequired = false;
 
         /**
          * Creates a new instance of the {@code Builder}.
@@ -1288,18 +1267,6 @@
         }
 
         /**
-         * Sets whether the keystore requires the screen to be unlocked before allowing decryption
-         * using this key. If this is set to {@code true}, any attempt to decrypt using this key
-         * while the screen is locked will fail. A locked device requires a PIN, password,
-         * fingerprint, or other trusted factor to access.
-         */
-        @NonNull
-        public Builder setUnlockedDeviceRequired(boolean unlockedDeviceRequired) {
-            mUnlockedDeviceRequired = unlockedDeviceRequired;
-            return this;
-        }
-
-        /**
          * Builds an instance of {@code KeyGenParameterSpec}.
          */
         @NonNull
@@ -1330,8 +1297,7 @@
                     mUserAuthenticationValidWhileOnBody,
                     mInvalidatedByBiometricEnrollment,
                     mIsStrongBoxBacked,
-                    mUserConfirmationRequired,
-                    mUnlockedDeviceRequired);
+                    mUserConfirmationRequired);
         }
     }
 }
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
index 7f8259b..b5b3281 100644
--- a/keystore/java/android/security/keystore/KeyProtection.java
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -212,7 +212,7 @@
  * ...
  * }</pre>
  */
-public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
+public final class KeyProtection implements ProtectionParameter {
     private final Date mKeyValidityStart;
     private final Date mKeyValidityForOriginationEnd;
     private final Date mKeyValidityForConsumptionEnd;
@@ -229,8 +229,6 @@
     private final long mBoundToSecureUserId;
     private final boolean mCriticalToDeviceEncryption;
     private final boolean mUserConfirmationRequired;
-    private final boolean mTrustedUserPresenceRequired;
-    private final boolean mUnlockedDeviceRequired;
 
     private KeyProtection(
             Date keyValidityStart,
@@ -244,13 +242,11 @@
             boolean randomizedEncryptionRequired,
             boolean userAuthenticationRequired,
             int userAuthenticationValidityDurationSeconds,
-            boolean trustedUserPresenceRequired,
             boolean userAuthenticationValidWhileOnBody,
             boolean invalidatedByBiometricEnrollment,
             long boundToSecureUserId,
             boolean criticalToDeviceEncryption,
-            boolean userConfirmationRequired,
-            boolean unlockedDeviceRequired) {
+            boolean userConfirmationRequired) {
         mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart);
         mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd);
         mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd);
@@ -269,8 +265,6 @@
         mBoundToSecureUserId = boundToSecureUserId;
         mCriticalToDeviceEncryption = criticalToDeviceEncryption;
         mUserConfirmationRequired = userConfirmationRequired;
-        mTrustedUserPresenceRequired = trustedUserPresenceRequired;
-        mUnlockedDeviceRequired = unlockedDeviceRequired;
     }
 
     /**
@@ -443,14 +437,6 @@
     }
 
     /**
-     * Returns {@code true} if the key is authorized to be used only if a test of user presence has
-     * been performed between the {@code Signature.initSign()} and {@code Signature.sign()} calls.
-     */
-    public boolean isTrustedUserPresenceRequired() {
-        return mTrustedUserPresenceRequired;
-    }
-
-    /**
      * Returns {@code true} if the key will be de-authorized when the device is removed from the
      * user's body.  This option has no effect on keys that don't have an authentication validity
      * duration, and has no effect if the device lacks an on-body sensor.
@@ -508,15 +494,6 @@
     }
 
     /**
-     * Returns {@code true} if the key cannot be used unless the device screen is unlocked.
-     *
-     * @see Builder#SetRequireDeviceUnlocked(boolean)
-     */
-    public boolean isUnlockedDeviceRequired() {
-        return mUnlockedDeviceRequired;
-    }
-
-    /**
      * Builder of {@link KeyProtection} instances.
      */
     public final static class Builder {
@@ -535,9 +512,6 @@
         private boolean mUserAuthenticationValidWhileOnBody;
         private boolean mInvalidatedByBiometricEnrollment = true;
         private boolean mUserConfirmationRequired;
-        private boolean mTrustedUserPresenceRequired = false;
-        private boolean mUnlockedDeviceRequired = false;
-
         private long mBoundToSecureUserId = GateKeeper.INVALID_SECURE_USER_ID;
         private boolean mCriticalToDeviceEncryption = false;
 
@@ -837,16 +811,6 @@
         }
 
         /**
-         * Sets whether a test of user presence is required to be performed between the
-         * {@code Signature.initSign()} and {@code Signature.sign()} method calls.
-         */
-        @NonNull
-        public Builder setTrustedUserPresenceRequired(boolean required) {
-            mTrustedUserPresenceRequired = required;
-            return this;
-        }
-
-        /**
          * Sets whether the key will remain authorized only until the device is removed from the
          * user's body up to the limit of the authentication validity period (see
          * {@link #setUserAuthenticationValidityDurationSeconds} and
@@ -928,18 +892,6 @@
         }
 
         /**
-         * Sets whether the keystore requires the screen to be unlocked before allowing decryption
-         * using this key. If this is set to {@code true}, any attempt to decrypt using this key
-         * while the screen is locked will fail. A locked device requires a PIN, password,
-         * fingerprint, or other trusted factor to access.
-         */
-        @NonNull
-        public Builder setUnlockedDeviceRequired(boolean unlockedDeviceRequired) {
-            mUnlockedDeviceRequired = unlockedDeviceRequired;
-            return this;
-        }
-
-        /**
          * Builds an instance of {@link KeyProtection}.
          *
          * @throws IllegalArgumentException if a required field is missing
@@ -958,13 +910,11 @@
                     mRandomizedEncryptionRequired,
                     mUserAuthenticationRequired,
                     mUserAuthenticationValidityDurationSeconds,
-                    mTrustedUserPresenceRequired,
                     mUserAuthenticationValidWhileOnBody,
                     mInvalidatedByBiometricEnrollment,
                     mBoundToSecureUserId,
                     mCriticalToDeviceEncryption,
-                    mUserConfirmationRequired,
-                    mUnlockedDeviceRequired);
+                    mUserConfirmationRequired);
         }
     }
 }
diff --git a/keystore/java/android/security/keystore/KeymasterUtils.java b/keystore/java/android/security/keystore/KeymasterUtils.java
index 5bd0e74..4e28601 100644
--- a/keystore/java/android/security/keystore/KeymasterUtils.java
+++ b/keystore/java/android/security/keystore/KeymasterUtils.java
@@ -18,7 +18,6 @@
 
 import android.util.Log;
 import android.hardware.fingerprint.FingerprintManager;
-import android.os.UserHandle;
 import android.security.GateKeeper;
 import android.security.KeyStore;
 import android.security.keymaster.KeymasterArguments;
@@ -102,27 +101,22 @@
      *         require user authentication.
      */
     public static void addUserAuthArgs(KeymasterArguments args,
-            UserAuthArgs spec) {
-        if (spec.isTrustedUserPresenceRequired()) {
-            args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED);
-        }
-
-        if (spec.isUserConfirmationRequired()) {
+            boolean userAuthenticationRequired,
+            int userAuthenticationValidityDurationSeconds,
+            boolean userAuthenticationValidWhileOnBody,
+            boolean invalidatedByBiometricEnrollment,
+            long boundToSpecificSecureUserId,
+            boolean userConfirmationRequired) {
+        if (userConfirmationRequired) {
             args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_CONFIRMATION_REQUIRED);
         }
 
-        if (spec.isUnlockedDeviceRequired()) {
-            args.addBoolean(KeymasterDefs.KM_TAG_UNLOCKED_DEVICE_REQUIRED);
-            // Once keymaster is properly ignoring this tag, it should be added to every auth list
-            args.addUnsignedInt(KeymasterDefs.KM_TAG_USER_ID, UserHandle.getCallingUserId());
-        }
-
-        if (!spec.isUserAuthenticationRequired()) {
+        if (!userAuthenticationRequired) {
             args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
             return;
         }
 
-        if (spec.getUserAuthenticationValidityDurationSeconds() == -1) {
+        if (userAuthenticationValidityDurationSeconds == -1) {
             // Every use of this key needs to be authorized by the user. This currently means
             // fingerprint-only auth.
             FingerprintManager fingerprintManager =
@@ -138,9 +132,9 @@
             }
 
             long sid;
-            if (spec.getBoundToSpecificSecureUserId() != GateKeeper.INVALID_SECURE_USER_ID) {
-                sid = spec.getBoundToSpecificSecureUserId();
-            } else if (spec.isInvalidatedByBiometricEnrollment()) {
+            if (boundToSpecificSecureUserId != GateKeeper.INVALID_SECURE_USER_ID) {
+                sid = boundToSpecificSecureUserId;
+            } else if (invalidatedByBiometricEnrollment) {
                 // The fingerprint-only SID will change on fingerprint enrollment or removal of all,
                 // enrolled fingerprints, invalidating the key.
                 sid = fingerprintOnlySid;
@@ -153,14 +147,14 @@
             args.addUnsignedLong(
                     KeymasterDefs.KM_TAG_USER_SECURE_ID, KeymasterArguments.toUint64(sid));
             args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, KeymasterDefs.HW_AUTH_FINGERPRINT);
-            if (spec.isUserAuthenticationValidWhileOnBody()) {
+            if (userAuthenticationValidWhileOnBody) {
                 throw new ProviderException("Key validity extension while device is on-body is not "
                         + "supported for keys requiring fingerprint authentication");
             }
         } else {
             long sid;
-            if (spec.getBoundToSpecificSecureUserId() != GateKeeper.INVALID_SECURE_USER_ID) {
-                sid = spec.getBoundToSpecificSecureUserId();
+            if (boundToSpecificSecureUserId != GateKeeper.INVALID_SECURE_USER_ID) {
+                sid = boundToSpecificSecureUserId;
             } else {
                 // The key is authorized for use for the specified amount of time after the user has
                 // authenticated. Whatever unlocks the secure lock screen should authorize this key.
@@ -171,8 +165,8 @@
             args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
                     KeymasterDefs.HW_AUTH_PASSWORD | KeymasterDefs.HW_AUTH_FINGERPRINT);
             args.addUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
-                    spec.getUserAuthenticationValidityDurationSeconds());
-            if (spec.isUserAuthenticationValidWhileOnBody()) {
+                    userAuthenticationValidityDurationSeconds);
+            if (userAuthenticationValidWhileOnBody) {
                 args.addBoolean(KeymasterDefs.KM_TAG_ALLOW_WHILE_ON_BODY);
             }
         }
diff --git a/keystore/java/android/security/keystore/UserAuthArgs.java b/keystore/java/android/security/keystore/UserAuthArgs.java
deleted file mode 100644
index 3a7017e..0000000
--- a/keystore/java/android/security/keystore/UserAuthArgs.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2017 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.security.keystore;
-
-/**
- * @hide
- *
- * This is an interface to encapsulate the user authentication arguments that
- * are passed to KeymasterUtils.addUserAuthArgs. Classes that represent
- * authorization characteristics for new or imported keys can implement this
- * interface to be passed to that method.
- */
-public interface UserAuthArgs {
-
-    boolean isUserAuthenticationRequired();
-    int getUserAuthenticationValidityDurationSeconds();
-    boolean isUserAuthenticationValidWhileOnBody();
-    boolean isInvalidatedByBiometricEnrollment();
-    boolean isTrustedUserPresenceRequired();
-    boolean isUnlockedDeviceRequired();
-    boolean isUserConfirmationRequired();
-    long getBoundToSpecificSecureUserId();
-
-}
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 9d246ff..21c91a2 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -310,7 +310,7 @@
     for (uint32_t i = 0; i < surface->mImageCount; ++i) {
         GrVkImageInfo info;
         info.fImage = surface->mImages[i];
-        info.fAlloc = {VK_NULL_HANDLE, 0, 0, 0};
+        info.fAlloc = GrVkAlloc();
         info.fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
         info.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
         info.fFormat = format;
diff --git a/media/java/android/media/MediaPlayer2.java b/media/java/android/media/MediaPlayer2.java
index 2f3d972..1446660 100644
--- a/media/java/android/media/MediaPlayer2.java
+++ b/media/java/android/media/MediaPlayer2.java
@@ -1223,7 +1223,7 @@
      *
      * @return the current position in milliseconds
      */
-    public abstract int getCurrentPosition();
+    public abstract long getCurrentPosition();
 
     /**
      * Gets the duration of the file.
@@ -1231,7 +1231,7 @@
      * @return the duration in milliseconds, if no duration is available
      *         (for example, if streaming live content), -1 is returned.
      */
-    public abstract int getDuration();
+    public abstract long getDuration();
 
     /**
      * Gets the media metadata.
@@ -1278,27 +1278,6 @@
     }
 
     /**
-     * Set the MediaPlayer2 to start when this MediaPlayer2 finishes playback
-     * (i.e. reaches the end of the stream).
-     * The media framework will attempt to transition from this player to
-     * the next as seamlessly as possible. The next player can be set at
-     * any time before completion, but shall be after setDataSource has been
-     * called successfully. The next player must be prepared by the
-     * app, and the application should not call play() on it.
-     * The next MediaPlayer2 must be different from 'this'. An exception
-     * will be thrown if next == this.
-     * The application may call setNextMediaPlayer(null) to indicate no
-     * next player should be started at the end of playback.
-     * If the current player is looping, it will keep looping and the next
-     * player will not be started.
-     *
-     * @param next the player to start after this one completes playback.
-     *
-     * @hide
-     */
-    public void setNextMediaPlayer(MediaPlayer2 next) { }
-
-    /**
      * Resets the MediaPlayer2 to its uninitialized state. After calling
      * this method, you will have to initialize it again by setting the
      * data source and calling prepareAsync().
@@ -1326,6 +1305,13 @@
     public abstract void setAudioAttributes(AudioAttributes attributes);
 
     /**
+     * Gets the audio attributes for this MediaPlayer2.
+     * @return attributes a set of audio attributes
+     * @throws IllegalArgumentException if the attributes are null or invalid.
+     */
+    public abstract AudioAttributes getAudioAttributes();
+
+    /**
      * Sets the player to be looping or non-looping.
      *
      * @param looping whether to loop or not
@@ -2029,8 +2015,9 @@
          * Called to give the app the opportunity to configure DRM before the session is created
          *
          * @param mp the {@code MediaPlayer2} associated with this callback
+         * @param srcId the Id of this data source
          */
-        public void onDrmConfig(MediaPlayer2 mp);
+        public void onDrmConfig(MediaPlayer2 mp, long srcId);
     }
 
     /**
@@ -2051,24 +2038,25 @@
         /**
          * Called to indicate DRM info is available
          *
-         * @param mp       the {@code MediaPlayer2} associated with this callback
-         * @param drmInfo  DRM info of the source including PSSH, and subset
-         *                 of crypto schemes supported by this device
+         * @param mp the {@code MediaPlayer2} associated with this callback
+         * @param srcId the Id of this data source
+         * @param drmInfo DRM info of the source including PSSH, and subset
+         *                of crypto schemes supported by this device
          */
-        public void onDrmInfo(MediaPlayer2 mp, DrmInfo drmInfo) { }
+        public void onDrmInfo(MediaPlayer2 mp, long srcId, DrmInfo drmInfo) { }
 
         /**
          * Called to notify the client that {@code prepareDrm} is finished and ready for key request/response.
          *
-         * @param mp      the {@code MediaPlayer2} associated with this callback
-         * @param status  the result of DRM preparation which can be
+         * @param mp the {@code MediaPlayer2} associated with this callback
+         * @param srcId the Id of this data source
+         * @param status the result of DRM preparation which can be
          * {@link #PREPARE_DRM_STATUS_SUCCESS},
          * {@link #PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR},
          * {@link #PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR}, or
          * {@link #PREPARE_DRM_STATUS_PREPARATION_ERROR}.
          */
-        public void onDrmPrepared(MediaPlayer2 mp, @PrepareDrmStatusCode int status) { }
-
+        public void onDrmPrepared(MediaPlayer2 mp, long srcId, @PrepareDrmStatusCode int status) { }
     }
 
     /**
diff --git a/media/java/android/media/MediaPlayer2Impl.java b/media/java/android/media/MediaPlayer2Impl.java
index 1b21b5b..7794e08 100644
--- a/media/java/android/media/MediaPlayer2Impl.java
+++ b/media/java/android/media/MediaPlayer2Impl.java
@@ -1889,7 +1889,7 @@
      * @return the current position in milliseconds
      */
     @Override
-    public native int getCurrentPosition();
+    public native long getCurrentPosition();
 
     /**
      * Gets the duration of the file.
@@ -1898,7 +1898,7 @@
      *         (for example, if streaming live content), -1 is returned.
      */
     @Override
-    public native int getDuration();
+    public native long getDuration();
 
     /**
      * Gets the media metadata.
@@ -1986,28 +1986,6 @@
     }
 
     /**
-     * Set the MediaPlayer2 to start when this MediaPlayer2 finishes playback
-     * (i.e. reaches the end of the stream).
-     * The media framework will attempt to transition from this player to
-     * the next as seamlessly as possible. The next player can be set at
-     * any time before completion, but shall be after setDataSource has been
-     * called successfully. The next player must be prepared by the
-     * app, and the application should not call play() on it.
-     * The next MediaPlayer2 must be different from 'this'. An exception
-     * will be thrown if next == this.
-     * The application may call setNextMediaPlayer(null) to indicate no
-     * next player should be started at the end of playback.
-     * If the current player is looping, it will keep looping and the next
-     * player will not be started.
-     *
-     * @param next the player to start after this one completes playback.
-     *
-     * @hide
-     */
-    @Override
-    public native void setNextMediaPlayer(MediaPlayer2 next);
-
-    /**
      * Resets the MediaPlayer2 to its uninitialized state. After calling
      * this method, you will have to initialize it again by setting the
      * data source and calling prepareAsync().
@@ -2078,10 +2056,11 @@
      * @param key key indicates the parameter to be set.
      * @param value value of the parameter to be set.
      * @return true if the parameter is set successfully, false otherwise
-     * {@hide}
      */
     private native boolean setParameter(int key, Parcel value);
 
+    private native Parcel getParameter(int key);
+
     /**
      * Sets the audio attributes for this MediaPlayer2.
      * See {@link AudioAttributes} for how to build and configure an instance of this class.
@@ -2105,6 +2084,14 @@
         pattributes.recycle();
     }
 
+    @Override
+    public AudioAttributes getAudioAttributes() {
+        Parcel pattributes = getParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES);
+        AudioAttributes attributes = AudioAttributes.CREATOR.createFromParcel(pattributes);
+        pattributes.recycle();
+        return attributes;
+    }
+
     /**
      * Sets the player to be looping or non-looping.
      *
@@ -3211,11 +3198,12 @@
                     }
 
                     // notifying the client outside the lock
+                    // TODO: get srcId
                     if (drmInfo != null) {
                         synchronized (mEventCbLock) {
                             for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) {
                                 cb.first.execute(() -> cb.second.onDrmInfo(
-                                        mMediaPlayer, drmInfo));
+                                        mMediaPlayer, 0, drmInfo));
                             }
                         }
                     }
@@ -3747,8 +3735,9 @@
 
 
         // call the callback outside the lock
+        // TODO: get srcId
         if (mOnDrmConfigHelper != null)  {
-            mOnDrmConfigHelper.onDrmConfig(this);
+            mOnDrmConfigHelper.onDrmConfig(this, 0);
         }
 
         synchronized (mDrmLock) {
@@ -3818,11 +3807,12 @@
 
 
         // if finished successfully without provisioning, call the callback outside the lock
+        // TODO: get srcId
         if (allDoneWithoutProvisioning) {
             synchronized (mDrmEventCbLock) {
                 for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) {
                     cb.first.execute(() -> cb.second.onDrmPrepared(
-                            this, PREPARE_DRM_STATUS_SUCCESS));
+                            this, 0, PREPARE_DRM_STATUS_SUCCESS));
                 }
             }
         }
@@ -4488,9 +4478,10 @@
                 } // synchronized
 
                 // calling the callback outside the lock
+                // TODO: get srcId
                 synchronized (mDrmEventCbLock) {
                     for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) {
-                        cb.first.execute(() -> cb.second.onDrmPrepared(mediaPlayer, status));
+                        cb.first.execute(() -> cb.second.onDrmPrepared(mediaPlayer, 0, status));
                     }
                 }
             } else {   // blocking mode already has the lock
diff --git a/media/java/android/media/update/VideoView2Provider.java b/media/java/android/media/update/VideoView2Provider.java
index 21cc61f..4333c96 100644
--- a/media/java/android/media/update/VideoView2Provider.java
+++ b/media/java/android/media/update/VideoView2Provider.java
@@ -18,6 +18,7 @@
 
 import android.annotation.SystemApi;
 import android.media.AudioAttributes;
+import android.media.MediaMetadata2;
 import android.media.MediaPlayerInterface;
 import android.media.session.MediaController;
 import android.media.session.PlaybackState;
@@ -51,8 +52,10 @@
     void initialize(AttributeSet attrs, int defStyleAttr, int defStyleRes);
 
     void setMediaControlView2_impl(MediaControlView2 mediaControlView, long intervalMs);
+    void setMediaMetadata_impl(MediaMetadata2 metadata);
     MediaController getMediaController_impl();
     MediaControlView2 getMediaControlView2_impl();
+    MediaMetadata2 getMediaMetadata_impl();
     void setSubtitleEnabled_impl(boolean enable);
     boolean isSubtitleEnabled_impl();
     // TODO: remove setSpeed_impl once MediaController2 is ready.
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index fe2f64f..3c8af8a 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -51,6 +51,7 @@
         "libexif",
         "libpiex",
         "libandroidfw",
+        "libhidlallocatorutils",
         "libhidlbase",
         "libhidltransport",
         "android.hardware.cas@1.0",
@@ -106,6 +107,7 @@
         "liblog",  // NDK
         "libdrmframework",  // for FileSource, MediaHTTP
         "libgui",  // for VideoFrameScheduler
+        "libhidlallocatorutils",
         "libhidlbase",  // VNDK???
         "libmediandk",  // NDK
         "libpowermanager",  // for JWakeLock. to be removed
diff --git a/media/jni/android_media_MediaDescrambler.cpp b/media/jni/android_media_MediaDescrambler.cpp
index e77e855..add47463 100644
--- a/media/jni/android_media_MediaDescrambler.cpp
+++ b/media/jni/android_media_MediaDescrambler.cpp
@@ -27,12 +27,13 @@
 #include <android/hardware/cas/native/1.0/BnHwDescrambler.h>
 #include <binder/MemoryDealer.h>
 #include <hidl/HidlSupport.h>
+#include <hidlmemory/FrameworkUtils.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <nativehelper/ScopedLocalRef.h>
 
 namespace android {
 
-using hardware::hidl_handle;
+using hardware::fromHeap;
 
 struct fields_t {
     jfieldID context;
@@ -146,14 +147,8 @@
         return false;
     }
 
-    native_handle_t* nativeHandle = native_handle_create(1, 0);
-    if (!nativeHandle) {
-        ALOGE("ensureBufferCapacity: failed to create native handle");
-        return false;
-    }
-    nativeHandle->data[0] = heap->getHeapID();
-    mDescramblerSrcBuffer.heapBase = hidl_memory("ashmem",
-            hidl_handle(nativeHandle), heap->getSize());
+    mHidlMemory = fromHeap(heap);
+    mDescramblerSrcBuffer.heapBase = *mHidlMemory;
     mDescramblerSrcBuffer.offset = (uint64_t) offset;
     mDescramblerSrcBuffer.size = (uint64_t) size;
     return true;
diff --git a/media/jni/android_media_MediaDescrambler.h b/media/jni/android_media_MediaDescrambler.h
index 015fad2..2354dc2 100644
--- a/media/jni/android_media_MediaDescrambler.h
+++ b/media/jni/android_media_MediaDescrambler.h
@@ -28,7 +28,10 @@
 class IMemory;
 class MemoryDealer;
 
-using hardware::hidl_memory;
+namespace hardware {
+class HidlMemory;
+};
+using hardware::HidlMemory;
 using hardware::hidl_string;
 using hardware::hidl_vec;
 using namespace hardware::cas::V1_0;
@@ -58,6 +61,7 @@
     sp<IDescrambler> mDescrambler;
     sp<IMemory> mMem;
     sp<MemoryDealer> mDealer;
+    sp<HidlMemory> mHidlMemory;
     SharedBuffer mDescramblerSrcBuffer;
 
     Mutex mSharedMemLock;
diff --git a/media/jni/android_media_MediaPlayer2.cpp b/media/jni/android_media_MediaPlayer2.cpp
index cf115a4..2258c78 100644
--- a/media/jni/android_media_MediaPlayer2.cpp
+++ b/media/jni/android_media_MediaPlayer2.cpp
@@ -760,7 +760,8 @@
         return;
     }
     ALOGV("seekTo: %lld(msec), mode=%d", (long long)msec, mode);
-    process_media_player_call( env, thiz, mp->seekTo((int)msec, (MediaPlayer2SeekMode)mode), NULL, NULL );
+    process_media_player_call(env, thiz, mp->seekTo((int64_t)msec, (MediaPlayer2SeekMode)mode),
+                              NULL, NULL);
 }
 
 static void
@@ -838,7 +839,7 @@
     return mybundle;
 }
 
-static jint
+static jlong
 android_media_MediaPlayer2_getCurrentPosition(JNIEnv *env, jobject thiz)
 {
     sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
@@ -846,13 +847,13 @@
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
         return 0;
     }
-    int msec;
+    int64_t msec;
     process_media_player_call( env, thiz, mp->getCurrentPosition(&msec), NULL, NULL );
-    ALOGV("getCurrentPosition: %d (msec)", msec);
-    return (jint) msec;
+    ALOGV("getCurrentPosition: %lld (msec)", (long long)msec);
+    return (jlong) msec;
 }
 
-static jint
+static jlong
 android_media_MediaPlayer2_getDuration(JNIEnv *env, jobject thiz)
 {
     sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
@@ -860,10 +861,10 @@
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
         return 0;
     }
-    int msec;
+    int64_t msec;
     process_media_player_call( env, thiz, mp->getDuration(&msec), NULL, NULL );
-    ALOGV("getDuration: %d (msec)", msec);
-    return (jint) msec;
+    ALOGV("getDuration: %lld (msec)", (long long)msec);
+    return (jlong) msec;
 }
 
 static void
@@ -911,6 +912,28 @@
     }
 }
 
+static jobject
+android_media_MediaPlayer2_getParameter(JNIEnv *env, jobject thiz, jint key)
+{
+    ALOGV("getParameter: key %d", key);
+    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
+    if (mp == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException", NULL);
+        return NULL;
+    }
+
+    jobject jParcel = createJavaParcelObject(env);
+    if (jParcel != NULL) {
+        Parcel* nativeParcel = parcelForJavaObject(env, jParcel);
+        status_t err = mp->getParameter(key, nativeParcel);
+        if (err != OK) {
+            env->DeleteLocalRef(jParcel);
+            return NULL;
+        }
+    }
+    return jParcel;
+}
+
 static void
 android_media_MediaPlayer2_setLooping(JNIEnv *env, jobject thiz, jboolean looping)
 {
@@ -1171,33 +1194,6 @@
     process_media_player_call( env, thiz, mp->attachAuxEffect(effectId), NULL, NULL );
 }
 
-static void
-android_media_MediaPlayer2_setNextMediaPlayer(JNIEnv *env, jobject thiz, jobject java_player)
-{
-    ALOGV("setNextMediaPlayer");
-    sp<MediaPlayer2> thisplayer = getMediaPlayer(env, thiz);
-    if (thisplayer == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException", "This player not initialized");
-        return;
-    }
-    sp<MediaPlayer2> nextplayer = (java_player == NULL) ? NULL : getMediaPlayer(env, java_player);
-    if (nextplayer == NULL && java_player != NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException", "That player not initialized");
-        return;
-    }
-
-    if (nextplayer == thisplayer) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", "Next player can't be self");
-        return;
-    }
-    // tie the two players together
-    process_media_player_call(
-            env, thiz, thisplayer->setNextMediaPlayer(nextplayer),
-            "java/lang/IllegalArgumentException",
-            "setNextMediaPlayer failed." );
-    ;
-}
-
 /////////////////////////////////////////////////////////////////////////////////////
 // Modular DRM begin
 
@@ -1498,12 +1494,13 @@
     {"_notifyAt",           "(J)V",                             (void *)android_media_MediaPlayer2_notifyAt},
     {"_pause",              "()V",                              (void *)android_media_MediaPlayer2_pause},
     {"isPlaying",           "()Z",                              (void *)android_media_MediaPlayer2_isPlaying},
-    {"getCurrentPosition",  "()I",                              (void *)android_media_MediaPlayer2_getCurrentPosition},
-    {"getDuration",         "()I",                              (void *)android_media_MediaPlayer2_getDuration},
+    {"getCurrentPosition",  "()J",                              (void *)android_media_MediaPlayer2_getCurrentPosition},
+    {"getDuration",         "()J",                              (void *)android_media_MediaPlayer2_getDuration},
     {"_release",            "()V",                              (void *)android_media_MediaPlayer2_release},
     {"_reset",              "()V",                              (void *)android_media_MediaPlayer2_reset},
     {"_getAudioStreamType", "()I",                              (void *)android_media_MediaPlayer2_getAudioStreamType},
     {"setParameter",        "(ILandroid/os/Parcel;)Z",          (void *)android_media_MediaPlayer2_setParameter},
+    {"getParameter",        "(I)Landroid/os/Parcel;",           (void *)android_media_MediaPlayer2_getParameter},
     {"setLooping",          "(Z)V",                             (void *)android_media_MediaPlayer2_setLooping},
     {"isLooping",           "()Z",                              (void *)android_media_MediaPlayer2_isLooping},
     {"_setVolume",          "(FF)V",                            (void *)android_media_MediaPlayer2_setVolume},
@@ -1517,7 +1514,6 @@
     {"setAudioSessionId",   "(I)V",                             (void *)android_media_MediaPlayer2_set_audio_session_id},
     {"_setAuxEffectSendLevel", "(F)V",                          (void *)android_media_MediaPlayer2_setAuxEffectSendLevel},
     {"attachAuxEffect",     "(I)V",                             (void *)android_media_MediaPlayer2_attachAuxEffect},
-    {"setNextMediaPlayer",  "(Landroid/media/MediaPlayer2;)V",  (void *)android_media_MediaPlayer2_setNextMediaPlayer},
     // Modular DRM
     { "_prepareDrm", "([B[B)V",                                 (void *)android_media_MediaPlayer2_prepareDrm },
     { "_releaseDrm", "()V",                                     (void *)android_media_MediaPlayer2_releaseDrm },
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java
index 06723c3..24449fd 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java
@@ -16,6 +16,8 @@
 
 package com.android.printspooler.model;
 
+import static android.content.Context.BIND_AUTO_CREATE;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -32,7 +34,7 @@
         mContext = context;
         mCallback = callback;
         Intent intent = new Intent(mContext, PrintSpoolerService.class);
-        mContext.bindService(intent, this, 0);
+        mContext.bindService(intent, this, BIND_AUTO_CREATE);
     }
 
     public PrintSpoolerService getSpooler() {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index d73a5d7..83d7e16 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -306,19 +306,22 @@
         // This will take just a few milliseconds, so just wait to
         // bind to the local service before showing the UI.
         mSpoolerProvider = new PrintSpoolerProvider(this,
-                new Runnable() {
-            @Override
-            public void run() {
-                if (isFinishing() || isDestroyed()) {
-                    // onPause might have not been able to cancel the job, see PrintActivity#onPause
-                    // To be sure, cancel the job again. Double canceling does no harm.
-                    mSpoolerProvider.getSpooler().setPrintJobState(mPrintJob.getId(),
-                            PrintJobInfo.STATE_CANCELED, null);
-                } else {
-                    onConnectedToPrintSpooler(adapter);
-                }
-            }
-        });
+                () -> {
+                    if (isFinishing() || isDestroyed()) {
+                        if (savedInstanceState != null) {
+                            // onPause might have not been able to cancel the job, see
+                            // PrintActivity#onPause
+                            // To be sure, cancel the job again. Double canceling does no harm.
+                            mSpoolerProvider.getSpooler().setPrintJobState(mPrintJob.getId(),
+                                    PrintJobInfo.STATE_CANCELED, null);
+                        }
+                    } else {
+                        if (savedInstanceState == null) {
+                            mSpoolerProvider.getSpooler().createPrintJob(mPrintJob);
+                        }
+                        onConnectedToPrintSpooler(adapter);
+                    }
+                });
 
         getLoaderManager().initLoader(LOADER_ID_ENABLED_PRINT_SERVICES, null, this);
     }
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index f2c05bf..6c8c69a 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"የሲም መዳረሻ"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"ኤችዲ ኦዲዮ፦ <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"ኤችዲ ኦዲዮ"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"መስሚያ አጋዥ መሣሪያ"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"ከመስሚያ አጋዥ መሣሪያ ጋር ተገናኝቷል"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"ወደ ማህደረ  መረጃ  አውዲዮ ተያይዟል"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ወደ ስልክ አውዲዮ ተያይዟል"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ወደ ፋይል ዝውውር አገልጋይ ተያይዟል"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ለስልክ ድምፅ ተጠቀም"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ለፋይል ዝውውር ተጠቀም"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ለውፅአት ተጠቀም"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"ለመስሚያ አጋዥ መሣሪያ ተጠቀም"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"አጣምር"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"አጣምር"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"ይቅር"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 6acc8e9..40c16b9 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"‏الوصول إلى شريحة SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"صوت عالي الدقة: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"صوت عالي الدقة"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"سماعة الأذن الطبية"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"تم توصيل سماعة الأذن الطبية"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"متصل بالإعدادات الصوتية للوسائط"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"متصل بالإعدادات الصوتية للهاتف"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"متصل بخادم نقل الملف"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"الاستخدام لإعدادات الهاتف الصوتية"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"استخدامه لنقل الملفات"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"استخدام للإدخال"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"استخدام سماعة الأذن الطبية"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"اقتران"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"إقران"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"إلغاء"</string>
diff --git a/packages/SettingsLib/res/values-as/arrays.xml b/packages/SettingsLib/res/values-as/arrays.xml
new file mode 100644
index 0000000..0eff708
--- /dev/null
+++ b/packages/SettingsLib/res/values-as/arrays.xml
@@ -0,0 +1,253 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2015 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wifi_status">
+    <item msgid="1922181315419294640"></item>
+    <item msgid="8934131797783724664">"স্কেন কৰি থকা হৈছে…"</item>
+    <item msgid="8513729475867537913">"সংযোগ কৰি থকা হৈছে…"</item>
+    <item msgid="515055375277271756">"বিস্বাশযোগ্যতা প্ৰমাণ কৰি থকা হৈছে …"</item>
+    <item msgid="1943354004029184381">"আইপি ঠিকনা সংগ্ৰহ কৰি থকা হৈছে…"</item>
+    <item msgid="4221763391123233270">"সংযোগ কৰা হ’ল"</item>
+    <item msgid="624838831631122137">"স্থগিত"</item>
+    <item msgid="7979680559596111948">"সংযোগ বিচ্ছিন্ন কৰি থকা হৈছে"</item>
+    <item msgid="1634960474403853625">"সংযোগ বিচ্ছিন্ন"</item>
+    <item msgid="746097431216080650">"অসফল"</item>
+    <item msgid="6367044185730295334">"অৱৰোধিত"</item>
+    <item msgid="503942654197908005">"কিছুসময়ৰ বাবে দুৰ্বল সংযোগ দেখুওৱা হোৱা নাই"</item>
+  </string-array>
+  <string-array name="wifi_status_with_ssid">
+    <item msgid="7714855332363650812"></item>
+    <item msgid="8878186979715711006">"স্কেন কৰি থকা হৈছে…"</item>
+    <item msgid="355508996603873860">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>ৰ সৈতে সংযোগ কৰি থকা হৈছে…"</item>
+    <item msgid="554971459996405634">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>ৰ জৰিয়তে সত্যাপন কৰি থকা হৈছে…"</item>
+    <item msgid="7928343808033020343">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>ৰ আইপি ঠিকনা পৰা সংগ্ৰহ কৰি থকা হৈছে…"</item>
+    <item msgid="8937994881315223448">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>ৰ সৈতে সংযোগ কৰা হ\'ল"</item>
+    <item msgid="1330262655415760617">"স্থগিত"</item>
+    <item msgid="7698638434317271902">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>ৰ পৰা সংযোগ বিচ্ছিন্ন কৰি থকা হৈছে…"</item>
+    <item msgid="197508606402264311">"সংযোগ বিচ্ছিন্ন"</item>
+    <item msgid="8578370891960825148">"বিফল হৈছে"</item>
+    <item msgid="5660739516542454527">"অৱৰোধিত"</item>
+    <item msgid="1805837518286731242">"কিছুসময়ৰ বাবে দুৰ্বল সংযোগ দেখুওৱা হোৱা নাই"</item>
+  </string-array>
+  <string-array name="hdcp_checking_titles">
+    <item msgid="441827799230089869">"কেতিয়াও পৰীক্ষা নকৰিব"</item>
+    <item msgid="6042769699089883931">"কেৱল DRM সমলৰ বাবে পৰীক্ষা কৰক"</item>
+    <item msgid="9174900380056846820">"সদায় পৰীক্ষা কৰক"</item>
+  </string-array>
+  <string-array name="hdcp_checking_summaries">
+    <item msgid="505558545611516707">"কেতিয়াও HDCP পৰীক্ষণ ব্যৱহাৰ নকৰিব"</item>
+    <item msgid="3878793616631049349">"কেৱল DRM সমলৰ বাবে HDCP পৰীক্ষণ ব্যৱহাৰ কৰক"</item>
+    <item msgid="45075631231212732">"সদায় HDCP পৰীক্ষণ ব্যৱহাৰ কৰক"</item>
+  </string-array>
+  <string-array name="bluetooth_avrcp_versions">
+    <item msgid="5347678900838034763">"AVRCP ১.৪ (ডিফ’ল্ট)"</item>
+    <item msgid="2809759619990248160">"AVRCP ১.৩"</item>
+    <item msgid="6199178154704729352">"AVRCP ১.৫"</item>
+    <item msgid="5172170854953034852">"AVRCP ১.৬"</item>
+  </string-array>
+  <string-array name="bluetooth_avrcp_version_values">
+    <item msgid="2838624067805073303">"avrcp14"</item>
+    <item msgid="3011533352527449572">"avrcp১৩"</item>
+    <item msgid="8837606198371920819">"avrcp১৫"</item>
+    <item msgid="3422726142222090896">"avrcp১৬"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_titles">
+    <item msgid="7065842274271279580">"ছিষ্টেমৰ বাছনি ব্যৱহাৰ কৰক (ডিফ\'ল্ট)"</item>
+    <item msgid="7539690996561263909">"এছবিচি"</item>
+    <item msgid="686685526567131661">"এএচি"</item>
+    <item msgid="5254942598247222737">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> অডিঅ\'"</item>
+    <item msgid="2091430979086738145">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> অডিঅ’"</item>
+    <item msgid="6751080638867012696">"LDAC"</item>
+    <item msgid="723675059572222462">"বিকল্প ক\'ডেকসমূহ সক্ষম কৰক"</item>
+    <item msgid="3304843301758635896">"বিকল্প ক\'ডেকসমূহ অসক্ষম কৰক"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_summaries">
+    <item msgid="5062108632402595000">"ছিষ্টেমৰ বাছনি ব্যৱহাৰ কৰক (ডিফল্ট)"</item>
+    <item msgid="6898329690939802290">"এছবিচি"</item>
+    <item msgid="6839647709301342559">"এএচি"</item>
+    <item msgid="7848030269621918608">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> অডিঅ’"</item>
+    <item msgid="298198075927343893">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> অডিঅ’"</item>
+    <item msgid="7950781694447359344">"LDAC"</item>
+    <item msgid="2209680154067241740">"বিকল্প ক\'ডেকসমূহ সক্ষম কৰক"</item>
+    <item msgid="741805482892725657">"ঐচ্ছিক ক’ডেকসমূহ অক্ষম কৰক"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
+    <item msgid="3093023430402746802">"ছিষ্টেমৰ বাছনি ব্যৱহাৰ কৰক (ডিফ\'ল্ট)"</item>
+    <item msgid="8895532488906185219">"৪৪.১ কিল\'হাৰ্টজ"</item>
+    <item msgid="2909915718994807056">"৪৮.০ কিল’হাৰ্টজ"</item>
+    <item msgid="3347287377354164611">"৮৮.২ কিল\'হাৰ্টজ"</item>
+    <item msgid="1234212100239985373">"৯৬.০ কিল’হাৰ্টজ"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_sample_rate_summaries">
+    <item msgid="3214516120190965356">"ছিষ্টেমৰ বাছনি ব্যৱহাৰ কৰক (ডিফ’ল্ট)"</item>
+    <item msgid="4482862757811638365">"৪৪.১ কিল’হাৰ্টজ"</item>
+    <item msgid="354495328188724404">"৪৮.০ কিল’হাৰ্টজ"</item>
+    <item msgid="7329816882213695083">"৮৮.২ কিল\'হাৰ্টজ"</item>
+    <item msgid="6967397666254430476">"৯৬.০ কিল’হাৰ্টজ"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_bits_per_sample_titles">
+    <item msgid="2684127272582591429">"ছিষ্টেমৰ বাছনি ব্যৱহাৰ কৰক (ডিফ\'ল্ট)"</item>
+    <item msgid="5618929009984956469">"১৬ বিট/নমুনা"</item>
+    <item msgid="3412640499234627248">"২৪ বিট/নমুনা"</item>
+    <item msgid="121583001492929387">"৩২ বিট/নমুনা"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_bits_per_sample_summaries">
+    <item msgid="1081159789834584363">"ছিষ্টেমৰ বাছনি ব্যৱহাৰ কৰক (ডিফ’ল্ট)"</item>
+    <item msgid="4726688794884191540">"১৬ বিট/নমুনা"</item>
+    <item msgid="305344756485516870">"২৪ বিট/নমুনা"</item>
+    <item msgid="244568657919675099">"৩২ বিট/নমুনা"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_channel_mode_titles">
+    <item msgid="5226878858503393706">"ছিষ্টেমৰ বাছনি ব্যৱহাৰ কৰক (ডিফ\'ল্ট)"</item>
+    <item msgid="4106832974775067314">"ম\'ন\'"</item>
+    <item msgid="5571632958424639155">"ষ্টেৰিঅ\'"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_channel_mode_summaries">
+    <item msgid="4118561796005528173">"ছিষ্টেমৰ বাছনি ব্যৱহাৰ কৰক (ডিফ\'ল্ট)"</item>
+    <item msgid="8900559293912978337">"ম\'ন\'"</item>
+    <item msgid="8883739882299884241">"ষ্টেৰিঅ\'"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
+    <item msgid="7158319962230727476">"ধ্বনিৰ মানৰ বাবে অপ্টিমাইজ কৰা হৈছে (৯৯০কি.বা.প্ৰ.ছে./৯০৯কি.বা.প্ৰ.ছে.)"</item>
+    <item msgid="2921767058740704969">"ধ্বনি আৰু সংযোগৰ সন্তুলিত গুণগত মান (৬৬০কে.বি.প্ৰ.ছে./৬০৬কে.বি.প্ৰ.ছে."</item>
+    <item msgid="8860982705384396512">"সংযোগৰ ক্ষমতা অনুযায়ী সৰ্বোত্তম (৩৩০কে.বি.প্ৰ.ছে/৩০৩কে.বি.প্ৰ.ছে)"</item>
+    <item msgid="4414060457677684127">"সৰ্বশ্ৰেষ্ঠ প্ৰচেষ্টা (খাপ খাব পৰা ৰেইট)"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
+    <item msgid="6398189564246596868">"অডিঅ\' গুণমানৰ বাবে অপ্টিমাইজ কৰা হৈছে"</item>
+    <item msgid="4327143584633311908">"ধ্বনি আৰু সংযোগৰ সন্তুলিত গুণগত মান"</item>
+    <item msgid="4681409244565426925">"সংযোগৰ ক্ষমতা অনুযায়ী সৰ্বোত্তম"</item>
+    <item msgid="364670732877872677">"উত্তম প্ৰচেষ্টা (খাপ খাব পৰা বিট ৰেইট)"</item>
+  </string-array>
+  <string-array name="select_logd_size_titles">
+    <item msgid="8665206199209698501">"অফ কৰক"</item>
+    <item msgid="1593289376502312923">"৬৪কে."</item>
+    <item msgid="487545340236145324">"২৫৬কে."</item>
+    <item msgid="2423528675294333831">"১মি."</item>
+    <item msgid="180883774509476541">"4M"</item>
+    <item msgid="2803199102589126938">"১৬মি."</item>
+  </string-array>
+  <string-array name="select_logd_size_lowram_titles">
+    <item msgid="6089470720451068364">"অফ কৰক"</item>
+    <item msgid="4622460333038586791">"৬৪কে."</item>
+    <item msgid="2212125625169582330">"২৫৬কে."</item>
+    <item msgid="1704946766699242653">"১মি."</item>
+  </string-array>
+  <string-array name="select_logd_size_summaries">
+    <item msgid="6921048829791179331">"অফ কৰক"</item>
+    <item msgid="2969458029344750262">"প্ৰতিটো লগ বাফাৰত ৬৪কে."</item>
+    <item msgid="1342285115665698168">"প্ৰতি লগ বাফাৰত 256K"</item>
+    <item msgid="1314234299552254621">"প্ৰতিটো লগ বাফাৰত ১মি."</item>
+    <item msgid="3606047780792894151">"প্ৰতিটো লগ বাফাৰত ৪মি."</item>
+    <item msgid="5431354956856655120">"প্ৰতিটো লগ বাফাৰত ১৬মি."</item>
+  </string-array>
+  <string-array name="select_logpersist_titles">
+    <item msgid="1744840221860799971">"অফ অৱস্থাত আছে"</item>
+    <item msgid="3054662377365844197">"সকলো"</item>
+    <item msgid="688870735111627832">"ৰেডিঅ\'ৰ বাহিৰে সকলো"</item>
+    <item msgid="2850427388488887328">"কেৱল কাৰ্ণেল"</item>
+  </string-array>
+  <string-array name="select_logpersist_summaries">
+    <item msgid="2216470072500521830">"অফ কৰক"</item>
+    <item msgid="172978079776521897">"সকলো লগ বাফাৰ"</item>
+    <item msgid="3873873912383879240">"ৰেডিঅ\' লগ বাফাৰৰ বাহিৰে সকলো"</item>
+    <item msgid="8489661142527693381">"কেৱল কাৰ্ণেল লগ বাফাৰ"</item>
+  </string-array>
+  <string-array name="window_animation_scale_entries">
+    <item msgid="8134156599370824081">"এনিমেশ্বন অফ"</item>
+    <item msgid="6624864048416710414">"এনিমেশ্বন স্কেল .৫গুণ"</item>
+    <item msgid="2219332261255416635">"এনিমেশ্বন স্কেল ১গুণ"</item>
+    <item msgid="3544428804137048509">"এনিমেশ্বন স্কেল ১.৫গুণ"</item>
+    <item msgid="3110710404225974514">"এনিমেশ্বন স্কেল ২গুণ"</item>
+    <item msgid="4402738611528318731">"এনিমেশ্বন স্কেল ৫গুণ"</item>
+    <item msgid="6189539267968330656">"এনিমেশ্বন স্কেল ১০গু"</item>
+  </string-array>
+  <string-array name="transition_animation_scale_entries">
+    <item msgid="8464255836173039442">"এনিমেশ্বন অফ"</item>
+    <item msgid="3375781541913316411">"এনিমেশ্বন স্কেল .৫গুণ"</item>
+    <item msgid="1991041427801869945">"এনিমেশ্বন স্কেল 1গু"</item>
+    <item msgid="4012689927622382874">"এনিমেশ্বন স্কেল .৫গুণ"</item>
+    <item msgid="3289156759925947169">"এনিমেশ্বন স্কেল ২গুণ"</item>
+    <item msgid="7705857441213621835">"এনিমেশ্বন স্কেল ৫গুণ"</item>
+    <item msgid="6660750935954853365">"এনিমেশ্বন স্কেল ১০গুণ"</item>
+  </string-array>
+  <string-array name="animator_duration_scale_entries">
+    <item msgid="6039901060648228241">"এনিমেশ্বন অফ অৱস্থাত আছে"</item>
+    <item msgid="1138649021950863198">"এনিমেশ্বন স্কেল .৫গুণ"</item>
+    <item msgid="4394388961370833040">"এনিমেশ্বন স্কেল ১গুণ"</item>
+    <item msgid="8125427921655194973">"এনিমেশ্বন স্কেল ১.৫গুণ"</item>
+    <item msgid="3334024790739189573">"এনিমেশ্বন স্কেল ২গুণ"</item>
+    <item msgid="3170120558236848008">"এনিমেশ্বন স্কেল ৫গুণ"</item>
+    <item msgid="1069584980746680398">"এনিমেশ্বন স্কেল ১০গুণ"</item>
+  </string-array>
+  <string-array name="overlay_display_devices_entries">
+    <item msgid="1606809880904982133">"নাই"</item>
+    <item msgid="9033194758688161545">"৪৮০পি."</item>
+    <item msgid="1025306206556583600">"৪৮০পি. (সুৰক্ষিত)"</item>
+    <item msgid="1853913333042744661">"৭২০পি."</item>
+    <item msgid="3414540279805870511">"৭২০পি. (সুৰক্ষিত)"</item>
+    <item msgid="9039818062847141551">"১০৮০পি."</item>
+    <item msgid="4939496949750174834">"১০৮০পি. (সুৰক্ষিত)"</item>
+    <item msgid="1833612718524903568">"4K"</item>
+    <item msgid="238303513127879234">"৪কে. (সুৰক্ষিত)"</item>
+    <item msgid="3547211260846843098">"৪কে. (বৰ্ধিত)"</item>
+    <item msgid="5411365648951414254">"৪কে. (বৰ্ধিত, সুৰক্ষিত)"</item>
+    <item msgid="1311305077526792901">"৭২০পি., ১০৮০পি. (দ্বৈত স্ক্ৰীণ)"</item>
+  </string-array>
+  <string-array name="enable_opengl_traces_entries">
+    <item msgid="3191973083884253830">"নাই"</item>
+    <item msgid="9089630089455370183">"লগকেট"</item>
+    <item msgid="5397807424362304288">"ছিছট্ৰেইচ (গ্ৰাফিক্স)"</item>
+    <item msgid="1340692776955662664">"glGetErrorত কলৰ খাপ"</item>
+  </string-array>
+  <string-array name="show_non_rect_clip_entries">
+    <item msgid="993742912147090253">"অফ কৰক"</item>
+    <item msgid="675719912558941285">"আয়তাকাৰ নোহোৱা ক্লিপ অঞ্চল নীলাৰে আঁকক"</item>
+    <item msgid="1064373276095698656">"পৰীক্ষণ কৰা চিত্ৰাংকণ কমাণ্ডবোৰ সেউজীয়া ৰঙত হাইলাইট কৰক"</item>
+  </string-array>
+  <string-array name="track_frame_time_entries">
+    <item msgid="2193584639058893150">"অফ"</item>
+    <item msgid="2751513398307949636">"স্ক্ৰীণত দণ্ড হিচাপে"</item>
+    <item msgid="2355151170975410323">"<xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g>ত"</item>
+  </string-array>
+  <string-array name="debug_hw_overdraw_entries">
+    <item msgid="8190572633763871652">"বন্ধ কৰক"</item>
+    <item msgid="7688197031296835369">"পিক্সেল একাধিকবাৰ ব্যৱহৃত অংশসমূহ দেখুৱাওক"</item>
+    <item msgid="2290859360633824369">"ডিউটাৰএন\'মেলীৰ অংশসমূহ দেখুৱাওক"</item>
+  </string-array>
+  <string-array name="app_process_limit_entries">
+    <item msgid="3401625457385943795">"মান্য সীমা"</item>
+    <item msgid="4071574792028999443">"নেপথ্যত কোনো প্ৰক্ৰিয়া চলি থকা নাই"</item>
+    <item msgid="4810006996171705398">"সৰ্বাধিক ১টা প্ৰক্ৰিয়া"</item>
+    <item msgid="8586370216857360863">"সৰ্বাধিক ২টা প্ৰক্ৰিয়া"</item>
+    <item msgid="836593137872605381">"সৰ্বাধিক ৩টা প্ৰক্ৰিয়া"</item>
+    <item msgid="7899496259191969307">"সৰ্বাধিক ৪টা প্ৰক্ৰিয়া"</item>
+  </string-array>
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"চ্চাৰ্জ কৰি থকা হৈছে"</item>
+    <item msgid="5220695614993094977">"এমটিপি (মিডিয়া ট্ৰান্সফাৰ প্ৰ’ট’কল)"</item>
+    <item msgid="2086000968159047375">"পিটিপি (পিকচাৰ ট্ৰান্সফাৰ প্ৰ’ট’কল)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB ইথাৰনেট)"</item>
+    <item msgid="1718924214939774352">"ধ্বনিৰ উৎস"</item>
+    <item msgid="8126315616613006284">"এমআইডিআই"</item>
+  </string-array>
+</resources>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
new file mode 100644
index 0000000..b4d1af8
--- /dev/null
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -0,0 +1,466 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2015 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_fail_to_scan" msgid="1265540342578081461">"নেটৱৰ্ক বিচাৰি স্কেন কৰিব পৰা নাই"</string>
+    <string name="wifi_security_none" msgid="7985461072596594400">"নাই"</string>
+    <string name="wifi_remembered" msgid="4955746899347821096">"ছেভ কৰি থোৱা নেটৱৰ্কসমূহ"</string>
+    <string name="wifi_disabled_generic" msgid="4259794910584943386">"নিষ্ক্ৰিয় হৈ আছে"</string>
+    <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP কনফিগাৰেশ্বন বিফল হৈছে"</string>
+    <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"নিম্নমানৰ নেটৱৰ্কৰ বাবে সংযোগ কৰা হোৱা নাই"</string>
+    <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"ৱাই-ফাই সংযোগ বিফল হৈছে"</string>
+    <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"সত্য়াপন কৰাত সমস্যা হৈছে"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"সংযোগ কৰিব নোৱাৰে"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\'ৰ সৈতে সংযোগ কৰিব পৰা নাই"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"পাছৱৰ্ড পৰীক্ষা কৰি আকৌ চেষ্টা কৰক"</string>
+    <string name="wifi_not_in_range" msgid="1136191511238508967">"পৰিসৰৰ ভিতৰত নাই"</string>
+    <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"স্বয়ংক্ৰিয়ভাৱে সংযোগ নহ\'ব"</string>
+    <string name="wifi_no_internet" msgid="4663834955626848401">"ইণ্টাৰনেট সংযোগ নাই"</string>
+    <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g>এ ছেভ কৰিছে"</string>
+    <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s মাধ্যমেদি স্বয়ংক্ৰিয়ভাৱে সংযোগ কৰা হৈছে"</string>
+    <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"নেটৱৰ্ক ৰেটিং প্ৰদানকাৰীৰ জৰিয়তে স্বয়ং সংয়োগ কৰা হ\'ল"</string>
+    <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s-ৰ মাধ্যমেদি সংযোগ কৰা হৈছে"</string>
+    <string name="available_via_passpoint" msgid="1617440946846329613">"%1$sৰ মাধ্যমেৰে উপলব্ধ"</string>
+    <string name="wifi_connected_no_internet" msgid="8202906332837777829">"সংযোজিত, ইণ্টাৰনেট নাই"</string>
+    <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"একচেছ পইণ্ট কিছু সময়ৰ বাবে পূৰ্ণ হৈ আছে"</string>
+    <string name="connected_via_carrier" msgid="7583780074526041912">"%1$sৰ যোগেৰে সংযোজিত"</string>
+    <string name="available_via_carrier" msgid="1469036129740799053">"%1$sৰ মাধ্যমেৰে উপলব্ধ"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"অতি লেহেম"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"লেহেমীয়া"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"ঠিক"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"মধ্যমীয়া"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"দ্ৰুত"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"অতি দ্ৰুত"</string>
+    <string name="preference_summary_default_combination" msgid="8532964268242666060">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
+    <string name="bluetooth_disconnected" msgid="6557104142667339895">"সংযোগ বিচ্ছিন্ন কৰা হ’ল"</string>
+    <string name="bluetooth_disconnecting" msgid="8913264760027764974">"সংযোগ বিচ্ছিন্ন কৰি থকা হৈছে…"</string>
+    <string name="bluetooth_connecting" msgid="8555009514614320497">"সংযোগ কৰি থকা হৈছে…"</string>
+    <!-- no translation found for bluetooth_connected (5427152882755735944) -->
+    <skip />
+    <string name="bluetooth_pairing" msgid="1426882272690346242">"যোৰা লগোৱা হৈছে…"</string>
+    <!-- no translation found for bluetooth_connected_no_headset (616068069034994802) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_a2dp (3736431800395923868) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_map (3200033913678466453) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp (2047403011284187056) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_battery_level (5162924691231307748) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_headset_battery_level (1610296229139400266) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (3908466636369853652) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1163440823807659316) -->
+    <skip />
+    <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"মিডিয়াৰ অডিঅ’"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ফ\'ন কলসমূহ"</string>
+    <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ফাইল স্থানান্তৰণ"</string>
+    <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ইনপুট ডিভাইচ"</string>
+    <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ইণ্টাৰনেট সংযোগ"</string>
+    <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"শ্বেয়াৰিঙৰ সৈতে যোগাযোগ কৰক"</string>
+    <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"সম্পৰ্ক শ্বেয়াৰ কৰিবলৈ ব্যৱহাৰ কৰক"</string>
+    <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ইণ্টাৰনেট সংযোগ শ্বেয়াৰ"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"পাঠ বাৰ্তা"</string>
+    <string name="bluetooth_profile_sap" msgid="5764222021851283125">"ছিম প্ৰৱেশ"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"এইচ্ছডি অডি\'অ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"এইচ্ছডি অডিঅ’"</string>
+    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
+    <skip />
+    <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"মিডিয়া অডিঅ’লৈ সংযোগ হৈছে"</string>
+    <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ফোন অডিঅ\'ৰ লগত সংযোগ কৰা হ\'ল"</string>
+    <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ফাইল ট্ৰান্সফাৰ ছাৰ্ভাৰৰ সৈতে সংযোজিত হৈ আছে"</string>
+    <string name="bluetooth_map_profile_summary_connected" msgid="8191407438851351713">"মেপৰ সৈতে সংযোগ কৰক"</string>
+    <string name="bluetooth_sap_profile_summary_connected" msgid="8561765057453083838">"SAPৰ সৈতে সংযোজিত হৈ আছে"</string>
+    <string name="bluetooth_opp_profile_summary_not_connected" msgid="1267091356089086285">"ফাইল স্থানান্তৰণ ছাৰ্ভাৰৰ সৈতে সংযোজিত হৈ থকা নাই"</string>
+    <string name="bluetooth_hid_profile_summary_connected" msgid="3381760054215168689">"ইনপুট ডিভাইচৰ সৈতে সংযোজিত হৈ আছে"</string>
+    <string name="bluetooth_pan_user_profile_summary_connected" msgid="6436258151814414028">"ইণ্টাৰনেটৰ বাবে ডিভাইচৰ সৈতে সংযোজিত"</string>
+    <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1322694224800769308">"ডিভাইচৰ সৈতে স্থানীয় ইণ্টাৰনেট সংযোগ শ্বেয়াৰ কৰা হৈছে"</string>
+    <string name="bluetooth_pan_profile_summary_use_for" msgid="5736111170225304239">"ইণ্টাৰনেট চলাবলৈ ব্যৱহাৰ কৰক"</string>
+    <string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"মেপৰ বাবে ব্যৱহাৰ কৰক"</string>
+    <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"ছিমত প্ৰৱেশৰ বাবে ব্যৱহাৰ কৰক"</string>
+    <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"মিডিয়া অডিঅ\'ৰ বাবে ব্যৱহাৰ কৰক"</string>
+    <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ফ\'ন অডিঅ\'ৰ বাবে ব্যৱহাৰ কৰক"</string>
+    <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ফাইল স্থানান্তৰ কৰিবলৈ ব্যৱহাৰ কৰক"</string>
+    <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ইনপুটৰ বাবে ব্যৱহাৰ কৰক"</string>
+    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
+    <skip />
+    <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"যোৰা লগাওক"</string>
+    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"যোৰা লগাওক"</string>
+    <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"বাতিল কৰক"</string>
+    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"যোৰা লগালে ইয়ে সংযোজিত কৰাৰ সময়ত আপোনাৰ সম্পৰ্কসমূহ আৰু কলৰ ইতিহাস চাবলৈ অনুমতি দিব।"</string>
+    <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>ৰ সৈতে যোৰা লগাব পৰা নগ\'ল৷"</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"এটা ভুল পিন বা পাছকীৰ কাৰণে <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ৰ সৈতে যোৰা লগাব পৰা নাই৷"</string>
+    <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>ৰ সৈতে যোগাযোগ কৰিব পৰা নগ\'ল"</string>
+    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>এ যোৰা লগাব বিচৰা নাই"</string>
+    <string name="bluetooth_talkback_computer" msgid="4875089335641234463">"কম্পিউটাৰ"</string>
+    <string name="bluetooth_talkback_headset" msgid="5140152177885220949">"হেডছেট"</string>
+    <string name="bluetooth_talkback_phone" msgid="4260255181240622896">"ফ\'ন"</string>
+    <string name="bluetooth_talkback_imaging" msgid="551146170554589119">"ইমেজিং"</string>
+    <string name="bluetooth_talkback_headphone" msgid="26580326066627664">"হেডফ\'ন"</string>
+    <string name="bluetooth_talkback_input_peripheral" msgid="5165842622743212268">"ইনপুট সম্পৰ্কীয় বাহ্য় ডিভাইচ"</string>
+    <string name="bluetooth_talkback_bluetooth" msgid="5615463912185280812">"ব্লুটুথ"</string>
+    <string name="accessibility_wifi_off" msgid="1166761729660614716">"ৱাই-ফাই অফহৈ আছে।"</string>
+    <string name="accessibility_no_wifi" msgid="8834610636137374508">"ৱাইফাই সংযোগ বিচ্ছিন্ন হৈ আছে।"</string>
+    <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"ৱাই-ফাই এদাল দণ্ড।"</string>
+    <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"ৱাই-ফাইৰ দুডাল দণ্ড।"</string>
+    <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"ৱাই-ফাইৰ তিনিডাল দণ্ড।"</string>
+    <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"ৱাই-ফাই সংকেত সৰ্বোচ্চ।"</string>
+    <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"মুক্ত নেটৱৰ্ক"</string>
+    <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"সুৰক্ষিত নেটৱৰ্ক"</string>
+    <string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
+    <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"আঁতৰোৱা এপ্‌সমূহ"</string>
+    <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"আঁতৰোৱা এপ্‌ আৰু ব্যৱহাৰকাৰীসমূহ"</string>
+    <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB টেডাৰিং"</string>
+    <string name="tether_settings_title_wifi" msgid="3277144155960302049">"প\'ৰ্টেবল হটস্পট"</string>
+    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"ব্লুটুথ টেডাৰিং"</string>
+    <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"টেডাৰ কৰি থকা হৈছে"</string>
+    <string name="tether_settings_title_all" msgid="8356136101061143841">"টেদৰিং আৰু প\'ৰ্টেবল হ\'টস্পট"</string>
+    <string name="managed_user_title" msgid="8109605045406748842">"কৰ্মস্থানৰ সকলো এপ"</string>
+    <string name="user_guest" msgid="8475274842845401871">"অতিথি"</string>
+    <string name="unknown" msgid="1592123443519355854">"অজ্ঞাত"</string>
+    <string name="running_process_item_user_label" msgid="3129887865552025943">"ব্যৱহাৰকাৰী: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="launch_defaults_some" msgid="313159469856372621">"কিছুমান ডিফ\'ল্ট ছেট কৰা হৈছে"</string>
+    <string name="launch_defaults_none" msgid="4241129108140034876">"কোনো ডিফ\'ল্ট ছেট কৰা হোৱা নাই"</string>
+    <string name="tts_settings" msgid="8186971894801348327">"পাঠৰ পৰা কথনৰ ছেটিংসমূহ"</string>
+    <string name="tts_settings_title" msgid="1237820681016639683">"পাঠৰ পৰা কথনৰ আউটপুট"</string>
+    <string name="tts_default_rate_title" msgid="6030550998379310088">"কথা কোৱাৰ হাৰ"</string>
+    <string name="tts_default_rate_summary" msgid="4061815292287182801">"পাঠ কথনৰ বেগ"</string>
+    <string name="tts_default_pitch_title" msgid="6135942113172488671">"পিচ্চ"</string>
+    <string name="tts_default_pitch_summary" msgid="1944885882882650009">"সংশ্লেষিত কথনৰ সুৰক প্ৰভাৱিত কৰে"</string>
+    <string name="tts_default_lang_title" msgid="8018087612299820556">"ভাষা"</string>
+    <string name="tts_lang_use_system" msgid="2679252467416513208">"ছিষ্টেমৰ ভাষা ব্যৱহাৰ কৰক"</string>
+    <string name="tts_lang_not_selected" msgid="7395787019276734765">"ভাষা বাছনি কৰা হোৱা নাই"</string>
+    <string name="tts_default_lang_summary" msgid="5219362163902707785">"কথিত পাঠৰ বাবে ভাষা-নিৰ্দিষ্ট কণ্ঠস্বৰ ছেট কৰে"</string>
+    <string name="tts_play_example_title" msgid="7094780383253097230">"এটা উদাহৰণ মাতি শুনোৱা শুনক"</string>
+    <string name="tts_play_example_summary" msgid="8029071615047894486">"কণ্ঠস্বৰ সংশ্লেষণৰ এটা চুটি উদাহৰণ দেখুৱাওক"</string>
+    <string name="tts_install_data_title" msgid="4264378440508149986">"ভইচ ডেটা ইনষ্টল কৰক"</string>
+    <string name="tts_install_data_summary" msgid="5742135732511822589">"কণ্ঠস্বৰ সংশ্লেষণৰ বাবে দৰকাৰী ভইচ ডেটা ইনষ্টল কৰক"</string>
+    <string name="tts_engine_security_warning" msgid="8786238102020223650">"এই কণ্ঠধ্বনি সংশ্লেষক ইঞ্জিনটোৱে কথিত ব্যক্তিগত ডেটা যেনে পাছৱৰ্ড আৰু ক্ৰেডিট কাৰ্ডৰ নম্বৰ আদিকে ধৰি সকলো পাঠ সংগ্ৰহ কৰবলৈ সক্ষম হ\'ব পাৰে। ই <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> ইঞ্জিনটোৰ লগত আহিছে। এই কণ্ঠধ্বনি সংশ্লেষক ইঞ্জিনটো সক্ষম কৰিবনে?"</string>
+    <string name="tts_engine_network_required" msgid="1190837151485314743">"পাঠৰ পৰা কথন আউটপুটৰ বাবে এই ভাষাটোক এক কৰ্মক্ষম নেটৱৰ্ক সংযোগৰ দৰকাৰ।"</string>
+    <string name="tts_default_sample_string" msgid="4040835213373086322">"কথনভংগী সংশ্লেষণৰ ই এটা উদাহৰণ"</string>
+    <string name="tts_status_title" msgid="7268566550242584413">"ভাষাৰ ডিফ\'ল্ট স্থিতি"</string>
+    <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> সম্পূৰ্ণৰূপে সমৰ্থিত"</string>
+    <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g>ক নেটৱৰ্ক সংযোগৰ দৰকাৰ"</string>
+    <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> সমৰ্থিত নহয়"</string>
+    <string name="tts_status_checking" msgid="5339150797940483592">"পৰীক্ষা কৰি থকা হৈছে…"</string>
+    <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>ৰ বাবে ছেটিংসমূহ"</string>
+    <string name="tts_engine_settings_button" msgid="1030512042040722285">"ইঞ্জিনৰ ছেটিংসমূহ লঞ্চ কৰক"</string>
+    <string name="tts_engine_preference_section_title" msgid="448294500990971413">"অগ্ৰাধিকাৰপ্ৰাপ্ত ইঞ্জিন"</string>
+    <string name="tts_general_section_title" msgid="4402572014604490502">"সাধাৰণ"</string>
+    <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"কথনভংগী তীব্ৰতা ৰিছেট কৰক"</string>
+    <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"পাঠ উচ্চাৰণৰ স্বৰ-তীব্ৰতা ৰিছেট কৰক যিটো ডিফল্ট হিচাপে ব্যৱহাৰ কৰা হ\'ব।"</string>
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"অতি লেহেম"</item>
+    <item msgid="4795095314303559268">"লেহেমীয়া"</item>
+    <item msgid="8903157781070679765">"সাধাৰণ"</item>
+    <item msgid="164347302621392996">"দ্ৰুত"</item>
+    <item msgid="5794028588101562009">"দ্ৰুত"</item>
+    <item msgid="7163942783888652942">"অতি দ্ৰুত"</item>
+    <item msgid="7831712693748700507">"দ্ৰুত"</item>
+    <item msgid="5194774745031751806">"অতি দ্ৰুত"</item>
+    <item msgid="9085102246155045744">"দ্ৰুততম"</item>
+  </string-array>
+    <string name="choose_profile" msgid="6921016979430278661">"প্ৰ’ফাইল বাছনি কৰক"</string>
+    <string name="category_personal" msgid="1299663247844969448">"ব্যক্তিগত"</string>
+    <string name="category_work" msgid="8699184680584175622">"কৰ্মস্থান-সম্পৰ্কীয়"</string>
+    <string name="development_settings_title" msgid="215179176067683667">"বিকাশকৰ্তাৰ বিকল্পসমূহ"</string>
+    <string name="development_settings_enable" msgid="542530994778109538">"বিকাশকৰ্তা বিষয়ক বিকল্পসমূহ সক্ষম কৰক"</string>
+    <string name="development_settings_summary" msgid="1815795401632854041">"এপৰ বিকাশৰ বাবে বিকল্পসমূহ ছেট কৰক"</string>
+    <string name="development_settings_not_available" msgid="4308569041701535607">"এইজন ব্যৱহাৰকাৰীৰ বাবে বিকাশকৰ্তাৰ বিকল্পসমূহ উপলব্ধ নহয়"</string>
+    <string name="vpn_settings_not_available" msgid="956841430176985598">"ভিপিএন ছেটিংসমূহ এই ব্যৱহাৰকাৰীজনৰ বাবে উপলব্ধ নহয়"</string>
+    <string name="tethering_settings_not_available" msgid="6765770438438291012">"এই ব্যৱহাৰকাৰীৰ বাবে টেডাৰিং ছেটিংসমূহ উপলব্ধ নহয়"</string>
+    <string name="apn_settings_not_available" msgid="7873729032165324000">"এই ব্যৱহাৰকাৰীৰ বাবে একচেছ পইণ্টৰ নাম ছেটিংসমূহ উপলব্ধ নহয়"</string>
+    <string name="enable_adb" msgid="7982306934419797485">"ইউএছবি ডিবাগিং"</string>
+    <string name="enable_adb_summary" msgid="4881186971746056635">"USB সংযোগ হৈ থকাৰ অৱস্থাত ডিবাগ ম\'ড"</string>
+    <string name="clear_adb_keys" msgid="4038889221503122743">"ইউএছবি ডিবাগিং অনুমতিসমূহ প্ৰত্যাহাৰ কৰক"</string>
+    <string name="bugreport_in_power" msgid="7923901846375587241">"বাগ ৰিপৰ্টৰ শ্ৱৰ্টকাট"</string>
+    <string name="bugreport_in_power_summary" msgid="1778455732762984579">"পাৱাৰ মেনুত বাগ প্ৰতিবেদন গ্ৰহণ কৰিবলৈ এটা বুটাম দেখুৱাওক"</string>
+    <string name="keep_screen_on" msgid="1146389631208760344">"জাগ্ৰত কৰি ৰাখক"</string>
+    <string name="keep_screen_on_summary" msgid="2173114350754293009">"চ্চাৰ্জ হৈ থকাৰ সময়ত স্ক্ৰীণ কেতিয়াও সুপ্ত অৱস্থালৈ নাযায়"</string>
+    <string name="bt_hci_snoop_log" msgid="3340699311158865670">"ব্লুটুথ HCI স্নুপ ল’গ সক্ষম কৰক"</string>
+    <string name="bt_hci_snoop_log_summary" msgid="730247028210113851">"ব্লুটুথ HCI পেকেটসমূহ এটা ফাইলত ৰাখক"</string>
+    <string name="oem_unlock_enable" msgid="6040763321967327691">"ঔইএম আনলক"</string>
+    <string name="oem_unlock_enable_summary" msgid="4720281828891618376">"বুটল\'ডাৰটো আনলক কৰিবলৈ অনুমতি দিয়ক"</string>
+    <string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"ঔইএম আনলক কৰাৰ অনুমতি দিবনে?"</string>
+    <string name="confirm_enable_oem_unlock_text" msgid="5517144575601647022">"সাৱধান: এই ছেটিংটো সক্ষম কৰি থাকোতে ডিভাইচৰ সুৰক্ষা সুবিধাসমূহে কাম নকৰিব।"</string>
+    <string name="mock_location_app" msgid="7966220972812881854">"নকল অৱস্থানৰ এপ্ বাছনি কৰক"</string>
+    <string name="mock_location_app_not_set" msgid="809543285495344223">"কোনো নকল অৱস্থান এপ্ নিৰ্ধাৰণ কৰা হোৱা নাই"</string>
+    <string name="mock_location_app_set" msgid="8966420655295102685">"নকল অৱস্থানৰ এপ্: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="debug_networking_category" msgid="7044075693643009662">"নেটৱৰ্কিং"</string>
+    <string name="wifi_display_certification" msgid="8611569543791307533">"বেতাঁৰ ডিছপ্লে প্ৰমাণীকৰণ"</string>
+    <string name="wifi_verbose_logging" msgid="4203729756047242344">"ৱাই-ফাই ভাৰ্ব\'ছ লগিং সক্ষম কৰক"</string>
+    <!-- no translation found for wifi_connected_mac_randomization (3168165236877957767) -->
+    <skip />
+    <string name="mobile_data_always_on" msgid="8774857027458200434">"ম\'বাইল ডেটা সদা-সক্ৰিয়"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"টেডাৰিং হাৰ্ডৱেৰ ত্বৰণ"</string>
+    <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"নামবিহীন ব্লুটুথ ডিভাইচসমূহ দেখুৱাওক"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"পূৰ্ণ মাত্ৰাৰ ভলিউম অক্ষম কৰক"</string>
+    <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ব্লুটুথ AVRCP সংস্কৰণ"</string>
+    <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ব্লুটুথ AVRCP সংস্কৰণ বাছনি কৰক"</string>
+    <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ব্লুটুথ অডিঅ’ ক’ডেক"</string>
+    <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ব্লুটুথ অডিঅ’ ক’ডেক বাছনি কৰক"</string>
+    <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ব্লুটুথ অডিঅ\' ছেম্পল ৰেইট"</string>
+    <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5628790207448471613">"ব্লুটুথ অডিঅ\' ক\'ডেক বাছনি কৰক:\nনমুনাৰ হাৰ"</string>
+    <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="2099645202720164141">"প্ৰতি ছেম্পলত ব্লুটুথ অডিঅ\' বিটসমূহ"</string>
+    <string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4546131401358681321">"ব্লুটুথ অডিঅ\' ক\'ডেক বাছনি কৰক:\nবিট প্ৰতি নমুনা"</string>
+    <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="884855779449390540">"ব্লুটুথ অডিঅ\' চেনেল ম\'ড"</string>
+    <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="9133545781346216071">"ব্লুটুথ অডিঅ\' ক\'ডেক বাছনি কৰক:\nচ্চেনেল ম\'ড"</string>
+    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"ব্লুটুথ অডিঅ’ LDAC ক’ডেক: পৰিৱেশনৰ মান"</string>
+    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"ব্লুটুথ LDAC ক\'ডেক বাছনি কৰক:\nপৰিৱেশনৰ মান"</string>
+    <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ষ্ট্ৰীম কৰি থকা হৈছে: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
+    <string name="select_private_dns_configuration_title" msgid="3700456559305263922">"ব্যক্তিগত DNS"</string>
+    <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"ব্যক্তিগত DNS ম\'ড বাছনি কৰক"</string>
+    <string name="private_dns_mode_off" msgid="8236575187318721684">"অফ"</string>
+    <string name="private_dns_mode_opportunistic" msgid="7608409735589131766">"সুবিধাবাদী"</string>
+    <string name="private_dns_mode_provider" msgid="8354935160639360804">"ব্যক্তিগত ডিএনএছ প্ৰদানকাৰীৰ হোষ্টনাম"</string>
+    <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"ডিএনএছ সেৱা যোগানকাৰীৰ হ\'ষ্টনাম দিয়ক"</string>
+    <string name="wifi_display_certification_summary" msgid="1155182309166746973">"বেতাঁৰ ডিছপ্লে প্ৰমাণপত্ৰৰ বাবে বিকল্পসমূহ দেখুৱাওক"</string>
+    <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ৱাই-ফাই লগিঙৰ মাত্ৰা বঢ়াওক, Wi‑Fi পিকাৰত প্ৰতি SSID RSSI দেখুৱাওক"</string>
+    <!-- no translation found for wifi_connected_mac_randomization_summary (1743059848752201485) -->
+    <skip />
+    <string name="select_logd_size_title" msgid="7433137108348553508">"লগাৰৰ বাফাৰৰ আকাৰ"</string>
+    <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"প্ৰতিটো লগ বাফাৰত ল\'গাৰৰ আকাৰ বাছনি কৰক"</string>
+    <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"লগাৰৰ স্থায়ী সঞ্চয়াগাৰৰ বস্তুবোৰ মচিবনে?"</string>
+    <string name="dev_logpersist_clear_warning_message" msgid="2256582531342994562">"পাৰ্ছিছটেণ্ট লগাৰ ব্যৱহাৰ কৰ নিৰীক্ষণ নকৰাৰ সময়ত, আমি আপোনাৰ ডিভাইচত থকা লগাৰ ডেটা নিৱাসীক মচা দৰকাৰ।"</string>
+    <string name="select_logpersist_title" msgid="7530031344550073166">"ডিভাইচটোত লগাৰৰ ডেটা নিৰবচ্ছিন্নভাৱে সঞ্চয় কৰক"</string>
+    <string name="select_logpersist_dialog_title" msgid="4003400579973269060">"ডিভাইচত স্থায়ীভাৱে সঞ্চয় কৰিবলৈ লগ বাফাৰবোৰ বাছনি কৰক"</string>
+    <string name="select_usb_configuration_title" msgid="2649938511506971843">"ইউএছবি কনফিগাৰেশ্বন বাছনি কৰক"</string>
+    <string name="select_usb_configuration_dialog_title" msgid="6385564442851599963">"ইউএছবি কনফিগাৰেশ্বন বাছনি কৰক"</string>
+    <string name="allow_mock_location" msgid="2787962564578664888">"নকল অৱস্থানৰ অনুমতি দিয়ক"</string>
+    <string name="allow_mock_location_summary" msgid="317615105156345626">"নকল অৱস্থানৰ অনুমতি দিয়ক"</string>
+    <string name="debug_view_attributes" msgid="6485448367803310384">"দৃশ্যৰ গুণাগুণ নিৰীক্ষণ সক্ষম কৰক"</string>
+    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ৱাই-ফাই থকা সময়তো সদায় ম\'বাইল ডেটা সক্ৰিয় ৰাখক (খৰতকীয়াকৈ নেটৱৰ্ক সলনি কৰিবৰ বাবে)।"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"যদিহে উপলব্ধ হয় তেন্তে টেডাৰিং হাৰ্ডৱেৰ ত্বৰণ ব্যৱহাৰ কৰক"</string>
+    <string name="adb_warning_title" msgid="6234463310896563253">"ইউএছবি ডিবাগিঙৰ অনুমতি দিয়েনে?"</string>
+    <string name="adb_warning_message" msgid="7316799925425402244">"ইউএছবি ডিবাগ কৰা কাৰ্য কেৱল বিকাশৰ উদ্দেশ্যৰেহে কৰা হৈছে৷ আপোনাৰ কম্পিউটাৰ আৰু আপোনাৰ ডিভাইচৰ মাজত ডেটা প্ৰতিলিপি কৰিবলৈ এইটো ব্যৱহাৰ কৰক, কোনো জাননী নিদিয়াকৈয়ে আপোনাৰ ডিভাইচত এপ্‌সমূহ ইনষ্টল কৰক আৰু লগ ডেটা পঢ়ক৷"</string>
+    <string name="adb_keys_warning_message" msgid="5659849457135841625">"আপুনি আগতে ইউএছবি ডিবাগিঙৰ বাবে প্ৰৱেশৰ অনুমতি দিয়া সকলো কম্পিউটাৰৰ পৰা সেই অনুমতি প্ৰত্যাহাৰ কৰেনে?"</string>
+    <string name="dev_settings_warning_title" msgid="7244607768088540165">"বিকাশৰ কামৰ বাবে থকা ছেটিংবিলাকক অনুমতি দিবনে?"</string>
+    <string name="dev_settings_warning_message" msgid="2298337781139097964">"এই ছেটিংসমূহ বিকাশৰ কামত ব্যৱহাৰ কৰিবলৈ তৈয়াৰ কৰা হৈছে। সেইবিলাকে আপোনাৰ ডিভাইচ আৰু তাত থকা এপ্লিকেশ্বনসমূহক অকামিলা কৰি পেলাব পাৰে আৰু সেইবিলাকৰ কাৰণে এপ্লিকেশ্বনসমূহে অদ্ভুত আচৰণ কৰিব পাৰে।"</string>
+    <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"ইউএছবিৰ যোগেৰে এপৰ সত্যাপন কৰক"</string>
+    <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ADB/ADTৰ যোগেৰে ইনষ্টল কৰা এপসমূহে কিবা ক্ষতিকাৰক আচৰণ কৰিছে নেকি পৰীক্ষা কৰক।"</string>
+    <string name="bluetooth_show_devices_without_names_summary" msgid="2351196058115755520">"নামহীন ব্লুটুথ ডিভাইচসমূহ (মাত্ৰ MAC ঠিকনাযুক্ত) দেখুওৱা হ\'ব"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"ৰিম\'ট ডিভাইচবিলাকৰ সৈতে ভলিউম সম্পৰ্কীয় সমস্যা, যেনেকৈ অতি উচ্চ ভলিউম বা নিয়ন্ত্ৰণ কৰিবই নোৱাৰা অৱস্থাত ব্লুটুথৰ পূৰ্ণ ভলিউম সুবিধা অক্ষম কৰে।"</string>
+    <string name="enable_terminal_title" msgid="95572094356054120">"স্থানীয় টাৰ্মিনেল"</string>
+    <string name="enable_terminal_summary" msgid="67667852659359206">"স্থানীয় শ্বেল প্ৰৱেশাধিকাৰ দিয়া টাৰ্মিনেল এপ্ সক্ষম কৰক"</string>
+    <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP পৰীক্ষণ"</string>
+    <string name="hdcp_checking_dialog_title" msgid="5141305530923283">"HDCP পৰীক্ষণ আচৰণ ছেট কৰক"</string>
+    <string name="debug_debugging_category" msgid="6781250159513471316">"ডিবাগিং"</string>
+    <string name="debug_app" msgid="8349591734751384446">"ডিবাগ এপ্ বাছনি কৰক"</string>
+    <string name="debug_app_not_set" msgid="718752499586403499">"কোনো ডিবাগ এপ্লিকেশ্বন ছেট কৰা হোৱা নাই"</string>
+    <string name="debug_app_set" msgid="2063077997870280017">"ডিবাগিং এপ্লিকেশ্বন: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="select_application" msgid="5156029161289091703">"এপ্লিকেশ্বন বাছনি কৰক"</string>
+    <string name="no_application" msgid="2813387563129153880">"একোৱেই নাই"</string>
+    <string name="wait_for_debugger" msgid="1202370874528893091">"ডিবাগাৰৰ বাবে অপেক্ষা কৰক"</string>
+    <string name="wait_for_debugger_summary" msgid="1766918303462746804">"ডিবাগ কৰা এপ্লিকেশ্বনবোৰে কাৰ্য ৰূপায়ণ কৰাৰ আগতে ডিবাগাৰ সংলগ্ন হোৱা কাৰ্যলৈ অপেক্ষা কৰে"</string>
+    <string name="debug_input_category" msgid="1811069939601180246">"ইনপুট"</string>
+    <string name="debug_drawing_category" msgid="6755716469267367852">"অংকন"</string>
+    <string name="debug_hw_drawing_category" msgid="6220174216912308658">"হাৰ্ডৱেৰৰদ্বাৰা ত্বৰিত ৰেণ্ডাৰিং"</string>
+    <string name="media_category" msgid="4388305075496848353">"মিডিয়া"</string>
+    <string name="debug_monitoring_category" msgid="7640508148375798343">"নিৰীক্ষণ কৰি থকা হৈছে"</string>
+    <string name="strict_mode" msgid="1938795874357830695">"কঠোৰ ম’ড সক্ষম কৰা হৈছে"</string>
+    <string name="strict_mode_summary" msgid="142834318897332338">"যেতিয়া এপসমূহে মুখ্য থ্ৰেডত দীঘলীয়া কাৰ্যকলাপ চলাই, তেতিয়া স্ক্ৰীণ ফ্লাশ্ব কৰক"</string>
+    <string name="pointer_location" msgid="6084434787496938001">"পইণ্টাৰৰ অৱস্থান"</string>
+    <string name="pointer_location_summary" msgid="840819275172753713">"চলিত স্পৰ্শ-বিষয়ক তথ্যসহ স্ক্ৰীণ অভাৰলে\'"</string>
+    <string name="show_touches" msgid="2642976305235070316">"টেপসমূহ দেখুৱাওক"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"টিপিলে দৃশ্যায়িত ফীডবেক দিয়ক"</string>
+    <string name="show_screen_updates" msgid="5470814345876056420">"পৃষ্ঠভাগৰ আপডেইট দেখুৱাওক"</string>
+    <string name="show_screen_updates_summary" msgid="2569622766672785529">"আপডেইট হওতে গোটেই ৱিণ্ড পৃষ্ঠসমূহ ফ্লাশ্ব কৰক"</string>
+    <string name="show_hw_screen_updates" msgid="5036904558145941590">"জিপিইউৰ দৰ্শন আপডেইটসমূহ দেখুৱাওক"</string>
+    <string name="show_hw_screen_updates_summary" msgid="1115593565980196197">"জিপিইউৰ জৰিয়তে অঁকাৰ সময়ত ৱিণ্ড’ৰ ভিতৰত ফ্লাশ্ব দৰ্শন"</string>
+    <string name="show_hw_layers_updates" msgid="5645728765605699821">"হাৰ্ডৱেৰৰ তৰপৰ আপডেইট দেখুৱাওক"</string>
+    <string name="show_hw_layers_updates_summary" msgid="5296917233236661465">"হাৰ্ডৱেৰ লেয়াৰ আপডেইট হওতে সিঁহতক সেউজীয়া ৰঙেৰে ফ্লাশ্ব কৰক"</string>
+    <string name="debug_hw_overdraw" msgid="2968692419951565417">"GPU অভাৰড্ৰ ডিবাগ কৰক"</string>
+    <string name="disable_overlays" msgid="2074488440505934665">"HW অ’ভাৰলে অক্ষম কৰক"</string>
+    <string name="disable_overlays_summary" msgid="3578941133710758592">"স্ক্ৰীণ কম্প’জিট কৰাৰ বাবে সদায় জিপিইউ ব্যৱহাৰ কৰক"</string>
+    <string name="simulate_color_space" msgid="6745847141353345872">"ৰঙৰ ঠাই ছিমিউলেইট কৰক"</string>
+    <string name="enable_opengl_traces_title" msgid="6790444011053219871">"OpenGL ট্ৰেছ সক্ষম কৰক"</string>
+    <string name="usb_audio_disable_routing" msgid="8114498436003102671">"ইউএছবি অডিঅ\' ৰাউটিং অক্ষম কৰক"</string>
+    <string name="usb_audio_disable_routing_summary" msgid="980282760277312264">"স্বয়ংক্ৰিয়ভাৱে ইউএছবি ধ্বনিৰ আনুষংগিক আহিলাবিলাকলৈ ৰাউটিং কৰাটো অক্ষম কৰক"</string>
+    <string name="debug_layout" msgid="5981361776594526155">"লেআউটৰ সময় দেখুৱাওক"</string>
+    <string name="debug_layout_summary" msgid="2001775315258637682">"ক্লিপ বাউণ্ড, মাৰ্জিন আদিসমূহ দেখুৱাওক"</string>
+    <string name="force_rtl_layout_all_locales" msgid="2259906643093138978">"আৰটিএল চানেকিৰ দিশ বলেৰে সলনি কৰক"</string>
+    <string name="force_rtl_layout_all_locales_summary" msgid="9192797796616132534">"সকলো ভাষাৰ বাবে স্ক্ৰীণৰ চানেকিৰ দিশ RTLলৈ বলেৰে সলনি কৰক"</string>
+    <string name="force_hw_ui" msgid="6426383462520888732">"জিপিইউ ৰেণ্ডাৰিং বলেৰে ব্যৱহাৰ কৰক"</string>
+    <string name="force_hw_ui_summary" msgid="5535991166074861515">"2d চিত্ৰাংকনৰ বাবে GPUক বলেৰে ব্যৱহাৰ কৰক"</string>
+    <string name="force_msaa" msgid="7920323238677284387">"বল ৪গুণ MSAA"</string>
+    <string name="force_msaa_summary" msgid="9123553203895817537">"OpenGL ES 2.0 এপত ৪গুণ MSAA সক্ষম কৰক"</string>
+    <string name="show_non_rect_clip" msgid="505954950474595172">"আয়তাকৃতিৰ নোহোৱা ক্লিপ প্ৰক্ৰিয়াসমূহ ডিবাগ কৰক"</string>
+    <string name="track_frame_time" msgid="6146354853663863443">"প্ৰ\'ফাইল জিপিইউ ৰেণ্ডাৰিং"</string>
+    <string name="enable_gpu_debug_layers" msgid="3848838293793255097">"জিপিইউ ডিবাগ স্তৰবোৰ সক্ষম কৰক"</string>
+    <string name="enable_gpu_debug_layers_summary" msgid="8009136940671194940">"ডিবাগ এপসমূহৰ বাবে জিপিইউ ডিবাগ তৰপ ল\'ড কৰিবলৈ অনুমতি দিয়ক"</string>
+    <string name="window_animation_scale_title" msgid="6162587588166114700">"ৱিণ্ড\' এনিমেশ্বন স্কেল"</string>
+    <string name="transition_animation_scale_title" msgid="387527540523595875">"ট্ৰাঞ্জিশ্বন এনিমেশ্বন স্কেল"</string>
+    <string name="animator_duration_scale_title" msgid="3406722410819934083">"এনিমেটৰ কালদৈৰ্ঘ্য স্কেল"</string>
+    <string name="overlay_display_devices_title" msgid="5364176287998398539">"গৌণ প্ৰদৰ্শনৰ নকল বনাওক"</string>
+    <string name="debug_applications_category" msgid="4206913653849771549">"এপসমূহ"</string>
+    <string name="immediately_destroy_activities" msgid="1579659389568133959">"কাৰ্যকলাপসমূহ নাৰাখিব"</string>
+    <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"ব্যৱহাৰকাৰী ওলোৱাৰ লগে লগে সকলো কাৰ্যকলাপ মচক"</string>
+    <string name="app_process_limit_title" msgid="4280600650253107163">"নেপথ্যত চলা প্ৰক্ৰিয়াৰ সীমা"</string>
+    <string name="show_all_anrs" msgid="28462979638729082">"সকলো এএনআৰ দেখুৱাওক"</string>
+    <string name="show_all_anrs_summary" msgid="641908614413544127">"নেপথ্য এপসমূহৰ বাবে এপে সঁহাৰি দিয়া নাই মন্তব্য দেখুৱাওক"</string>
+    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"জাননী চ্চেনেলৰ সকীয়নিসমূহ দেখুৱাওক"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"কোনো এপে বৈধ চ্চেনেল নোহোৱাকৈ কোনো জাননী প\'ষ্ট কৰিলে স্ক্ৰীণত সকীয়নি প্ৰদৰ্শন হয়"</string>
+    <string name="force_allow_on_external" msgid="3215759785081916381">"বাহ্যিক সঞ্চয়াগাৰত এপক বলেৰে অনুমতি দিয়ক"</string>
+    <string name="force_allow_on_external_summary" msgid="3640752408258034689">"মেনিফেষ্টৰ মান যিয়েই নহওক, বাহ্যিক সঞ্চয়াগাৰত লিখিবলৈ যিকোনো এপক উপযুক্ত কৰি তোলে"</string>
+    <string name="force_resizable_activities" msgid="8615764378147824985">"বলেৰে কাৰ্যকলাপসমূহৰ আকাৰ সলনি কৰিব পৰা কৰক"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"মেনিফেষ্টৰ মান যিয়েই নহওক, মাল্টি-ৱিণ্ডৰ বাবে সকলো কাৰ্যকলাপৰ আকাৰ সলনি কৰিব পৰা কৰক।"</string>
+    <string name="enable_freeform_support" msgid="1461893351278940416">"ফ্ৰিফৰ্ম ৱিণ্ড\'জ সক্ষম কৰক"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"পৰীক্ষামূলক ফ্ৰী-ফৰ্ম ৱিণ্ড’বোৰৰ বাবে সহায়তা সক্ষম কৰক৷"</string>
+    <string name="local_backup_password_title" msgid="3860471654439418822">"ডেস্কটপ বেকআপ পাছৱৰ্ড"</string>
+    <string name="local_backup_password_summary_none" msgid="6951095485537767956">"ডেস্কটপৰ পূৰ্ণ বেকআপ এতিয়ালৈকে সংৰক্ষিত অৱস্থাত নাই"</string>
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"ডেস্কটপ সম্পূৰ্ণ বেকআপৰ বাবে পাছৱৰ্ডটো সলনি কৰিবলৈ বা আঁতৰাবলৈ টিপক"</string>
+    <string name="local_backup_password_toast_success" msgid="582016086228434290">"নতুন বেকআপ পাছৱৰ্ড ছেট কৰা হ\'ল"</string>
+    <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"নতুন পাছৱৰ্ডটোৰ লগত নিশ্চিত কৰা পাছৱৰ্ডটো মিলা নাই"</string>
+    <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"বেকআপ পাছৱৰ্ড নিৰ্ধাৰণ কৰিব পৰা নহ\'ল"</string>
+  <string-array name="color_mode_names">
+    <item msgid="2425514299220523812">"জীৱন্ত (ডিফল্ট)"</item>
+    <item msgid="8446070607501413455">"প্ৰাকৃতিক"</item>
+    <item msgid="6553408765810699025">"মানক"</item>
+  </string-array>
+  <string-array name="color_mode_descriptions">
+    <item msgid="4979629397075120893">"বৰ্ধিত ৰং"</item>
+    <item msgid="8280754435979370728">"চকুৱে দেখা পোৱা ধৰণৰ প্ৰাকৃতিক ৰং"</item>
+    <item msgid="5363960654009010371">"ডিজিটেল সমলৰ বাবে ৰং অপ্টিমাইজ কৰা হৈছে"</item>
+  </string-array>
+    <!-- no translation found for inactive_apps_title (9042996804461901648) -->
+    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"নিষ্ক্ৰিয়। ট\'গল কৰিবলৈ টিপক।"</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"সক্ৰিয়। ট\'গল কৰিবলৈ টিপক।"</string>
+    <!-- no translation found for standby_bucket_summary (6567835350910684727) -->
+    <skip />
+    <string name="runningservices_settings_title" msgid="8097287939865165213">"চলিত সেৱা"</string>
+    <string name="runningservices_settings_summary" msgid="854608995821032748">"বৰ্তমান চলি থকা সেৱাসমূহ চাওক আৰু নিয়ন্ত্ৰণ কৰক"</string>
+    <string name="select_webview_provider_title" msgid="4628592979751918907">"ৱেবভিউ প্ৰয়োগ"</string>
+    <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"ৱেবভিউ প্ৰয়োগ ছেট কৰক"</string>
+    <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"বাছনিটো এতিয়া আৰু মান্য় নহয়। আকৌ চেষ্টা কৰক।"</string>
+    <string name="convert_to_file_encryption" msgid="3060156730651061223">"ফাইল এনক্ৰিপশ্বন কৰিবলৈ ৰূপান্তৰ কৰক"</string>
+    <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"ৰূপান্তৰ কৰক…"</string>
+    <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"ফাইল ইতিমধ্যে এনক্ৰিপ্ট কৰা হৈছে"</string>
+    <string name="title_convert_fbe" msgid="1263622876196444453">"ফাইল-ভিত্তিক এনক্ৰিপশ্বনলৈ ৰূপান্তৰ কৰা হৈছে"</string>
+    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"ডেটা বিভাজনক ফাইল ভিত্তিক এনক্ৰিপশ্বনলৈ সলনি কৰক।\n !!সাৱধান!! ই আপোনাৰ সকলো ডেটা মচিব।\n এই সুবিধাটো আলফা পৰীক্ষণ অৱস্থাত আছে গতিকে ই সঠিকভাৱে কাম নকৰিব পাৰে।\n অব্যাহত ৰাখিবলৈ \'মচক আৰু ৰূপান্তৰ কৰক…\' দবাওক।"</string>
+    <string name="button_convert_fbe" msgid="5152671181309826405">"মচক আৰু ৰূপান্তৰ কৰক…"</string>
+    <string name="picture_color_mode" msgid="4560755008730283695">"চিত্ৰৰ ৰং ম’ড"</string>
+    <string name="picture_color_mode_desc" msgid="1141891467675548590">"এছআৰজিবি ব্যৱহাৰ কৰক"</string>
+    <string name="daltonizer_mode_disabled" msgid="7482661936053801862">"নিষ্ক্ৰিয় হৈ আছে"</string>
+    <string name="daltonizer_mode_monochromacy" msgid="8485709880666106721">"ম\'ন\'ক্ৰ\'মেচী"</string>
+    <string name="daltonizer_mode_deuteranomaly" msgid="5475532989673586329">"ডিউটাৰএন\'মেলী (ৰঙা-সেউজীয়া)"</string>
+    <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"প্ৰ’টানোমালি (ৰঙা-সেউজীয়া)"</string>
+    <string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"ট্ৰাইটান\'মেলী (নীলা-হালধীয়া)"</string>
+    <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ৰং শুধৰণী"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"এই সুবিধাটো পৰীক্ষামূলক, সেয়ে ই কাৰ্যক্ষমতাৰ ওপৰত প্ৰভাৱ পেলাব পাৰে।"</string>
+    <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g>ৰ দ্বাৰা অগ্ৰাহ্য কৰা হৈছে"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"প্ৰায় <xliff:g id="TIME">%1$s</xliff:g> বাকী আছে"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"আপোনাৰ ব্যৱহাৰৰ ওপৰত ভিত্তি কৰি প্ৰায় <xliff:g id="TIME">%1$s</xliff:g> বাকী আছে"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"সম্পূৰ্ণকৈ চ্চাৰ্জ হ\'বলৈ <xliff:g id="TIME">%1$s</xliff:g> বাকী"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> বাকী"</string>
+    <!-- no translation found for power_remaining_less_than_duration_only (5996752448813295329) -->
+    <skip />
+    <!-- no translation found for power_remaining_less_than_duration (7967078125657859046) -->
+    <skip />
+    <!-- no translation found for power_remaining_more_than_subtext (6846716609975752316) -->
+    <skip />
+    <!-- no translation found for power_remaining_only_more_than_subtext (8884488700395194194) -->
+    <skip />
+    <!-- no translation found for power_remaining_duration_only_shutdown_imminent (8168317165722752881) -->
+    <skip />
+    <!-- no translation found for power_remaining_duration_only_shutdown_imminent (5957064378548718872) -->
+    <skip />
+    <!-- no translation found for power_remaining_duration_only_shutdown_imminent (9055596817716471373) -->
+    <skip />
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - প্ৰায় <xliff:g id="TIME">%2$s</xliff:g> বাকী আছে"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - আপোনাৰ ব্যৱহাৰক ভিত্তি কৰি প্ৰায় <xliff:g id="TIME">%2$s</xliff:g> বাকী আছে"</string>
+    <!-- no translation found for power_remaining_duration_shutdown_imminent (7679005631124015335) -->
+    <skip />
+    <!-- no translation found for power_remaining_duration_shutdown_imminent (261050880878965621) -->
+    <skip />
+    <!-- no translation found for power_remaining_duration_shutdown_imminent (2020049829798578618) -->
+    <skip />
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> সম্পূৰ্ণৰূপে চ্চাৰ্জ হোৱা পৰ্যন্ত"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"অজ্ঞাত"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"চাৰ্জ কৰি থকা হৈছে"</string>
+    <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"চ্চাৰ্জ হৈ আছে"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"চ্চাৰ্জ কৰা নাই"</string>
+    <string name="battery_info_status_not_charging" msgid="8523453668342598579">"প্লাগ কৰি থোৱা হৈছে, এই মুহূৰ্তত চ্চাৰ্জ কৰিব নোৱাৰি"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"পূৰ্ণ"</string>
+    <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"এডমিনৰ দ্বাৰা নিয়ন্ত্ৰিত"</string>
+    <string name="enabled_by_admin" msgid="5302986023578399263">"প্ৰশাসকে সক্ষম কৰিছে"</string>
+    <string name="disabled_by_admin" msgid="8505398946020816620">"এডমিনে অক্ষম কৰিছে ৰাখিছে"</string>
+    <string name="disabled" msgid="9206776641295849915">"নিষ্ক্ৰিয়"</string>
+    <string name="external_source_trusted" msgid="2707996266575928037">"অনুমতি দিয়া হৈছে"</string>
+    <string name="external_source_untrusted" msgid="2677442511837596726">"অনুমতি দিয়া হোৱা নাই"</string>
+    <string name="install_other_apps" msgid="6986686991775883017">"অজ্ঞাত এপ্ ইনষ্টল কৰক"</string>
+    <string name="home" msgid="3256884684164448244">"ছেটিংসমূহৰ গৃহপৃষ্ঠা"</string>
+  <string-array name="battery_labels">
+    <item msgid="8494684293649631252">"০%"</item>
+    <item msgid="8934126114226089439">"৫০%"</item>
+    <item msgid="1286113608943010849">"১০০%"</item>
+  </string-array>
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> আগত"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> বাকী আছে"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"সৰু"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ডিফ’ল্ট"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ডাঙৰ"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"বৃহত্তৰ"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"সকলোতকৈ ডাঙৰ"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"নিজৰ উপযোগিতা অনুযায়ী (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
+    <string name="help_feedback_label" msgid="6815040660801785649">"সহায় আৰু ফীডবেক"</string>
+    <string name="content_description_menu_button" msgid="8182594799812351266">"মেনু"</string>
+    <string name="retail_demo_reset_message" msgid="118771671364131297">"ডেম’ ম\'ডত ফেক্টৰী ৰিছেট কৰিবলৈ পাছৱৰ্ড দিয়ক"</string>
+    <string name="retail_demo_reset_next" msgid="8356731459226304963">"পৰৱৰ্তী"</string>
+    <string name="retail_demo_reset_title" msgid="696589204029930100">"পাছৱৰ্ড দৰকাৰী"</string>
+    <string name="active_input_method_subtypes" msgid="3596398805424733238">"সক্ৰিয়হৈ থকা ইনপুট পদ্ধতিসমূহ"</string>
+    <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"ছিষ্টেমৰ ভাষা ব্যৱহাৰ কৰক"</string>
+    <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>ৰ ছেটিংবিলাক খুলিব পৰা নগ\'ল"</string>
+    <string name="ime_security_warning" msgid="4135828934735934248">"এই ইনপুট পদ্ধতিটোৱে আপুনি টাইপ কৰা আপোনাৰ ব্যক্তিগত ডেটা যেনে পাছৱৰ্ডসমূহ আৰু ক্ৰেডিট কাৰ্ডৰ নম্বৰসমূহকে ধৰি সকলো পাঠ সংগ্ৰহ কৰিবলৈ সক্ষম হ\'ব পাৰে। <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> এপটোৰ লগত ই সংলগ্ন। এই ইনপুট পদ্ধতিটো ব্যৱহাৰ কৰেনে?"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"টোকা: ৰিবুট কৰাৰ পিছত আপুনি ফ\'নটো আনলক নকৰালৈকে এই এপটো ষ্টাৰ্ট নহ\'ব"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"আইএমএছ পঞ্জীয়ন স্থিতি"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"পঞ্জীকৃত"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"পঞ্জীকৃত নহয়"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"উপলব্ধ নহয়"</string>
+    <!-- no translation found for wifi_tether_connected_summary (3871603864314407780) -->
+    <!-- no translation found for accessibility_manual_zen_more_time (1636187409258564291) -->
+    <skip />
+    <!-- no translation found for accessibility_manual_zen_less_time (6590887204171164991) -->
+    <skip />
+    <!-- no translation found for zen_mode_enable_dialog_turn_on (8287824809739581837) -->
+    <skip />
+    <string name="cancel" msgid="6859253417269739139">"বাতিল কৰক"</string>
+    <!-- no translation found for zen_mode_settings_turn_on_dialog_title (2297134204747331078) -->
+    <skip />
+    <string name="zen_mode_settings_summary_off" msgid="6119891445378113334">"কেতিয়াও নহয়"</string>
+    <!-- no translation found for zen_interruption_level_priority (2078370238113347720) -->
+    <skip />
+    <!-- no translation found for zen_mode_and_condition (4927230238450354412) -->
+    <skip />
+    <!-- no translation found for zen_alarm_warning_indef (3007988140196673193) -->
+    <skip />
+    <!-- no translation found for zen_alarm_warning (6236690803924413088) -->
+    <skip />
+    <!-- no translation found for alarm_template (4996153414057676512) -->
+    <skip />
+    <!-- no translation found for alarm_template_far (3779172822607461675) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 97ccf91..1a0a251 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Доступ да SIM-карты"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Аўдыя ў HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Аўдыя ў HD"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Слыхавы апарат"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Падключана да слыхавога апарата"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Падключана да аўдыё медыа"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Падключана да аўдыё тэлефона"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Падключаны да серверу перадачы файлаў"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Выкарыстоўваць для аўдыё тэлефона"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Выкарыстоўваць для перадачы файлаў"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Выкарыстоўваць для ўводу"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Выкарыстоўваць для слыхавога апарата"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Падлучыць"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"СПАЛУЧЫЦЬ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Скасаваць"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 9bde546..d071c64 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Достъп до SIM картата"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Висококачествено аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Висококачествено аудио"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Слухов апарат"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Има връзка със слуховия апарат"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Установена е връзка с медийно аудио"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Връзка със звука на телефона"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Установена е връзка със сървър за трансфер на файлове"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Използване на телефон за аудио"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Използване на за пренос на файлове"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Да се използва за въвеждане"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Използване за слухов апарат"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Сдвояване"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"СДВОЯВАНЕ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Отказ"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 28b879bd..baa31e6 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"সিম -এর অ্যাক্সেস"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD অডিও: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD অডিও"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"হিয়ারিং এড"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"শ্রবণ যন্ত্রের সাথে কানেক্ট রয়েছে"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"মিডিয়া অডিওতে সংযুক্ত রয়েছে"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ফোন অডিওতে সংযুক্ত"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ফাইল স্থানান্তর সার্ভারের সঙ্গে সংযুক্ত"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ফোন অডিওয়ের জন্য ব্যবহার করুন"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ফাইল স্থানান্তরের জন্য ব্যবহার করুন"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ইনপুটের জন্য ব্যবহার করুন"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"শ্রবণ যন্ত্রের জন্য ব্যবহার করুন"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"যুক্ত করুন"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"যুক্ত করুন"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"বাতিল করুন"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 998ef58..fe1c6bc 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Πρόσβαση SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Ήχος HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Ήχος HD"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Βοήθημα ακοής"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Συνδέθηκε σε βοήθημα ακοής"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Συνδέθηκε σε ήχο πολυμέσων"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Συνδεδεμένο στον ήχο τηλεφώνου"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Συνδεδεμένο σε διακομιστή μεταφοράς αρχείων"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Χρήση για ήχο τηλεφώνου"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Χρήση για τη μεταφορά αρχείων"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Χρήση για είσοδο"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Χρήση για βοήθημα ακοής"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Σύζευξη"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ΣΥΖΕΥΞΗ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Ακύρωση"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index f38643f..bf62e59 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acceso SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Audio en HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Audio en HD"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Audífonos"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Conectado a un audífono"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Conectado al audio multimedia"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Conectado al audio del dispositivo"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Conectado al servidor de transferencia de archivo"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Utilizar para el audio del dispositivo"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Utilizar para la transferencia de archivos"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Utilizar para entrada"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Usar con audífonos"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Vincular"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"SINCRONIZAR"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Cancelar"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 382a514..77d55ff 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-kaardi juurdepääs"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD-heli: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD-heli"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Kuuldeaparaat"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Kuuldeaparaadiga ühendatud"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Ühendatud meediumiheliga"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Ühendatud telefoniheliga"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Ühendatud failiedastuse serveriga"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Kasuta telefoniheli jaoks"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Kasutage failide edastamiseks"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Kasutage sisendi jaoks"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Kuuldeaparaadiga kasutamiseks"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Seo"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"SEO"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Tühista"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 15fe55b..effcd47 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acceso á SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Audio en HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Audio en HD"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Audiófonos"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Conectouse aos audiófonos"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Conectado ao audio multimedia"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Conectado ao audio do teléfono"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Conectado ao servidor de transferencia de ficheiros"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Utilízase para o audio do teléfono"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Utilízase para a transferencia de ficheiros"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Utilízase para a entrada"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Usar para o audiófono"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Sincronizar"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"SINCRONIZAR"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Cancelar"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 617230e..c517b8b 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"સિમ ઍક્સેસ"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ઑડિઓ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ઑડિઓ"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"સાંભળવામાં સહાય આપતું યંત્ર"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"સાંભળવામાં સહાય આપતા યંત્ર સાથે કનેક્ટ કરેલ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"મીડિયા ઑડિઓ સાથે કનેક્ટ કર્યુ"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ફોન ઑડિઓ સાથે કનેક્ટ થયાં"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ફાઇલ સ્થાનાંતરણ સેવાથી કનેક્ટ થયાં"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ફોન ઑડિઓ માટે ઉપયોગ કરો"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ફાઇલ સ્થાનાંતર માટે ઉપયોગ કરો"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ઇનપુટ માટે ઉપયોગ કરો"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"સાંભળવામાં સહાય આપતા યંત્ર માટે ઉપયોગ કરો"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"જોડી"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"જોડાણ બનાવો"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"રદ કરો"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 4a12196..2726c46 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"सिम ऐक्सेस"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ऑडियो: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ऑडियो"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"सुनने में मददगार डिवाइस"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"सुनने में मददगार डिवाइस से जाेड़ा गया"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"मीडिया ऑडियो से कनेक्‍ट किया गया"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"फ़ोन ऑडियो से कनेक्‍ट किया गया"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"फ़ाइल स्‍थानांतरण सर्वर से कनेक्‍ट किया गया"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"फ़ोन ऑडियो के लिए उपयोग करें"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"फ़ाइल स्‍थानांतरण के लिए उपयोग करें"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"इनपुट के लिए उपयोग करें"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"सुनने में मददगार डिवाइस के लिए इस्तेमाल करें"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"युग्‍म बनाएं"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"दूसरे डिवाइस से जोड़ें"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"रद्द करें"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 8e5cf7d..35a5560 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-elérés"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD audio"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Hallókészülék"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Csatlakoztatva a hallókészülékhez"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Csatlakoztatva az eszköz hangjához"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Csatlakoztatva a telefon hangjához"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Csatlakozva a fájlküldő szerverhez"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Felhasználás a telefon hangjához"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Felhasználás fájlátvitelre"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Használat beviteli eszközként"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Használat hallókészülékhez"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Párosítás"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"PÁROSÍTÁS"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Mégse"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index e5e5beb..44a1714 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM քարտի հասանելիություն"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD աուդիո՝ <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD աուդիո"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Լսողական ապարատ"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Միացված է լսողական ապարատին"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Միացված է մեդիա աուդիոյին"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Միացված է հեռախոսի ձայնային տվյալներին"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Միացված է ֆայլերի փոխանցման սերվերին"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Օգտագործել հեռախոսի աուդիոյի համար"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Օգտագործել ֆայլի փոխանցման համար"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Օգտագործել ներմուծման համար"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Օգտագործել լսողական ապարատի համար"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Զուգավորել"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"Զուգավորել"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Չեղարկել"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index b957898..81307f7 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"‏גישה ל-SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"‏אודיו באיכות HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"‏אודיו באיכות HD"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"מכשיר שמיעה"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"מחובר למכשיר שמיעה"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"מחובר לאודיו של מדיה"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"מחובר לאודיו של הטלפון"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"מחובר לשרת העברת קבצים"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"השתמש עבור האודיו של הטלפון"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"השתמש להעברת קבצים"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"השתמש לקלט"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"יש להשתמש עבור מכשיר שמיעה"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"התאם"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"התאם"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"ביטול"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 953b2e3..346a96d 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIMアクセス"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD オーディオ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD オーディオ"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"補聴器"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"補聴器に接続済み"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"メディアの音声に接続"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"携帯電話の音声に接続"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ファイル転送サーバーに接続"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"携帯電話の音声に使用"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ファイル転送に使用"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"入力に使用"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"補聴器に使用"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"ペア設定する"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ペア設定する"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"キャンセル"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index a5fd213..db03069 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM წვდომა"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD აუდიო: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD აუდიო"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"სმენის აპარატი"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"დაკავშირებულია სმენის აპარატთან"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"დაკავშირებულია აუდიო მულტიმედიურ სისტემასთან"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"დაკავშირებულია ტელეფონის აუდიო მოწყობილობასთან"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"დაკავშირებულია ფაილების გადაცემის სერვერთან"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"გამოიყენეთ ტელეფონის აუდიომოწყობილობაში"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ფაილების ტრანსფერისათვის გამოყენება"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"შეტანისთვის გამოყენება"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"სმენის აპარატის გამოყენება"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"დაწყვილება"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"დაწყვილება"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"გაუქმება"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 4e2dacb..acd7d87 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM картасына кіру"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD форматты аудиомазмұн: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD форматты аудиомазмұн"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Есту аппараты"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Есту аппаратына жалғанған"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Медиа аудиосына жалғанған"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Телефон аудиосына қосылған"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Файл жіберу серверіне жалғанған"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Телефон аудиосы үшін қолдану"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Файлды жіберу үшін қолдану"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Кіріс үшін қолдану"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Есту аппаратына пайдалану"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Жұптау"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ЖҰПТАУ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Бас тарту"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 400be09..9f55983 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"ಸಿಮ್ ಪ್ರವೇಶ"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ಆಡಿಯೋ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ಆಡಿಯೋ"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"ಶ್ರವಣ ಸಾಧನ"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"ಶ್ರವಣ ಸಾಧನಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"ಮಾಧ್ಯಮ ಆಡಿಯೋಗೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ಫೋನ್ ಆಡಿಯೋಗೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ಫೈಲ್ ವರ್ಗಾವಣೆ ಸರ್ವರ್‌ಗೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ಫೋನ್‌ ಆಡಿಯೋಗಾಗಿ ಬಳಕೆ"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ಫೈಲ್‌ ವರ್ಗಾವಣೆಗಾಗಿ ಬಳಸು"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ಇನ್‌ಪುಟ್‌ಗಾಗಿ ಬಳಸು"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"ಶ್ರವಣ ಸಾಧನಕ್ಕಾಗಿ ಬಳಸಿ"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"ಜೋಡಿ"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ಜೋಡಿ ಮಾಡು"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"ರದ್ದುಮಾಡಿ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index ab02029..35a2867 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM 액세스"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD 오디오: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD 오디오"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"보청기"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"보청기에 연결됨"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"미디어 오디오에 연결됨"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"휴대전화 오디오에 연결됨"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"파일 전송 서버에 연결됨"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"휴대전화 오디오에 사용"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"파일 전송에 사용"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"입력에 사용"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"보청기에 사용"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"페어링"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"페어링"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"취소"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 993fc33..c1f73cc 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM картаны пайдалануу мүмкүнчүлүгү"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD форматындагы аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD форматындагы аудио"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Угуу аппараты"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Угуу аппаратына туташты"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Медиа аудиого туташты"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Телефон аудиосуна туташты"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Файл өткөрүү серверине туташты"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Телефон аудиосу үчүн колдонулсун"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Файл өткөрүү үчүн колдонулсун"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Киргизүү үчүн колдонулсун"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Угуу аппараты үчүн колдонуу"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Жупташтыруу"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ЖУПТАШТЫРУУ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Жок"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index dc771f8..24cc69e 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Piekļuve SIM kartei"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD audio"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Dzirdes aparāts"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Izveidots savienojums ar dzirdes aparātu"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Savienots ar multivides audio"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Savienots ar tālruņa audio"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Savienots ar failu pārsūtīšanas serveri"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Izmantot tālruņa skaņai"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Izmantot faila pārsūtīšanai"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Izmantot ievadei"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Izmantot dzirdes aparātam"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Izveidot pāri"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"SAVIENOT PĀRĪ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Atcelt"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 4ef3e86..4798a6f 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Пристап до SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD аудио"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Слушно помагало"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Поврзано со слушно помагало"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Поврзан со аудио на медиуми"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Поврзан со аудио на телефон"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Поврзан со сервер за пренос на датотеки"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Користи за аудио на телефон"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Користи за пренос на датотеки"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Користи за внес"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Користете како слушно помагало"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Спари"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"СПАРИ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Откажи"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index c242701..04b08f4 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM ആക്സസ്"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ഓഡിയോ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ഓഡിയോ"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"ശ്രവണ സഹായി"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"ശ്രവണ സഹായിലേക്ക് കണക്റ്റ് ചെയ്‌‌തു"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"മീഡിയ ഓഡിയോയിലേക്ക് കണ‌ക്റ്റുചെയ്‌തു"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ഫോൺ ഓഡിയോയിൽ കണ‌ക്റ്റുചെ‌യ്‌തു"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ഫയൽ കൈമാറ്റ സെർവറിലേക്ക് കണ‌ക്റ്റുചെ‌യ്‌തു"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ഫോൺ ഓഡിയോയ്ക്കായി ഉപയോഗിക്കുക"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ഫയൽ കൈമാറ്റത്തിനായി ഉപയോഗിക്കുന്നു"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ഇൻപുട്ടിനായി ഉപയോഗിക്കുക"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"ശ്രവണ സഹായത്തിനായി ഉപയോഗിക്കുക"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"ജോടിയാക്കുക"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ജോടിയാക്കുക"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"റദ്ദാക്കുക"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 7934e8d..26f4344 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"सिम प्रवेश"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ऑडिओ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ऑडिओ"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"ऐकण्याची सुविधा"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"ऐकण्याच्या सुविधेशी कनेक्ट केलेले आहे"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"मीडिया ऑडिओवर कनेक्ट केले"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"फोन ऑडिओ वर कनेक्ट केले"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"फाईल स्थानांतर सर्व्हरवर कनेक्ट केले"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"फोन ऑडिओसाठी वापरा"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"फाईल स्थानांतरणासाठी वापरा"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"इनपुट साठी वापरा"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"ऐकण्याच्या सुविधेसाठी वापरा"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"पेअर करा"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"पेअर करा"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"रद्द करा"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index e1aa376..8e24cee 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Akses SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Audio HD"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Alat Bantu Pendengaran"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Disambungkan ke Alat Bantu Pendengaran"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Disambungkan ke audio media"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Disambungkan ke audio telefon"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Bersambung ke pelayan pemindahan fail"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Gunakan untuk audio telefon"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Gunakan untuk pemindahan fail"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Gunakan untuk input"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Gunakan untuk Alat Bantu Pendengaran"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Jadikan pasangan"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"JADIKAN PASANGAN"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Batal"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index f962316..0b54624 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Tilgang til SIM-kortet"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD-lyd: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD-lyd"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Høreapparat"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Koblet til høreapparat"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Koblet til medielyd"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Koblet til telefonlyd"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Koblet til tjener for filoverføring"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Bruk for telefonlyd"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Bruk til filoverføring"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Bruk for inndata"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Bruk for høreapparat"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Sammenkoble"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"KOBLE TIL"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Avbryt"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 0cac05e..7b78009 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM पहुँच"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD अडियो: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD अडियो"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"सुन्नमा मद्दत गर्ने यन्त्र"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"सुन्नमा मद्दत गर्ने यन्त्रमा जडान गरियो"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"मिडिया अडियोसँग जडित"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"फोन अडियोमा जडान गरियो"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"फाइल ट्रान्सफर सर्भरमा जडान गरियो"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"फोन अडियोको लागि प्रयोग गर्नुहोस्"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"फाइल ट्रान्सफरका लागि प्रयोग गर्नुहोस्"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"इनपुटको लागि प्रयोग गर्नुहोस्"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"सुन्नमा मद्दत गर्ने यन्त्रका लागि प्रयोग गर्नुहोस्"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"जोडी"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"जोडी"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"रद्द गर्नुहोस्"</string>
diff --git a/packages/SettingsLib/res/values-or/arrays.xml b/packages/SettingsLib/res/values-or/arrays.xml
new file mode 100644
index 0000000..22f6eda
--- /dev/null
+++ b/packages/SettingsLib/res/values-or/arrays.xml
@@ -0,0 +1,253 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2015 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wifi_status">
+    <item msgid="1922181315419294640"></item>
+    <item msgid="8934131797783724664">"ସ୍କାନ୍‌ କରୁଛି…"</item>
+    <item msgid="8513729475867537913">"ସଂଯୋଗ କରୁଛି…"</item>
+    <item msgid="515055375277271756">"ପ୍ରାମାଣିକୀକରଣ କରାଯାଉଛି…"</item>
+    <item msgid="1943354004029184381">"IP ଠିକଣା ପ୍ରାପ୍ତ କରୁଛି…"</item>
+    <item msgid="4221763391123233270">"ସଂଯୋଜିତ"</item>
+    <item msgid="624838831631122137">"ନିଲମ୍ବିତ"</item>
+    <item msgid="7979680559596111948">"ବିଚ୍ଛିନ୍ନ ହେଉଛି…"</item>
+    <item msgid="1634960474403853625">"ବିଚ୍ଛିନ୍ନ"</item>
+    <item msgid="746097431216080650">"ଅସଫଳ"</item>
+    <item msgid="6367044185730295334">"ଅବରୋଧିତ"</item>
+    <item msgid="503942654197908005">"ସାମୟିକ ଭାବେ ଖରାପ ସଂଯୋଜନାକୁ ଏଡାଉଛି"</item>
+  </string-array>
+  <string-array name="wifi_status_with_ssid">
+    <item msgid="7714855332363650812"></item>
+    <item msgid="8878186979715711006">"ସ୍କାନ୍‌ କରୁଛି…"</item>
+    <item msgid="355508996603873860">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>କୁ ସଂଯୋଗ କରାଯାଉଛି…"</item>
+    <item msgid="554971459996405634">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> ସହ ପ୍ରମାଣିତ ହେଉଛି…"</item>
+    <item msgid="7928343808033020343">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>ରୁ IP ଠିକଣା ହାସଲ କରୁଛି…"</item>
+    <item msgid="8937994881315223448">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> ସହ ସଂଯୁକ୍ତ"</item>
+    <item msgid="1330262655415760617">"କଟିଯାଇଛି"</item>
+    <item msgid="7698638434317271902">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>ରୁ ବିଚ୍ଛିନ୍ନ ହେଉଛି…"</item>
+    <item msgid="197508606402264311">"ସଂଯୁକ୍ତ ନାହିଁ"</item>
+    <item msgid="8578370891960825148">"ଅସଫଳ"</item>
+    <item msgid="5660739516542454527">"ଅବରୋଧିତ"</item>
+    <item msgid="1805837518286731242">"ଦୁର୍ବଳ ସଂଯୋଗକୂ ସାମୟିକ ଭାବେ ଏଡ଼ାଉଛି"</item>
+  </string-array>
+  <string-array name="hdcp_checking_titles">
+    <item msgid="441827799230089869">"ଆଦୌ ଯାଞ୍ଚ କରନାହିଁ"</item>
+    <item msgid="6042769699089883931">"କେବଳ DRM କଣ୍ଟେଣ୍ଟ ଠାବ କର"</item>
+    <item msgid="9174900380056846820">"ସର୍ବଦା ଠାବ କର"</item>
+  </string-array>
+  <string-array name="hdcp_checking_summaries">
+    <item msgid="505558545611516707">"କଦାପି HDCP ଯାଞ୍ଚ କରିବା ବ୍ୟବହାର କରନ୍ତୁ ନାହିଁ"</item>
+    <item msgid="3878793616631049349">"କେବଳ DRM ବିଷୟବସ୍ତୁ ପାଇଁ HDCP ଯାଞ୍ଚ ବ୍ୟବହାର କରନ୍ତୁ"</item>
+    <item msgid="45075631231212732">"ସର୍ବଦା HDCP ଯାଞ୍ଚ ବ୍ୟବହାର କରନ୍ତୁ"</item>
+  </string-array>
+  <string-array name="bluetooth_avrcp_versions">
+    <item msgid="5347678900838034763">"AVRCP 1.4 (ଡିଫଲ୍ଟ)"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
+  </string-array>
+  <string-array name="bluetooth_avrcp_version_values">
+    <item msgid="2838624067805073303">"avrcp14"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_titles">
+    <item msgid="7065842274271279580">"ସିଷ୍ଟମ୍ ଚୟନ ବ୍ୟବହାର କରନ୍ତୁ (ଡିଫଲ୍ଟ)"</item>
+    <item msgid="7539690996561263909">"SBC"</item>
+    <item msgid="686685526567131661">"AAC"</item>
+    <item msgid="5254942598247222737">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ଅଡିଓ"</item>
+    <item msgid="2091430979086738145">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ଅଡିଓ"</item>
+    <item msgid="6751080638867012696">"LDAC"</item>
+    <item msgid="723675059572222462">"ବିକଳ୍ପ କୋଡେକ୍ସକୁ ସକ୍ଷମ କରନ୍ତୁ"</item>
+    <item msgid="3304843301758635896">"ବିକଳ୍ପ କୋଡେକ୍‌ଗୁଡ଼ିକୁ ଅକ୍ଷମ କରନ୍ତୁ"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_summaries">
+    <item msgid="5062108632402595000">"ସିଷ୍ଟମ୍‌ର ଚୟନ (ପୂର୍ବ-ନିର୍ଦ୍ଧାରିତ) ବ୍ୟବହାର କରନ୍ତୁ"</item>
+    <item msgid="6898329690939802290">"SBC"</item>
+    <item msgid="6839647709301342559">"AAC"</item>
+    <item msgid="7848030269621918608">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ଅଡିଓ"</item>
+    <item msgid="298198075927343893">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ଅଡିଓ"</item>
+    <item msgid="7950781694447359344">"LDAC"</item>
+    <item msgid="2209680154067241740">"ବିକଳ୍ପ କୋଡେକ୍ସ ସକ୍ଷମ କରନ୍ତୁ"</item>
+    <item msgid="741805482892725657">"ବିକଳ୍ପ କୋଡେକ୍ସ ଅକ୍ଷମ କରନ୍ତୁ"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
+    <item msgid="3093023430402746802">"ସିଷ୍ଟମ୍‌ର ଚୟନ (ପୂର୍ବ-ନିର୍ଦ୍ଧାରିତ) ବ୍ୟବହାର କରନ୍ତୁ"</item>
+    <item msgid="8895532488906185219">"44.1 kHz"</item>
+    <item msgid="2909915718994807056">"48.0 kHz"</item>
+    <item msgid="3347287377354164611">"88.2 kHz"</item>
+    <item msgid="1234212100239985373">"96.0 kHz"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_sample_rate_summaries">
+    <item msgid="3214516120190965356">"ସିଷ୍ଟମ୍‌ ଚୟନ ବ୍ୟବହାର କରନ୍ତୁ (ପୂର୍ବ-ନିର୍ଦ୍ଧାରିତ)"</item>
+    <item msgid="4482862757811638365">"44.1 kHz"</item>
+    <item msgid="354495328188724404">"48.0 kHz"</item>
+    <item msgid="7329816882213695083">"88.2 kHz"</item>
+    <item msgid="6967397666254430476">"96.0 kHz"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_bits_per_sample_titles">
+    <item msgid="2684127272582591429">"ସିଷ୍ଟମ୍‌ର ଚୟନ (ପୂର୍ବ-ନିର୍ଦ୍ଧାରିତ) ବ୍ୟବହାର କରନ୍ତୁ"</item>
+    <item msgid="5618929009984956469">"16 ବିଟ୍ସ/ସାମ୍ପଲ୍‌"</item>
+    <item msgid="3412640499234627248">"24 ବିଟ୍ସ/ନମୁନା"</item>
+    <item msgid="121583001492929387">"32 ବିଟସ୍‌/ନମୂନା"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_bits_per_sample_summaries">
+    <item msgid="1081159789834584363">"ସିଷ୍ଟମ୍‌ ମନୋନୟନ (ଡିଫଲ୍ଟ) ବ୍ୟବହାର କରନ୍ତୁ"</item>
+    <item msgid="4726688794884191540">"୧୬ ବିଟସ୍‌/ନମୁନା"</item>
+    <item msgid="305344756485516870">"24 ବିଟସ୍‌/ନମୂନା"</item>
+    <item msgid="244568657919675099">"32 ବିଟସ୍‌/ନମୁନା"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_channel_mode_titles">
+    <item msgid="5226878858503393706">"ସିଷ୍ଟମ୍ ଚୟନ ବ୍ୟବହାର କରନ୍ତୁ (ଡିଫଲ୍ଟ)"</item>
+    <item msgid="4106832974775067314">"ମୋନୋ"</item>
+    <item msgid="5571632958424639155">"ଷ୍ଟେରିଓ"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_channel_mode_summaries">
+    <item msgid="4118561796005528173">"ସିଷ୍ଟମ୍ ଚୟନ ବ୍ୟବହାର କରନ୍ତୁ(ପୂର୍ବ-ନିର୍ଦ୍ଧାରିତ)"</item>
+    <item msgid="8900559293912978337">"ମୋନୋ"</item>
+    <item msgid="8883739882299884241">"ଷ୍ଟେରିଓ"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
+    <item msgid="7158319962230727476">"ଅଡିଓ ଗୁଣବତ୍ତା ପାଇଁ ଅନୁକୂଳିତ(990kbps/909kbps)"</item>
+    <item msgid="2921767058740704969">"ସନ୍ତୁଳିତ ଅଡିଓ ଓ ସଂଯୋଗ ଗୁଣବତ୍ତା (660kbps/606kbps)"</item>
+    <item msgid="8860982705384396512">"ସଂଯୋଗର ଗୁଣବତ୍ତା (330kbps/303kbps) ପାଇଁ ଉପଯୁକ୍ତ କରାଯାଇଛି"</item>
+    <item msgid="4414060457677684127">"ସର୍ବୋତ୍ତମ ପ୍ରୟାସ (ଅନୁକୁଳ ବିଟ୍‌ ରେଟ୍‌)"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
+    <item msgid="6398189564246596868">"ଅଡିଓର ଗୁଣବତ୍ତା ପାଇଁ ଅନୁକୂଳିତ"</item>
+    <item msgid="4327143584633311908">"ସନ୍ତୁଳିତ ଅଡିଓ ଓ ସଂଯୋଗ କ୍ୱାଲିଟୀ"</item>
+    <item msgid="4681409244565426925">"ସଂଯୋଗର ଗୁଣବତ୍ତା ପାଇଁ ଅନୁକୂଳିତ"</item>
+    <item msgid="364670732877872677">"ସର୍ବୋତ୍ତମ ପ୍ରୟାସ (ଅନୁକୂଳ ବିଟ୍‌ ରେଟ୍‌)"</item>
+  </string-array>
+  <string-array name="select_logd_size_titles">
+    <item msgid="8665206199209698501">"ଅଫ୍"</item>
+    <item msgid="1593289376502312923">"64K"</item>
+    <item msgid="487545340236145324">"256K"</item>
+    <item msgid="2423528675294333831">"1M"</item>
+    <item msgid="180883774509476541">"4M"</item>
+    <item msgid="2803199102589126938">"16M"</item>
+  </string-array>
+  <string-array name="select_logd_size_lowram_titles">
+    <item msgid="6089470720451068364">"ବନ୍ଦ"</item>
+    <item msgid="4622460333038586791">"64K"</item>
+    <item msgid="2212125625169582330">"256K"</item>
+    <item msgid="1704946766699242653">"1M"</item>
+  </string-array>
+  <string-array name="select_logd_size_summaries">
+    <item msgid="6921048829791179331">"ବନ୍ଦ"</item>
+    <item msgid="2969458029344750262">"64K ପିଛା ଲଗ୍‌ ବଫର୍‌"</item>
+    <item msgid="1342285115665698168">"256K ଲଗ୍‌ ପ୍ରତି ବଫର୍‌"</item>
+    <item msgid="1314234299552254621">"ଲଗ୍‌ ବଫର୍‌ ପ୍ରତି 1M"</item>
+    <item msgid="3606047780792894151">"ଲଗ୍‌ ବଫର୍‌ ପ୍ରତି 4M"</item>
+    <item msgid="5431354956856655120">"16M ଲଗ ପିଛା ବଫର୍‌"</item>
+  </string-array>
+  <string-array name="select_logpersist_titles">
+    <item msgid="1744840221860799971">"ବନ୍ଦ"</item>
+    <item msgid="3054662377365844197">"ସମସ୍ତ"</item>
+    <item msgid="688870735111627832">"ରେଡିଓ ଛଡ଼ା ଅନ୍ୟ ସବୁ"</item>
+    <item msgid="2850427388488887328">"କେବଳ କର୍ନେଲ୍"</item>
+  </string-array>
+  <string-array name="select_logpersist_summaries">
+    <item msgid="2216470072500521830">"ଅଫ"</item>
+    <item msgid="172978079776521897">"ସମସ୍ତ ଲଗ୍‌ ବଫର୍‌"</item>
+    <item msgid="3873873912383879240">"ରେଡିଓ ଲଗ୍‌ ବଫର୍‌‌ଗୁଡିକ ଛଡ଼ା ଅନ୍ୟ ସବୁ"</item>
+    <item msgid="8489661142527693381">"କେବଳ କର୍ନେଲ୍‌ ଲଗ୍‌ ବଫର୍‌"</item>
+  </string-array>
+  <string-array name="window_animation_scale_entries">
+    <item msgid="8134156599370824081">"ଆନିମେଶନ୍‌ ବନ୍ଦ କରନ୍ତୁ"</item>
+    <item msgid="6624864048416710414">"ଆନିମେଶନ ସ୍କେଲ .5x"</item>
+    <item msgid="2219332261255416635">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ 1x"</item>
+    <item msgid="3544428804137048509">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ 1.5x"</item>
+    <item msgid="3110710404225974514">"ଆନିମେଶନ ସ୍କେଲ 2x"</item>
+    <item msgid="4402738611528318731">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ 5x"</item>
+    <item msgid="6189539267968330656">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ 10x"</item>
+  </string-array>
+  <string-array name="transition_animation_scale_entries">
+    <item msgid="8464255836173039442">"ଆନିମେଶନ୍‌ ବନ୍ଦ କରନ୍ତୁ"</item>
+    <item msgid="3375781541913316411">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ .5x"</item>
+    <item msgid="1991041427801869945">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ 1x"</item>
+    <item msgid="4012689927622382874">"ଆନିମେସନ୍‌ ସ୍କେଲ 1.5x"</item>
+    <item msgid="3289156759925947169">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ 2x"</item>
+    <item msgid="7705857441213621835">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ 5x"</item>
+    <item msgid="6660750935954853365">"ଆନିମେସନ୍‌ ସ୍କେଲ୍‌ 10x"</item>
+  </string-array>
+  <string-array name="animator_duration_scale_entries">
+    <item msgid="6039901060648228241">"ଆନିମେଶନ୍ ବନ୍ଦ"</item>
+    <item msgid="1138649021950863198">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ .5x"</item>
+    <item msgid="4394388961370833040">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ 1x"</item>
+    <item msgid="8125427921655194973">"ଆନିମେଶନ୍ ସ୍କେଲ୍ 1.5x"</item>
+    <item msgid="3334024790739189573">"ଆନିମେଶନ୍ ସ୍କେଲ୍ 2x"</item>
+    <item msgid="3170120558236848008">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ 5x"</item>
+    <item msgid="1069584980746680398">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ 10x"</item>
+  </string-array>
+  <string-array name="overlay_display_devices_entries">
+    <item msgid="1606809880904982133">"କିଛି ନାହିଁ"</item>
+    <item msgid="9033194758688161545">"480p"</item>
+    <item msgid="1025306206556583600">"480p (ସୁରକ୍ଷିତ)"</item>
+    <item msgid="1853913333042744661">"p"</item>
+    <item msgid="3414540279805870511">"720p (ସୁରକ୍ଷିତ)"</item>
+    <item msgid="9039818062847141551">"1080p"</item>
+    <item msgid="4939496949750174834">"1080p (ସୁରକ୍ଷିତ)"</item>
+    <item msgid="1833612718524903568">"4K"</item>
+    <item msgid="238303513127879234">"4K (ସୁରକ୍ଷିତ)"</item>
+    <item msgid="3547211260846843098">"4K (ଅପ୍‌ସ୍କେଲ୍‌ କରାଯାଇଛି)"</item>
+    <item msgid="5411365648951414254">"4K (ଉତ୍ତମ, ସୁରକ୍ଷିତ)"</item>
+    <item msgid="1311305077526792901">"720p, 1080p (ଡୁଆଲ୍ ସ୍କ୍ରୀନ୍‌)"</item>
+  </string-array>
+  <string-array name="enable_opengl_traces_entries">
+    <item msgid="3191973083884253830">"କିଛିନାହିଁ"</item>
+    <item msgid="9089630089455370183">"Logcat"</item>
+    <item msgid="5397807424362304288">"Systrace (ଗ୍ରାଫିକ୍ସ)"</item>
+    <item msgid="1340692776955662664">"glGetError ରେ କଲ୍‌ ଷ୍ଟାକ୍"</item>
+  </string-array>
+  <string-array name="show_non_rect_clip_entries">
+    <item msgid="993742912147090253">"ଅଫ୍"</item>
+    <item msgid="675719912558941285">"ଅଣ-ଆୟତାକାର କ୍ଲିପ୍ କ୍ଷେତ୍ର ନୀଳ ରଙ୍ଗରେ ଆଙ୍କନ୍ତୁ"</item>
+    <item msgid="1064373276095698656">"ଟେଷ୍ଟ ହୋଇଥିବା ଅଙ୍କନ କମାଣ୍ଡଗୁଡ଼ିକୁ ସବୁଜରେ ଚିହ୍ନିତ କରନ୍ତୁ"</item>
+  </string-array>
+  <string-array name="track_frame_time_entries">
+    <item msgid="2193584639058893150">"ବନ୍ଦ"</item>
+    <item msgid="2751513398307949636">"ସ୍କ୍ରୀନ୍‌ରେ ବାର୍‌ ପରି"</item>
+    <item msgid="2355151170975410323">"ରେ <xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g>"</item>
+  </string-array>
+  <string-array name="debug_hw_overdraw_entries">
+    <item msgid="8190572633763871652">"ଅଫ୍"</item>
+    <item msgid="7688197031296835369">"ଓଭର୍‌ ଡ୍ର କ୍ଷେତ୍ରଗୁଡ଼ିକୁ ଦେଖାଅ"</item>
+    <item msgid="2290859360633824369">"ଡିଉଟେରାନୋମାଲୀ ପାଇଁ କ୍ଷେତ୍ର ଦେଖନ୍ତୁ"</item>
+  </string-array>
+  <string-array name="app_process_limit_entries">
+    <item msgid="3401625457385943795">"ମାନକ ସୀମା"</item>
+    <item msgid="4071574792028999443">"କୌଣସି ବ୍ୟାକ୍‌ଗ୍ରାଉଣ୍ଡ ପ୍ରୋସେସ୍ ଚାଲୁନାହିଁ"</item>
+    <item msgid="4810006996171705398">"ସର୍ବାଧିକ 1ଟି ପ୍ରକ୍ରିୟା"</item>
+    <item msgid="8586370216857360863">"ସର୍ବାଧିକ 2 ଟି ପ୍ରକ୍ରିୟା"</item>
+    <item msgid="836593137872605381">"ଅତିବେଶୀରେ 3ଟି ପ୍ରକ୍ରିୟା"</item>
+    <item msgid="7899496259191969307">"ସର୍ବାଧିକ 4 ଟି ପ୍ରକ୍ରିୟା"</item>
+  </string-array>
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"ଚାର୍ଜ ହେଉଛି"</item>
+    <item msgid="5220695614993094977">"MTP (ମିଡିଆ ସ୍ଥାନାନ୍ତର ପ୍ରୋଟୋକଲ୍‌)"</item>
+    <item msgid="2086000968159047375">"PTP (ପିକଚର୍‌ ଟ୍ରାନ୍ସଫର୍‌ ପ୍ରୋଟୋକଲ୍‌)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB ଏଥରନେଟ)"</item>
+    <item msgid="1718924214939774352">"ଅଡିଓ ଉତ୍ସ"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
+</resources>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
new file mode 100644
index 0000000..0c2cbda
--- /dev/null
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -0,0 +1,466 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2015 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_fail_to_scan" msgid="1265540342578081461">"ନେଟ୍‌ୱର୍କଗୁଡ଼ିକୁ ଖୋଜିପାରୁନାହିଁ"</string>
+    <string name="wifi_security_none" msgid="7985461072596594400">"କିଛି ନାହିଁ"</string>
+    <string name="wifi_remembered" msgid="4955746899347821096">"ସେଭ୍‌ ହୋଇଗଲା"</string>
+    <string name="wifi_disabled_generic" msgid="4259794910584943386">"ଅକ୍ଷମ ହୋଇଛି"</string>
+    <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP କନଫିଗରେଶନ ବିଫଳ ହୋଇଛି"</string>
+    <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"ନିମ୍ନ ମାନର ନେଟ୍‌ୱର୍କ କାରଣରୁ ସଂଯୁକ୍ତ ହୋଇନାହିଁ"</string>
+    <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"ୱାଇଫାଇ ସଂଯୋଗ ବିଫଳ ହୋଇଛି"</string>
+    <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"ସତ୍ୟାପନରେ ସମସ୍ୟା"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"ସଂଯୋଗ କରିପାରିବ ନାହିଁ"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' ସହିତ ସଂଯୁକ୍ତ ହୋଇପାରୁନାହିଁ"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"ପାସ୍‌ୱର୍ଡ ଯାଞ୍ଚ କରନ୍ତୁ ଏବଂ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
+    <string name="wifi_not_in_range" msgid="1136191511238508967">"ପରିସୀମାରେ ନାହିଁ"</string>
+    <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"ସ୍ୱଚାଳିତ ଭାବେ ସଂଯୁକ୍ତ ହେବନାହିଁ"</string>
+    <string name="wifi_no_internet" msgid="4663834955626848401">"ଇଣ୍ଟରନେଟ୍‌ର କୌଣସି ଆକ୍‌ସେସ୍‌ ନାହିଁ"</string>
+    <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> ଦ୍ୱାରା ସେଭ କରାଯାଇଛି"</string>
+    <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s ମାଧ୍ୟମରେ ଅଟୋମେଟିକାଲୀ ସଂଯୁକ୍ତ"</string>
+    <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"ନେଟୱର୍କ ମୂଲ୍ୟାୟନ ପ୍ରଦାତାଙ୍କ ମାଧ୍ୟମରେ ଅଟୋମେଟିକାଲ୍ୟ ସଂଯୁକ୍ତ"</string>
+    <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ମାଧ୍ୟମରେ ସଂଯୁକ୍ତ"</string>
+    <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ମାଧ୍ୟମରେ ଉପଲବ୍ଧ"</string>
+    <string name="wifi_connected_no_internet" msgid="8202906332837777829">"ସଂଯୁକ୍ତ, ଇଣ୍ଟର୍‌ନେଟ୍‌ ନାହିଁ"</string>
+    <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ଆକ୍ସେସ୍ ପଏଣ୍ଟ ସାମୟିକ ଭାବେ ପୂର୍ଣ୍ଣ"</string>
+    <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s ମାଧ୍ୟମରେ ସଂଯୁକ୍ତ"</string>
+    <string name="available_via_carrier" msgid="1469036129740799053">"%1$s ମାଧ୍ୟମରେ ଉପଲବ୍ଧ"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"ବହୁତ ମନ୍ଥର"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"କମ୍‌ ବେଗ"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"ଠିକ୍‌ ଅଛି"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"ମଧ୍ୟମ"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"ଦ୍ରୁତ"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"ଅତି ଦ୍ରୁତ"</string>
+    <string name="preference_summary_default_combination" msgid="8532964268242666060">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
+    <string name="bluetooth_disconnected" msgid="6557104142667339895">"ବିଛିନ୍ନ ହେଲା"</string>
+    <string name="bluetooth_disconnecting" msgid="8913264760027764974">"ବିଚ୍ଛିନ୍ନ କରୁଛି…"</string>
+    <string name="bluetooth_connecting" msgid="8555009514614320497">"ସଂଯୋଗ କରାଯାଉଛି…"</string>
+    <!-- no translation found for bluetooth_connected (5427152882755735944) -->
+    <skip />
+    <string name="bluetooth_pairing" msgid="1426882272690346242">"ପେୟାର୍‌ କରୁଛି…"</string>
+    <!-- no translation found for bluetooth_connected_no_headset (616068069034994802) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_a2dp (3736431800395923868) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_map (3200033913678466453) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp (2047403011284187056) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_battery_level (5162924691231307748) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_headset_battery_level (1610296229139400266) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (3908466636369853652) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1163440823807659316) -->
+    <skip />
+    <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"ମିଡିଆ ଅଡିଓ"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ଫୋନ୍‌ କଲ୍‌‌ଗୁଡ଼ିକ"</string>
+    <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ଫାଇଲ୍‌ ଟ୍ରାନ୍ସଫର୍‌"</string>
+    <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ଇନ୍‌ପୁଟ୍‌ ଡିଭାଇସ୍"</string>
+    <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ଇଣ୍ଟର୍‌ନେଟ୍‌ ଆକ୍ସେସ୍"</string>
+    <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"ଯୋଗାଯୋଗ ଶେୟାରିଙ୍ଗ"</string>
+    <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"ଯୋଗାଯୋଗ ଶେୟାର୍‌ କରିବା ପାଇଁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ଇଣ୍ଟର୍‌ନେଟ୍‌ ସଂଯୋଗ ଶେୟାରିଙ୍ଗ"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"ଟେକ୍ସଟ୍ ମେସେଜ୍"</string>
+    <string name="bluetooth_profile_sap" msgid="5764222021851283125">"ସିମ୍‌ ଆକ୍ସେସ୍‌"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ଅଡିଓ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ଅଡିଓ"</string>
+    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
+    <skip />
+    <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"ମିଡିଆ ଅଡିଓ ସହ ସଂଯୁକ୍ତ"</string>
+    <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ଫୋନ୍‌ ଅଡିଓ ସହିତ ସଂଯୁକ୍ତ"</string>
+    <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ଫାଇଲ୍‌ ଟ୍ରାନ୍ସଫର୍‌ ସର୍ଭର୍‌ ସହ ସଂଯୁକ୍ତ"</string>
+    <string name="bluetooth_map_profile_summary_connected" msgid="8191407438851351713">"ମାନଚିତ୍ର ସହିତ ସଂଯୁକ୍ତ"</string>
+    <string name="bluetooth_sap_profile_summary_connected" msgid="8561765057453083838">"SAP ସହିତ ସଂଯୁକ୍ତ"</string>
+    <string name="bluetooth_opp_profile_summary_not_connected" msgid="1267091356089086285">"ଫାଇଲ୍‌ ଟ୍ରାନ୍ସଫର୍ ସର୍ଭର୍‍ ସହ ସଂଯୁକ୍ତ ହୋଇନାହିଁ"</string>
+    <string name="bluetooth_hid_profile_summary_connected" msgid="3381760054215168689">"ଇନ୍‌ପୁଟ୍‌ ଡିଇଭାସ୍‌ ସହ ସଂଯୁକ୍ତ"</string>
+    <string name="bluetooth_pan_user_profile_summary_connected" msgid="6436258151814414028">"ଆଭ୍ୟନ୍ତରୀଣ ଆକ୍ସେସ୍ ପାଇଁ ଡିଭାଇସ୍‌ ସହିତ ସଂଯୁକ୍ତ"</string>
+    <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1322694224800769308">"ଡିଭାଇସ୍‌‌ ସହ ସ୍ଥାନୀୟ ଇଣ୍ଟରନେଟ୍‌ ସଂଯୋଗ ଶେୟାର୍‌ କରାଯାଉଛି"</string>
+    <string name="bluetooth_pan_profile_summary_use_for" msgid="5736111170225304239">"ଇଣ୍ଟର୍‌ନେଟ୍‌ ଆକ୍ସେସ୍‌ ପାଇଁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"ମାନଚିତ୍ର ପାଇଁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"SIM ଆକସେସ୍‌ ପାଇଁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"ମିଡିଆ ଅଡିଓ ପାଇଁ ବ୍ୟବହାର କର"</string>
+    <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ଫୋନ୍‌ ଅଡିଓ ପାଇଁ ବ୍ୟବହାର କର"</string>
+    <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ଫାଇଲ୍‌ ଟ୍ରାନ୍ସଫର୍‌ ପାଇଁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ଇନ୍‌ପୁଟ୍‌ ପାଇଁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
+    <skip />
+    <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"ପେୟାର୍‌"</string>
+    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ପେୟାର୍‌"</string>
+    <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"କ୍ୟାନ୍ସଲ୍‌ କରନ୍ତୁ"</string>
+    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"ପେୟାରିଂ ଫଳରେ ସଂଯୁକ୍ତ ଥିବା ବେଳେ ଆପଣଙ୍କ ସମ୍ପର୍କଗୁଡ଼ିକୁ ଏବଂ କଲ୍‌ର ଇତିବୃତିକୁ ଆକସେସ୍‌ ମଞ୍ଜୁର ହୁଏ।"</string>
+    <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ସହ ପେୟାର୍‌ କରିହେଲା ନାହିଁ।"</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"ଏକ ଭୁଲ୍‌ PIN କିମ୍ବା ପାସକୀ କାରଣରୁ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ସହ ପେୟାର୍‌ କରିପାରିଲା ନାହିଁ।"</string>
+    <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ସହ ଯୋଗାଯୋଗ ସ୍ଥାପନା କରିପାରୁନାହିଁ।"</string>
+    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ଦ୍ୱାରା ପେୟାରିଙ୍ଗ ପାଇଁ ପ୍ରତ୍ୟାଖ୍ୟାନ କରିଦିଆଗଲା।"</string>
+    <string name="bluetooth_talkback_computer" msgid="4875089335641234463">"କମ୍ପ୍ୟୁଟର୍"</string>
+    <string name="bluetooth_talkback_headset" msgid="5140152177885220949">"ହେଡ୍‌ସେଟ୍‌"</string>
+    <string name="bluetooth_talkback_phone" msgid="4260255181240622896">"ଫୋନ୍‌"</string>
+    <string name="bluetooth_talkback_imaging" msgid="551146170554589119">"ଇମେଜିଙ୍ଗ"</string>
+    <string name="bluetooth_talkback_headphone" msgid="26580326066627664">"ହେଡ୍‌ଫୋନ୍‌"</string>
+    <string name="bluetooth_talkback_input_peripheral" msgid="5165842622743212268">"ଇନ୍‌ପୁଟ୍‌ ଉପକରଣ"</string>
+    <string name="bluetooth_talkback_bluetooth" msgid="5615463912185280812">"ବ୍ଲୁଟୂଥ୍‌"</string>
+    <string name="accessibility_wifi_off" msgid="1166761729660614716">"ୱାଇ-ଫାଇ ବନ୍ଦ।"</string>
+    <string name="accessibility_no_wifi" msgid="8834610636137374508">"ୱାଇଫାଇ ବିଚ୍ଛିନ୍ନ କରାଗଲା।"</string>
+    <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wifiର 1 ବାର"</string>
+    <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"ୱାଇ-ଫାଇର ଦୁଇଟି ବାର୍‌ ଅଛି।"</string>
+    <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"ୱାଇ-ଫାଇର ତିନୋଟି ବାର୍।"</string>
+    <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"ୱାଇ-ଫାଇର ସଙ୍କେତ ସର୍ବୋଚ୍ଚ।"</string>
+    <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"ଖୋଲା ନେଟୱର୍କ"</string>
+    <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"ସୁରକ୍ଷିତ ନେଟ୍‌ୱର୍କ"</string>
+    <string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
+    <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"କଢ଼ାଯାଇଥିବା ଆପ୍‌ଗୁଡ଼ିକ"</string>
+    <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"ଆପ୍‌ ଏବଂ ଉପଯୋଗକର୍ତ୍ତା ବାହାର କରାଗଲା"</string>
+    <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB ଟିଥରିଙ୍ଗ"</string>
+    <string name="tether_settings_title_wifi" msgid="3277144155960302049">"ପୋର୍ଟବଲ୍‌ ହଟସ୍ପଟ୍‌"</string>
+    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"ବ୍ଲୁଟୂଥ ଟିଥରିଙ୍ଗ"</string>
+    <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"ଟିଥର୍‌ କରୁଛି"</string>
+    <string name="tether_settings_title_all" msgid="8356136101061143841">"ଟିଥରିଙ୍ଗ ଓ ପୋର୍ଟବଲ୍ ହଟ୍‌ସ୍ପଟ୍‌"</string>
+    <string name="managed_user_title" msgid="8109605045406748842">"ସମସ୍ତ କାର୍ଯ୍ୟ ଆପ୍‌"</string>
+    <string name="user_guest" msgid="8475274842845401871">"ଅତିଥି"</string>
+    <string name="unknown" msgid="1592123443519355854">"ଅଜଣା"</string>
+    <string name="running_process_item_user_label" msgid="3129887865552025943">"ଉପଯୋଗକର୍ତ୍ତା: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="launch_defaults_some" msgid="313159469856372621">"କିଛି ପୂର୍ବ-ନିର୍ଦ୍ଧାରିତ ମାନ ସେଟ୍‌ ହୋଇଛି"</string>
+    <string name="launch_defaults_none" msgid="4241129108140034876">"କୌଣସି ପୂର୍ବ-ନିର୍ଦ୍ଧାରଣ ସେଟ୍‍ ହୋଇନାହିଁ"</string>
+    <string name="tts_settings" msgid="8186971894801348327">"ଲେଖା-ରୁ-କଥା ସେଟିଙ୍ଗ୍‌"</string>
+    <string name="tts_settings_title" msgid="1237820681016639683">"ଲେଖା-ରୁ-କଥା ଆଉଟ୍‌ପୁଟ୍‌"</string>
+    <string name="tts_default_rate_title" msgid="6030550998379310088">"ସ୍ପୀଚ୍‌ ଦର"</string>
+    <string name="tts_default_rate_summary" msgid="4061815292287182801">"ଲେଖା ପଢ଼ିବାର ବେଗ"</string>
+    <string name="tts_default_pitch_title" msgid="6135942113172488671">"ପିଚ୍‌"</string>
+    <string name="tts_default_pitch_summary" msgid="1944885882882650009">"ସଂଶ୍ଳେଷିତ ସ୍ପିଚ୍‌‌ର ଟୋନ୍‌ରେ ପ୍ରଭାବ ପକାଏ"</string>
+    <string name="tts_default_lang_title" msgid="8018087612299820556">"ଭାଷା"</string>
+    <string name="tts_lang_use_system" msgid="2679252467416513208">"ସିଷ୍ଟମ୍‌ ଭାଷା ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="tts_lang_not_selected" msgid="7395787019276734765">"ଭାଷା ମନୋନୀତ ନୁହେଁ"</string>
+    <string name="tts_default_lang_summary" msgid="5219362163902707785">"ପଢ଼ାଯାଇଥିବା ଲେଖା ପାଇଁ ଭାଷା-ନିର୍ଦ୍ଦିଷ୍ଟ ସ୍ୱର ସେଟ୍‌ କରେ"</string>
+    <string name="tts_play_example_title" msgid="7094780383253097230">"ଗୋଟିଏ ଉଦାହରଣକୁ ଶୁଣନ୍ତୁ"</string>
+    <string name="tts_play_example_summary" msgid="8029071615047894486">"ସ୍ପୀଚ୍‌ ସିନ୍ଥେସିସ୍‌ର ଏକ ଛୋଟ ନମୁନା ଶୁଣନ୍ତୁ"</string>
+    <string name="tts_install_data_title" msgid="4264378440508149986">"ଭଏସ୍‌ ଡାଟା ଇନ୍‌ଷ୍ଟଲ୍ କରନ୍ତୁ"</string>
+    <string name="tts_install_data_summary" msgid="5742135732511822589">"ସ୍ପୀଚ୍‌ ସିନ୍ଥେସିସ୍‌ ପାଇଁ ଆବଶ୍ୟକ ଭଏସ୍‌ ଡାଟା ଇନ୍‌ଷ୍ଟଲ୍‌ କରନ୍ତୁ"</string>
+    <string name="tts_engine_security_warning" msgid="8786238102020223650">"ପାସ୍‌ୱର୍ଡ ଓ କ୍ରେଡିଟ୍‌ କାର୍ଡ ନମ୍ୱର୍‌ଗୁଡ଼ିକ ଭଳି ବ୍ୟକ୍ତିଗତ ତଥ୍ୟ ସମେତ କୁହାଯିବାକୁ ଥିବା ସମସ୍ତ ଲେଖାକୁ, ସ୍ପୀଚ୍‌ ସିନ୍ଥେସିସ୍‌ ଇଞ୍ଜିନ୍‌ ସଂଗ୍ରହ କରିପାରେ। ଏହା, <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> ଇଞ୍ଜିନ୍‌ରୁ ଆସିଛି। ଏହି ସ୍ପୀଚ୍‌ ସିନ୍ଥେସିସ୍‌ ଇଞ୍ଜିନ୍‌ର ବ୍ୟବହାରକୁ ସକ୍ଷମ କରିବେ?"</string>
+    <string name="tts_engine_network_required" msgid="1190837151485314743">"ଟେକ୍ସଟ୍-ରୁ-କଥା ଆଉଟପୁଟ୍‌ ପାଇଁ ଏହି ଭାଷା ଏକ କାମକରୁଥିବା ନେଟୱାର୍କ ସଂଯୋଗ ଆବଶ୍ୟକ କରେ।"</string>
+    <string name="tts_default_sample_string" msgid="4040835213373086322">"ଏହା ହେଉଛି ସ୍ପୀଚ୍‌ ସିନ୍ଥେସିସ୍‌ର ଏକ ଉଦାହରଣ"</string>
+    <string name="tts_status_title" msgid="7268566550242584413">"ଡିଫଲ୍ଟ ଭାଷା ଷ୍ଟାଟସ୍"</string>
+    <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> ପୂର୍ଣ୍ଣରୂପେ ସମର୍ଥିତ"</string>
+    <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> ନେଟ୍‌ୱର୍କ ସଂଯୋଜନା ଆବଶ୍ୟକ କରେ"</string>
+    <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> ସପୋର୍ଟ କରୁ ନାହିଁ"</string>
+    <string name="tts_status_checking" msgid="5339150797940483592">"ଯାଞ୍ଚ କରାଯାଉଛି…"</string>
+    <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> ପାଇଁ ସେଟିଙ୍ଗ"</string>
+    <string name="tts_engine_settings_button" msgid="1030512042040722285">"ଇଞ୍ଜିନ୍‌ ସେଟିଙ୍ଗ ଆରମ୍ଭ କରନ୍ତୁ"</string>
+    <string name="tts_engine_preference_section_title" msgid="448294500990971413">"ନିଜ ପସନ୍ଦର ଇଞ୍ଜିନ୍‌"</string>
+    <string name="tts_general_section_title" msgid="4402572014604490502">"ସାଧାରଣ"</string>
+    <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"ସ୍ପୀଚ୍‌ର ପିଚ୍‌ ରିସେଟ୍‌ କରନ୍ତୁ"</string>
+    <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"ପିଚକୁ ରିସେଟ କରନ୍ତୁ, ଯେଉଁଠାରେ ଲେଖା, ଡିଫଲ୍ଟ ଭାବେ କୁହାଯାଏ।"</string>
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"ବହୁତ ମନ୍ଥର"</item>
+    <item msgid="4795095314303559268">"ମନ୍ଥର"</item>
+    <item msgid="8903157781070679765">"ସାମାନ୍ୟ"</item>
+    <item msgid="164347302621392996">"ଦ୍ରୁତ"</item>
+    <item msgid="5794028588101562009">"ଦ୍ରୁତତର"</item>
+    <item msgid="7163942783888652942">"ଅତି ଦ୍ରୁତ"</item>
+    <item msgid="7831712693748700507">"ଦ୍ରୁତ"</item>
+    <item msgid="5194774745031751806">"ଅତି ତୀବ୍ର"</item>
+    <item msgid="9085102246155045744">"ଦ୍ରୁତତ୍ତମ"</item>
+  </string-array>
+    <string name="choose_profile" msgid="6921016979430278661">"ପ୍ରୋଫାଇଲ୍‌ ବାଛନ୍ତୁ"</string>
+    <string name="category_personal" msgid="1299663247844969448">"ବ୍ୟକ୍ତିଗତ"</string>
+    <string name="category_work" msgid="8699184680584175622">"କାମ"</string>
+    <string name="development_settings_title" msgid="215179176067683667">"ଡେଭଲପର୍‌ଙ୍କ ପାଇଁ ବିକଳ୍ପମାନ"</string>
+    <string name="development_settings_enable" msgid="542530994778109538">"ଡେଭଲପର୍‌ ବିକଳ୍ପଗୁଡ଼ିକ ସକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="development_settings_summary" msgid="1815795401632854041">"ଆପ୍‌ର ବିକାଶ ପାଇଁ ବିକଳ୍ପମାନ ସେଟ୍‌ କରନ୍ତୁ"</string>
+    <string name="development_settings_not_available" msgid="4308569041701535607">"ଏହି ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ ଡେଭଲପରଙ୍କ ବିକଳ୍ପସମୂହ ଉପଲବ୍ଧ ନୁହେଁ"</string>
+    <string name="vpn_settings_not_available" msgid="956841430176985598">"VPN ସେଟିଙ୍ଗ ଏହି ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ ଉପଲବ୍ଧ ନୁହେଁ"</string>
+    <string name="tethering_settings_not_available" msgid="6765770438438291012">"ଏହି ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ ଟିଥରିଙ୍ଗ ସେଟିଙ୍ଗ ଉପଲବ୍ଧ ନାହିଁ"</string>
+    <string name="apn_settings_not_available" msgid="7873729032165324000">"ଆକ୍ସେସ୍‌ ପଏଣ୍ଟ ନାମର ସେଟିଙ୍ଗ ଏହି ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ ଉପଲବ୍ଧ ନାହିଁ"</string>
+    <string name="enable_adb" msgid="7982306934419797485">"USB ଡିବଗ୍‌ ହେଉଛି"</string>
+    <string name="enable_adb_summary" msgid="4881186971746056635">"USB ସଂଯୁକ୍ତ ହେବାବେଳେ ଡିବଗ୍‌ ମୋଡ୍‌"</string>
+    <string name="clear_adb_keys" msgid="4038889221503122743">"USB ଡିବଗିଙ୍ଗ ଅଧିକାରକୁ କାଢ଼ିଦିଅନ୍ତୁ"</string>
+    <string name="bugreport_in_power" msgid="7923901846375587241">"ବଗ୍‌ ରିପୋର୍ଟ ଶର୍ଟକଟ୍‌"</string>
+    <string name="bugreport_in_power_summary" msgid="1778455732762984579">"ତ୍ରୁଟି ରିପୋର୍ଟ ଦେବାପାଇଁ ପାୱର୍‌ ମେନୁରେ ଏକ ବଟନ୍‌ ଦେଖନ୍ତୁ"</string>
+    <string name="keep_screen_on" msgid="1146389631208760344">"ଜାଗ୍ରତ ରଖନ୍ତୁ"</string>
+    <string name="keep_screen_on_summary" msgid="2173114350754293009">"ଚାର୍ଜ ହେବାବେଳେ ସ୍କ୍ରୀନ୍‌ ଆଦୌ ବନ୍ଦ ହେବନାହିଁ"</string>
+    <string name="bt_hci_snoop_log" msgid="3340699311158865670">"ବ୍ଲୁଟୁଥ୍‌ HCI ସ୍ନୁପ୍‌ ଲଗ୍‌ ସକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="bt_hci_snoop_log_summary" msgid="730247028210113851">"ଗୋଟିଏ ଫାଇଲ୍‌ରେ ସମସ୍ତ ବ୍ଲୁଟୂଥ୍‌ HCI ପ୍ୟାକେଟ୍‌ଗୁଡିକୁ କ୍ୟାପଚର୍‌ କରନ୍ତୁ"</string>
+    <string name="oem_unlock_enable" msgid="6040763321967327691">"OEM ଅନଲକ୍‌ କରିବା"</string>
+    <string name="oem_unlock_enable_summary" msgid="4720281828891618376">"bootloaderକୁ ଅନ୍‌ଲକ୍‌ ହେବାର ଅନୁମତି ଦିଅନ୍ତୁ"</string>
+    <string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM ଅନଲକ୍‌ କରିବା ଅନୁମତି ଦେବେ?"</string>
+    <string name="confirm_enable_oem_unlock_text" msgid="5517144575601647022">"ଚେତାବନୀ: ଏହି ସେଟିଙ୍ଗ ଚାଲୁ ଥିବାବେଳେ ଡିଭାଇସ୍‌ର ସୁରକ୍ଷା ବୈଶିଷ୍ଟ୍ୟ କାମ କରିବ ନାହିଁ"</string>
+    <string name="mock_location_app" msgid="7966220972812881854">"ନକଲି ଲୋକେଶନ୍‌ ଆପ୍‌ର ଚୟନ କରନ୍ତୁ"</string>
+    <string name="mock_location_app_not_set" msgid="809543285495344223">"କୌଣସି ନକଲି ଲୋକେଶନ ଏପ ସେଟ କରାଯାଇନାହିଁ"</string>
+    <string name="mock_location_app_set" msgid="8966420655295102685">"ନକଲି ଲୋକେଶନ୍‌ ଆପ୍‌: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="debug_networking_category" msgid="7044075693643009662">"ନେଟ୍‌ୱର୍କିଙ୍ଗ"</string>
+    <string name="wifi_display_certification" msgid="8611569543791307533">"ୱାୟର୍‌ଲେସ୍‌ ଡିସ୍‌ପ୍ଲେ ସର୍ଟିଫିକେଶନ୍‌"</string>
+    <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi ଭରବୋସ୍‌ ଲଗିଙ୍ଗ ସକ୍ଷମ କରନ୍ତୁ"</string>
+    <!-- no translation found for wifi_connected_mac_randomization (3168165236877957767) -->
+    <skip />
+    <string name="mobile_data_always_on" msgid="8774857027458200434">"ମୋବାଇଲ୍‌ ଡାଟା ସର୍ବଦା ସକ୍ରିୟ"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ଟିଥରିଙ୍ଗ ହାର୍ଡୱେର ବେଗ"</string>
+    <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"ବ୍ଲୁଟୂଥ୍‌ ଡିଭାଇସ୍‌ଗୁଡ଼ିକୁ ନାମ ବିନା ଦେଖନ୍ତୁ"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ପୂର୍ଣ୍ଣ ଭଲ୍ୟୁମ୍‌ ଅକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ବ୍ଲୁଟୂଥ୍‌ AVRCP ଭର୍ସନ୍"</string>
+    <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ବ୍ଲୁଟୂଥ୍‌ AVRCP ଭର୍ସନ୍‌"</string>
+    <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ବ୍ଲୁଟୁଥ୍‌ ଅଡିଓ କୋଡେକ୍‌"</string>
+    <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ବ୍ଲୁଟୁଥ୍‌ ଅଡିଓ କୋଡେକ୍‌ ଚୟନ କରନ୍ତୁ"</string>
+    <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ବ୍ଲୁଟୂଥ୍‌ ଅଡିଓ ସାମ୍ପଲ୍‌ ରେଟ୍‌"</string>
+    <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5628790207448471613">"ବ୍ଲୁଟୁଥ୍‌ ଅଡିଓ କୋଡେକ୍ ଚୟନ କରନ୍ତୁ: \n ନମୁନା ଦର"</string>
+    <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="2099645202720164141">"ନମୁନା ପିଛା ବ୍ଲୁଟୁଥ୍‌ ଅଡିଓ ବିଟ୍ସ"</string>
+    <string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4546131401358681321">"ବ୍ଲୁଟୂଥ ଅଡିଓ କୋଡେକ୍‌ ବାଛନ୍ତୁ:\nନମୂନା ପ୍ରତି ବିଟସ୍‌"</string>
+    <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="884855779449390540">"ବ୍ଲୁଟୂଥ୍‌ ଅଡିଓ ଚ୍ୟାନେଲ୍‌ ମୋଡ୍"</string>
+    <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="9133545781346216071">"ବ୍ଲୁଟୂଥ୍‌ ଅଡ଼ିଓ କୋଡେକ୍‌:\nଚାନେଲ୍‌ ମୋଡ୍‌ ବାଛନ୍ତୁ"</string>
+    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"ବ୍ଲୁଟୁଥ୍‌ ଅଡିଓ LDAC କୋଡେକ୍‌: ପ୍ଲେବ୍ୟାକ୍‌ ଗୁଣବତ୍ତା"</string>
+    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"ବ୍ଲୁଟୂଥ୍‌ ଅଡିଓ LDAC କୋଡେକ୍‌ ବାଛନ୍ତୁ:\nପ୍ଲେବ୍ୟାକ୍‌ କ୍ୱାଲିଟୀ"</string>
+    <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ଷ୍ଟ୍ରିମ୍ କରୁଛି: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
+    <string name="select_private_dns_configuration_title" msgid="3700456559305263922">"ବ୍ୟକ୍ତିଗତ DNS"</string>
+    <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"ବ୍ୟକ୍ତିଗତ DNS ମୋଡ୍‌ ବାଛନ୍ତୁ"</string>
+    <string name="private_dns_mode_off" msgid="8236575187318721684">"ଅଫ୍"</string>
+    <string name="private_dns_mode_opportunistic" msgid="7608409735589131766">"ସୁଯୋଗବାଦୀ"</string>
+    <string name="private_dns_mode_provider" msgid="8354935160639360804">"ବ୍ୟକ୍ତିଗତ DNS ପ୍ରଦାତା ହୋଷ୍ଟନାମ"</string>
+    <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"DNS ପ୍ରଦାନକାରୀଙ୍କ ହୋଷ୍ଟନାମ ପ୍ରବେଶ କରନ୍ତୁ"</string>
+    <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ୱେୟାରଲେସ୍‌ ପ୍ରଦର୍ଶନ ସାର୍ଟିଫିକେସନ୍‌ ପାଇଁ ବିକଳ୍ପଗୁଡିକ ଦେଖାନ୍ତୁ"</string>
+    <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ୱାଇ-ଫାଇ ଲଗିଙ୍ଗ ସ୍ତର ବଢ଼ାନ୍ତୁ, ୱାଇ-ଫାଇ ପିକର୍‌ରେ ପ୍ରତି SSID RSSI ଦେଖାନ୍ତୁ"</string>
+    <!-- no translation found for wifi_connected_mac_randomization_summary (1743059848752201485) -->
+    <skip />
+    <string name="select_logd_size_title" msgid="7433137108348553508">"ଲଗର୍‌ ବଫର୍‌ ଆକାରଗୁଡ଼ିକ"</string>
+    <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"ଲଗ୍‌ ବଫର୍‌ ପିଛା ଲଗର୍‌ ଆକାରଗୁଡିକର ଚୟନ କରନ୍ତୁ"</string>
+    <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"ଲଗର୍‌ ରୋଧି ଷ୍ଟୋରେଜ୍‌ ଖାଲି କରିବେ?"</string>
+    <string name="dev_logpersist_clear_warning_message" msgid="2256582531342994562">"ଯଦି ଆମେ ଦୃଢ ଲଗର୍‌ ସହିତ ଆଉ ତଦାରଖ କରୁନଥିବୁ, ତେବେ ଆମକୁ ଆପଣଙ୍କ ଡିଭାଇସ୍‌ରେ ଥିବା ଲଗର୍‌ ଡାଟାକୁ ଲିଭାଇବାକୁ ପଡ଼ିବ।"</string>
+    <string name="select_logpersist_title" msgid="7530031344550073166">"ଡିଭାଇସ୍‌ରେ ଲଗାତର ଲଗର୍‌ ଡାଟା ଷ୍ଟୋର୍‌ କରନ୍ତୁ"</string>
+    <string name="select_logpersist_dialog_title" msgid="4003400579973269060">"ଡିଭାଇସ୍‌ରେ ଲଗାତର ଷ୍ଟୋର୍‌ କରିବାକୁ ଲଗ୍‌ ବଫର୍‌ ଚୟନ କରନ୍ତୁ"</string>
+    <string name="select_usb_configuration_title" msgid="2649938511506971843">"USB କନଫିଗ୍ୟୁରେସନ୍‌ ଚୟନ କରନ୍ତୁ"</string>
+    <string name="select_usb_configuration_dialog_title" msgid="6385564442851599963">"USB କନଫିଗ୍ୟୁରେସନ୍‌ ଚୟନ କରନ୍ତୁ"</string>
+    <string name="allow_mock_location" msgid="2787962564578664888">"ନକଲି ଲୋକେଶନ୍‌ର ଅନୁମତି ଦିଅନ୍ତୁ"</string>
+    <string name="allow_mock_location_summary" msgid="317615105156345626">"ନକଲି ଲୋକେଶନ୍‌ର ଅନୁମତି ଦିଅନ୍ତୁ"</string>
+    <string name="debug_view_attributes" msgid="6485448367803310384">"ବିଶେଷତା ଯାଞ୍ଚ ଦର୍ଶନ ସକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ୱାଇ-ଫାଇ ସକ୍ରିୟ ଥିଲେ ମଧ୍ୟ ସର୍ବଦା ମୋବାଇଲ୍‌ ଡାଟାକୁ ସକ୍ରିୟ ରଖନ୍ତୁ (ଦ୍ରୁତ ନେଟ୍‌ୱର୍କ ସ୍ୱିଚିଙ୍ଗ ପାଇଁ)।"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"ଯଦି ଉପଲବ୍ଧ ଥାଏ, ଟିଥରିଙ୍ଗ ହାର୍ଡୱେର୍‌ ଆକ୍ସଲରେଶନ୍‌ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="adb_warning_title" msgid="6234463310896563253">"USB ଡିବଗିଙ୍ଗ କରିବେ?"</string>
+    <string name="adb_warning_message" msgid="7316799925425402244">"USB ଡିବଗିଂ କେବଳ ଡେଭଲପମେଣ୍ଟ ଉଦ୍ଦେଶ୍ୟ ପାଇଁ ଉଦ୍ଦିଷ୍ଟ ଅଟେ। ଆପଣଙ୍କ କମ୍ପ୍ୟୁଟର ଏବଂ ଡିଭାଇସ୍‌ ମଧ୍ୟରେ ଡାଟା କପି କରିବାକୁ, ବିନା ବିଜ୍ଞପ୍ତିରେ ଆପଣଙ୍କ ଡିଭାଇସରେ ଆପସ୍‌ ସଂସ୍ଥାପନ କରିବାକୁ, ଏବଂ ଲଗ୍‌ ଡାଟା ପଢିବାକୁ ଏହା ବ୍ୟବହାର କରନ୍ତୁ।"</string>
+    <string name="adb_keys_warning_message" msgid="5659849457135841625">"ଅଧିକୃତ ସମସ୍ତ କମ୍ପ୍ୟୁଟରରୁ USB ଡିବଗ୍‌ କରିବା ଆକ୍ସେସ୍‌ ପ୍ରତ୍ୟାହାର କରିବେ କି?"</string>
+    <string name="dev_settings_warning_title" msgid="7244607768088540165">"ଡେଭଲପମେଣ୍ଟ ସେଟିଙ୍ଗ ଅନୁମତି ଦେବେ?"</string>
+    <string name="dev_settings_warning_message" msgid="2298337781139097964">"ଏହି ସେଟିଙ୍ଗଗୁଡ଼ିକ କେବଳ ବିକାଶ ବ୍ୟବହାର ପାଇଁ ଉଦ୍ଦିଷ୍ଟ। ସେଗୁଡ଼ିକ କାରଣରୁ ଆପଣଙ୍କ ଡିଭାଇସ୍‌ ଓ ଆପ୍ଲିକେଶନ୍‍‍ଗୁଡ଼ିକ ଠିକ୍‌ ଭାବେ କାମ ନକରିପାରେ।"</string>
+    <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB ଜରିଆରେ ଆପ୍‌ଗୁଡ଼ିକୁ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
+    <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ADB/ADT ମାଧ୍ୟମରେ ଇନଷ୍ଟଲ ହୋଇଥିବା ଆପ୍‌ଗୁଡ଼ିକ ହାନିକାରକ କାର୍ଯ୍ୟକଳାପ କରୁଛି କି ନାହିଁ ଯାଞ୍ଚ କରନ୍ତୁ।"</string>
+    <string name="bluetooth_show_devices_without_names_summary" msgid="2351196058115755520">"(କେବଳ MAC ଠିକଣା ଥାଇ) ନାମ ବିନା ବ୍ଲୁଟୂଥ ଡିଭାଇସଗୁଡ଼ିକ ପ୍ରଦର୍ଶିତ ହେବ"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"ରିମୋଟ୍‌ ଡିଭାଇସ୍‌ଗୁଡ଼ିକରେ ଯଦି ଅସ୍ୱୀକାର୍ଯ୍ୟ ଭାବେ ଉଚ୍ଚ ଭଲ୍ୟୁମ କିମ୍ବା ନିୟନ୍ତ୍ରଣର ଅଭାବ ପରି ଭଲ୍ୟୁମ ସମସ୍ୟା ଥାଏ ବ୍ଲୁଟୁଥ୍‌ ଆବସଲ୍ୟୁଟ୍‌ ଭଲ୍ୟୁମ ବୈଶିଷ୍ଟ୍ୟ ଅକ୍ଷମ କରେ।"</string>
+    <string name="enable_terminal_title" msgid="95572094356054120">"ସ୍ଥାନୀୟ ଟର୍ମିନାଲ୍‌"</string>
+    <string name="enable_terminal_summary" msgid="67667852659359206">"ସ୍ଥାନୀୟ ଶେଲ୍‌କୁ ଆକ‌ସେସ୍‌ ଦେଉଥିବା ଟର୍ମିନଲ୍‌ ଆପ୍‌କୁ ସକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP ଯାଞ୍ଚ କରୁଛି"</string>
+    <string name="hdcp_checking_dialog_title" msgid="5141305530923283">"HDCPର ଯାଞ୍ଚ ଗତିବିଧି ସେଟ୍‍ କରନ୍ତୁ"</string>
+    <string name="debug_debugging_category" msgid="6781250159513471316">"ଡିବଗ୍‌ କରୁଛି"</string>
+    <string name="debug_app" msgid="8349591734751384446">"ଡିବଗ୍‌ ଆପ୍‌ ବାଛି ନିଅନ୍ତୁ"</string>
+    <string name="debug_app_not_set" msgid="718752499586403499">"କୌଣସି ଡିବଗ୍‌ ଆପ୍ଲିକେଶନ୍‌ ସେଟ୍‌ ହୋଇନାହିଁ"</string>
+    <string name="debug_app_set" msgid="2063077997870280017">"ଆପ୍ଲିକେଶନ୍‌ ଡିବଗ୍‌ କରୁଛି: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="select_application" msgid="5156029161289091703">"ଆପ୍ଲିକେଶନ୍‌ ବାଛନ୍ତୁ"</string>
+    <string name="no_application" msgid="2813387563129153880">"କିଛି ନୁହେଁ"</string>
+    <string name="wait_for_debugger" msgid="1202370874528893091">"ଡିବଗର୍‌ ପାଇଁ ଅପେକ୍ଷା କରନ୍ତୁ"</string>
+    <string name="wait_for_debugger_summary" msgid="1766918303462746804">"ଡିବଗ୍‌ ହୋଇଥିବା ଆପ୍ଲିକେଶନ୍‍, ନିଷ୍ପାଦନ ପୂର୍ବରୁ ଆଟାଚ୍‌ କରିବା ପାଇଁ ଡିବଗର୍‌କୁ ଅପେକ୍ଷା କରେ"</string>
+    <string name="debug_input_category" msgid="1811069939601180246">"ଇନପୁଟ୍"</string>
+    <string name="debug_drawing_category" msgid="6755716469267367852">"ଅଙ୍କନ"</string>
+    <string name="debug_hw_drawing_category" msgid="6220174216912308658">"ହାର୍ଡୱେର୍‌ ଆକ୍ସଲରେଟେଡ୍ ରେଣ୍ଡରିଙ୍ଗ"</string>
+    <string name="media_category" msgid="4388305075496848353">"ମିଡିଆ"</string>
+    <string name="debug_monitoring_category" msgid="7640508148375798343">"ତଦାରାଖ କରିବା"</string>
+    <string name="strict_mode" msgid="1938795874357830695">"କଡ଼ା ମୋଡ୍ ସକ୍ଷମ କରାଯାଇଛି"</string>
+    <string name="strict_mode_summary" msgid="142834318897332338">"ମୁଖ୍ୟ ଥ୍ରେଡ୍‌ରେ ଆପ୍‌ ଦୀର୍ଘ ସମୟ କାର୍ଯ୍ୟ କରିବା ବେଳେ ସ୍କ୍ରିନ୍‌ ଫ୍ଲାସ୍‌ କରନ୍ତୁ"</string>
+    <string name="pointer_location" msgid="6084434787496938001">"ପଏଣ୍ଟର୍‌ ଲୋକେଶନ୍‌"</string>
+    <string name="pointer_location_summary" msgid="840819275172753713">"ଏବେର ଟଚ୍‌ ଡାଟା ଦେଖାଉଥିବା ସ୍କ୍ରୀନ୍‌ ଓଭର୍‌ଲେ"</string>
+    <string name="show_touches" msgid="2642976305235070316">"ଟାପ୍‌ଗୁଡ଼ିକୁ ଦେଖାଅ"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"ଟାପ୍ସ ପାଇଁ ଦୃଶ୍ୟ ମତାମତ ଦେଖାଅ"</string>
+    <string name="show_screen_updates" msgid="5470814345876056420">"ସର୍ଫେସ୍‌ ଅପ୍‌ଡେଟ୍‌ ଦେଖାଅ"</string>
+    <string name="show_screen_updates_summary" msgid="2569622766672785529">"ସମଗ୍ର ୱିଣ୍ଡୋ ପୃଷ୍ଠ ଅପଡେଟ୍‌ ହେବା ବେଳେ ସେଗୁଡ଼ିକ ଫ୍ଲାସ୍‌ କରନ୍ତୁ"</string>
+    <string name="show_hw_screen_updates" msgid="5036904558145941590">"GPU ଭ୍ୟୁ ଅପଡେଟ୍‌ ଦେଖନ୍ତୁ"</string>
+    <string name="show_hw_screen_updates_summary" msgid="1115593565980196197">"GPU ସହ ଅଙ୍କାଯାଇଥିବା ବେଳେ ୱିଣ୍ଡୋ ଭିତରେ ଦୃଶ୍ୟଗୁଡ଼ିକ ଫ୍ଲାଶ କରନ୍ତୁ"</string>
+    <string name="show_hw_layers_updates" msgid="5645728765605699821">"ହାର୍ଡୱେର୍‌ ଲେୟର୍‌ର ଅପଡେଟଗୁଡ଼ିକ ଦେଖାନ୍ତୁ"</string>
+    <string name="show_hw_layers_updates_summary" msgid="5296917233236661465">"ହାର୍ଡୱେୟାର ଲେୟାରଗୁଡିକ ଅପଡେଟ୍‌ ହେବା ବେଳେ ସେଗୁଡିକ ସବୁଜ ଫ୍ଲାସ୍‌ କରନ୍ତୁ"</string>
+    <string name="debug_hw_overdraw" msgid="2968692419951565417">"GPU ଓଭର୍‌ଡ୍ର ଡିବଗ୍‌ କର"</string>
+    <string name="disable_overlays" msgid="2074488440505934665">"HW ଓଭରଲେସ ଅକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="disable_overlays_summary" msgid="3578941133710758592">"ସ୍କ୍ରୀନ୍‌ କମ୍ପୋଜିଟିଙ୍ଗ ପାଇଁ ସର୍ବଦା GPU ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="simulate_color_space" msgid="6745847141353345872">"ରଙ୍ଗ ସ୍ଥାନ ଅନୁକରଣ କରନ୍ତୁ"</string>
+    <string name="enable_opengl_traces_title" msgid="6790444011053219871">"OpenGL ଟ୍ରେସ୍‌ ସକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="usb_audio_disable_routing" msgid="8114498436003102671">"USB ଅଡିଓ ରାଉଟିଙ୍ଗ ଅକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="usb_audio_disable_routing_summary" msgid="980282760277312264">"USB ଅଡିଓ ଉପକରଣଗୁଡ଼ିକୁ ଅଟୋମେଟିକ୍ ରୂଟିଙ୍ଗ ଅକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="debug_layout" msgid="5981361776594526155">"ଲେଆଉଟ୍‌ ବାଉଣ୍ଡ ଦେଖାଅ"</string>
+    <string name="debug_layout_summary" msgid="2001775315258637682">"କ୍ଲିପ୍‌ ବାଉଣ୍ଡ, ମାର୍ଜିନ୍‌ ଆଦି ଦେଖନ୍ତୁ"</string>
+    <string name="force_rtl_layout_all_locales" msgid="2259906643093138978">"RTL ଲେଆଉଟ୍ ଦିଗ ବାଧ୍ୟ କରନ୍ତୁ"</string>
+    <string name="force_rtl_layout_all_locales_summary" msgid="9192797796616132534">"ସମସ୍ତ ଲୋକେଲ୍‌ ପାଇଁ ସ୍କ୍ରିନ୍‌ ଲେଆଉଟ୍‌ ଦିଗ ଡାହାଣରୁ ବାମକୁ ବାଧ୍ୟ କରନ୍ତୁ"</string>
+    <string name="force_hw_ui" msgid="6426383462520888732">"GPU ରେଣ୍ଡରିଂ ବାଧ୍ୟ କରନ୍ତୁ"</string>
+    <string name="force_hw_ui_summary" msgid="5535991166074861515">"2D ଅଙ୍କନ ପାଇଁ ଜିପିୟୁର ବ୍ୟବହାର ଉପରେ ଜୋର ଦେବା"</string>
+    <string name="force_msaa" msgid="7920323238677284387">"4x MSAA ବାଧ୍ୟ କରନ୍ତୁ"</string>
+    <string name="force_msaa_summary" msgid="9123553203895817537">"OpenGL ES 2.0 ଆପ୍‌ରେ 4x MSAA ସକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="show_non_rect_clip" msgid="505954950474595172">"ଅଣ-ଆୟତାକାର କ୍ଲିପ୍‌ କାର୍ଯ୍ୟକୁ ଡିବଗ୍‌ କରନ୍ତୁ"</string>
+    <string name="track_frame_time" msgid="6146354853663863443">"ପ୍ରୋଫାଇଲ୍‌ GPU ରେଣ୍ଡରିଂ"</string>
+    <string name="enable_gpu_debug_layers" msgid="3848838293793255097">"GPU ଡିବଗ୍‌ ଲେୟର୍‌ ସକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="enable_gpu_debug_layers_summary" msgid="8009136940671194940">"ଡିବଗ୍‌ ଆପ୍‌ଗୁଡ଼ିକ ପାଇଁ GPU ଡିବଗ୍‌ ଲେୟର୍‌ ଲୋଡ୍ କରିବାର ଅନୁମତି ଦିଅନ୍ତୁ"</string>
+    <string name="window_animation_scale_title" msgid="6162587588166114700">"ୱିଣ୍ଡୋ ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌"</string>
+    <string name="transition_animation_scale_title" msgid="387527540523595875">"ଟ୍ରାଞ୍ଜିସନ୍‌ ଆନିମେସନ୍‌ ସ୍କେଲ୍‌"</string>
+    <string name="animator_duration_scale_title" msgid="3406722410819934083">"ଆନିମେଟର୍‌ ଅବଧି ସ୍କେଲ୍‌"</string>
+    <string name="overlay_display_devices_title" msgid="5364176287998398539">"ମଧ୍ୟମ ଡିସ୍‌ପ୍ଲେର ଛଳନା କରନ୍ତୁ"</string>
+    <string name="debug_applications_category" msgid="4206913653849771549">"ଆପ୍‌ଗୁଡ଼ିକ"</string>
+    <string name="immediately_destroy_activities" msgid="1579659389568133959">"କାର୍ଯ୍ୟକଳାପଗୁଡ଼ିକୁ ରଖନ୍ତୁ ନାହିଁ"</string>
+    <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"ଉପଯୋଗକର୍ତ୍ତା ଏହାକୁ ଛାଡ଼ିବା କ୍ଷଣି ସମସ୍ତ କାର୍ଯ୍ୟକଳାପକୁ ନଷ୍ଟ କରିଦିଅନ୍ତୁ"</string>
+    <string name="app_process_limit_title" msgid="4280600650253107163">"ପୃଷ୍ଠପଟ ପ୍ରକ୍ରିୟା ସୀମା"</string>
+    <string name="show_all_anrs" msgid="28462979638729082">"ସମସ୍ତ ANRs ଦେଖାଦେଉ"</string>
+    <string name="show_all_anrs_summary" msgid="641908614413544127">"ବ୍ୟାକ୍‌ଗ୍ରାଉଣ୍ଡ ଆପ୍‌ଗୁଡ଼ିକ ପାଇଁ \"ଆପ୍‌ ଉତ୍ତର ଦେଉନାହିଁ\" ଡାୟଲଗ୍‌ ଦେଖାଅ"</string>
+    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"ବିଜ୍ଞପ୍ତି ଚାନେଲ୍‌ ଚେତାବନୀ ଦେଖାଦେଉ"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"ଏକ ବୈଧ ଚ୍ୟାନେଲ୍‌ ବିନା ଏକ ଆପ୍‌ ଗୋଟିଏ ବିଜ୍ଞପ୍ତି ପୋଷ୍ଠ କରିବା ବେଳେ ଅନ୍‌-ସ୍କ୍ରୀନ୍‌ ସତର୍କତା ଦେଖାଏ"</string>
+    <string name="force_allow_on_external" msgid="3215759785081916381">"ଏକ୍ସଟର୍ନଲ୍ ଆପ୍‌ଗୁଡ଼ିକୁ ଜବରଦସ୍ତି ଅନୁମତି ଦିଅନ୍ତୁ"</string>
+    <string name="force_allow_on_external_summary" msgid="3640752408258034689">"ଯେକୌଣସି ଆପ୍‌କୁ ଏକ୍ସଟର୍ନଲ୍ ଷ୍ଟୋରେଜ୍‌ରେ ଲେଖାଯୋଗ୍ୟ କରନ୍ତୁ, ମେନିଫେଷ୍ଟ ମୂଲ୍ୟ ଯାହା ହୋଇଥାଉ ନା କାହିଁକି"</string>
+    <string name="force_resizable_activities" msgid="8615764378147824985">"ଆକାର ବଦଳାଇବା ପାଇଁ କାର୍ଯ୍ୟକଳାପକୁ ବାଧ୍ୟ କରନ୍ତୁ"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"ସ୍ପଷ୍ଟ ଭାଲ୍ୟୁର ଚିନ୍ତା ନକରି ମଲ୍ଟୀ-ୱିଣ୍ଡୋ ପାଇଁ ସମସ୍ତ କାର୍ଯ୍ୟ ବଦଳାଇବାଯୋଗ୍ୟ କରନ୍ତୁ"</string>
+    <string name="enable_freeform_support" msgid="1461893351278940416">"ଫ୍ରୀଫର୍ମ ୱିଣ୍ଡୋ ସକ୍ଷମ କର"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"ପରୀକ୍ଷାମୂଳକ ଫ୍ରୀଫର୍ମ ୱିଣ୍ଡୋସ୍‌ ପାଇଁ ସପୋର୍ଟ ସକ୍ଷମ କରନ୍ତୁ।"</string>
+    <string name="local_backup_password_title" msgid="3860471654439418822">"ଡେସ୍କଟପ୍‌ ବ୍ୟାକ୍‌ଅପ୍‌ର ପାସ୍‌ୱର୍ଡ"</string>
+    <string name="local_backup_password_summary_none" msgid="6951095485537767956">"ଡେସ୍କଟପ୍‌ ପୂର୍ଣ୍ଣ ବ୍ୟାକ୍‌ଅପ୍‌ଗୁଡ଼ିକ ବର୍ତ୍ତମାନ ସୁରକ୍ଷିତ ନୁହେଁ"</string>
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"ଡେସ୍କଟପ୍‌ର ସମ୍ପୂର୍ଣ୍ଣ ବ୍ୟାକ୍‌ଅପ୍‌ ପାଇଁ ପାସ୍‌ୱର୍ଡ ବଦଳାଇବା କିମ୍ୱା କାଢ଼ିଦେବା ନିମନ୍ତେ ଟାପ୍‌ କରନ୍ତୁ"</string>
+    <string name="local_backup_password_toast_success" msgid="582016086228434290">"ନୂଆ ବ୍ୟାକ୍‌ଅପ୍‌ ପାସ୍‌ୱର୍ଡ ସେଟ୍‌ କରିଦିଆଗଲା"</string>
+    <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"ନୂଆ ପାସ୍‌ୱର୍ଡ ଓ ସୁନିଶ୍ଚିତତା ମେଳ ହେଉନାହିଁ"</string>
+    <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"ବ୍ୟାକ୍‌ଅପ୍‌ ପାସ୍‌ୱର୍ଡ ସେଟିଙ୍ଗ ବିଫଳ ହୋଇଛି"</string>
+  <string-array name="color_mode_names">
+    <item msgid="2425514299220523812">"ଜୀବନ୍ତ (ପୂର୍ବ-ନିର୍ଦ୍ଧାରିତ)"</item>
+    <item msgid="8446070607501413455">"ପ୍ରାକୃତିକ"</item>
+    <item msgid="6553408765810699025">"ମାନକ"</item>
+  </string-array>
+  <string-array name="color_mode_descriptions">
+    <item msgid="4979629397075120893">"ବର୍ଦ୍ଧିତ ରଙ୍ଗ"</item>
+    <item msgid="8280754435979370728">"ଆଖି ଦ୍ୱାରା ଦେଖାଯାଇଥିବା ପରି ପ୍ରାକୃତିକ ରଙ୍ଗ"</item>
+    <item msgid="5363960654009010371">"ଡିଜିଟାଲ୍‌ କଣ୍ଟେଣ୍ଟ ପାଇଁ ରଙ୍ଗଗୁଡ଼ିକ ଅନୁକୂଳିତ ହୋଇଛି"</item>
+  </string-array>
+    <!-- no translation found for inactive_apps_title (9042996804461901648) -->
+    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"ନିଷ୍କ୍ରିୟ। ଟୋଗଲ୍‌ କରିବାକୁ ଟାପ୍‌ କରନ୍ତୁ।"</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"ସକ୍ରିୟ। ବଦଳାଇବା ପାଇଁ ଟାପ୍‌ କରନ୍ତୁ"</string>
+    <!-- no translation found for standby_bucket_summary (6567835350910684727) -->
+    <skip />
+    <string name="runningservices_settings_title" msgid="8097287939865165213">"ଚାଲୁଥିବା ସେବାଗୁଡ଼ିକ"</string>
+    <string name="runningservices_settings_summary" msgid="854608995821032748">"ଏବେ ଚାଲୁଥିବା ସେବାଗୁଡ଼ିକୁ ଦେଖନ୍ତୁ ଓ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ"</string>
+    <string name="select_webview_provider_title" msgid="4628592979751918907">"ୱେବ୍‌ଦୃଶ୍ୟ ପ୍ରୟୋଗ"</string>
+    <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView କାର୍ଯ୍ୟକାରିତାକୁ ସେଟ୍‍ କରନ୍ତୁ"</string>
+    <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"ଏହି ପସନ୍ଦ ଆଉ ମାନ୍ୟ ନାହିଁ। ପୁଣିଥରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
+    <string name="convert_to_file_encryption" msgid="3060156730651061223">"ଫାଇଲ ଏନକ୍ରିପ୍ସନକୁ ବଦଳାଅ"</string>
+    <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"ବଦଳାନ୍ତୁ…"</string>
+    <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"ଫାଇଲ୍‌ ଏନ୍‌କ୍ରିପ୍ଟ ହୋଇସାରିଲାଣି"</string>
+    <string name="title_convert_fbe" msgid="1263622876196444453">"ଫାଇଲ୍‌ ଭିତ୍ତିକ ଏନ୍‌କ୍ରିପ୍ସନ୍‌ ପାଇଁ ବଦଳାଉଛି"</string>
+    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"ଫାଇଲ୍‌ ଭିତ୍ତିକ ଏନ୍‌କ୍ରିପ୍ସନ୍‌ରେ ଡାଟା ପାର୍ଟିଶନ୍‌ ବଦଳାନ୍ତୁ।\n !!ଚେତାବନୀ!! ଏହା ଆପଣଙ୍କର ସମସ୍ତ ଡାଟା ଉଡ଼ାଇଦେବ।\n ଏହି ବୈଶିଷ୍ଟ୍ୟ ହେଉଛି ଆଲ୍‌ଫା ଏବଂ ଠିକ ଭାବେ କାମ କରିନପାରେ।\n ଜାରି ରଖିବା ପାଇଁ \"ୱାଇପ୍‌ ଓ କନ୍‌ଭର୍ଟ…\" ଦାବନ୍ତୁ"</string>
+    <string name="button_convert_fbe" msgid="5152671181309826405">"ଲିଭାନ୍ତୁ ଏବଂ ବଦଳାନ୍ତୁ…"</string>
+    <string name="picture_color_mode" msgid="4560755008730283695">"ପିକ୍‌ଚର୍‌ ରଙ୍ଗ ମୋଡ୍"</string>
+    <string name="picture_color_mode_desc" msgid="1141891467675548590">"sRGB ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="daltonizer_mode_disabled" msgid="7482661936053801862">"ଅକ୍ଷମ ହୋଇଛି"</string>
+    <string name="daltonizer_mode_monochromacy" msgid="8485709880666106721">"ସମ୍ପୂର୍ଣ୍ଣ ବର୍ଣ୍ଣାନ୍ଧତା"</string>
+    <string name="daltonizer_mode_deuteranomaly" msgid="5475532989673586329">"ବର୍ଣ୍ଣାନ୍ଧତା (ନାଲି-ସବୁଜ)"</string>
+    <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"ପ୍ରୋଟାନୋମାଲି (ଲାଲ୍‌-ସବୁଜ)"</string>
+    <string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"Tritanomaly (ନୀଳ-ହଳଦିଆ)"</string>
+    <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ରଙ୍ଗ ସଠିକତା"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ଏହି ପରୀକ୍ଷାମୂଳକ ବୈଶିଷ୍ଟ୍ୟ ପର୍ଫର୍ମେନ୍ସକୁ ପ୍ରଭାବିତ କରିପାରେ।"</string>
+    <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ଦ୍ୱାରା ଓଭର୍‌ରାଇଡ୍‌ କରାଯାଇଛି"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"ପ୍ରାୟ <xliff:g id="TIME">%1$s</xliff:g> ଅବଶିଷ୍ଟ ରହିଛି"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"ଆପଣଙ୍କ ବ୍ୟବହାରକୁ ଆଧାର କରି ପ୍ରାୟ <xliff:g id="TIME">%1$s</xliff:g> ଅବଶିଷ୍ଟ"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"ସମ୍ପୂର୍ଣ୍ଣ ଚାର୍ଜ ହେବାପାଇଁ <xliff:g id="TIME">%1$s</xliff:g> ଅବଶିଷ୍ଟ ଅଛି"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ଅବଶିଷ୍ଟ"</string>
+    <!-- no translation found for power_remaining_less_than_duration_only (5996752448813295329) -->
+    <skip />
+    <!-- no translation found for power_remaining_less_than_duration (7967078125657859046) -->
+    <skip />
+    <!-- no translation found for power_remaining_more_than_subtext (6846716609975752316) -->
+    <skip />
+    <!-- no translation found for power_remaining_only_more_than_subtext (8884488700395194194) -->
+    <skip />
+    <!-- no translation found for power_remaining_duration_only_shutdown_imminent (8168317165722752881) -->
+    <skip />
+    <!-- no translation found for power_remaining_duration_only_shutdown_imminent (5957064378548718872) -->
+    <skip />
+    <!-- no translation found for power_remaining_duration_only_shutdown_imminent (9055596817716471373) -->
+    <skip />
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ପ୍ରାୟ <xliff:g id="TIME">%2$s</xliff:g> ଅବଶିଷ୍ଟ ରହିଛି"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - ଆପଣଙ୍କ ବ୍ୟବହାରକୁ ଆଧାର କରି ପ୍ରାୟ <xliff:g id="TIME">%2$s</xliff:g> ଅବଶିଷ୍ଟ"</string>
+    <!-- no translation found for power_remaining_duration_shutdown_imminent (7679005631124015335) -->
+    <skip />
+    <!-- no translation found for power_remaining_duration_shutdown_imminent (261050880878965621) -->
+    <skip />
+    <!-- no translation found for power_remaining_duration_shutdown_imminent (2020049829798578618) -->
+    <skip />
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ପୂର୍ଣ୍ଣ ଚାର୍ଜ ହେବା ପର୍ଯ୍ୟନ୍ତ"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"ଅଜ୍ଞାତ"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"ଚାର୍ଜ ହେଉଛି"</string>
+    <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ଚାର୍ଜ ହେଉଛି"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"ଚାର୍ଜ ହେଉନାହିଁ"</string>
+    <string name="battery_info_status_not_charging" msgid="8523453668342598579">"ପ୍ଲଗ୍‌ରେ ଲାଗିଛି, ହେଲେ ଏବେ ଚାର୍ଜ କରିପାରିବ ନାହିଁ"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"ସମ୍ପୂର୍ଣ୍ଣ"</string>
+    <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ଆଡ୍‌ମିନ୍‌ ଦ୍ୱାରା ନିୟନ୍ତ୍ରିତ"</string>
+    <string name="enabled_by_admin" msgid="5302986023578399263">"ଆଡମିନ୍‌ଙ୍କ ଦ୍ୱାରା ସକ୍ଷମ କରାଯାଇଛି"</string>
+    <string name="disabled_by_admin" msgid="8505398946020816620">"ଆଡ୍‌ମିନ୍‌ ଦ୍ଵାରା ଅକ୍ଷମ କରାଯାଇଛି"</string>
+    <string name="disabled" msgid="9206776641295849915">"ଅକ୍ଷମ ହୋଇଛି"</string>
+    <string name="external_source_trusted" msgid="2707996266575928037">"ଅନୁମୋଦିତ"</string>
+    <string name="external_source_untrusted" msgid="2677442511837596726">"ଅନୁମତି ନାହିଁ"</string>
+    <string name="install_other_apps" msgid="6986686991775883017">"ଅଜଣା ଆପ୍‌ଗୁଡଡ଼ିକ ଇନ୍‌ଷ୍ଟଲ୍‌ କର"</string>
+    <string name="home" msgid="3256884684164448244">"ସେଟିଙ୍ଗ ହୋମ୍‌"</string>
+  <string-array name="battery_labels">
+    <item msgid="8494684293649631252">"0%"</item>
+    <item msgid="8934126114226089439">"୫୦%"</item>
+    <item msgid="1286113608943010849">"୧୦୦%"</item>
+  </string-array>
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ପୂର୍ବେ"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> ଅବଶିଷ୍ଟ"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"ଛୋଟ"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ଡିଫଲ୍ଟ"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ବଡ"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"ବୃହତ୍ତମ"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"ବୃହତ୍ତମ"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"କଷ୍ଟମ୍‌ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
+    <string name="help_feedback_label" msgid="6815040660801785649">"ସହାୟତା ଓ ମତାମତ"</string>
+    <string name="content_description_menu_button" msgid="8182594799812351266">"ମେନୁ"</string>
+    <string name="retail_demo_reset_message" msgid="118771671364131297">"ଡେମୋ ମୋଡ୍‌ରେ ଫ୍ୟାକ୍ଟୋରୀ ରିସେଟ୍‌ କରିବାକୁ ପାସ୍‌ୱାର୍ଡ ଲେଖନ୍ତୁ"</string>
+    <string name="retail_demo_reset_next" msgid="8356731459226304963">"ପରବର୍ତ୍ତୀ"</string>
+    <string name="retail_demo_reset_title" msgid="696589204029930100">"ପାସ୍‌ୱର୍ଡ ଆବଶ୍ୟକ"</string>
+    <string name="active_input_method_subtypes" msgid="3596398805424733238">"ସକ୍ରିୟ ଇନପୁଟ୍‌-ପଦ୍ଧତିଗୁଡ଼ିକ"</string>
+    <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"ସିଷ୍ଟମ୍‌ ଭାଷା ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> ପାଇଁ ସେଟିଙ୍ଗ ଖୋଲିବାରେ ବିଫଳ"</string>
+    <string name="ime_security_warning" msgid="4135828934735934248">"ଏହି ଇନ୍‌ପୁଟ୍‌ ପଦ୍ଧତି, ପାସ୍‌ୱର୍ଡ ଓ କ୍ରେଡିଟ୍‌ କାର୍ଡ ନମ୍ୱର୍‌ ଭଳି ବ୍ୟକ୍ତିଗତ ଡାଟା ସମେତ ଆପଣ ଟାଇପ୍‌ କରିଥିବା ସମସ୍ତ ଅକ୍ଷର ସଂଗହ କରିପାରେ।ଏହା, <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> ଆପ୍‌ରୁ ଆସିଛି| ଏହି ଇନ୍‌ପୁଟ୍‌ ପଦ୍ଧତି ବ୍ୟବହାର କରିବେ?"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"ଧ୍ୟାନଦିଅନ୍ତୁ: ରିବୁଟ୍‌ କରିବା ପରେ, ଆପଣଙ୍କ ଫୋନ୍‌ ଅନଲକ୍‌ ନହେବା ପର୍ଯ୍ୟନ୍ତ ଏହି ଆପ୍‌ ଆରମ୍ଭ ହୋଇପାରିବ ନାହିଁ"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS ପଞ୍ଜିକରଣ ସ୍ଥିତି"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"ପଞ୍ଜିକୃତ"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"ପଞ୍ଜିକୃତ ହୋଇନାହିଁ"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"ଉପଲବ୍ଧ ନାହିଁ"</string>
+    <!-- no translation found for wifi_tether_connected_summary (3871603864314407780) -->
+    <!-- no translation found for accessibility_manual_zen_more_time (1636187409258564291) -->
+    <skip />
+    <!-- no translation found for accessibility_manual_zen_less_time (6590887204171164991) -->
+    <skip />
+    <!-- no translation found for zen_mode_enable_dialog_turn_on (8287824809739581837) -->
+    <skip />
+    <string name="cancel" msgid="6859253417269739139">"କ୍ୟାନ୍ସଲ୍"</string>
+    <!-- no translation found for zen_mode_settings_turn_on_dialog_title (2297134204747331078) -->
+    <skip />
+    <string name="zen_mode_settings_summary_off" msgid="6119891445378113334">"କଦାପି ନୁହେଁ"</string>
+    <!-- no translation found for zen_interruption_level_priority (2078370238113347720) -->
+    <skip />
+    <!-- no translation found for zen_mode_and_condition (4927230238450354412) -->
+    <skip />
+    <!-- no translation found for zen_alarm_warning_indef (3007988140196673193) -->
+    <skip />
+    <!-- no translation found for zen_alarm_warning (6236690803924413088) -->
+    <skip />
+    <!-- no translation found for alarm_template (4996153414057676512) -->
+    <skip />
+    <!-- no translation found for alarm_template_far (3779172822607461675) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index bfea9a8..6549861 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"ਸਿਮ ਪਹੁੰਚ"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ਆਡੀਓ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ਆਡੀਓ"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"ਸੁਣਨ ਦਾ ਸਾਧਨ"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"ਸੁਣਨ ਦੇ ਸਾਧਨ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"ਮੀਡੀਆ  ਆਡੀਓ  ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ਫ਼ੋਨ ਔਡੀਓ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ਫਾਈਲ ਟ੍ਰਾਂਸਫ਼ਰ ਸਰਵਰ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ਫ਼ੋਨ ਔਡੀਓ ਲਈ ਵਰਤੋ"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ ਲਈ ਵਰਤੋ"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ਇਨਪੁਟ ਲਈ ਵਰਤੋ"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"ਸੁਣਨ ਦੇ ਸਾਧਨ ਲਈ ਵਰਤੋ"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"ਪੇਅਰ ਕਰੋ"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ਪੇਅਰ ਕਰੋ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"ਰੱਦ ਕਰੋ"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index fd177e5..55e43089 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Dostop do kartice SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Zvok visoke kakovosti: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Zvok visoke kakovosti"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Slušni pripomoček"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Povezava s slušnim pripomočkom je vzpostavljena"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Povezan s profilom za predstavnostni zvok"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Povezava s profilom za zvok telefona vzpostavljena"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Povezava s strežnikom za prenos datotek je vzpostavljena"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Uporabi za zvok telefona"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Uporabi za prenos datotek"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Uporabi za vnos"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Uporaba za slušni pripomoček"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Seznani"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"SEZNANI"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Prekliči"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index cf0fe12..5524e2c 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Qasje në kartën SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Audio HD"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Aparati i dëgjimit"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Lidhur me aparatin e dëgjimit"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"U lidh me audion e medias"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"U lidh me audion e telefonit"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"U lidh me serverin e transferimit të skedarëve"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Përdor për audion e telefonit"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Përdor për transferimin e skedarëve"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Përdore për hyrjen"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Përdore për aparatin e dëgjimit"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Çifto"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ÇIFTO"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Anulo"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 4509470..d8c6e4d 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-åtkomst"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD-ljud: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD-ljud"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Hörapparat"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Ansluten till hörapparat"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Ansluten till medialjud"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Ansluten till telefonens ljud"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Ansluten till filöverföringsserver"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Använd för telefonens ljud"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Använd för filöverföring"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Använd för inmatning"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Använd med hörapparat"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Parkoppling"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"PARKOPPLA"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Avbryt"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 274222b..b417cfb 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"சிம் அணுகல்"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ஆடியோ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ஆடியோ"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"செவித்துணைக் கருவி"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"செவித்துணைக் கருவியுடன் இணைக்கப்பட்டிருக்கும்போது"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"மீடியா ஆடியோவுடன் இணைக்கப்பட்டது"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"மொபைல் ஆடியோவுடன் இணைக்கப்பட்டது"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"கோப்பைப் பரிமாற்றும் சேவையகத்துடன் இணைக்கப்பட்டது"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"மொபைல் ஆடியோவைப் பயன்படுத்து"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"கோப்பு பரிமாற்றத்திற்காகப் பயன்படுத்து"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"உள்ளீட்டுக்குப் பயன்படுத்து"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"செவித்துணைக் கருவிக்காகப் பயன்படுத்து"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"இணை"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"இணை"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"ரத்துசெய்"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 31f0cdf..99a35a3 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM యాక్సెస్"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ఆడియో: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ఆడియో"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"వినికిడి పరికరం"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"వినికిడి పరికరానికి కనెక్ట్ చేస్తోంది"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"మీడియా ఆడియోకు కనెక్ట్ చేయబడింది"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ఫోన్ ఆడియోకు కనెక్ట్ చేయబడింది"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ఫైల్ బదిలీ సర్వర్‌కు కనెక్ట్ చేయబడింది"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ఫోన్ ఆడియో కోసం ఉపయోగించు"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ఫైల్ బదిలీ కోసం ఉపయోగించు"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ఇన్‌పుట్ కోసం ఉపయోగించు"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"వినికిడి పరికరం కోసం ఉపయోగించు"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"జత చేయి"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"జత చేయి"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"రద్దు చేయి"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 1985bda..9fdeb4a 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM Erişimi"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ses: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ses"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"İşitme Cihazı"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"İşitme Cihazına bağlandı"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Medya sesine bağlanıldı"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Telefon sesine bağlandı"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Dosya aktarım sunucusuna bağlandı"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Telefon sesi için kullan"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Dosya aktarımı için kullan"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Giriş için kullan"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"İşitme Cihazı için kullan"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Eşle"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"EŞLE"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"İptal"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 90c77741..7c221d7 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"‏SIM رسائی"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"‏HD آڈیو: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"‏HD آڈیو"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"سماعتی آلہ"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"سماعتی آلے سے منسلک"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"میڈیا آڈیو سے مربوط"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"فون آڈیو سے مربوط"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"فائل منتقلی سرور سے مربوط ہو گیا ہے"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"فون آڈیو کیلئے استعمال کریں"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"فائل منتقل کرنے کیلئے استعمال کریں"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ان پٹ کیلئے استعمال"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"سماعتی آلے کیلئے استعمال کریں"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"جوڑا بنائیں"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"جوڑا بنائیں"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"منسوخ کریں"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index e37ab74..74bac0a 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Quyền truy cập SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Âm thanh HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Âm thanh HD"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Trợ thính"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Đã kết nối với thiết bị trợ thính"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Đã kết nối với âm thanh phương tiện"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Đã kết nối với âm thanh điện thoại"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Đã kết nối với máy chủ chuyển tệp"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Sử dụng cho âm thanh điện thoại"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Sử dụng để chuyển tệp"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Sử dụng để nhập"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Sử dụng cho thiết bị trợ thính"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Ghép nối"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"GHÉP NỐI"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Hủy"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 89edf54..3590ace 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM 卡存取权限"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD 音频:<xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD 音频"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"助听器"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"已连接到助听器"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"已连接到媒体音频"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"已连接到手机音频"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"已连接到文件传输服务器"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"用于手机音频"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"用于文件传输"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"用于输入"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"用于助听器"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"配对"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"配对"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"取消"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 9b0ec86..f2162f4 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM 卡存取"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"高清音訊:<xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"高清音訊"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"助聽器"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"已連線至助聽器"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"已連接媒體音頻裝置"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"已連接手機耳機"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"已連線至檔案傳輸伺服器"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"用於手機音效"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"用於傳輸檔案"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"用於輸入"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"用於助聽器"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"配對"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"配對"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"取消"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 1d6b4b9..fa3001a 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM 卡存取權"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD 高解析音訊:<xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD 高解析音訊"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"助聽器"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"已連接到助聽器"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"連接至媒體音訊"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"連接至電話音訊"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"已連線到檔案傳輸伺服器"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"用於電話音訊"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"用於傳輸檔案"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"用於輸入"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"用於助聽器"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"配對"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"配對"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"取消"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionController.java b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionController.java
index f740f7c..b0451b7 100644
--- a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionController.java
@@ -107,7 +107,7 @@
         } catch (NullPointerException e) {
             Log.w(TAG, "mRemote service detached before able to query", e);
             return null;
-        } catch (RemoteException e) {
+        } catch (RemoteException | RuntimeException e) {
             Log.w(TAG, "Error when calling getSuggestion()", e);
             return null;
         }
@@ -120,7 +120,7 @@
         }
         try {
             mRemoteService.dismissSuggestion(suggestion);
-        } catch (RemoteException e) {
+        } catch (RemoteException | RuntimeException e) {
             Log.w(TAG, "Error when calling dismissSuggestion()", e);
         }
     }
@@ -133,7 +133,7 @@
 
         try {
             mRemoteService.launchSuggestion(suggestion);
-        } catch (RemoteException e) {
+        } catch (RemoteException | RuntimeException e) {
             Log.w(TAG, "Error when calling launchSuggestion()", e);
         }
     }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/CustomEditTextPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/CustomEditTextPreferenceTest.java
index f50c0a4..9d7f59a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/CustomEditTextPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/CustomEditTextPreferenceTest.java
@@ -26,7 +26,6 @@
 import android.widget.EditText;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -35,7 +34,6 @@
 import org.robolectric.util.ReflectionHelpers;
 
 @RunWith(SettingsLibRobolectricTestRunner.class)
-@Ignore
 public class CustomEditTextPreferenceTest {
 
     @Mock
@@ -50,7 +48,6 @@
     }
 
     @Test
-    @Ignore
     public void bindDialogView_shouldRequestFocus() {
         final String testText = "";
         final EditText editText = spy(new EditText(RuntimeEnvironment.application));
@@ -63,7 +60,6 @@
     }
 
     @Test
-    @Ignore
     public void getEditText_noDialog_shouldNotCrash() {
         ReflectionHelpers.setField(mPreference, "mFragment",
                 mock(CustomEditTextPreference.CustomPreferenceDialogFragment.class));
diff --git a/packages/SystemUI/README.md b/packages/SystemUI/README.md
index ae0a362..b441bbd 100644
--- a/packages/SystemUI/README.md
+++ b/packages/SystemUI/README.md
@@ -1,4 +1,170 @@
-# SystemUI Documentation
+# SystemUI
+
+“Everything you see in Android that's not an app”
+
+SystemUI is a persistent process that provides UI for the system but outside
+of the system_server process.
+
+The starting point for most of sysui code is a list of services that extend
+SystemUI that are started up by SystemUIApplication. These services then depend
+on some custom dependency injection provided by Dependency.
+
+Inputs directed at sysui (as opposed to general listeners) generally come in
+through IStatusBar. Outputs from sysui are through a variety of private APIs to
+the android platform all over.
+
+## SystemUIApplication
+
+When SystemUIApplication starts up, it will start up the services listed in
+config_systemUIServiceComponents or config_systemUIServiceComponentsPerUser.
+
+Each of these services extend SystemUI. SystemUI provides them with a Context
+and gives them callbacks for onConfigurationChanged (this historically was
+the main path for onConfigurationChanged, now also happens through
+ConfigurationController). They also receive a callback for onBootCompleted
+since these objects may be started before the device has finished booting.
+
+SystemUI and SystemUIApplication also have methods for putComponent and
+getComponent which were existing systems to get a hold of other parts of
+sysui before Dependency existed. Generally new things should not be added
+to putComponent, instead Dependency and other refactoring is preferred to
+make sysui structure cleaner.
+
+Each SystemUI service is expected to be a major part of system ui and the
+goal is to minimize communication between them. So in general they should be
+relatively silo'd.
+
+## Dependencies
+
+The first SystemUI service that is started should always be Dependency.
+Dependency provides a static method for getting a hold of dependencies that
+have a lifecycle that spans sysui. Dependency has code for how to create all
+dependencies manually added. SystemUIFactory is also capable of
+adding/replacing these dependencies.
+
+Dependencies are lazily initialized, so if a Dependency is never referenced at
+runtime, it will never be created.
+
+If an instantiated dependency implements Dumpable it will be included in dumps
+of sysui (and bug reports), allowing it to include current state information.
+This is how \*Controllers dump state to bug reports.
+
+If an instantiated dependency implements ConfigurationChangeReceiver it will
+receive onConfigurationChange callbacks when the configuration changes.
+
+## IStatusBar
+
+CommandQueue is the object that receives all of the incoming events from the
+system_server. It extends IStatusBar and dispatches those callbacks back any
+number of listeners. The system_server gets a hold of the IStatusBar when
+StatusBar calls IStatusBarService#registerStatusBar, so if StatusBar is not
+included in the XML service list, it will not be registered with the OS.
+
+CommandQueue posts all incoming callbacks to a handler and then dispatches
+those messages to each callback that is currently registered. CommandQueue
+also tracks the current value of disable flags and will call #disable
+immediately for any callbacks added.
+
+There are a few places where CommandQueue is used as a bus to communicate
+across sysui. Such as when StatusBar calls CommandQueue#recomputeDisableFlags.
+This is generally used a shortcut to directly trigger CommandQueue rather than
+calling StatusManager and waiting for the call to come back to IStatusBar.
+
+## Default SystemUI services list
+
+### [com.android.systemui.Dependency](/packages/SystemUI/src/com/android/systemui/Dependency.java)
+
+Provides custom dependency injection.
+
+### [com.android.systemui.util.NotificationChannels](/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java)
+
+Creates/initializes the channels sysui uses when posting notifications.
+
+### [com.android.systemui.statusbar.CommandQueue$CommandQueueStart](/packages/SystemUI/src/com/android/systemui/sstatusbar/CommandQueue.java)
+
+Creates CommandQueue and calls putComponent because its always been there
+and sysui expects it to be there :/
+
+### [com.android.systemui.keyguard.KeyguardViewMediator](/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java)
+
+Manages keyguard view state.
+
+### [com.android.systemui.recents.Recents](/packages/SystemUI/src/com/android/systemui/recents/Recents.java)
+
+Recents tracks all the data needed for recents and starts/stops the recents
+activity. It provides this cached data to RecentsActivity when it is started.
+
+### [com.android.systemui.volume.VolumeUI](/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java)
+
+Registers all the callbacks/listeners required to show the Volume dialog when
+it should be shown.
+
+### [com.android.systemui.stackdivider.Divider](/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java)
+
+Shows the drag handle for the divider between two apps when in split screen
+mode.
+
+### [com.android.systemui.SystemBars](/packages/SystemUI/src/com/android/systemui/SystemBars.java)
+
+This is a proxy to the actual SystemUI for the status bar. This loads from
+config_statusBarComponent which defaults to StatusBar. (maybe this should be
+removed and copy how config_systemUiVendorServiceComponent works)
+
+### [com.android.systemui.status.phone.StatusBar](/packages/SystemUI/src/com/android/systemui/status/phone/StatusBar.java)
+
+This shows the UI for the status bar and the notification shade it contains.
+It also contains a significant amount of other UI that interacts with these
+surfaces (keyguard, AOD, etc.). StatusBar also contains a notification listener
+to receive notification callbacks.
+
+### [com.android.systemui.usb.StorageNotification](/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java)
+
+Tracks USB status and sends notifications for it.
+
+### [com.android.systemui.power.PowerUI](/packages/SystemUI/src/com/android/systemui/power/PowerUI.java)
+
+Tracks power status and sends notifications for low battery/power saver.
+
+### [com.android.systemui.media.RingtonePlayer](/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java)
+
+Plays ringtones.
+
+### [com.android.systemui.keyboard.KeyboardUI](/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java)
+
+Shows UI for keyboard shortcuts (triggered by keyboard shortcut).
+
+### [com.android.systemui.pip.PipUI](/packages/SystemUI/src/com/android/systemui/pip/PipUI.java)
+
+Shows the overlay controls when Pip is showing.
+
+### [com.android.systemui.shortcut.ShortcutKeyDispatcher](/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java)
+
+Dispatches shortcut to System UI components.
+
+### @string/config_systemUIVendorServiceComponent
+
+Component allowing the vendor/OEM to inject a custom component.
+
+### [com.android.systemui.util.leak.GarbageMonitor$Service](/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java)
+
+Tracks large objects in sysui to see if there are leaks.
+
+### [com.android.systemui.LatencyTester](/packages/SystemUI/src/com/android/systemui/LatencyTester.java)
+
+Class that only runs on debuggable builds that listens to broadcasts that
+simulate actions in the system that are used for testing the latency.
+
+### [com.android.systemui.globalactions.GlobalActionsComponent](/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java)
+
+Shows the global actions dialog (long-press power).
+
+### [com.android.systemui.ScreenDecorations](/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java)
+
+Draws decorations about the screen in software (e.g. rounded corners, cutouts).
+
+### [com.android.systemui.fingerprint.FingerprintDialogImpl](/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java)
+
+Fingerprint UI.
 
 ---
 
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
index d0389eb..828c9df 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
@@ -34,6 +34,7 @@
               android:layout_marginBottom="7dp"
               android:paddingStart="64dp"
               android:paddingEnd="64dp"
+              android:textColor="?attr/wallpaperTextColor"
               android:theme="@style/TextAppearance.Keyguard"
     />
     <LinearLayout android:id="@+id/row"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
index 31635a5..713c573 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
@@ -76,6 +76,7 @@
                 android:layout_marginTop="22dp"
                 android:layout_below="@id/clock_view"
                 android:background="#f00"
+                android:backgroundTint="?attr/wallpaperTextColor"
                 android:layout_centerHorizontal="true" />
 
             <include layout="@layout/keyguard_status_area"
diff --git a/packages/SystemUI/res/color/white_disabled.xml b/packages/SystemUI/res/color/white_disabled.xml
new file mode 100644
index 0000000..617e232
--- /dev/null
+++ b/packages/SystemUI/res/color/white_disabled.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="@android:color/white"
+          android:alpha="?android:attr/disabledAlpha" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/brightness_mirror_background.xml b/packages/SystemUI/res/drawable/brightness_mirror_background.xml
index b3a0484..43c9b73 100644
--- a/packages/SystemUI/res/drawable/brightness_mirror_background.xml
+++ b/packages/SystemUI/res/drawable/brightness_mirror_background.xml
@@ -16,4 +16,5 @@
   -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android">
     <solid android:color="@color/qs_background_dark" />
+    <corners android:radius="8dp" />
 </shape>
diff --git a/packages/SystemUI/res/drawable/brightness_progress_drawable.xml b/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
new file mode 100644
index 0000000..45d8dc1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@android:id/background"
+          android:gravity="center_vertical|fill_horizontal">
+        <shape android:shape="rectangle"
+               android:tint="?android:attr/colorControlActivated">
+            <size android:height="@dimen/seek_bar_height" />
+            <solid android:color="@color/white_disabled" />
+            <corners android:radius="@dimen/seek_bar_corner_radius" />
+        </shape>
+    </item>
+    <item android:id="@android:id/progress"
+          android:gravity="center_vertical|fill_horizontal">
+        <scale android:scaleWidth="100%">
+            <shape android:shape="rectangle"
+                   android:tint="?android:attr/colorControlActivated">
+                <size android:height="@dimen/seek_bar_height" />
+                <solid android:color="@android:color/white" />
+                <corners android:radius="@dimen/seek_bar_corner_radius" />
+            </shape>
+        </scale>
+    </item>
+</layer-list>
diff --git a/packages/SystemUI/res/drawable/ic_brightness_thumb.xml b/packages/SystemUI/res/drawable/ic_brightness_thumb.xml
index beedcbb..8281836 100644
--- a/packages/SystemUI/res/drawable/ic_brightness_thumb.xml
+++ b/packages/SystemUI/res/drawable/ic_brightness_thumb.xml
@@ -14,14 +14,14 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="28.0dp"
-        android:height="28.0dp"
+        android:width="24dp"
+        android:height="24dp"
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
     <path
         android:pathData="m18.250000,12.000000a6.250000,6.250000 0.000000,1.000000 1.000000,-12.500000 0.000000,6.250000 6.250000,0.000000 1.000000,1.000000 12.500000,0.000000z"
-        android:fillColor="?android:attr/colorPrimary" />
+        android:fillColor="@android:color/transparent" />
     <path
         android:pathData="M20,8.69L20,5c0,-0.55 -0.45,-1 -1,-1h-3.69l-2.6,-2.6a0.996,0.996 0,0 0,-1.41 0L8.69,4L5,4c-0.55,0 -1,0.45 -1,1v3.69l-2.6,2.6a0.996,0.996 0,0 0,0 1.41L4,15.3L4,19c0,0.55 0.45,1 1,1h3.69l2.6,2.6c0.39,0.39 1.02,0.39 1.41,0l2.6,-2.6L19,20c0.55,0 1,-0.45 1,-1v-3.69l2.6,-2.6a0.996,0.996 0,0 0,0 -1.41L20,8.69zM12,18.08c-3.36,0 -6.08,-2.73 -6.08,-6.08S8.64,5.92 12,5.92s6.08,2.73 6.08,6.08 -2.72,6.08 -6.08,6.08zM12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4z"
-        android:fillColor="?android:attr/colorControlNormal" />
+        android:fillColor="?android:attr/colorControlActivated" />
 </vector>
diff --git a/packages/SystemUI/res/layout/brightness_mirror.xml b/packages/SystemUI/res/layout/brightness_mirror.xml
index d6e7507..e3440b5 100644
--- a/packages/SystemUI/res/layout/brightness_mirror.xml
+++ b/packages/SystemUI/res/layout/brightness_mirror.xml
@@ -14,19 +14,19 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/brightness_mirror"
     android:layout_width="@dimen/qs_panel_width"
-    android:layout_height="wrap_content"
+    android:layout_height="@dimen/brightness_mirror_height"
     android:layout_gravity="@integer/notification_panel_layout_gravity"
     android:visibility="invisible">
     <FrameLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:background="@drawable/brightness_mirror_background"
-        android:elevation="2dp">
-        <include layout="@layout/quick_settings_brightness_dialog"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"/>
+        android:layout_marginLeft="@dimen/notification_side_paddings"
+        android:layout_marginRight="@dimen/notification_side_paddings"
+        android:background="@drawable/brightness_mirror_background">
+        <include layout="@layout/quick_settings_brightness_dialog" />
     </FrameLayout>
 </FrameLayout>
diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
index 080f553..2efae71 100644
--- a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
+++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
@@ -15,8 +15,9 @@
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
-    android:layout_height="48dp"
+    android:layout_height="wrap_content"
     android:layout_width="match_parent"
+    android:layout_gravity="center_vertical"
     android:paddingLeft="16dp"
     android:paddingRight="16dp"
     style="@style/BrightnessDialogContainer">
@@ -34,7 +35,7 @@
     <com.android.systemui.settings.ToggleSliderView
         android:id="@+id/brightness_slider"
         android:layout_width="0dp"
-        android:layout_height="wrap_content"
+        android:layout_height="48dp"
         android:layout_gravity="center_vertical"
         android:layout_weight="1"
         android:contentDescription="@string/accessibility_brightness"
diff --git a/packages/SystemUI/res/layout/status_bar_toggle_slider.xml b/packages/SystemUI/res/layout/status_bar_toggle_slider.xml
index 062e6cb..942f3dd 100644
--- a/packages/SystemUI/res/layout/status_bar_toggle_slider.xml
+++ b/packages/SystemUI/res/layout/status_bar_toggle_slider.xml
@@ -16,10 +16,7 @@
 -->
 
 <!--    android:background="@drawable/status_bar_closed_default_background" -->
-<merge
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
-    >
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
     <CheckBox
         android:id="@+id/toggle"
         android:layout_width="48dp"
@@ -44,6 +41,7 @@
         android:paddingTop="16dp"
         android:paddingBottom="16dp"
         android:thumb="@drawable/ic_brightness_thumb"
+        android:progressDrawable="@drawable/brightness_progress_drawable"
         android:splitTrack="false"
         />
     <TextView
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index ca05240..e37ca1c 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -22,8 +22,10 @@
     <dimen name="docked_divider_handle_width">2dp</dimen>
     <dimen name="docked_divider_handle_height">16dp</dimen>
 
+    <dimen name="brightness_mirror_height">96dp</dimen>
+
     <dimen name="qs_tile_margin_top">2dp</dimen>
-    <dimen name="qs_brightness_padding_top">0dp</dimen>
+    <dimen name="qs_header_tooltip_height">24dp</dimen>
 
     <dimen name="battery_detail_graph_space_top">9dp</dimen>
     <dimen name="battery_detail_graph_space_bottom">9dp</dimen>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 59c009f..1ec59bf 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -259,6 +259,8 @@
 
     <dimen name="notification_panel_width">@dimen/match_parent</dimen>
 
+    <dimen name="brightness_mirror_height">108dp</dimen>
+
     <!-- The width of the panel that holds the quick settings. -->
     <dimen name="qs_panel_width">@dimen/notification_panel_width</dimen>
 
@@ -300,7 +302,7 @@
 
     <dimen name="qs_tile_height">106dp</dimen>
     <dimen name="qs_tile_margin">19dp</dimen>
-    <dimen name="qs_tile_margin_top">32dp</dimen>
+    <dimen name="qs_tile_margin_top">18dp</dimen>
     <dimen name="qs_quick_tile_size">48dp</dimen>
     <dimen name="qs_quick_tile_padding">12dp</dimen>
     <dimen name="qs_header_gear_translation">16dp</dimen>
@@ -326,7 +328,6 @@
     <dimen name="qs_detail_image_height">56dp</dimen>
     <dimen name="qs_detail_image_padding">16dp</dimen>
     <dimen name="qs_detail_item_height">48dp</dimen>
-    <dimen name="qs_brightness_padding_top">6dp</dimen>
     <dimen name="qs_detail_header_text_size">20sp</dimen>
     <dimen name="qs_detail_button_text_size">14sp</dimen>
     <dimen name="qs_detail_item_primary_text_size">16sp</dimen>
@@ -344,9 +345,7 @@
     <dimen name="qs_detail_item_icon_width">32dp</dimen>
     <dimen name="qs_detail_item_icon_marginStart">0dp</dimen>
     <dimen name="qs_detail_item_icon_marginEnd">20dp</dimen>
-    <dimen name="qs_header_padding_start">16dp</dimen>
-    <dimen name="qs_header_padding_end">24dp</dimen>
-    <dimen name="qs_header_tooltip_height">32dp</dimen>
+    <dimen name="qs_header_tooltip_height">30dp</dimen>
     <dimen name="qs_footer_padding_start">16dp</dimen>
     <dimen name="qs_footer_padding_end">24dp</dimen>
     <dimen name="qs_footer_icon_size">16dp</dimen>
@@ -373,6 +372,9 @@
     <!-- Padding between subtitles and the following text in the QSFooter dialog -->
     <dimen name="qs_footer_dialog_subtitle_padding">20dp</dimen>
 
+    <dimen name="seek_bar_height">3dp</dimen>
+    <dimen name="seek_bar_corner_radius">3dp</dimen>
+
     <!-- Zen mode panel: condition item button padding -->
     <dimen name="zen_mode_condition_detail_button_padding">8dp</dimen>
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index 5d1bdab..b54d09a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -16,6 +16,7 @@
 
 package com.android.keyguard;
 
+import android.annotation.ColorInt;
 import android.app.PendingIntent;
 import android.arch.lifecycle.LiveData;
 import android.arch.lifecycle.Observer;
@@ -34,6 +35,7 @@
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.graphics.ColorUtils;
 import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
@@ -160,8 +162,8 @@
             mRow.addView(button);
 
             PendingIntent pendingIntent = null;
-            if (rc.getContentIntent() != null) {
-                pendingIntent = rc.getContentIntent().getAction();
+            if (rc.getPrimaryAction() != null) {
+                pendingIntent = rc.getPrimaryAction().getAction();
             }
             mClickActions.put(button, pendingIntent);
 
@@ -307,10 +309,17 @@
         }
     }
 
-    public int getTextColor() {
+    @VisibleForTesting
+    int getTextColor() {
         return ColorUtils.blendARGB(mTextColor, Color.WHITE, mDarkAmount);
     }
 
+    @VisibleForTesting
+    void setTextColor(@ColorInt int textColor) {
+        mTextColor = textColor;
+        updateTextColors();
+    }
+
     /**
      * Representation of an item that appears under the clock on main keyguard message.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java b/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java
index f201165..be3168c 100644
--- a/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java
@@ -16,6 +16,9 @@
 
 package com.android.systemui.net;
 
+import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
+import static android.net.NetworkTemplate.MATCH_MOBILE;
+
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
@@ -32,11 +35,6 @@
 
 import com.android.systemui.R;
 
-import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
-import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER;
-import static android.net.NetworkTemplate.MATCH_MOBILE_4G;
-import static android.net.NetworkTemplate.MATCH_MOBILE_ALL;
-
 /**
  * Notify user that a {@link NetworkTemplate} is over its
  * {@link NetworkPolicy#limitBytes}, giving them the choice of acknowledging or
@@ -85,11 +83,7 @@
 
     private static int getLimitedDialogTitleForTemplate(NetworkTemplate template) {
         switch (template.getMatchRule()) {
-            case MATCH_MOBILE_3G_LOWER:
-                return R.string.data_usage_disabled_dialog_3g_title;
-            case MATCH_MOBILE_4G:
-                return R.string.data_usage_disabled_dialog_4g_title;
-            case MATCH_MOBILE_ALL:
+            case MATCH_MOBILE:
                 return R.string.data_usage_disabled_dialog_mobile_title;
             default:
                 return R.string.data_usage_disabled_dialog_title;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipAppOpsListener.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipAppOpsListener.java
index f0e4ccc..1e0d4d0 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipAppOpsListener.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipAppOpsListener.java
@@ -26,12 +26,14 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Handler;
 import android.util.Pair;
 
 public class PipAppOpsListener {
     private static final String TAG = PipAppOpsListener.class.getSimpleName();
 
     private Context mContext;
+    private Handler mHandler;
     private IActivityManager mActivityManager;
     private AppOpsManager mAppOpsManager;
 
@@ -50,7 +52,7 @@
                     if (appInfo.packageName.equals(topPipActivityInfo.first.getPackageName()) &&
                             mAppOpsManager.checkOpNoThrow(OP_PICTURE_IN_PICTURE, appInfo.uid,
                                     packageName) != MODE_ALLOWED) {
-                        mMotionHelper.dismissPip();
+                        mHandler.post(() -> mMotionHelper.dismissPip());
                     }
                 }
             } catch (NameNotFoundException e) {
@@ -63,6 +65,7 @@
     public PipAppOpsListener(Context context, IActivityManager activityManager,
             PipMotionHelper motionHelper) {
         mContext = context;
+        mHandler = new Handler(mContext.getMainLooper());
         mActivityManager = activityManager;
         mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
         mMotionHelper = motionHelper;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 476cb40..a92e346 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -254,8 +254,10 @@
 
     public void updateResources() {
         final Resources res = mContext.getResources();
-        setPadding(0, res.getDimensionPixelSize(R.dimen.qs_brightness_padding_top),
-                0, res.getDimensionPixelSize(R.dimen.qs_panel_padding_bottom));
+        setPadding(0, 0, 0, res.getDimensionPixelSize(R.dimen.qs_panel_padding_bottom));
+        mTooltipView.getLayoutParams().height =
+                res.getDimensionPixelSize(R.dimen.qs_header_tooltip_height);
+        mTooltipView.setLayoutParams(mTooltipView.getLayoutParams());
         for (TileRecord r : mRecords) {
             r.tile.clearState();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
index 3597929..5aace97 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
@@ -16,12 +16,16 @@
 
 package com.android.systemui.qs.tiles;
 
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_MODE;
+
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.content.Intent;
+import android.metrics.LogMaker;
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
 import android.support.annotation.StringRes;
+import android.util.Log;
 import android.widget.Switch;
 
 import com.android.internal.app.ColorDisplayController;
@@ -65,6 +69,15 @@
 
     @Override
     protected void handleClick() {
+        // Enroll in forced auto mode if eligible.
+        if ("1".equals(Settings.Global.getString(mContext.getContentResolver(),
+                Settings.Global.NIGHT_DISPLAY_FORCED_AUTO_MODE_AVAILABLE))
+                && mController.getAutoModeRaw() == -1) {
+            mController.setAutoMode(ColorDisplayController.AUTO_MODE_CUSTOM);
+            Log.i("NightDisplayTile", "Enrolled in forced night display auto mode");
+        }
+
+        // Change current activation state.
         final boolean activated = !mState.value;
         mController.setActivated(activated);
     }
@@ -147,6 +160,11 @@
     }
 
     @Override
+    public LogMaker populate(LogMaker logMaker) {
+        return super.populate(logMaker).addTaggedData(FIELD_QS_MODE, mController.getAutoModeRaw());
+    }
+
+    @Override
     public Intent getLongClickIntent() {
         return new Intent(Settings.ACTION_NIGHT_DISPLAY_SETTINGS);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index dc400e6..e86d88d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -580,8 +580,7 @@
 
     private boolean shouldDisableNavbarGestures() {
         return !mStatusBar.isDeviceProvisioned()
-                || (mDisabledFlags1 & StatusBarManager.DISABLE_SEARCH) != 0
-                || mNavigationBarView.getRecentsButton().getVisibility() != View.VISIBLE;
+                || (mDisabledFlags1 & StatusBarManager.DISABLE_SEARCH) != 0;
     }
 
     private void repositionNavigationBar() {
@@ -600,13 +599,10 @@
 
         // Change the cancel pin gesture to home and back if recents button is invisible
         boolean recentsVisible = mNavigationBarView.isRecentsButtonVisible();
-        ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
         ButtonDispatcher backButton = mNavigationBarView.getBackButton();
         if (recentsVisible) {
-            homeButton.setOnLongClickListener(this::onHomeLongClick);
             backButton.setOnLongClickListener(this::onLongPressBackRecents);
         } else {
-            homeButton.setOnLongClickListener(this::onLongPressBackHome);
             backButton.setOnLongClickListener(this::onLongPressBackHome);
         }
     }
@@ -629,6 +625,7 @@
 
         ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
         homeButton.setOnTouchListener(this::onHomeTouch);
+        homeButton.setOnLongClickListener(this::onHomeLongClick);
 
         ButtonDispatcher accessibilityButton = mNavigationBarView.getAccessibilityButton();
         accessibilityButton.setOnClickListener(this::onAccessibilityClick);
@@ -681,6 +678,9 @@
 
     @VisibleForTesting
     boolean onHomeLongClick(View v) {
+        if (!mNavigationBarView.isRecentsButtonVisible() && mNavigationBarView.inScreenPinning()) {
+            return onLongPressBackHome(v);
+        }
         if (shouldDisableNavbarGestures()) {
             return false;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubController.java
index dd4d1f6..b82b0ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubController.java
@@ -380,7 +380,7 @@
     }
 
     private void startQuickScrub() {
-        if (!mQuickScrubActive) {
+        if (!mQuickScrubActive && mDraggingActive) {
             mQuickScrubActive = true;
             mLightTrackColor = mContext.getColor(R.color.quick_step_track_background_light);
             mDarkTrackColor = mContext.getColor(R.color.quick_step_track_background_dark);
@@ -394,6 +394,9 @@
             } catch (RemoteException e) {
                 Log.e(TAG, "Failed to send start of quick scrub.", e);
             }
+        } else {
+            // After long press do not allow quick scrub/switch
+            mTouchDownX = -1;
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
index a011952..06a56ff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.policy;
 
 import android.annotation.NonNull;
+import android.content.res.Resources;
 import android.util.ArraySet;
 import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
@@ -111,10 +112,10 @@
     public void updateResources() {
         FrameLayout.LayoutParams lp =
                 (FrameLayout.LayoutParams) mBrightnessMirror.getLayoutParams();
-        lp.width = mBrightnessMirror.getResources().getDimensionPixelSize(
-                R.dimen.qs_panel_width);
-        lp.gravity = mBrightnessMirror.getResources().getInteger(
-                R.integer.notification_panel_layout_gravity);
+        Resources r = mBrightnessMirror.getResources();
+        lp.width = r.getDimensionPixelSize(R.dimen.qs_panel_width);
+        lp.height = r.getDimensionPixelSize(R.dimen.brightness_mirror_height);
+        lp.gravity = r.getInteger(R.integer.notification_panel_layout_gravity);
         mBrightnessMirror.setLayoutParams(lp);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
new file mode 100644
index 0000000..7686948
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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
+ */
+package com.android.keyguard;
+
+import android.graphics.Color;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.LayoutInflater;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWithLooper
+@RunWith(AndroidTestingRunner.class)
+public class KeyguardSliceViewTest extends SysuiTestCase {
+    private KeyguardSliceView mKeyguardSliceView;
+
+    @Before
+    public void setUp() throws Exception {
+        mKeyguardSliceView = (KeyguardSliceView) LayoutInflater.from(getContext())
+                .inflate(R.layout.keyguard_status_area, null);
+    }
+
+    @Test
+    public void getTextColor_whiteTextWhenAOD() {
+        // Set text color to red since the default is white and test would always pass
+        mKeyguardSliceView.setTextColor(Color.RED);
+        mKeyguardSliceView.setDark(0);
+        Assert.assertEquals("Should be using regular text color", Color.RED,
+                mKeyguardSliceView.getTextColor());
+        mKeyguardSliceView.setDark(1);
+        Assert.assertEquals("Should be using AOD text color", Color.WHITE,
+                mKeyguardSliceView.getTextColor());
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
index 7d4d31e..7ab69b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
@@ -47,7 +47,7 @@
 
     private static final String TEST_RESULT_KEY = "test_result_key";
     private static final String TEST_REPLY = "hello";
-    private static final String TEST_ACTION = "com.android.ACTION";
+    private static final String TEST_ACTION = "com.android.REMOTE_INPUT_VIEW_ACTION";
 
     @Mock private RemoteInputController mController;
     @Mock private ShortcutManager mShortcutManager;
@@ -93,6 +93,7 @@
     @Test
     public void testNoCrashWithoutVisibilityListener() {
         mView.setOnVisibilityChangedListener(null);
-        mView.onVisibilityChanged(mView, View.VISIBLE);
+        mView.setVisibility(View.INVISIBLE);
+        mView.setVisibility(View.VISIBLE);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
index 92e60f9..fc043c5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
@@ -26,7 +26,6 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.Resources;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -47,7 +46,7 @@
 @SmallTest
 public class SmartReplyViewTest extends SysuiTestCase {
     private static final String TEST_RESULT_KEY = "test_result_key";
-    private static final String TEST_ACTION = "com.android.ACTION";
+    private static final String TEST_ACTION = "com.android.SMART_REPLY_VIEW_ACTION";
 
     private static final String[] TEST_CHOICES = new String[]{"Hello", "What's up?", "I'm here"};
 
@@ -77,7 +76,6 @@
         mSpacing = res.getDimensionPixelSize(R.dimen.smart_reply_button_spacing);
     }
 
-    @FlakyTest
     @Test
     public void testSendSmartReply_intentContainsResultsAndSource() throws InterruptedException {
         setRepliesFromRemoteInput(TEST_CHOICES);
@@ -182,7 +180,6 @@
         assertEqualLayouts(expectedView.getChildAt(2), mView.getChildAt(2));
     }
 
-    @FlakyTest
     @Test
     public void testMeasure_choiceWithThreeLines() {
         final CharSequence[] choices = new CharSequence[]{"Hi", "Hello\nevery\nbody", "Bye"};
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index eba9830..50968a0 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -22,6 +22,7 @@
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS;
 
 import static com.android.internal.util.FunctionalUtils.ignoreRemoteException;
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 
 import android.Manifest;
 import android.accessibilityservice.AccessibilityService;
@@ -100,18 +101,20 @@
 import android.view.accessibility.IAccessibilityManagerClient;
 
 import com.android.internal.R;
+import com.android.internal.accessibility.AccessibilityShortcutController;
+import com.android.internal.accessibility.AccessibilityShortcutController.ToggleableFrameworkFeatureInfo;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IntPair;
+import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.LocalServices;
-import com.android.internal.accessibility.AccessibilityShortcutController;
-import com.android.internal.accessibility.AccessibilityShortcutController.ToggleableFrameworkFeatureInfo;
 import com.android.server.wm.WindowManagerInternal;
 
 import libcore.util.EmptyArray;
+
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.FileDescriptor;
@@ -126,8 +129,8 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.function.Consumer;
+import java.util.function.IntSupplier;
 
 /**
  * This class is instantiated by the system as a system level service and can be
@@ -293,6 +296,12 @@
         return mFingerprintGestureDispatcher;
     }
 
+    private UserState getUserState(int userId) {
+        synchronized (mLock) {
+            return getUserStateLocked(userId);
+        }
+    }
+
     private UserState getUserStateLocked(int userId) {
         UserState state = mUserStates.get(userId);
         if (state == null) {
@@ -540,9 +549,9 @@
                     dispatchEvent = true;
                 }
                 if (mHasInputFilter && mInputFilter != null) {
-                    mMainHandler.obtainMessage(
-                            MainHandler.MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER,
-                            AccessibilityEvent.obtain(event)).sendToTarget();
+                    mMainHandler.sendMessage(obtainMessage(
+                            AccessibilityManagerService::sendAccessibilityEventToInputFilter,
+                            this, AccessibilityEvent.obtain(event)));
                 }
             }
         }
@@ -568,6 +577,15 @@
         }
     }
 
+    private void sendAccessibilityEventToInputFilter(AccessibilityEvent event) {
+        synchronized (mLock) {
+            if (mHasInputFilter && mInputFilter != null) {
+                mInputFilter.notifyAccessibilityEvent(event);
+            }
+        }
+        event.recycle();
+    }
+
     @Override
     public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList(int userId) {
         synchronized (mLock) {
@@ -1024,8 +1042,9 @@
 
             // Disable the local managers for the old user.
             if (oldUserState.mUserClients.getRegisteredCallbackCount() > 0) {
-                mMainHandler.obtainMessage(MainHandler.MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER,
-                        oldUserState.mUserId, 0).sendToTarget();
+                mMainHandler.sendMessage(obtainMessage(
+                        AccessibilityManagerService::sendStateToClients,
+                        this, 0, oldUserState.mUserId));
             }
 
             // Announce user changes only if more that one exist.
@@ -1045,12 +1064,29 @@
 
             if (announceNewUser) {
                 // Schedule announcement of the current user if needed.
-                mMainHandler.sendEmptyMessageDelayed(MainHandler.MSG_ANNOUNCE_NEW_USER_IF_NEEDED,
+                mMainHandler.sendMessageDelayed(
+                        obtainMessage(AccessibilityManagerService::announceNewUserIfNeeded, this),
                         WAIT_FOR_USER_STATE_FULLY_INITIALIZED_MILLIS);
             }
         }
     }
 
+    private void announceNewUserIfNeeded() {
+        synchronized (mLock) {
+            UserState userState = getCurrentUserStateLocked();
+            if (userState.isHandlingAccessibilityEvents()) {
+                UserManager userManager = (UserManager) mContext.getSystemService(
+                        Context.USER_SERVICE);
+                String message = mContext.getString(R.string.user_switched,
+                        userManager.getUserInfo(mCurrentUserId).name);
+                AccessibilityEvent event = AccessibilityEvent.obtain(
+                        AccessibilityEvent.TYPE_ANNOUNCEMENT);
+                event.getText().add(message);
+                sendAccessibilityEventLocked(event, mCurrentUserId);
+            }
+        }
+    }
+
     private void unlockUser(int userId) {
         synchronized (mLock) {
             int parentUserId = mSecurityPolicy.resolveProfileParentLocked(userId);
@@ -1154,8 +1190,8 @@
         }
         if (potentialTargets == 1) {
             if (state.mIsNavBarMagnificationEnabled) {
-                mMainHandler.obtainMessage(
-                        MainHandler.MSG_SEND_ACCESSIBILITY_BUTTON_TO_INPUT_FILTER).sendToTarget();
+                mMainHandler.sendMessage(obtainMessage(
+                        AccessibilityManagerService::sendAccessibilityButtonToInputFilter, this));
                 return;
             } else {
                 for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
@@ -1169,12 +1205,12 @@
         } else {
             if (state.mServiceAssignedToAccessibilityButton == null
                     && !state.mIsNavBarMagnificationAssignedToAccessibilityButton) {
-                mMainHandler.obtainMessage(
-                        MainHandler.MSG_SHOW_ACCESSIBILITY_BUTTON_CHOOSER).sendToTarget();
+                mMainHandler.sendMessage(obtainMessage(
+                        AccessibilityManagerService::showAccessibilityButtonTargetSelection, this));
             } else if (state.mIsNavBarMagnificationEnabled
                     && state.mIsNavBarMagnificationAssignedToAccessibilityButton) {
-                mMainHandler.obtainMessage(
-                        MainHandler.MSG_SEND_ACCESSIBILITY_BUTTON_TO_INPUT_FILTER).sendToTarget();
+                mMainHandler.sendMessage(obtainMessage(
+                        AccessibilityManagerService::sendAccessibilityButtonToInputFilter, this));
                 return;
             } else {
                 for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
@@ -1187,11 +1223,25 @@
                 }
             }
             // The user may have turned off the assigned service or feature
-            mMainHandler.obtainMessage(
-                    MainHandler.MSG_SHOW_ACCESSIBILITY_BUTTON_CHOOSER).sendToTarget();
+            mMainHandler.sendMessage(obtainMessage(
+                    AccessibilityManagerService::showAccessibilityButtonTargetSelection, this));
         }
     }
 
+    private void sendAccessibilityButtonToInputFilter() {
+        synchronized (mLock) {
+            if (mHasInputFilter && mInputFilter != null) {
+                mInputFilter.notifyAccessibilityButtonClicked();
+            }
+        }
+    }
+
+    private void showAccessibilityButtonTargetSelection() {
+        Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        mContext.startActivityAsUser(intent, UserHandle.of(mCurrentUserId));
+    }
+
     private void notifyAccessibilityButtonVisibilityChangedLocked(boolean available) {
         final UserState state = getCurrentUserStateLocked();
         mIsAccessibilityButtonShown = available;
@@ -1555,28 +1605,54 @@
                 && (mGlobalClients.getRegisteredCallbackCount() > 0
                         || userState.mUserClients.getRegisteredCallbackCount() > 0)) {
             userState.mLastSentClientState = clientState;
-            mMainHandler.obtainMessage(MainHandler.MSG_SEND_STATE_TO_CLIENTS,
-                    clientState, userState.mUserId).sendToTarget();
+            mMainHandler.sendMessage(obtainMessage(
+                    AccessibilityManagerService::sendStateToAllClients,
+                    this, clientState, userState.mUserId));
         }
     }
 
-    private void showAccessibilityButtonTargetSelection() {
-        Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-        mContext.startActivityAsUser(intent, UserHandle.of(mCurrentUserId));
+    private void sendStateToAllClients(int clientState, int userId) {
+        sendStateToClients(clientState, mGlobalClients);
+        sendStateToClients(clientState, userId);
+    }
+
+    private void sendStateToClients(int clientState, int userId) {
+        sendStateToClients(clientState, getUserState(userId).mUserClients);
+    }
+
+    private void sendStateToClients(int clientState,
+            RemoteCallbackList<IAccessibilityManagerClient> clients) {
+        clients.broadcast(ignoreRemoteException(
+                client -> client.setState(clientState)));
     }
 
     private void scheduleNotifyClientsOfServicesStateChange(UserState userState) {
-        mMainHandler.obtainMessage(MainHandler.MSG_SEND_SERVICES_STATE_CHANGED_TO_CLIENTS,
-                userState.mUserId).sendToTarget();
+        mMainHandler.sendMessage(obtainMessage(
+                AccessibilityManagerService::sendServicesStateChanged,
+                this, userState.mUserClients));
+    }
+
+    private void sendServicesStateChanged(
+            RemoteCallbackList<IAccessibilityManagerClient> userClients) {
+        notifyClientsOfServicesStateChange(mGlobalClients);
+        notifyClientsOfServicesStateChange(userClients);
+    }
+
+    private void notifyClientsOfServicesStateChange(
+            RemoteCallbackList<IAccessibilityManagerClient> clients) {
+        clients.broadcast(ignoreRemoteException(
+                client -> client.notifyServicesStateChanged()));
     }
 
     private void scheduleUpdateInputFilter(UserState userState) {
-        mMainHandler.obtainMessage(MainHandler.MSG_UPDATE_INPUT_FILTER, userState).sendToTarget();
+        mMainHandler.sendMessage(obtainMessage(
+                AccessibilityManagerService::updateInputFilter, this, userState));
     }
 
     private void scheduleUpdateFingerprintGestureHandling(UserState userState) {
-        mMainHandler.obtainMessage(MainHandler.MSG_UPDATE_FINGERPRINT, userState).sendToTarget();
+        mMainHandler.sendMessage(obtainMessage(
+                AccessibilityManagerService::updateFingerprintGestureHandling,
+                this, userState));
     }
 
     private void updateInputFilter(UserState userState) {
@@ -2039,9 +2115,9 @@
                 return true;
             } else if (mEnableTouchExplorationDialog == null
                     || !mEnableTouchExplorationDialog.isShowing()) {
-                mMainHandler.obtainMessage(
-                        MainHandler.MSG_SHOW_ENABLED_TOUCH_EXPLORATION_DIALOG,
-                        service).sendToTarget();
+                mMainHandler.sendMessage(obtainMessage(
+                        AccessibilityManagerService::showEnableTouchExplorationDialog,
+                        this, service));
             }
         } else {
             // Starting in JB-MR2 we request an accessibility service to declare
@@ -2293,9 +2369,9 @@
     private void sendAccessibilityEventLocked(AccessibilityEvent event, int userId) {
         // Resync to avoid calling out with the lock held
         event.setEventTime(SystemClock.uptimeMillis());
-        mMainHandler.obtainMessage(
-                MainHandler.MSG_SEND_ACCESSIBILITY_EVENT, userId, 0 /* unused */, event)
-                .sendToTarget();
+        mMainHandler.sendMessage(obtainMessage(
+                AccessibilityManagerService::sendAccessibilityEvent,
+                this, event, userId));
     }
 
     /**
@@ -2419,22 +2495,9 @@
         }
     }
 
+    //TODO remove after refactoring KeyEventDispatcherTest
     final class MainHandler extends Handler {
-        public static final int MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER = 1;
-        public static final int MSG_SEND_STATE_TO_CLIENTS = 2;
-        public static final int MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER = 3;
-        public static final int MSG_ANNOUNCE_NEW_USER_IF_NEEDED = 5;
-        public static final int MSG_UPDATE_INPUT_FILTER = 6;
-        public static final int MSG_SHOW_ENABLED_TOUCH_EXPLORATION_DIALOG = 7;
         public static final int MSG_SEND_KEY_EVENT_TO_INPUT_FILTER = 8;
-        public static final int MSG_CLEAR_ACCESSIBILITY_FOCUS = 9;
-        public static final int MSG_SEND_SERVICES_STATE_CHANGED_TO_CLIENTS = 10;
-        public static final int MSG_UPDATE_FINGERPRINT = 11;
-        public static final int MSG_SEND_RELEVANT_EVENTS_CHANGED_TO_CLIENTS = 12;
-        public static final int MSG_SEND_ACCESSIBILITY_BUTTON_TO_INPUT_FILTER = 13;
-        public static final int MSG_SHOW_ACCESSIBILITY_BUTTON_CHOOSER = 14;
-        public static final int MSG_INIT_SERVICE = 15;
-        public static final int MSG_SEND_ACCESSIBILITY_EVENT = 16;
 
         public MainHandler(Looper looper) {
             super(looper);
@@ -2442,143 +2505,25 @@
 
         @Override
         public void handleMessage(Message msg) {
-            final int type = msg.what;
-            switch (type) {
-                case MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER: {
-                    AccessibilityEvent event = (AccessibilityEvent) msg.obj;
-                    synchronized (mLock) {
-                        if (mHasInputFilter && mInputFilter != null) {
-                            mInputFilter.notifyAccessibilityEvent(event);
-                        }
+            if (msg.what == MSG_SEND_KEY_EVENT_TO_INPUT_FILTER) {
+                KeyEvent event = (KeyEvent) msg.obj;
+                final int policyFlags = msg.arg1;
+                synchronized (mLock) {
+                    if (mHasInputFilter && mInputFilter != null) {
+                        mInputFilter.sendInputEvent(event, policyFlags);
                     }
-                    event.recycle();
-                } break;
-
-                case MSG_SEND_KEY_EVENT_TO_INPUT_FILTER: {
-                    KeyEvent event = (KeyEvent) msg.obj;
-                    final int policyFlags = msg.arg1;
-                    synchronized (mLock) {
-                        if (mHasInputFilter && mInputFilter != null) {
-                            mInputFilter.sendInputEvent(event, policyFlags);
-                        }
-                    }
-                    event.recycle();
-                } break;
-
-                case MSG_SEND_STATE_TO_CLIENTS: {
-                    final int clientState = msg.arg1;
-                    final int userId = msg.arg2;
-                    sendStateToClients(clientState, mGlobalClients);
-                    sendStateToClients(clientState, getUserClientsForId(userId));
-                } break;
-
-                case MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER: {
-                    final int userId = msg.arg1;
-                    sendStateToClients(0, getUserClientsForId(userId));
-                } break;
-
-                case MSG_ANNOUNCE_NEW_USER_IF_NEEDED: {
-                    announceNewUserIfNeeded();
-                } break;
-
-                case MSG_UPDATE_INPUT_FILTER: {
-                    UserState userState = (UserState) msg.obj;
-                    updateInputFilter(userState);
-                } break;
-
-                case MSG_SHOW_ENABLED_TOUCH_EXPLORATION_DIALOG: {
-                    AccessibilityServiceConnection service =
-                            (AccessibilityServiceConnection) msg.obj;
-                    showEnableTouchExplorationDialog(service);
-                } break;
-
-                case MSG_CLEAR_ACCESSIBILITY_FOCUS: {
-                    final int windowId = msg.arg1;
-                    getInteractionBridge().clearAccessibilityFocusNotLocked(windowId);
-                } break;
-
-                case MSG_SEND_SERVICES_STATE_CHANGED_TO_CLIENTS: {
-                    final int userId = msg.arg1;
-                    notifyClientsOfServicesStateChange(mGlobalClients);
-                    notifyClientsOfServicesStateChange(getUserClientsForId(userId));
-                } break;
-
-                case MSG_UPDATE_FINGERPRINT: {
-                    updateFingerprintGestureHandling((UserState) msg.obj);
-                } break;
-
-                case MSG_SEND_RELEVANT_EVENTS_CHANGED_TO_CLIENTS: {
-                    final int userId = msg.arg1;
-                    final int relevantEventTypes = msg.arg2;
-                    final UserState userState;
-                    synchronized (mLock) {
-                        userState = getUserStateLocked(userId);
-                    }
-                    broadcastToClients(userState, ignoreRemoteException(
-                            client -> client.mCallback.setRelevantEventTypes(relevantEventTypes)));
-                } break;
-
-               case MSG_SEND_ACCESSIBILITY_BUTTON_TO_INPUT_FILTER: {
-                    synchronized (mLock) {
-                        if (mHasInputFilter && mInputFilter != null) {
-                            mInputFilter.notifyAccessibilityButtonClicked();
-                        }
-                    }
-                } break;
-
-                case MSG_SHOW_ACCESSIBILITY_BUTTON_CHOOSER: {
-                    showAccessibilityButtonTargetSelection();
-                } break;
-
-                case MSG_INIT_SERVICE: {
-                    final AccessibilityServiceConnection service =
-                            (AccessibilityServiceConnection) msg.obj;
-                    service.initializeService();
-                } break;
-
-                case MSG_SEND_ACCESSIBILITY_EVENT: {
-                    final AccessibilityEvent event = (AccessibilityEvent) msg.obj;
-                    final int userId = msg.arg1;
-                    sendAccessibilityEvent(event, userId);
                 }
+                event.recycle();
             }
         }
+    }
 
-        private void announceNewUserIfNeeded() {
-            synchronized (mLock) {
-                UserState userState = getCurrentUserStateLocked();
-                if (userState.isHandlingAccessibilityEvents()) {
-                    UserManager userManager = (UserManager) mContext.getSystemService(
-                            Context.USER_SERVICE);
-                    String message = mContext.getString(R.string.user_switched,
-                            userManager.getUserInfo(mCurrentUserId).name);
-                    AccessibilityEvent event = AccessibilityEvent.obtain(
-                            AccessibilityEvent.TYPE_ANNOUNCEMENT);
-                    event.getText().add(message);
-                    sendAccessibilityEventLocked(event, mCurrentUserId);
-                }
-            }
-        }
+    void clearAccessibilityFocus(IntSupplier windowId) {
+        clearAccessibilityFocus(windowId.getAsInt());
+    }
 
-        private RemoteCallbackList<IAccessibilityManagerClient> getUserClientsForId(int userId) {
-            final UserState userState;
-            synchronized (mLock) {
-                userState = getUserStateLocked(userId);
-            }
-            return userState.mUserClients;
-        }
-
-        private void sendStateToClients(int clientState,
-                RemoteCallbackList<IAccessibilityManagerClient> clients) {
-            clients.broadcast(ignoreRemoteException(
-                    client -> client.setState(clientState)));
-        }
-
-        private void notifyClientsOfServicesStateChange(
-                RemoteCallbackList<IAccessibilityManagerClient> clients) {
-            clients.broadcast(ignoreRemoteException(
-                    client -> client.notifyServicesStateChanged()));
-        }
+    void clearAccessibilityFocus(int windowId) {
+        getInteractionBridge().clearAccessibilityFocusNotLocked(windowId);
     }
 
     private int findWindowIdLocked(IBinder token) {
@@ -2912,7 +2857,7 @@
          * Has no effect if no item has accessibility focus, if the item with accessibility
          * focus does not expose the specified action, or if the action fails.
          *
-         * @param actionId The id of the action to perform.
+         * @param action The action to perform.
          *
          * @return {@code true} if the action was performed. {@code false} if it was not.
          */
@@ -3353,8 +3298,9 @@
                 case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: {
                     synchronized (mLock) {
                         if (mAccessibilityFocusedWindowId != windowId) {
-                            mMainHandler.obtainMessage(MainHandler.MSG_CLEAR_ACCESSIBILITY_FOCUS,
-                                    mAccessibilityFocusedWindowId, 0).sendToTarget();
+                            mMainHandler.sendMessage(obtainMessage(
+                                    AccessibilityManagerService::clearAccessibilityFocus,
+                                    AccessibilityManagerService.this, 0));
                             mSecurityPolicy.setAccessibilityFocusedWindowLocked(windowId);
                             mAccessibilityFocusNodeId = nodeId;
                         }
@@ -3406,12 +3352,17 @@
                 if (oldActiveWindow != mSecurityPolicy.mActiveWindowId
                         && mAccessibilityFocusedWindowId == oldActiveWindow
                         && getCurrentUserStateLocked().mAccessibilityFocusOnlyInActiveWindow) {
-                    mMainHandler.obtainMessage(MainHandler.MSG_CLEAR_ACCESSIBILITY_FOCUS,
-                            oldActiveWindow, 0).sendToTarget();
+                    mMainHandler.sendMessage(obtainMessage(
+                            AccessibilityManagerService::clearAccessibilityFocus,
+                            AccessibilityManagerService.this, box(oldActiveWindow)));
                 }
             }
         }
 
+        private IntSupplier box(int value) {
+            return PooledLambda.obtainSupplier(value).recycleOnUse();
+        }
+
         public int getActiveWindowId() {
             if (mActiveWindowId == INVALID_WINDOW_ID && !mTouchInteractionInProgress) {
                 mActiveWindowId = getFocusedWindowId();
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
index 96b8979..89bf82d 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
@@ -18,6 +18,8 @@
 
 import static android.provider.Settings.Secure.SHOW_MODE_AUTO;
 
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.accessibilityservice.IAccessibilityServiceClient;
 import android.content.ComponentName;
@@ -158,8 +160,8 @@
             mSystemSupport.onClientChange(false);
             // Initialize the service on the main handler after we're done setting up for
             // the new configuration (for example, initializing the input filter).
-            mMainHandler.obtainMessage(
-                    AccessibilityManagerService.MainHandler.MSG_INIT_SERVICE, this).sendToTarget();
+            mMainHandler.sendMessage(obtainMessage(
+                    AccessibilityServiceConnection::initializeService, this));
         }
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index db62961..05237af 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -524,6 +524,7 @@
 
     private void addCompatibilityModeRequestsLocked(@NonNull AutofillManagerServiceImpl service
             , int userId) {
+        mAutofillCompatState.reset();
         final ArrayMap<String, Pair<Long, String>> compatPackages =
                 service.getCompatibilityPackagesLocked();
         if (compatPackages == null || compatPackages.isEmpty()) {
@@ -626,6 +627,15 @@
                 }
             }
         }
+
+        void reset() {
+            synchronized (mLock) {
+                if (mUserSpecs != null) {
+                    mUserSpecs.clear();
+                    mUserSpecs = null;
+                }
+            }
+        }
     }
 
     final class AutoFillManagerServiceStub extends IAutoFillManager.Stub {
@@ -1045,6 +1055,9 @@
                     Settings.Secure.AUTOFILL_SERVICE), false, this, UserHandle.USER_ALL);
             resolver.registerContentObserver(Settings.Secure.getUriFor(
                     Settings.Secure.USER_SETUP_COMPLETE), false, this, UserHandle.USER_ALL);
+            resolver.registerContentObserver(Settings.Global.getUriFor(
+                    Settings.Global.AUTOFILL_COMPAT_ALLOWED_PACKAGES), false, this,
+                    UserHandle.USER_ALL);
         }
 
         @Override
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 32f03b3..bcfe1b6 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -76,6 +76,7 @@
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.TimeUtils;
+import android.view.KeyEvent;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillManager;
 import android.view.autofill.AutofillValue;
@@ -812,6 +813,27 @@
         }
     }
 
+    @Override
+    public void dispatchUnhandledKey(AutofillId id, KeyEvent keyEvent) {
+        synchronized (mLock) {
+            if (mDestroyed) {
+                Slog.w(TAG, "Call to Session#dispatchUnhandledKey() rejected - session: "
+                        + id + " destroyed");
+                return;
+            }
+            if (id.equals(mCurrentViewId)) {
+                try {
+                    mClient.dispatchUnhandledKey(this.id, id, keyEvent);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Error requesting to dispatch unhandled key", e);
+                }
+            } else {
+                Slog.w(TAG, "Do not dispatch unhandled key on " + id
+                        + " as it is not the current view (" + mCurrentViewId + ") anymore");
+            }
+        }
+    }
+
     // AutoFillUiCallback
     @Override
     public void requestHideFillUi(AutofillId id) {
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index dc36518..e28a204 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -34,6 +34,7 @@
 import android.service.autofill.ValueFinder;
 import android.text.TextUtils;
 import android.util.Slog;
+import android.view.KeyEvent;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillManager;
 import android.view.autofill.IAutofillWindowPresenter;
@@ -78,6 +79,7 @@
                 IAutofillWindowPresenter presenter);
         void requestHideFillUi(AutofillId id);
         void startIntentSender(IntentSender intentSender);
+        void dispatchUnhandledKey(AutofillId id, KeyEvent keyEvent);
     }
 
     public AutoFillUI(@NonNull Context context) {
@@ -240,6 +242,13 @@
                         mCallback.startIntentSender(intentSender);
                     }
                 }
+
+                @Override
+                public void dispatchUnhandledKey(KeyEvent keyEvent) {
+                    if (mCallback != null) {
+                        mCallback.dispatchUnhandledKey(focusedId, keyEvent);
+                    }
+                }
             });
         });
     }
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index d64244d..7278e83 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -18,6 +18,7 @@
 import static com.android.server.autofill.Helper.sDebug;
 import static com.android.server.autofill.Helper.sVerbose;
 
+import android.annotation.AttrRes;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.PendingIntent;
@@ -31,8 +32,10 @@
 import android.service.autofill.Dataset.DatasetFieldFilter;
 import android.service.autofill.FillResponse;
 import android.text.TextUtils;
+import android.util.AttributeSet;
 import android.util.Slog;
 import android.util.TypedValue;
+import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
@@ -47,6 +50,7 @@
 import android.widget.BaseAdapter;
 import android.widget.Filter;
 import android.widget.Filterable;
+import android.widget.FrameLayout;
 import android.widget.ListView;
 import android.widget.RemoteViews;
 
@@ -69,6 +73,28 @@
 
     private static final TypedValue sTempTypedValue = new TypedValue();
 
+    public static final class AutofillFrameLayout extends FrameLayout {
+
+        OnKeyListener mUnhandledListener;
+
+        public AutofillFrameLayout(Context context, AttributeSet attrs) {
+            super(context, attrs);
+        }
+
+        public AutofillFrameLayout(Context context, AttributeSet attrs, @AttrRes int defStyleAttr) {
+            super(context, attrs, defStyleAttr);
+        }
+
+        @Override
+        public boolean dispatchKeyEvent(KeyEvent event) {
+            boolean handled = super.dispatchKeyEvent(event);
+            if (!handled) {
+                handled = mUnhandledListener.onKey(this, event.getKeyCode(), event);
+            }
+            return handled;
+        }
+    }
+
     interface Callback {
         void onResponsePicked(@NonNull FillResponse response);
         void onDatasetPicked(@NonNull Dataset dataset);
@@ -78,6 +104,7 @@
                 IAutofillWindowPresenter windowPresenter);
         void requestHideFillUi();
         void startIntentSender(IntentSender intentSender);
+        void dispatchUnhandledKey(KeyEvent keyEvent);
     }
 
     private final @NonNull Point mTempPoint = new Point();
@@ -122,6 +149,31 @@
                 mFullScreen ? R.layout.autofill_dataset_picker_fullscreen
                         : R.layout.autofill_dataset_picker, null);
 
+        // if autofill ui is not fullscreen, send unhandled keyevent to app window.
+        if (!mFullScreen) {
+            if (decor instanceof AutofillFrameLayout) {
+                ((AutofillFrameLayout) decor).mUnhandledListener =
+                        (View view, int keyCode, KeyEvent event) -> {
+                            switch (keyCode) {
+                                case KeyEvent.KEYCODE_BACK:
+                                case KeyEvent.KEYCODE_ESCAPE:
+                                case KeyEvent.KEYCODE_ENTER:
+                                case KeyEvent.KEYCODE_DPAD_CENTER:
+                                case KeyEvent.KEYCODE_DPAD_LEFT:
+                                case KeyEvent.KEYCODE_DPAD_UP:
+                                case KeyEvent.KEYCODE_DPAD_RIGHT:
+                                case KeyEvent.KEYCODE_DPAD_DOWN:
+                                    return false;
+                                default:
+                                    mCallback.dispatchUnhandledKey(event);
+                                    return true;
+                            }
+                        };
+            } else {
+                Slog.wtf(TAG, "Unable to send unhandled key");
+            }
+        }
+
         final RemoteViews.OnClickHandler interceptionHandler = new RemoteViews.OnClickHandler() {
             @Override
             public boolean onClickHandler(View view, PendingIntent pendingIntent,
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 83367f3..782bf71 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -2357,7 +2357,7 @@
 
         // If the caller does not hold the BACKUP permission, it can only request a
         // wipe of its own backed-up data.
-        HashSet<String> apps;
+        Set<String> apps;
         if ((mContext.checkPermission(android.Manifest.permission.BACKUP, Binder.getCallingPid(),
                 Binder.getCallingUid())) == PackageManager.PERMISSION_DENIED) {
             apps = mBackupParticipants.get(Binder.getCallingUid());
@@ -2365,10 +2365,9 @@
             // a caller with full permission can ask to back up any participating app
             // !!! TODO: allow data-clear of ANY app?
             if (MORE_DEBUG) Slog.v(TAG, "Privileged caller, allowing clear of other apps");
-            apps = SparseArrayUtils.union(mBackupParticipants);
+            apps = mProcessedPackagesJournal.getPackagesCopy();
         }
 
-        // Is the given app an available participant?
         if (apps.contains(packageName)) {
             // found it; fire off the clear request
             if (MORE_DEBUG) Slog.v(TAG, "Found the app - running clear process");
diff --git a/services/core/java/com/android/server/AppStateTracker.java b/services/core/java/com/android/server/AppStateTracker.java
index 9b29b32..fc4d463 100644
--- a/services/core/java/com/android/server/AppStateTracker.java
+++ b/services/core/java/com/android/server/AppStateTracker.java
@@ -53,6 +53,7 @@
 import com.android.internal.app.IAppOpsCallback;
 import com.android.internal.app.IAppOpsService;
 import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
 import com.android.server.ForceAppStandbyTrackerProto.ExemptedPackage;
 import com.android.server.ForceAppStandbyTrackerProto.RunAnyInBackgroundRestrictedPackages;
@@ -1182,72 +1183,67 @@
         }
     }
 
-    public void dump(PrintWriter pw, String indent) {
+    @Deprecated
+    public void dump(PrintWriter pw, String prefix) {
+        dump(new IndentingPrintWriter(pw, "  ").setIndent(prefix));
+    }
+
+    public void dump(IndentingPrintWriter pw) {
         synchronized (mLock) {
-            pw.print(indent);
             pw.println("Forced App Standby Feature enabled: " + mForcedAppStandbyEnabled);
 
-            pw.print(indent);
             pw.print("Force all apps standby: ");
             pw.println(isForceAllAppsStandbyEnabled());
 
-            pw.print(indent);
             pw.print("Small Battery Device: ");
             pw.println(isSmallBatteryDevice());
 
-            pw.print(indent);
             pw.print("Force all apps standby for small battery device: ");
             pw.println(mForceAllAppStandbyForSmallBattery);
 
-            pw.print(indent);
             pw.print("Plugged In: ");
             pw.println(mIsPluggedIn);
 
-            pw.print(indent);
             pw.print("Active uids: ");
             dumpUids(pw, mActiveUids);
 
-            pw.print(indent);
             pw.print("Foreground uids: ");
             dumpUids(pw, mForegroundUids);
 
-            pw.print(indent);
             pw.print("Whitelist appids: ");
             pw.println(Arrays.toString(mPowerWhitelistedAllAppIds));
 
-            pw.print(indent);
             pw.print("Temp whitelist appids: ");
             pw.println(Arrays.toString(mTempWhitelistedAppIds));
 
-            pw.print(indent);
             pw.println("Exempted packages:");
+            pw.increaseIndent();
             for (int i = 0; i < mExemptedPackages.size(); i++) {
-                pw.print(indent);
-                pw.print("  User ");
+                pw.print("User ");
                 pw.print(mExemptedPackages.keyAt(i));
                 pw.println();
 
+                pw.increaseIndent();
                 for (int j = 0; j < mExemptedPackages.sizeAt(i); j++) {
-                    pw.print(indent);
-                    pw.print("    ");
                     pw.print(mExemptedPackages.valueAt(i, j));
                     pw.println();
                 }
+                pw.decreaseIndent();
             }
+            pw.decreaseIndent();
             pw.println();
 
-            pw.print(indent);
             pw.println("Restricted packages:");
+            pw.increaseIndent();
             for (Pair<Integer, String> uidAndPackage : mRunAnyRestrictedPackages) {
-                pw.print(indent);
-                pw.print("  ");
                 pw.print(UserHandle.formatUid(uidAndPackage.first));
                 pw.print(" ");
                 pw.print(uidAndPackage.second);
                 pw.println();
             }
+            pw.decreaseIndent();
 
-            mStatLogger.dump(pw, indent);
+            mStatLogger.dump(pw);
         }
     }
 
diff --git a/services/core/java/com/android/server/StatLogger.java b/services/core/java/com/android/server/StatLogger.java
index 0e6f5e2..d85810d 100644
--- a/services/core/java/com/android/server/StatLogger.java
+++ b/services/core/java/com/android/server/StatLogger.java
@@ -21,6 +21,7 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.StatLoggerProto.Event;
 
 import java.io.PrintWriter;
@@ -78,19 +79,23 @@
         }
     }
 
+    @Deprecated
     public void dump(PrintWriter pw, String prefix) {
+        dump(new IndentingPrintWriter(pw, "  ").setIndent(prefix));
+    }
+
+    public void dump(IndentingPrintWriter pw) {
         synchronized (mLock) {
-            pw.print(prefix);
             pw.println("Stats:");
+            pw.increaseIndent();
             for (int i = 0; i < SIZE; i++) {
-                pw.print(prefix);
-                pw.print("  ");
                 final int count = mCountStats[i];
                 final double durationMs = mDurationStats[i] / 1000.0;
                 pw.println(String.format("%s: count=%d, total=%.1fms, avg=%.3fms",
                         mLabels[i], count, durationMs,
                         (count == 0 ? 0 : ((double) durationMs) / count)));
             }
+            pw.decreaseIndent();
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index efe5172..6fcdc3e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5689,8 +5689,7 @@
 
             final long origId = Binder.clearCallingIdentity();
 
-            if (self.state == ActivityState.RESUMED
-                    || self.state == ActivityState.PAUSING) {
+            if (self.isState(ActivityState.RESUMED, ActivityState.PAUSING)) {
                 mWindowManager.overridePendingAppTransition(packageName,
                         enterAnim, exitAnim, null);
             }
@@ -22774,7 +22773,7 @@
                         }
                     }
                     break;
-                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
+                } else if (r.isState(ActivityState.PAUSING, ActivityState.PAUSED)) {
                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                         app.adjType = "pause-activity";
@@ -22789,7 +22788,7 @@
                     app.cached = false;
                     app.empty = false;
                     foregroundActivities = true;
-                } else if (r.state == ActivityState.STOPPING) {
+                } else if (r.isState(ActivityState.STOPPING)) {
                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                         app.adjType = "stop-activity";
@@ -23183,9 +23182,8 @@
                     }
                     final ActivityRecord a = cr.activity;
                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
-                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
-                            (a.visible || a.state == ActivityState.RESUMED ||
-                             a.state == ActivityState.PAUSING)) {
+                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && (a.visible
+                                || a.isState(ActivityState.RESUMED, ActivityState.PAUSING))) {
                             adj = ProcessList.FOREGROUND_APP_ADJ;
                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index dadd869..07e27bc 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -25,6 +25,7 @@
 import android.app.IUidObserver;
 import android.app.ProfilerInfo;
 import android.app.WaitResult;
+import android.app.usage.AppStandbyInfo;
 import android.app.usage.ConfigurationStats;
 import android.app.usage.IUsageStatsManager;
 import android.app.usage.UsageStatsManager;
@@ -1944,15 +1945,16 @@
         if (!multiple) {
             usm.setAppStandbyBucket(packageName, bucketNameToBucketValue(value), userId);
         } else {
-            HashMap<String, Integer> buckets = new HashMap<>();
-            buckets.put(packageName, bucket);
+            ArrayList<AppStandbyInfo> bucketInfoList = new ArrayList<>();
+            bucketInfoList.add(new AppStandbyInfo(packageName, bucket));
             while ((packageName = getNextArg()) != null) {
                 value = getNextArgRequired();
                 bucket = bucketNameToBucketValue(value);
                 if (bucket < 0) continue;
-                buckets.put(packageName, bucket);
+                bucketInfoList.add(new AppStandbyInfo(packageName, bucket));
             }
-            usm.setAppStandbyBuckets(buckets, userId);
+            ParceledListSlice<AppStandbyInfo> slice = new ParceledListSlice<>(bucketInfoList);
+            usm.setAppStandbyBuckets(slice, userId);
         }
         return 0;
     }
@@ -1977,11 +1979,11 @@
             int bucket = usm.getAppStandbyBucket(packageName, null, userId);
             pw.println(bucket);
         } else {
-            Map<String, Integer> buckets = (Map<String, Integer>) usm.getAppStandbyBuckets(
+            ParceledListSlice<AppStandbyInfo> buckets = usm.getAppStandbyBuckets(
                     SHELL_PACKAGE_NAME, userId);
-            for (Map.Entry<String, Integer> entry: buckets.entrySet()) {
-                pw.print(entry.getKey()); pw.print(": ");
-                pw.println(entry.getValue());
+            for (AppStandbyInfo bucketInfo : buckets.getList()) {
+                pw.print(bucketInfo.mPackageName); pw.print(": ");
+                pw.println(bucketInfo.mStandbyBucket);
             }
         }
         return 0;
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index e6c1cd5..06faeb9 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -288,7 +288,7 @@
     HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold
     UriPermissionOwner uriPermissions; // current special URI access perms.
     ProcessRecord app;      // if non-null, hosting application
-    ActivityState state;    // current state we are in
+    private ActivityState mState;    // current state we are in
     Bundle  icicle;         // last saved activity state
     PersistableBundle persistentState; // last persistently saved activity state
     // TODO: See if this is still needed.
@@ -381,8 +381,8 @@
 
     String getLifecycleDescription(String reason) {
         return "name= " + this + ", component=" + intent.getComponent().flattenToShortString()
-                + ", package=" + packageName + ", state=" + state + ", reason=" + reason + ", time="
-                + System.currentTimeMillis();
+                + ", package=" + packageName + ", state=" + mState + ", reason=" + reason
+                + ", time=" + System.currentTimeMillis();
     }
 
     void dump(PrintWriter pw, String prefix) {
@@ -503,7 +503,7 @@
                 pw.println();
         pw.print(prefix); pw.print("haveState="); pw.print(haveState);
                 pw.print(" icicle="); pw.println(icicle);
-        pw.print(prefix); pw.print("state="); pw.print(state);
+        pw.print(prefix); pw.print("state="); pw.print(mState);
                 pw.print(" stopped="); pw.print(stopped);
                 pw.print(" delayedResume="); pw.print(delayedResume);
                 pw.print(" finishing="); pw.println(finishing);
@@ -841,7 +841,7 @@
         resultTo = _resultTo;
         resultWho = _resultWho;
         requestCode = _reqCode;
-        state = INITIALIZING;
+        setState(INITIALIZING, "ActivityRecord ctor");
         frontOfTask = false;
         launchFailed = false;
         stopped = false;
@@ -1000,6 +1000,11 @@
     }
 
     void removeWindowContainer() {
+        // Do not try to remove a window container if we have already removed it.
+        if (mWindowContainerController == null) {
+            return;
+        }
+
         // Resume key dispatching if it is currently paused before we remove the container.
         resumeKeyDispatchingLocked();
 
@@ -1259,7 +1264,7 @@
             return false;
         }
 
-        switch (state) {
+        switch (mState) {
             case RESUMED:
                 // When visible, allow entering PiP if the app is not locked.  If it is over the
                 // keyguard, then we will prompt to unlock in the caller before entering PiP.
@@ -1385,13 +1390,13 @@
         // - It is currently resumed or paused. i.e. it is currently visible to the user and we want
         //   the user to see the visual effects caused by the intent delivery now.
         // - The device is sleeping and it is the top activity behind the lock screen (b/6700897).
-        if ((state == RESUMED || state == PAUSED
+        if ((mState == RESUMED || mState == PAUSED
                 || isTopActivityWhileSleeping) && app != null && app.thread != null) {
             try {
                 ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
                 ar.add(rintent);
                 service.mLifecycleManager.scheduleTransaction(app.thread, appToken,
-                        NewIntentItem.obtain(ar, state == PAUSED));
+                        NewIntentItem.obtain(ar, mState == PAUSED));
                 unsent = false;
             } catch (RemoteException e) {
                 Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
@@ -1573,6 +1578,63 @@
         mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
     }
 
+    void setState(ActivityState state, String reason) {
+        if (DEBUG_STATES) Slog.v(TAG_STATES, "State movement: " + this + " from:" + getState()
+                        + " to:" + state + " reason:" + reason);
+        final boolean stateChanged = mState != state;
+        mState = state;
+
+        if (stateChanged && isState(DESTROYING, DESTROYED)) {
+            makeFinishingLocked();
+
+            // When moving to the destroyed state, immediately destroy the activity in the
+            // associated stack. Most paths for finishing an activity will handle an activity's path
+            // to destroy through mechanisms such as ActivityStackSupervisor#mFinishingActivities.
+            // However, moving to the destroyed state directly (as in the case of an app dying) and
+            // marking it as finished will lead to cleanup steps that will prevent later handling
+            // from happening.
+            if (isState(DESTROYED)) {
+                final ActivityStack stack = getStack();
+                if (stack != null) {
+                    stack.activityDestroyedLocked(this, reason);
+                }
+            }
+        }
+    }
+
+    ActivityState getState() {
+        return mState;
+    }
+
+    /**
+     * Returns {@code true} if the Activity is in the specified state.
+     */
+    boolean isState(ActivityState state) {
+        return state == mState;
+    }
+
+    /**
+     * Returns {@code true} if the Activity is in one of the specified states.
+     */
+    boolean isState(ActivityState state1, ActivityState state2) {
+        return state1 == mState || state2 == mState;
+    }
+
+    /**
+     * Returns {@code true} if the Activity is in one of the specified states.
+     */
+    boolean isState(ActivityState state1, ActivityState state2, ActivityState state3) {
+        return state1 == mState || state2 == mState || state3 == mState;
+    }
+
+    /**
+     * Returns {@code true} if the Activity is in one of the specified states.
+     */
+    boolean isState(ActivityState state1, ActivityState state2, ActivityState state3,
+            ActivityState state4) {
+        return state1 == mState || state2 == mState || state3 == mState || state4 == mState;
+    }
+
     void notifyAppResumed(boolean wasStopped) {
         mWindowContainerController.notifyAppResumed(wasStopped);
     }
@@ -1602,9 +1664,9 @@
 
     void makeVisibleIfNeeded(ActivityRecord starting) {
         // This activity is not currently visible, but is running. Tell it to become visible.
-        if (state == RESUMED || this == starting) {
+        if (mState == RESUMED || this == starting) {
             if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY,
-                    "Not making visible, r=" + this + " state=" + state + " starting=" + starting);
+                    "Not making visible, r=" + this + " state=" + mState + " starting=" + starting);
             return;
         }
 
@@ -1627,13 +1689,13 @@
             mStackSupervisor.mGoingToSleepActivities.remove(this);
 
             // If the activity is stopped or stopping, cycle to the paused state.
-            if (state == STOPPED || state == STOPPING) {
+            if (isState(STOPPED, STOPPING)) {
                 // Capture reason before state change
                 final String reason = getLifecycleDescription("makeVisibleIfNeeded");
 
                 // An activity must be in the {@link PAUSING} state for the system to validate
                 // the move to {@link PAUSED}.
-                state = PAUSING;
+                setState(PAUSING, "makeVisibleIfNeeded");
                 service.mLifecycleManager.scheduleTransaction(app.thread, appToken,
                         PauseActivityItem.obtain(finishing, false /* userLeaving */,
                                 configChangeFlags, false /* dontReport */)
@@ -1654,7 +1716,7 @@
             }
         } catch(RemoteException e) {
         }
-        return state == RESUMED;
+        return mState == RESUMED;
     }
 
     static void activityResumedLocked(IBinder token) {
@@ -1728,7 +1790,7 @@
     final void activityStoppedLocked(Bundle newIcicle, PersistableBundle newPersistentState,
             CharSequence description) {
         final ActivityStack stack = getStack();
-        if (state != STOPPING) {
+        if (mState != STOPPING) {
             Slog.i(TAG, "Activity reported stop, but no longer stopping: " + this);
             stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
             return;
@@ -1751,7 +1813,7 @@
             if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + this + " (stop complete)");
             stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
             stopped = true;
-            state = STOPPED;
+            setState(STOPPED, "activityStoppedLocked");
 
             mWindowContainerController.notifyAppStopped();
 
@@ -2021,8 +2083,7 @@
      * currently pausing, or is resumed.
      */
     public boolean isInterestingToUserLocked() {
-        return visible || nowVisible || state == PAUSING ||
-                state == RESUMED;
+        return visible || nowVisible || mState == PAUSING || mState == RESUMED;
     }
 
     void setSleeping(boolean _sleeping) {
@@ -2084,8 +2145,7 @@
     }
 
     final boolean isDestroyable() {
-        if (finishing || app == null || state == DESTROYING
-                || state == DESTROYED) {
+        if (finishing || app == null) {
             // This would be redundant.
             return false;
         }
@@ -2151,7 +2211,7 @@
                 compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
                 prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(),
                 allowTaskSnapshot(),
-                state.ordinal() >= RESUMED.ordinal() && state.ordinal() <= STOPPED.ordinal(),
+                mState.ordinal() >= RESUMED.ordinal() && mState.ordinal() <= STOPPED.ordinal(),
                 fromRecents);
         if (shown) {
             mStartingWindowState = STARTING_WINDOW_SHOWN;
@@ -2328,7 +2388,7 @@
         }
 
         // Skip updating configuration for activity that are stopping or stopped.
-        if (state == STOPPING || state == STOPPED) {
+        if (mState == STOPPING || mState == STOPPED) {
             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                     "Skipping config check stopped or stopping: " + this);
             return true;
@@ -2378,7 +2438,7 @@
 
         setLastReportedConfiguration(service.getGlobalConfiguration(), newMergedOverrideConfig);
 
-        if (state == INITIALIZING) {
+        if (mState == INITIALIZING) {
             // No need to relaunch or schedule new config for activity that hasn't been launched
             // yet. We do, however, return after applying the config to activity record, so that
             // it will use it for launch transaction.
@@ -2431,7 +2491,7 @@
                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                         "Config is destroying non-running " + this);
                 stack.destroyActivityLocked(this, true, "config");
-            } else if (state == PAUSING) {
+            } else if (mState == PAUSING) {
                 // A little annoying: we are waiting for this activity to finish pausing. Let's not
                 // do anything now, but just flag that it needs to be restarted when done pausing.
                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
@@ -2439,7 +2499,7 @@
                 deferRelaunchUntilPaused = true;
                 preserveWindowOnDeferredRelaunch = preserveWindow;
                 return true;
-            } else if (state == RESUMED) {
+            } else if (mState == RESUMED) {
                 // Try to optimize this case: the configuration is changing and we need to restart
                 // the top, resumed activity. Instead of doing the normal handshaking, just say
                 // "restart!".
@@ -2609,7 +2669,7 @@
             service.showAskCompatModeDialogLocked(this);
         } else {
             service.mHandler.removeMessages(PAUSE_TIMEOUT_MSG, this);
-            state = PAUSED;
+            setState(PAUSED, "relaunchActivityLocked");
             // if the app is relaunched when it's stopped, and we're not resuming,
             // put it back into stopped state.
             if (stopped) {
@@ -2853,7 +2913,7 @@
         final long token = proto.start(fieldId);
         super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
         writeIdentifierToProto(proto, IDENTIFIER);
-        proto.write(STATE, state.toString());
+        proto.write(STATE, mState.toString());
         proto.write(VISIBLE, visible);
         proto.write(FRONT_OF_TASK, frontOfTask);
         if (app != null) {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index fe10670..817b699 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -70,7 +70,12 @@
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
+import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
+import static com.android.server.am.ActivityStack.ActivityState.FINISHING;
 import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
+import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
+import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
 import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
 import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
 import static com.android.server.am.ActivityStackSupervisor.FindTaskResult;
@@ -1353,8 +1358,7 @@
             final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
                 final ActivityRecord r = activities.get(activityNdx);
-                if (r.state == STOPPING || r.state == STOPPED
-                        || r.state == ActivityState.PAUSED || r.state == ActivityState.PAUSING) {
+                if (r.isState(STOPPING, STOPPED, PAUSED, PAUSING)) {
                     r.setSleeping(true);
                 }
             }
@@ -1401,7 +1405,7 @@
             ActivityRecord resuming, boolean pauseImmediately) {
         if (mPausingActivity != null) {
             Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
-                    + " state=" + mPausingActivity.state);
+                    + " state=" + mPausingActivity.getState());
             if (!shouldSleepActivities()) {
                 // Avoid recursion among check for sleep and complete pause during sleeping.
                 // Because activity will be paused immediately after resume, just let pause
@@ -1431,7 +1435,7 @@
         mLastPausedActivity = prev;
         mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                 || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
-        prev.state = ActivityState.PAUSING;
+        prev.setState(PAUSING, "startPausingLocked");
         prev.getTask().touchActiveTime();
         clearLaunchTime(prev);
         final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
@@ -1525,8 +1529,8 @@
                         r.userId, System.identityHashCode(r), r.shortComponentName,
                         mPausingActivity != null
                             ? mPausingActivity.shortComponentName : "(none)");
-                if (r.state == ActivityState.PAUSING) {
-                    r.state = ActivityState.PAUSED;
+                if (r.isState(PAUSING)) {
+                    r.setState(PAUSED, "activityPausedLocked");
                     if (r.finishing) {
                         if (DEBUG_PAUSE) Slog.v(TAG,
                                 "Executing finish of failed to pause activity: " + r);
@@ -1544,8 +1548,8 @@
         if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);
 
         if (prev != null) {
-            final boolean wasStopping = prev.state == STOPPING;
-            prev.state = ActivityState.PAUSED;
+            final boolean wasStopping = prev.isState(STOPPING);
+            prev.setState(PAUSED, "completePausedLocked");
             if (prev.finishing) {
                 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
                 prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false,
@@ -1566,7 +1570,7 @@
                     // We are also stopping, the stop request must have gone soon after the pause.
                     // We can't clobber it, because the stop confirmation will not be handled.
                     // We don't need to schedule another stop, we only need to let it happen.
-                    prev.state = STOPPING;
+                    prev.setState(STOPPING, "completePausedLocked");
                 } else if (!prev.visible || shouldSleepOrShutDownActivities()) {
                     // Clear out any deferred client hide we might currently have.
                     prev.setDeferHidingClient(false);
@@ -1843,7 +1847,7 @@
                     }
                     if (reallyVisible) {
                         if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make visible? " + r
-                                + " finishing=" + r.finishing + " state=" + r.state);
+                                + " finishing=" + r.finishing + " state=" + r.getState());
                         // First: if this is not the current activity being started, make
                         // sure it matches the current configuration.
                         if (r != starting) {
@@ -1875,7 +1879,7 @@
                         configChanges |= r.configChangeFlags;
                     } else {
                         if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r
-                                + " finishing=" + r.finishing + " state=" + r.state
+                                + " finishing=" + r.finishing + " state=" + r.getState()
                                 + " stackShouldBeVisible=" + stackShouldBeVisible
                                 + " behindFullscreenActivity=" + behindFullscreenActivity
                                 + " mLaunchTaskBehind=" + r.mLaunchTaskBehind);
@@ -2059,7 +2063,7 @@
         }
         // Now for any activities that aren't visible to the user, make sure they no longer are
         // keeping the screen frozen.
-        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making invisible: " + r + " " + r.state);
+        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making invisible: " + r + " " + r.getState());
         try {
             final boolean canEnterPictureInPicture = r.checkEnterPictureInPictureState(
                     "makeInvisible", true /* beforeStopping */);
@@ -2071,11 +2075,11 @@
             // the current contract for "auto-Pip" is that the app should enter it before onPause
             // returns. Just need to confirm this reasoning makes sense.
             final boolean deferHidingClient = canEnterPictureInPicture
-                    && r.state != STOPPING && r.state != STOPPED && r.state != PAUSED;
+                    && !r.isState(STOPPING, STOPPED, PAUSED);
             r.setDeferHidingClient(deferHidingClient);
             r.setVisible(false);
 
-            switch (r.state) {
+            switch (r.getState()) {
                 case STOPPING:
                 case STOPPED:
                     if (r.app != null && r.app.thread != null) {
@@ -2255,7 +2259,7 @@
         // TODO: move mResumedActivity to stack supervisor,
         // there should only be 1 global copy of resumed activity.
         mResumedActivity = r;
-        r.state = ActivityState.RESUMED;
+        r.setState(RESUMED, "setResumedActivityLocked");
         mService.setResumedActivityUncheckLocked(r, reason);
         mStackSupervisor.mRecentTasks.add(r.getTask());
     }
@@ -2294,8 +2298,8 @@
         next.delayedResume = false;
 
         // If the top activity is the resumed one, nothing to do.
-        if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
-                    mStackSupervisor.allResumedActivitiesComplete()) {
+        if (mResumedActivity == next && next.isState(RESUMED)
+                && mStackSupervisor.allResumedActivitiesComplete()) {
             // Make sure we have executed any pending transitions, since there
             // should be nothing left to do at this point.
             executeAppTransition(options);
@@ -2389,8 +2393,8 @@
             }
             if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
             return true;
-        } else if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
-                mStackSupervisor.allResumedActivitiesComplete()) {
+        } else if (mResumedActivity == next && next.isState(RESUMED)
+                && mStackSupervisor.allResumedActivitiesComplete()) {
             // It is possible for the activity to be resumed when we paused back stacks above if the
             // next activity doesn't have to wait for pause to complete.
             // So, nothing else to-do except:
@@ -2539,7 +2543,7 @@
 
                 ActivityRecord lastResumedActivity =
                         lastStack == null ? null :lastStack.mResumedActivity;
-                ActivityState lastState = next.state;
+                final ActivityState lastState = next.getState();
 
                 mService.updateCpuStats();
 
@@ -2645,7 +2649,7 @@
                     // Whoops, need to restart this activity!
                     if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to "
                             + lastState + ": " + next);
-                    next.state = lastState;
+                    next.setState(lastState, "resumeTopActivityInnerLocked");
                     if (lastStack != null) {
                         lastStack.mResumedActivity = lastResumedActivity;
                     }
@@ -3408,7 +3412,7 @@
                 r.stopped = false;
                 if (DEBUG_STATES) Slog.v(TAG_STATES,
                         "Moving to STOPPING: " + r + " (stop requested)");
-                r.state = STOPPING;
+                r.setState(STOPPING, "stopActivityLocked");
                 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                         "Stopping visible=" + r.visible + " for " + r);
                 if (!r.visible) {
@@ -3432,7 +3436,7 @@
                 // Just in case, assume it to be stopped.
                 r.stopped = true;
                 if (DEBUG_STATES) Slog.v(TAG_STATES, "Stop failed; moving to STOPPED: " + r);
-                r.state = STOPPED;
+                r.setState(STOPPED, "stopActivityLocked");
                 if (r.deferRelaunchUntilPaused) {
                     destroyActivityLocked(r, true, "stop-except");
                 }
@@ -3505,9 +3509,7 @@
         }
         if (activityNdx >= 0) {
             r = mTaskHistory.get(taskNdx).mActivities.get(activityNdx);
-            if (r.state == ActivityState.RESUMED
-                    || r.state == ActivityState.PAUSING
-                    || r.state == ActivityState.PAUSED) {
+            if (r.isState(RESUMED, PAUSING, PAUSED)) {
                 if (!r.isActivityTypeHome() || mService.mHomeProcess != r.app) {
                     Slog.w(TAG, "  Force finishing activity "
                             + r.intent.getComponent().flattenToShortString());
@@ -3671,7 +3673,7 @@
                 if (endTask) {
                     mService.mLockTaskController.clearLockedTask(task);
                 }
-            } else if (r.state != ActivityState.PAUSING) {
+            } else if (!r.isState(PAUSING)) {
                 // If the activity is PAUSING, we will complete the finish once
                 // it is done pausing; else we can just directly finish it here.
                 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r);
@@ -3738,7 +3740,7 @@
             }
             if (DEBUG_STATES) Slog.v(TAG_STATES,
                     "Moving to STOPPING: "+ r + " (finish requested)");
-            r.state = STOPPING;
+            r.setState(STOPPING, "finishCurrentActivityLocked");
             if (oomAdj) {
                 mService.updateOomAdjLocked();
             }
@@ -3752,15 +3754,15 @@
         if (mResumedActivity == r) {
             mResumedActivity = null;
         }
-        final ActivityState prevState = r.state;
+        final ActivityState prevState = r.getState();
         if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + r);
-        r.state = ActivityState.FINISHING;
+        r.setState(FINISHING, "finishCurrentActivityLocked");
         final boolean finishingActivityInNonFocusedStack
                 = r.getStack() != mStackSupervisor.getFocusedStack()
-                && prevState == ActivityState.PAUSED && mode == FINISH_AFTER_VISIBLE;
+                && prevState == PAUSED && mode == FINISH_AFTER_VISIBLE;
 
         if (mode == FINISH_IMMEDIATELY
-                || (prevState == ActivityState.PAUSED
+                || (prevState == PAUSED
                     && (mode == FINISH_AFTER_PAUSE || inPinnedWindowingMode()))
                 || finishingActivityInNonFocusedStack
                 || prevState == STOPPING
@@ -3981,7 +3983,7 @@
 
         if (setState) {
             if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + r + " (cleaning up)");
-            r.state = ActivityState.DESTROYED;
+            r.setState(DESTROYED, "cleanupActivityLocked");
             if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during cleanUp for activity " + r);
             r.app = null;
         }
@@ -4030,7 +4032,7 @@
         removeTimeoutsForActivityLocked(r);
         if (DEBUG_STATES) Slog.v(TAG_STATES,
                 "Moving to DESTROYED: " + r + " (removed from history)");
-        r.state = ActivityState.DESTROYED;
+        r.setState(DESTROYED, "removeActivityFromHistoryLocked");
         if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during remove for activity " + r);
         r.app = null;
         r.removeWindowContainer();
@@ -4114,7 +4116,8 @@
                     continue;
                 }
                 if (r.isDestroyable()) {
-                    if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Destroying " + r + " in state " + r.state
+                    if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Destroying " + r
+                            + " in state " + r.getState()
                             + " resumed=" + mResumedActivity
                             + " pausing=" + mPausingActivity + " for reason " + reason);
                     if (destroyActivityLocked(r, true, reason)) {
@@ -4131,7 +4134,7 @@
     final boolean safelyDestroyActivityLocked(ActivityRecord r, String reason) {
         if (r.isDestroyable()) {
             if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
-                    "Destroying " + r + " in state " + r.state + " resumed=" + mResumedActivity
+                    "Destroying " + r + " in state " + r.getState() + " resumed=" + mResumedActivity
                     + " pausing=" + mPausingActivity + " for reason " + reason);
             return destroyActivityLocked(r, true, reason);
         }
@@ -4159,7 +4162,7 @@
                 final ActivityRecord activity = activities.get(actNdx);
                 if (activity.app == app && activity.isDestroyable()) {
                     if (DEBUG_RELEASE) Slog.v(TAG_RELEASE, "Destroying " + activity
-                            + " in state " + activity.state + " resumed=" + mResumedActivity
+                            + " in state " + activity.getState() + " resumed=" + mResumedActivity
                             + " pausing=" + mPausingActivity + " for reason " + reason);
                     destroyActivityLocked(activity, true, reason);
                     if (activities.get(actNdx) != activity) {
@@ -4253,13 +4256,15 @@
             if (r.finishing && !skipDestroy) {
                 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYING: " + r
                         + " (destroy requested)");
-                r.state = ActivityState.DESTROYING;
+                r.setState(DESTROYING,
+                        "destroyActivityLocked. finishing and not skipping destroy");
                 Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG, r);
                 mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
             } else {
                 if (DEBUG_STATES) Slog.v(TAG_STATES,
                         "Moving to DESTROYED: " + r + " (destroy skipped)");
-                r.state = ActivityState.DESTROYED;
+                r.setState(DESTROYED,
+                        "destroyActivityLocked. not finishing or skipping destroy");
                 if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + r);
                 r.app = null;
             }
@@ -4270,7 +4275,7 @@
                 removedFromHistory = true;
             } else {
                 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + r + " (no app)");
-                r.state = ActivityState.DESTROYED;
+                r.setState(DESTROYED, "destroyActivityLocked. not finishing and had no app");
                 if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + r);
                 r.app = null;
             }
@@ -4288,24 +4293,29 @@
     final void activityDestroyedLocked(IBinder token, String reason) {
         final long origId = Binder.clearCallingIdentity();
         try {
-            ActivityRecord r = ActivityRecord.forTokenLocked(token);
-            if (r != null) {
-                mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
-            }
-            if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "activityDestroyedLocked: r=" + r);
-
-            if (isInStackLocked(r) != null) {
-                if (r.state == ActivityState.DESTROYING) {
-                    cleanUpActivityLocked(r, true, false);
-                    removeActivityFromHistoryLocked(r, reason);
-                }
-            }
-            mStackSupervisor.resumeFocusedStackTopActivityLocked();
+            activityDestroyedLocked(ActivityRecord.forTokenLocked(token), reason);
         } finally {
             Binder.restoreCallingIdentity(origId);
         }
     }
 
+    final void activityDestroyedLocked(ActivityRecord record, String reason) {
+        if (record != null) {
+            mHandler.removeMessages(DESTROY_TIMEOUT_MSG, record);
+        }
+
+        if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "activityDestroyedLocked: r=" + record);
+
+        if (isInStackLocked(record) != null) {
+            if (record.isState(DESTROYING, DESTROYED)) {
+                cleanUpActivityLocked(record, true, false);
+                removeActivityFromHistoryLocked(record, reason);
+            }
+        }
+
+        mStackSupervisor.resumeFocusedStackTopActivityLocked();
+    }
+
     private void removeHistoryRecordsForAppLocked(ArrayList<ActivityRecord> list,
             ProcessRecord app, String listName) {
         int i = list.size();
@@ -4374,14 +4384,14 @@
                                 + ": haveState=" + r.haveState
                                 + " stateNotNeeded=" + r.stateNotNeeded
                                 + " finishing=" + r.finishing
-                                + " state=" + r.state + " callers=" + Debug.getCallers(5));
+                                + " state=" + r.getState() + " callers=" + Debug.getCallers(5));
                         if (!r.finishing) {
                             Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
                             EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
                                     r.userId, System.identityHashCode(r),
                                     r.getTask().taskId, r.shortComponentName,
                                     "proc died without state saved");
-                            if (r.state == ActivityState.RESUMED) {
+                            if (r.getState() == RESUMED) {
                                 mService.updateUsageStats(r, false);
                             }
                         }
@@ -4417,7 +4427,7 @@
     private void updateTransitLocked(int transit, ActivityOptions options) {
         if (options != null) {
             ActivityRecord r = topRunningActivityLocked();
-            if (r != null && r.state != ActivityState.RESUMED) {
+            if (r != null && !r.isState(RESUMED)) {
                 r.updateOptionsLocked(options);
             } else {
                 ActivityOptions.abort(options);
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 9a3b102..5577186 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1005,7 +1005,7 @@
                 final ActivityStack stack = display.getChildAt(stackNdx);
                 if (isFocusedStack(stack)) {
                     final ActivityRecord r = stack.mResumedActivity;
-                    if (r != null && r.state != RESUMED) {
+                    if (r != null && !r.isState(RESUMED)) {
                         return false;
                     }
                 }
@@ -1069,10 +1069,10 @@
             for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
                 final ActivityStack stack = display.getChildAt(stackNdx);
                 final ActivityRecord r = stack.mPausingActivity;
-                if (r != null && r.state != PAUSED && r.state != STOPPED && r.state != STOPPING) {
+                if (r != null && !r.isState(PAUSED, STOPPED, STOPPING)) {
                     if (DEBUG_STATES) {
                         Slog.d(TAG_STATES,
-                                "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
+                                "allPausedActivitiesComplete: r=" + r + " state=" + r.getState());
                         pausing = false;
                     } else {
                         return false;
@@ -1522,7 +1522,7 @@
             // current icicle and other state.
             if (DEBUG_STATES) Slog.v(TAG_STATES,
                     "Moving to PAUSED: " + r + " (starting in paused state)");
-            r.state = PAUSED;
+            r.setState(PAUSED, "realStartActivityLocked");
         }
 
         // Launch the new version setup screen if needed.  We do this -after-
@@ -2099,9 +2099,9 @@
         }
 
         final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
-        if (r == null || r.state != RESUMED) {
+        if (r == null || !r.isState(RESUMED)) {
             mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
-        } else if (r.state == RESUMED) {
+        } else if (r.isState(RESUMED)) {
             // Kick off any lingering app transitions form the MoveTaskToFront operation.
             mFocusedStack.executeAppTransition(targetOptions);
         }
@@ -3540,14 +3540,14 @@
             // First, if we find an activity that is in the process of being destroyed,
             // then we just aren't going to do anything for now; we want things to settle
             // down before we try to prune more activities.
-            if (r.finishing || r.state == DESTROYING || r.state == DESTROYED) {
+            if (r.finishing || r.isState(DESTROYING, DESTROYED)) {
                 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r);
                 return;
             }
             // Don't consider any activies that are currently not in a state where they
             // can be destroyed.
-            if (r.visible || !r.stopped || !r.haveState || r.state == RESUMED || r.state == PAUSING
-                    || r.state == PAUSED || r.state == STOPPING) {
+            if (r.visible || !r.stopped || !r.haveState
+                    || r.isState(RESUMED, PAUSING, PAUSED, STOPPING)) {
                 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r);
                 continue;
             }
@@ -3683,7 +3683,7 @@
                         ? stack.shouldSleepOrShutDownActivities()
                         : mService.isSleepingOrShuttingDownLocked();
                 if (!waitingVisible || shouldSleepOrShutDown) {
-                    if (!processPausingActivities && s.state == PAUSING) {
+                    if (!processPausingActivities && s.isState(PAUSING)) {
                         // Defer processing pausing activities in this iteration and reschedule
                         // a delayed idle to reprocess it again
                         removeTimeoutsForActivityLocked(idleActivity);
@@ -3710,7 +3710,7 @@
             for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
                 final ActivityStack stack = display.getChildAt(stackNdx);
                 final ActivityRecord r = stack.topRunningActivityLocked();
-                final ActivityState state = r == null ? DESTROYED : r.state;
+                final ActivityState state = r == null ? DESTROYED : r.getState();
                 if (isFocusedStack(stack)) {
                     if (r == null) Slog.e(TAG,
                             "validateTop...: null top activity, stack=" + stack);
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 8205265..fcdf3d2 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1107,7 +1107,7 @@
                     case START_TASK_TO_FRONT: {
                         // ActivityRecord may represent a different activity, but it should not be
                         // in the resumed state.
-                        if (r.nowVisible && r.state == RESUMED) {
+                        if (r.nowVisible && r.isState(RESUMED)) {
                             outResult.timeout = false;
                             outResult.who = r.realActivity;
                             outResult.totalTime = 0;
@@ -1516,7 +1516,7 @@
                     final TaskRecord task = mSupervisor.anyTaskForIdLocked(
                             mOptions.getLaunchTaskId());
                     final ActivityRecord top = task != null ? task.getTopActivity() : null;
-                    if (top != null && top.state != RESUMED) {
+                    if (top != null && !top.isState(RESUMED)) {
 
                         // The caller specifies that we'd like to be avoided to be moved to the
                         // front, so be it!
diff --git a/services/core/java/com/android/server/am/GlobalSettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/GlobalSettingsToPropertiesMapper.java
index 71fd71b8..d7d18a9 100644
--- a/services/core/java/com/android/server/am/GlobalSettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/GlobalSettingsToPropertiesMapper.java
@@ -42,6 +42,7 @@
         {Settings.Global.SYS_VDSO, "sys.vdso"},
         {Settings.Global.FPS_DEVISOR, ThreadedRenderer.DEBUG_FPS_DIVISOR},
         {Settings.Global.DISPLAY_PANEL_LPM, "sys.display_panel_lpm"},
+        {Settings.Global.SYS_UIDCPUPOWER, "sys.uidcpupower"},
     };
 
 
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index d679439..a07afde 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -1103,7 +1103,7 @@
             // Increment the total number of non-finishing activities
             reportOut.numActivities++;
 
-            if (reportOut.top == null || (reportOut.top.state == ActivityState.INITIALIZING)) {
+            if (reportOut.top == null || (reportOut.top.isState(ActivityState.INITIALIZING))) {
                 reportOut.top = r;
                 // Reset the number of running activities until we hit the first non-initializing
                 // activity
diff --git a/services/core/java/com/android/server/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
similarity index 85%
rename from services/core/java/com/android/server/MultipathPolicyTracker.java
rename to services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
index 9e0a230..296b9ac 100644
--- a/services/core/java/com/android/server/MultipathPolicyTracker.java
+++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
@@ -16,11 +16,17 @@
 
 package com.android.server.connectivity;
 
+import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER;
+import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY;
+import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+
+import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH;
+
 import android.app.usage.NetworkStatsManager;
 import android.app.usage.NetworkStatsManager.UsageCallback;
 import android.content.Context;
-import android.net.INetworkStatsService;
-import android.net.INetworkPolicyManager;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
 import android.net.Network;
@@ -31,29 +37,17 @@
 import android.net.NetworkTemplate;
 import android.net.StringNetworkSpecifier;
 import android.os.Handler;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.telephony.TelephonyManager;
 import android.util.DebugUtils;
 import android.util.Slog;
 
-import java.util.Calendar;
-import java.util.concurrent.ConcurrentHashMap;
-
-import com.android.internal.R;
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
 import com.android.server.net.NetworkPolicyManagerInternal;
+import com.android.server.net.NetworkStatsManagerInternal;
 
-import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER;
-import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY;
-import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.provider.Settings.Global.NETWORK_AVOID_BAD_WIFI;
-import static android.provider.Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE;
-import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH;
+import java.util.Calendar;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * Manages multipath data budgets.
@@ -76,10 +70,8 @@
     private final Handler mHandler;
 
     private ConnectivityManager mCM;
-    private NetworkStatsManager mStatsManager;
     private NetworkPolicyManager mNPM;
-    private TelephonyManager mTelephonyManager;
-    private INetworkStatsService mStatsService;
+    private NetworkStatsManager mStatsManager;
 
     private NetworkCallback mMobileNetworkCallback;
     private NetworkPolicyManager.Listener mPolicyListener;
@@ -87,8 +79,6 @@
     // STOPSHIP: replace this with a configurable mechanism.
     private static final long DEFAULT_DAILY_MULTIPATH_QUOTA = 2_500_000;
 
-    private volatile int mMeteredMultipathPreference;
-
     public MultipathPolicyTracker(Context ctx, Handler handler) {
         mContext = ctx;
         mHandler = handler;
@@ -97,12 +87,9 @@
     }
 
     public void start() {
-        mCM = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-        mNPM = (NetworkPolicyManager) mContext.getSystemService(Context.NETWORK_POLICY_SERVICE);
-        mStatsManager = (NetworkStatsManager) mContext.getSystemService(
-                Context.NETWORK_STATS_SERVICE);
-        mStatsService = INetworkStatsService.Stub.asInterface(
-                ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
+        mCM = mContext.getSystemService(ConnectivityManager.class);
+        mNPM = mContext.getSystemService(NetworkPolicyManager.class);
+        mStatsManager = mContext.getSystemService(NetworkStatsManager.class);
 
         registerTrackMobileCallback();
         registerNetworkPolicyListener();
@@ -119,6 +106,9 @@
 
     // Called on an arbitrary binder thread.
     public Integer getMultipathPreference(Network network) {
+        if (network == null) {
+            return null;
+        }
         MultipathTracker t = mMultipathTrackers.get(network);
         if (t != null) {
             return t.getMultipathPreference();
@@ -149,8 +139,7 @@
                         network, nc, e.getMessage()));
             }
 
-            TelephonyManager tele = (TelephonyManager) mContext.getSystemService(
-                    Context.TELEPHONY_SERVICE);
+            TelephonyManager tele = mContext.getSystemService(TelephonyManager.class);
             if (tele == null) {
                 throw new IllegalStateException(String.format("Missing TelephonyManager"));
             }
@@ -162,7 +151,7 @@
 
             subscriberId = tele.getSubscriberId();
             mNetworkTemplate = new NetworkTemplate(
-                    NetworkTemplate.MATCH_MOBILE_ALL, subscriberId, new String[] { subscriberId },
+                    NetworkTemplate.MATCH_MOBILE, subscriberId, new String[] { subscriberId },
                     null, NetworkStats.METERED_ALL, NetworkStats.ROAMING_ALL,
                     NetworkStats.DEFAULT_NETWORK_NO);
             mUsageCallback = new UsageCallback() {
@@ -185,26 +174,21 @@
             start.set(Calendar.SECOND, 0);
             start.set(Calendar.MILLISECOND, 0);
 
-            long bytes;
             try {
-                // TODO: Consider using NetworkStatsManager.getSummaryForDevice instead.
-                bytes = mStatsService.getNetworkTotalBytes(mNetworkTemplate,
-                        start.getTimeInMillis(), end.getTimeInMillis());
-                if (DBG) Slog.w(TAG, "Non-default data usage: " + bytes);
-            } catch (RemoteException e) {
-                Slog.w(TAG, "Can't fetch daily data usage: " + e);
-                bytes = -1;
-            } catch (IllegalStateException e) {
-                // Bandwidth control disabled?
-                bytes = -1;
+                final long bytes = LocalServices.getService(NetworkStatsManagerInternal.class)
+                        .getNetworkTotalBytes(mNetworkTemplate, start.getTimeInMillis(),
+                                end.getTimeInMillis());
+                if (DBG) Slog.d(TAG, "Non-default data usage: " + bytes);
+                return bytes;
+            } catch (RuntimeException e) {
+                Slog.w(TAG, "Failed to get data usage: " + e);
+                return -1;
             }
-            return bytes;
         }
 
         void updateMultipathBudget() {
-            NetworkPolicyManagerInternal npms = LocalServices.getService(
-                    NetworkPolicyManagerInternal.class);
-            long quota = npms.getSubscriptionOpportunisticQuota(this.network, QUOTA_TYPE_MULTIPATH);
+            long quota = LocalServices.getService(NetworkPolicyManagerInternal.class)
+                    .getSubscriptionOpportunisticQuota(this.network, QUOTA_TYPE_MULTIPATH);
             if (DBG) Slog.d(TAG, "Opportunistic quota from data plan: " + quota + " bytes");
 
             if (quota == 0) {
@@ -223,8 +207,10 @@
             }
             mQuota = quota;
 
-            long usage = getDailyNonDefaultDataUsage();
-            long budget = Math.max(0, quota - usage);
+            // If we can't get current usage, assume the worst and don't give
+            // ourselves any budget to work with.
+            final long usage = getDailyNonDefaultDataUsage();
+            final long budget = (usage == -1) ? 0 : Math.max(0, quota - usage);
             if (budget > 0) {
                 if (DBG) Slog.d(TAG, "Setting callback for " + budget +
                         " bytes on network " + network);
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 692535c..3da3551 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -421,7 +421,7 @@
                 byteToken[i] = token.get(i);
             }
             // Send to Keystore
-            KeyStore.getInstance().addAuthToken(byteToken, mCurrentUserId);
+            KeyStore.getInstance().addAuthToken(byteToken);
         }
         if (client != null && client.onAuthenticated(fingerId, groupId)) {
             removeClient(client);
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index f3f4dfd..740866c 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -79,6 +79,7 @@
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
 import com.android.server.AppStateTracker;
 import com.android.server.DeviceIdleController;
@@ -86,7 +87,6 @@
 import com.android.server.LocalServices;
 import com.android.server.job.JobSchedulerServiceDumpProto.ActiveJob;
 import com.android.server.job.JobSchedulerServiceDumpProto.PendingJob;
-import com.android.server.job.JobStore.JobStatusFunctor;
 import com.android.server.job.controllers.AppIdleController;
 import com.android.server.job.controllers.BackgroundJobsController;
 import com.android.server.job.controllers.BatteryController;
@@ -110,6 +110,7 @@
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
+import java.util.function.Consumer;
 import java.util.function.Predicate;
 
 /**
@@ -163,15 +164,16 @@
      * {@link JobStatus#getServiceToken()}
      */
     final List<JobServiceContext> mActiveServices = new ArrayList<>();
+
     /** List of controllers that will notify this service of updates to jobs. */
-    List<StateController> mControllers;
+    private final List<StateController> mControllers;
     /** Need direct access to this for testing. */
-    BatteryController mBatteryController;
+    private final BatteryController mBatteryController;
     /** Need direct access to this for testing. */
-    StorageController mStorageController;
+    private final StorageController mStorageController;
     /** Need directly for sending uid state changes */
-    private BackgroundJobsController mBackgroundJobsController;
-    private DeviceIdleJobsController mDeviceIdleJobsController;
+    private final DeviceIdleJobsController mDeviceIdleJobsController;
+
     /**
      * Queue of pending jobs. The JobServiceContext class will receive jobs from this list
      * when ready to execute them.
@@ -253,12 +255,48 @@
      */
     int[] mTmpAssignPreferredUidForContext = new int[MAX_JOB_CONTEXTS_COUNT];
 
+    private class ConstantsObserver extends ContentObserver {
+        private ContentResolver mResolver;
+
+        public ConstantsObserver(Handler handler) {
+            super(handler);
+        }
+
+        public void start(ContentResolver resolver) {
+            mResolver = resolver;
+            mResolver.registerContentObserver(Settings.Global.getUriFor(
+                    Settings.Global.JOB_SCHEDULER_CONSTANTS), false, this);
+            updateConstants();
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            updateConstants();
+        }
+
+        private void updateConstants() {
+            synchronized (mLock) {
+                try {
+                    mConstants.updateConstantsLocked(Settings.Global.getString(mResolver,
+                            Settings.Global.JOB_SCHEDULER_CONSTANTS));
+                } catch (IllegalArgumentException e) {
+                    // Failed to parse the settings string, log this and move on
+                    // with defaults.
+                    Slog.e(TAG, "Bad jobscheduler settings", e);
+                }
+            }
+
+            // Reset the heartbeat alarm based on the new heartbeat duration
+            setNextHeartbeatAlarm();
+        }
+    }
+
     /**
      * All times are in milliseconds. These constants are kept synchronized with the system
      * global Settings. Any access to this class or its fields should be done while
      * holding the JobSchedulerService.mLock lock.
      */
-    private final class Constants extends ContentObserver {
+    public static class Constants {
         // Key names stored in the settings value.
         private static final String KEY_MIN_IDLE_COUNT = "min_idle_count";
         private static final String KEY_MIN_CHARGING_COUNT = "min_charging_count";
@@ -283,6 +321,8 @@
         private static final String KEY_STANDBY_WORKING_BEATS = "standby_working_beats";
         private static final String KEY_STANDBY_FREQUENT_BEATS = "standby_frequent_beats";
         private static final String KEY_STANDBY_RARE_BEATS = "standby_rare_beats";
+        private static final String KEY_CONN_CONGESTION_DELAY_FRAC = "conn_congestion_delay_frac";
+        private static final String KEY_CONN_PREFETCH_RELAX_FRAC = "conn_prefetch_relax_frac";
 
         private static final int DEFAULT_MIN_IDLE_COUNT = 1;
         private static final int DEFAULT_MIN_CHARGING_COUNT = 1;
@@ -306,6 +346,8 @@
         private static final int DEFAULT_STANDBY_WORKING_BEATS = 11;  // ~ 2 hours, with 11min beats
         private static final int DEFAULT_STANDBY_FREQUENT_BEATS = 43; // ~ 8 hours
         private static final int DEFAULT_STANDBY_RARE_BEATS = 130; // ~ 24 hours
+        private static final float DEFAULT_CONN_CONGESTION_DELAY_FRAC = 0.5f;
+        private static final float DEFAULT_CONN_PREFETCH_RELAX_FRAC = 0.5f;
 
         /**
          * Minimum # of idle jobs that must be ready in order to force the JMS to schedule things
@@ -400,7 +442,6 @@
          * hour or day, so that the heartbeat drifts relative to wall-clock milestones.
          */
         long STANDBY_HEARTBEAT_TIME = DEFAULT_STANDBY_HEARTBEAT_TIME;
-
         /**
          * Mapping: standby bucket -> number of heartbeats between each sweep of that
          * bucket's jobs.
@@ -415,171 +456,126 @@
                 DEFAULT_STANDBY_FREQUENT_BEATS,
                 DEFAULT_STANDBY_RARE_BEATS
         };
+        /**
+         * The fraction of a job's running window that must pass before we
+         * consider running it when the network is congested.
+         */
+        public float CONN_CONGESTION_DELAY_FRAC = DEFAULT_CONN_CONGESTION_DELAY_FRAC;
+        /**
+         * The fraction of a prefetch job's running window that must pass before
+         * we consider matching it against a metered network.
+         */
+        public float CONN_PREFETCH_RELAX_FRAC = DEFAULT_CONN_PREFETCH_RELAX_FRAC;
 
-        private ContentResolver mResolver;
         private final KeyValueListParser mParser = new KeyValueListParser(',');
 
-        public Constants(Handler handler) {
-            super(handler);
-        }
-
-        public void start(ContentResolver resolver) {
-            mResolver = resolver;
-            mResolver.registerContentObserver(Settings.Global.getUriFor(
-                    Settings.Global.JOB_SCHEDULER_CONSTANTS), false, this);
-            updateConstants();
-        }
-
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            updateConstants();
-        }
-
-        private void updateConstants() {
-            synchronized (mLock) {
-                try {
-                    mParser.setString(Settings.Global.getString(mResolver,
-                            Settings.Global.JOB_SCHEDULER_CONSTANTS));
-                } catch (IllegalArgumentException e) {
-                    // Failed to parse the settings string, log this and move on
-                    // with defaults.
-                    Slog.e(TAG, "Bad jobscheduler settings", e);
-                }
-
-                MIN_IDLE_COUNT = mParser.getInt(KEY_MIN_IDLE_COUNT,
-                        DEFAULT_MIN_IDLE_COUNT);
-                MIN_CHARGING_COUNT = mParser.getInt(KEY_MIN_CHARGING_COUNT,
-                        DEFAULT_MIN_CHARGING_COUNT);
-                MIN_BATTERY_NOT_LOW_COUNT = mParser.getInt(KEY_MIN_BATTERY_NOT_LOW_COUNT,
-                        DEFAULT_MIN_BATTERY_NOT_LOW_COUNT);
-                MIN_STORAGE_NOT_LOW_COUNT = mParser.getInt(KEY_MIN_STORAGE_NOT_LOW_COUNT,
-                        DEFAULT_MIN_STORAGE_NOT_LOW_COUNT);
-                MIN_CONNECTIVITY_COUNT = mParser.getInt(KEY_MIN_CONNECTIVITY_COUNT,
-                        DEFAULT_MIN_CONNECTIVITY_COUNT);
-                MIN_CONTENT_COUNT = mParser.getInt(KEY_MIN_CONTENT_COUNT,
-                        DEFAULT_MIN_CONTENT_COUNT);
-                MIN_READY_JOBS_COUNT = mParser.getInt(KEY_MIN_READY_JOBS_COUNT,
-                        DEFAULT_MIN_READY_JOBS_COUNT);
-                HEAVY_USE_FACTOR = mParser.getFloat(KEY_HEAVY_USE_FACTOR,
-                        DEFAULT_HEAVY_USE_FACTOR);
-                MODERATE_USE_FACTOR = mParser.getFloat(KEY_MODERATE_USE_FACTOR,
-                        DEFAULT_MODERATE_USE_FACTOR);
-                FG_JOB_COUNT = mParser.getInt(KEY_FG_JOB_COUNT,
-                        DEFAULT_FG_JOB_COUNT);
-                BG_NORMAL_JOB_COUNT = mParser.getInt(KEY_BG_NORMAL_JOB_COUNT,
-                        DEFAULT_BG_NORMAL_JOB_COUNT);
-                if ((FG_JOB_COUNT+BG_NORMAL_JOB_COUNT) > MAX_JOB_CONTEXTS_COUNT) {
-                    BG_NORMAL_JOB_COUNT = MAX_JOB_CONTEXTS_COUNT - FG_JOB_COUNT;
-                }
-                BG_MODERATE_JOB_COUNT = mParser.getInt(KEY_BG_MODERATE_JOB_COUNT,
-                        DEFAULT_BG_MODERATE_JOB_COUNT);
-                if ((FG_JOB_COUNT+BG_MODERATE_JOB_COUNT) > MAX_JOB_CONTEXTS_COUNT) {
-                    BG_MODERATE_JOB_COUNT = MAX_JOB_CONTEXTS_COUNT - FG_JOB_COUNT;
-                }
-                BG_LOW_JOB_COUNT = mParser.getInt(KEY_BG_LOW_JOB_COUNT,
-                        DEFAULT_BG_LOW_JOB_COUNT);
-                if ((FG_JOB_COUNT+BG_LOW_JOB_COUNT) > MAX_JOB_CONTEXTS_COUNT) {
-                    BG_LOW_JOB_COUNT = MAX_JOB_CONTEXTS_COUNT - FG_JOB_COUNT;
-                }
-                BG_CRITICAL_JOB_COUNT = mParser.getInt(KEY_BG_CRITICAL_JOB_COUNT,
-                        DEFAULT_BG_CRITICAL_JOB_COUNT);
-                if ((FG_JOB_COUNT+BG_CRITICAL_JOB_COUNT) > MAX_JOB_CONTEXTS_COUNT) {
-                    BG_CRITICAL_JOB_COUNT = MAX_JOB_CONTEXTS_COUNT - FG_JOB_COUNT;
-                }
-                MAX_STANDARD_RESCHEDULE_COUNT = mParser.getInt(KEY_MAX_STANDARD_RESCHEDULE_COUNT,
-                        DEFAULT_MAX_STANDARD_RESCHEDULE_COUNT);
-                MAX_WORK_RESCHEDULE_COUNT = mParser.getInt(KEY_MAX_WORK_RESCHEDULE_COUNT,
-                        DEFAULT_MAX_WORK_RESCHEDULE_COUNT);
-                MIN_LINEAR_BACKOFF_TIME = mParser.getDurationMillis(KEY_MIN_LINEAR_BACKOFF_TIME,
-                        DEFAULT_MIN_LINEAR_BACKOFF_TIME);
-                MIN_EXP_BACKOFF_TIME = mParser.getDurationMillis(KEY_MIN_EXP_BACKOFF_TIME,
-                        DEFAULT_MIN_EXP_BACKOFF_TIME);
-                STANDBY_HEARTBEAT_TIME = mParser.getDurationMillis(KEY_STANDBY_HEARTBEAT_TIME,
-                        DEFAULT_STANDBY_HEARTBEAT_TIME);
-                STANDBY_BEATS[1] = mParser.getInt(KEY_STANDBY_WORKING_BEATS,
-                        DEFAULT_STANDBY_WORKING_BEATS);
-                STANDBY_BEATS[2] = mParser.getInt(KEY_STANDBY_FREQUENT_BEATS,
-                        DEFAULT_STANDBY_FREQUENT_BEATS);
-                STANDBY_BEATS[3] = mParser.getInt(KEY_STANDBY_RARE_BEATS,
-                        DEFAULT_STANDBY_RARE_BEATS);
+        void updateConstantsLocked(String value) {
+            try {
+                mParser.setString(value);
+            } catch (Exception e) {
+                // Failed to parse the settings string, log this and move on
+                // with defaults.
+                Slog.e(TAG, "Bad jobscheduler settings", e);
             }
 
-            // Reset the heartbeat alarm based on the new heartbeat duration
-            setNextHeartbeatAlarm();
+            MIN_IDLE_COUNT = mParser.getInt(KEY_MIN_IDLE_COUNT,
+                    DEFAULT_MIN_IDLE_COUNT);
+            MIN_CHARGING_COUNT = mParser.getInt(KEY_MIN_CHARGING_COUNT,
+                    DEFAULT_MIN_CHARGING_COUNT);
+            MIN_BATTERY_NOT_LOW_COUNT = mParser.getInt(KEY_MIN_BATTERY_NOT_LOW_COUNT,
+                    DEFAULT_MIN_BATTERY_NOT_LOW_COUNT);
+            MIN_STORAGE_NOT_LOW_COUNT = mParser.getInt(KEY_MIN_STORAGE_NOT_LOW_COUNT,
+                    DEFAULT_MIN_STORAGE_NOT_LOW_COUNT);
+            MIN_CONNECTIVITY_COUNT = mParser.getInt(KEY_MIN_CONNECTIVITY_COUNT,
+                    DEFAULT_MIN_CONNECTIVITY_COUNT);
+            MIN_CONTENT_COUNT = mParser.getInt(KEY_MIN_CONTENT_COUNT,
+                    DEFAULT_MIN_CONTENT_COUNT);
+            MIN_READY_JOBS_COUNT = mParser.getInt(KEY_MIN_READY_JOBS_COUNT,
+                    DEFAULT_MIN_READY_JOBS_COUNT);
+            HEAVY_USE_FACTOR = mParser.getFloat(KEY_HEAVY_USE_FACTOR,
+                    DEFAULT_HEAVY_USE_FACTOR);
+            MODERATE_USE_FACTOR = mParser.getFloat(KEY_MODERATE_USE_FACTOR,
+                    DEFAULT_MODERATE_USE_FACTOR);
+            FG_JOB_COUNT = mParser.getInt(KEY_FG_JOB_COUNT,
+                    DEFAULT_FG_JOB_COUNT);
+            BG_NORMAL_JOB_COUNT = mParser.getInt(KEY_BG_NORMAL_JOB_COUNT,
+                    DEFAULT_BG_NORMAL_JOB_COUNT);
+            if ((FG_JOB_COUNT+BG_NORMAL_JOB_COUNT) > MAX_JOB_CONTEXTS_COUNT) {
+                BG_NORMAL_JOB_COUNT = MAX_JOB_CONTEXTS_COUNT - FG_JOB_COUNT;
+            }
+            BG_MODERATE_JOB_COUNT = mParser.getInt(KEY_BG_MODERATE_JOB_COUNT,
+                    DEFAULT_BG_MODERATE_JOB_COUNT);
+            if ((FG_JOB_COUNT+BG_MODERATE_JOB_COUNT) > MAX_JOB_CONTEXTS_COUNT) {
+                BG_MODERATE_JOB_COUNT = MAX_JOB_CONTEXTS_COUNT - FG_JOB_COUNT;
+            }
+            BG_LOW_JOB_COUNT = mParser.getInt(KEY_BG_LOW_JOB_COUNT,
+                    DEFAULT_BG_LOW_JOB_COUNT);
+            if ((FG_JOB_COUNT+BG_LOW_JOB_COUNT) > MAX_JOB_CONTEXTS_COUNT) {
+                BG_LOW_JOB_COUNT = MAX_JOB_CONTEXTS_COUNT - FG_JOB_COUNT;
+            }
+            BG_CRITICAL_JOB_COUNT = mParser.getInt(KEY_BG_CRITICAL_JOB_COUNT,
+                    DEFAULT_BG_CRITICAL_JOB_COUNT);
+            if ((FG_JOB_COUNT+BG_CRITICAL_JOB_COUNT) > MAX_JOB_CONTEXTS_COUNT) {
+                BG_CRITICAL_JOB_COUNT = MAX_JOB_CONTEXTS_COUNT - FG_JOB_COUNT;
+            }
+            MAX_STANDARD_RESCHEDULE_COUNT = mParser.getInt(KEY_MAX_STANDARD_RESCHEDULE_COUNT,
+                    DEFAULT_MAX_STANDARD_RESCHEDULE_COUNT);
+            MAX_WORK_RESCHEDULE_COUNT = mParser.getInt(KEY_MAX_WORK_RESCHEDULE_COUNT,
+                    DEFAULT_MAX_WORK_RESCHEDULE_COUNT);
+            MIN_LINEAR_BACKOFF_TIME = mParser.getDurationMillis(KEY_MIN_LINEAR_BACKOFF_TIME,
+                    DEFAULT_MIN_LINEAR_BACKOFF_TIME);
+            MIN_EXP_BACKOFF_TIME = mParser.getDurationMillis(KEY_MIN_EXP_BACKOFF_TIME,
+                    DEFAULT_MIN_EXP_BACKOFF_TIME);
+            STANDBY_HEARTBEAT_TIME = mParser.getDurationMillis(KEY_STANDBY_HEARTBEAT_TIME,
+                    DEFAULT_STANDBY_HEARTBEAT_TIME);
+            STANDBY_BEATS[1] = mParser.getInt(KEY_STANDBY_WORKING_BEATS,
+                    DEFAULT_STANDBY_WORKING_BEATS);
+            STANDBY_BEATS[2] = mParser.getInt(KEY_STANDBY_FREQUENT_BEATS,
+                    DEFAULT_STANDBY_FREQUENT_BEATS);
+            STANDBY_BEATS[3] = mParser.getInt(KEY_STANDBY_RARE_BEATS,
+                    DEFAULT_STANDBY_RARE_BEATS);
+            CONN_CONGESTION_DELAY_FRAC = mParser.getFloat(KEY_CONN_CONGESTION_DELAY_FRAC,
+                    DEFAULT_CONN_CONGESTION_DELAY_FRAC);
+            CONN_PREFETCH_RELAX_FRAC = mParser.getFloat(KEY_CONN_PREFETCH_RELAX_FRAC,
+                    DEFAULT_CONN_PREFETCH_RELAX_FRAC);
         }
 
-        void dump(PrintWriter pw) {
-            pw.println("  Settings:");
-
-            pw.print("    "); pw.print(KEY_MIN_IDLE_COUNT); pw.print("=");
-            pw.print(MIN_IDLE_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_MIN_CHARGING_COUNT); pw.print("=");
-            pw.print(MIN_CHARGING_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_MIN_BATTERY_NOT_LOW_COUNT); pw.print("=");
-            pw.print(MIN_BATTERY_NOT_LOW_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_MIN_STORAGE_NOT_LOW_COUNT); pw.print("=");
-            pw.print(MIN_STORAGE_NOT_LOW_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_MIN_CONNECTIVITY_COUNT); pw.print("=");
-            pw.print(MIN_CONNECTIVITY_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_MIN_CONTENT_COUNT); pw.print("=");
-            pw.print(MIN_CONTENT_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_MIN_READY_JOBS_COUNT); pw.print("=");
-            pw.print(MIN_READY_JOBS_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_HEAVY_USE_FACTOR); pw.print("=");
-            pw.print(HEAVY_USE_FACTOR); pw.println();
-
-            pw.print("    "); pw.print(KEY_MODERATE_USE_FACTOR); pw.print("=");
-            pw.print(MODERATE_USE_FACTOR); pw.println();
-
-            pw.print("    "); pw.print(KEY_FG_JOB_COUNT); pw.print("=");
-            pw.print(FG_JOB_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_BG_NORMAL_JOB_COUNT); pw.print("=");
-            pw.print(BG_NORMAL_JOB_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_BG_MODERATE_JOB_COUNT); pw.print("=");
-            pw.print(BG_MODERATE_JOB_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_BG_LOW_JOB_COUNT); pw.print("=");
-            pw.print(BG_LOW_JOB_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_BG_CRITICAL_JOB_COUNT); pw.print("=");
-            pw.print(BG_CRITICAL_JOB_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_MAX_STANDARD_RESCHEDULE_COUNT); pw.print("=");
-            pw.print(MAX_STANDARD_RESCHEDULE_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_MAX_WORK_RESCHEDULE_COUNT); pw.print("=");
-            pw.print(MAX_WORK_RESCHEDULE_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_MIN_LINEAR_BACKOFF_TIME); pw.print("=");
-            pw.print(MIN_LINEAR_BACKOFF_TIME); pw.println();
-
-            pw.print("    "); pw.print(KEY_MIN_EXP_BACKOFF_TIME); pw.print("=");
-            pw.print(MIN_EXP_BACKOFF_TIME); pw.println();
-
-            pw.print("    "); pw.print(KEY_STANDBY_HEARTBEAT_TIME); pw.print("=");
-            pw.print(STANDBY_HEARTBEAT_TIME); pw.println();
-
-            pw.print("    standby_beats={");
+        void dump(IndentingPrintWriter pw) {
+            pw.println("Settings:");
+            pw.increaseIndent();
+            pw.printPair(KEY_MIN_IDLE_COUNT, MIN_IDLE_COUNT).println();
+            pw.printPair(KEY_MIN_CHARGING_COUNT, MIN_CHARGING_COUNT).println();
+            pw.printPair(KEY_MIN_BATTERY_NOT_LOW_COUNT, MIN_BATTERY_NOT_LOW_COUNT).println();
+            pw.printPair(KEY_MIN_STORAGE_NOT_LOW_COUNT, MIN_STORAGE_NOT_LOW_COUNT).println();
+            pw.printPair(KEY_MIN_CONNECTIVITY_COUNT, MIN_CONNECTIVITY_COUNT).println();
+            pw.printPair(KEY_MIN_CONTENT_COUNT, MIN_CONTENT_COUNT).println();
+            pw.printPair(KEY_MIN_READY_JOBS_COUNT, MIN_READY_JOBS_COUNT).println();
+            pw.printPair(KEY_HEAVY_USE_FACTOR, HEAVY_USE_FACTOR).println();
+            pw.printPair(KEY_MODERATE_USE_FACTOR, MODERATE_USE_FACTOR).println();
+            pw.printPair(KEY_FG_JOB_COUNT, FG_JOB_COUNT).println();
+            pw.printPair(KEY_BG_NORMAL_JOB_COUNT, BG_NORMAL_JOB_COUNT).println();
+            pw.printPair(KEY_BG_MODERATE_JOB_COUNT, BG_MODERATE_JOB_COUNT).println();
+            pw.printPair(KEY_BG_LOW_JOB_COUNT, BG_LOW_JOB_COUNT).println();
+            pw.printPair(KEY_BG_CRITICAL_JOB_COUNT, BG_CRITICAL_JOB_COUNT).println();
+            pw.printPair(KEY_MAX_STANDARD_RESCHEDULE_COUNT, MAX_STANDARD_RESCHEDULE_COUNT).println();
+            pw.printPair(KEY_MAX_WORK_RESCHEDULE_COUNT, MAX_WORK_RESCHEDULE_COUNT).println();
+            pw.printPair(KEY_MIN_LINEAR_BACKOFF_TIME, MIN_LINEAR_BACKOFF_TIME).println();
+            pw.printPair(KEY_MIN_EXP_BACKOFF_TIME, MIN_EXP_BACKOFF_TIME).println();
+            pw.printPair(KEY_STANDBY_HEARTBEAT_TIME, STANDBY_HEARTBEAT_TIME).println();
+            pw.print("standby_beats={");
             pw.print(STANDBY_BEATS[0]);
             for (int i = 1; i < STANDBY_BEATS.length; i++) {
                 pw.print(", ");
                 pw.print(STANDBY_BEATS[i]);
             }
             pw.println('}');
+            pw.printPair(KEY_CONN_CONGESTION_DELAY_FRAC, CONN_CONGESTION_DELAY_FRAC).println();
+            pw.printPair(KEY_CONN_PREFETCH_RELAX_FRAC, CONN_PREFETCH_RELAX_FRAC).println();
+            pw.decreaseIndent();
         }
 
         void dump(ProtoOutputStream proto, long fieldId) {
             final long token = proto.start(fieldId);
-
             proto.write(ConstantsProto.MIN_IDLE_COUNT, MIN_IDLE_COUNT);
             proto.write(ConstantsProto.MIN_CHARGING_COUNT, MIN_CHARGING_COUNT);
             proto.write(ConstantsProto.MIN_BATTERY_NOT_LOW_COUNT, MIN_BATTERY_NOT_LOW_COUNT);
@@ -599,16 +595,17 @@
             proto.write(ConstantsProto.MIN_LINEAR_BACKOFF_TIME_MS, MIN_LINEAR_BACKOFF_TIME);
             proto.write(ConstantsProto.MIN_EXP_BACKOFF_TIME_MS, MIN_EXP_BACKOFF_TIME);
             proto.write(ConstantsProto.STANDBY_HEARTBEAT_TIME_MS, STANDBY_HEARTBEAT_TIME);
-
             for (int period : STANDBY_BEATS) {
                 proto.write(ConstantsProto.STANDBY_BEATS, period);
             }
-
+            proto.write(ConstantsProto.CONN_CONGESTION_DELAY_FRAC, CONN_CONGESTION_DELAY_FRAC);
+            proto.write(ConstantsProto.CONN_PREFETCH_RELAX_FRAC, CONN_PREFETCH_RELAX_FRAC);
             proto.end(token);
         }
     }
 
     final Constants mConstants;
+    final ConstantsObserver mConstantsObserver;
 
     static final Comparator<JobStatus> mEnqueueTimeComparator = (o1, o2) -> {
         if (o1.enqueueTime < o2.enqueueTime) {
@@ -778,6 +775,10 @@
         return mJobs;
     }
 
+    public Constants getConstants() {
+        return mConstants;
+    }
+
     @Override
     public void onStartUser(int userHandle) {
         mStartedUsers = ArrayUtils.appendInt(mStartedUsers, userHandle);
@@ -1097,7 +1098,8 @@
                 LocalServices.getService(ActivityManagerInternal.class));
 
         mHandler = new JobHandler(context.getMainLooper());
-        mConstants = new Constants(mHandler);
+        mConstants = new Constants();
+        mConstantsObserver = new ConstantsObserver(mHandler);
         mJobSchedulerStub = new JobSchedulerStub();
 
         // Set up the app standby bucketing tracker
@@ -1113,17 +1115,17 @@
 
         // Create the controllers.
         mControllers = new ArrayList<StateController>();
-        mControllers.add(ConnectivityController.get(this));
-        mControllers.add(TimeController.get(this));
-        mControllers.add(IdleController.get(this));
-        mBatteryController = BatteryController.get(this);
+        mControllers.add(new ConnectivityController(this));
+        mControllers.add(new TimeController(this));
+        mControllers.add(new IdleController(this));
+        mBatteryController = new BatteryController(this);
         mControllers.add(mBatteryController);
-        mStorageController = StorageController.get(this);
+        mStorageController = new StorageController(this);
         mControllers.add(mStorageController);
-        mControllers.add(BackgroundJobsController.get(this));
-        mControllers.add(AppIdleController.get(this));
-        mControllers.add(ContentObserverController.get(this));
-        mDeviceIdleJobsController = DeviceIdleJobsController.get(this);
+        mControllers.add(new BackgroundJobsController(this));
+        mControllers.add(new AppIdleController(this));
+        mControllers.add(new ContentObserverController(this));
+        mDeviceIdleJobsController = new DeviceIdleJobsController(this);
         mControllers.add(mDeviceIdleJobsController);
 
         // If the job store determined that it can't yet reschedule persisted jobs,
@@ -1184,7 +1186,7 @@
     @Override
     public void onBootPhase(int phase) {
         if (PHASE_SYSTEM_SERVICES_READY == phase) {
-            mConstants.start(getContext().getContentResolver());
+            mConstantsObserver.start(getContext().getContentResolver());
 
             mAppStateTracker = Preconditions.checkNotNull(
                     LocalServices.getService(AppStateTracker.class));
@@ -1227,13 +1229,10 @@
                                     getContext().getMainLooper()));
                 }
                 // Attach jobs to their controllers.
-                mJobs.forEachJob(new JobStatusFunctor() {
-                    @Override
-                    public void process(JobStatus job) {
-                        for (int controller = 0; controller < mControllers.size(); controller++) {
-                            final StateController sc = mControllers.get(controller);
-                            sc.maybeStartTrackingJobLocked(job, null);
-                        }
+                mJobs.forEachJob((job) -> {
+                    for (int controller = 0; controller < mControllers.size(); controller++) {
+                        final StateController sc = mControllers.get(controller);
+                        sc.maybeStartTrackingJobLocked(job, null);
                     }
                 });
                 // GO GO GO!
@@ -1602,11 +1601,11 @@
         }
     }
 
-    final class ReadyJobQueueFunctor implements JobStatusFunctor {
+    final class ReadyJobQueueFunctor implements Consumer<JobStatus> {
         ArrayList<JobStatus> newReadyJobs;
 
         @Override
-        public void process(JobStatus job) {
+        public void accept(JobStatus job) {
             if (isReadyToBeExecutedLocked(job)) {
                 if (DEBUG) {
                     Slog.d(TAG, "    queued " + job.toShortString());
@@ -1640,7 +1639,7 @@
      * If more than 4 jobs total are ready we send them all off.
      * TODO: It would be nice to consolidate these sort of high-level policies somewhere.
      */
-    final class MaybeReadyJobQueueFunctor implements JobStatusFunctor {
+    final class MaybeReadyJobQueueFunctor implements Consumer<JobStatus> {
         int chargingCount;
         int batteryNotLowCount;
         int storageNotLowCount;
@@ -1656,7 +1655,7 @@
 
         // Functor method invoked for each job via JobStore.forEachJob()
         @Override
-        public void process(JobStatus job) {
+        public void accept(JobStatus job) {
             if (isReadyToBeExecutedLocked(job)) {
                 try {
                     if (ActivityManager.getService().isAppStartModeDisabled(job.getUid(),
@@ -2173,12 +2172,9 @@
         public List<JobInfo> getSystemScheduledPendingJobs() {
             synchronized (mLock) {
                 final List<JobInfo> pendingJobs = new ArrayList<JobInfo>();
-                mJobs.forEachJob(Process.SYSTEM_UID, new JobStatusFunctor() {
-                    @Override
-                    public void process(JobStatus job) {
-                        if (job.getJob().isPeriodic() || !isCurrentlyActiveLocked(job)) {
-                            pendingJobs.add(job.getJob());
-                        }
+                mJobs.forEachJob(Process.SYSTEM_UID, (job) -> {
+                    if (job.getJob().isPeriodic() || !isCurrentlyActiveLocked(job)) {
+                        pendingJobs.add(job.getJob());
                     }
                 });
                 return pendingJobs;
@@ -2307,7 +2303,7 @@
         }
     }
 
-    static class DeferredJobCounter implements JobStatusFunctor {
+    static class DeferredJobCounter implements Consumer<JobStatus> {
         private int mDeferred = 0;
 
         public int numDeferred() {
@@ -2315,7 +2311,7 @@
         }
 
         @Override
-        public void process(JobStatus job) {
+        public void accept(JobStatus job) {
             if (job.getWhenStandbyDeferred() > 0) {
                 mDeferred++;
             }
@@ -2596,12 +2592,13 @@
                 }
             }
 
-            long identityToken = Binder.clearCallingIdentity();
+            final long identityToken = Binder.clearCallingIdentity();
             try {
                 if (proto) {
                     JobSchedulerService.this.dumpInternalProto(fd, filterUid);
                 } else {
-                    JobSchedulerService.this.dumpInternal(pw, filterUid);
+                    JobSchedulerService.this.dumpInternal(new IndentingPrintWriter(pw, "  "),
+                            filterUid);
                 }
             } finally {
                 Binder.restoreCallingIdentity(identityToken);
@@ -2900,10 +2897,14 @@
         });
     }
 
-    void dumpInternal(final PrintWriter pw, int filterUid) {
+    void dumpInternal(final IndentingPrintWriter pw, int filterUid) {
         final int filterUidFinal = UserHandle.getAppId(filterUid);
         final long nowElapsed = sElapsedRealtimeClock.millis();
         final long nowUptime = sUptimeMillisClock.millis();
+        final Predicate<JobStatus> predicate = (js) -> {
+            return filterUidFinal == -1 || UserHandle.getAppId(js.getUid()) == filterUidFinal
+                    || UserHandle.getAppId(js.getSourceUid()) == filterUidFinal;
+        };
         synchronized (mLock) {
             mConstants.dump(pw);
             pw.println();
@@ -2919,7 +2920,7 @@
                     pw.println(job.toShortStringExceptUniqueId());
 
                     // Skip printing details if the caller requested a filter
-                    if (!job.shouldDump(filterUidFinal)) {
+                    if (!predicate.test(job)) {
                         continue;
                     }
 
@@ -2953,7 +2954,10 @@
             }
             for (int i=0; i<mControllers.size(); i++) {
                 pw.println();
-                mControllers.get(i).dumpControllerStateLocked(pw, filterUidFinal);
+                pw.println(mControllers.get(i).getClass().getSimpleName() + ":");
+                pw.increaseIndent();
+                mControllers.get(i).dumpControllerStateLocked(pw, predicate);
+                pw.decreaseIndent();
             }
             pw.println();
             pw.println("Uid priority overrides:");
@@ -3056,6 +3060,10 @@
         final int filterUidFinal = UserHandle.getAppId(filterUid);
         final long nowElapsed = sElapsedRealtimeClock.millis();
         final long nowUptime = sUptimeMillisClock.millis();
+        final Predicate<JobStatus> predicate = (js) -> {
+            return filterUidFinal == -1 || UserHandle.getAppId(js.getUid()) == filterUidFinal
+                    || UserHandle.getAppId(js.getSourceUid()) == filterUidFinal;
+        };
 
         synchronized (mLock) {
             mConstants.dump(proto, JobSchedulerServiceDumpProto.SETTINGS);
@@ -3070,7 +3078,7 @@
                     job.writeToShortProto(proto, JobSchedulerServiceDumpProto.RegisteredJob.INFO);
 
                     // Skip printing details if the caller requested a filter
-                    if (!job.shouldDump(filterUidFinal)) {
+                    if (!predicate.test(job)) {
                         continue;
                     }
 
@@ -3103,7 +3111,7 @@
             }
             for (StateController controller : mControllers) {
                 controller.dumpControllerStateLocked(
-                        proto, JobSchedulerServiceDumpProto.CONTROLLERS, filterUidFinal);
+                        proto, JobSchedulerServiceDumpProto.CONTROLLERS, predicate);
             }
             for (int i=0; i< mUidPriorityOverride.size(); i++) {
                 int uid = mUidPriorityOverride.keyAt(i);
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index cf27882..7235faa 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -19,6 +19,7 @@
 import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
 import static com.android.server.job.JobSchedulerService.sSystemClock;
 
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.IActivityManager;
 import android.app.job.JobInfo;
@@ -62,6 +63,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
+import java.util.function.Consumer;
 import java.util.function.Predicate;
 
 /**
@@ -286,22 +288,23 @@
      * transient unified collections for them to iterate over and then discard, or creating
      * iterators every time a client needs to perform a sweep.
      */
-    public void forEachJob(JobStatusFunctor functor) {
-        mJobSet.forEachJob(functor);
+    public void forEachJob(Consumer<JobStatus> functor) {
+        mJobSet.forEachJob(null, functor);
     }
 
-    public void forEachJob(int uid, JobStatusFunctor functor) {
+    public void forEachJob(@Nullable Predicate<JobStatus> filterPredicate,
+            Consumer<JobStatus> functor) {
+        mJobSet.forEachJob(filterPredicate, functor);
+    }
+
+    public void forEachJob(int uid, Consumer<JobStatus> functor) {
         mJobSet.forEachJob(uid, functor);
     }
 
-    public void forEachJobForSourceUid(int sourceUid, JobStatusFunctor functor) {
+    public void forEachJobForSourceUid(int sourceUid, Consumer<JobStatus> functor) {
         mJobSet.forEachJobForSourceUid(sourceUid, functor);
     }
 
-    public interface JobStatusFunctor {
-        public void process(JobStatus jobStatus);
-    }
-
     /** Version of the db schema. */
     private static final int JOBS_FILE_VERSION = 0;
     /** Tag corresponds to constraints this job needs. */
@@ -342,12 +345,9 @@
             final List<JobStatus> storeCopy = new ArrayList<JobStatus>();
             synchronized (mLock) {
                 // Clone the jobs so we can release the lock before writing.
-                mJobSet.forEachJob(new JobStatusFunctor() {
-                    @Override
-                    public void process(JobStatus job) {
-                        if (job.isPersisted()) {
-                            storeCopy.add(new JobStatus(job));
-                        }
+                mJobSet.forEachJob(null, (job) -> {
+                    if (job.isPersisted()) {
+                        storeCopy.add(new JobStatus(job));
                     }
                 });
             }
@@ -1184,31 +1184,35 @@
             return total;
         }
 
-        public void forEachJob(JobStatusFunctor functor) {
+        public void forEachJob(@Nullable Predicate<JobStatus> filterPredicate,
+                Consumer<JobStatus> functor) {
             for (int uidIndex = mJobs.size() - 1; uidIndex >= 0; uidIndex--) {
                 ArraySet<JobStatus> jobs = mJobs.valueAt(uidIndex);
                 if (jobs != null) {
                     for (int i = jobs.size() - 1; i >= 0; i--) {
-                        functor.process(jobs.valueAt(i));
+                        final JobStatus jobStatus = jobs.valueAt(i);
+                        if ((filterPredicate == null) || filterPredicate.test(jobStatus)) {
+                            functor.accept(jobStatus);
+                        }
                     }
                 }
             }
         }
 
-        public void forEachJob(int callingUid, JobStatusFunctor functor) {
+        public void forEachJob(int callingUid, Consumer<JobStatus> functor) {
             ArraySet<JobStatus> jobs = mJobs.get(callingUid);
             if (jobs != null) {
                 for (int i = jobs.size() - 1; i >= 0; i--) {
-                    functor.process(jobs.valueAt(i));
+                    functor.accept(jobs.valueAt(i));
                 }
             }
         }
 
-        public void forEachJobForSourceUid(int sourceUid, JobStatusFunctor functor) {
+        public void forEachJobForSourceUid(int sourceUid, Consumer<JobStatus> functor) {
             final ArraySet<JobStatus> jobs = mJobsPerSourceUid.get(sourceUid);
             if (jobs != null) {
                 for (int i = jobs.size() - 1; i >= 0; i--) {
-                    functor.process(jobs.valueAt(i));
+                    functor.accept(jobs.valueAt(i));
                 }
             }
         }
diff --git a/services/core/java/com/android/server/job/controllers/AppIdleController.java b/services/core/java/com/android/server/job/controllers/AppIdleController.java
index 021eccd..bd8fe28 100644
--- a/services/core/java/com/android/server/job/controllers/AppIdleController.java
+++ b/services/core/java/com/android/server/job/controllers/AppIdleController.java
@@ -17,18 +17,18 @@
 package com.android.server.job.controllers;
 
 import android.app.usage.UsageStatsManagerInternal;
-import android.content.Context;
 import android.os.UserHandle;
 import android.util.Log;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
 import com.android.server.job.JobSchedulerService;
-import com.android.server.job.JobStore;
 import com.android.server.job.StateControllerProto;
 
-import java.io.PrintWriter;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
 
 /**
  * Controls when apps are considered idle and if jobs pertaining to those apps should
@@ -41,18 +41,15 @@
     private static final boolean DEBUG = JobSchedulerService.DEBUG
             || Log.isLoggable(TAG, Log.DEBUG);
 
-    // Singleton factory
-    private static Object sCreationLock = new Object();
-    private static volatile AppIdleController sController;
-    private final JobSchedulerService mJobSchedulerService;
     private final UsageStatsManagerInternal mUsageStatsInternal;
     private boolean mInitializedParoleOn;
     boolean mAppIdleParoleOn;
 
-    final class GlobalUpdateFunc implements JobStore.JobStatusFunctor {
+    final class GlobalUpdateFunc implements Consumer<JobStatus> {
         boolean mChanged;
 
-        @Override public void process(JobStatus jobStatus) {
+        @Override
+        public void accept(JobStatus jobStatus) {
             String packageName = jobStatus.getSourcePackageName();
             final boolean appIdle = !mAppIdleParoleOn && mUsageStatsInternal.isAppIdle(packageName,
                     jobStatus.getSourceUid(), jobStatus.getSourceUserId());
@@ -63,9 +60,9 @@
                 mChanged = true;
             }
         }
-    };
+    }
 
-    final static class PackageUpdateFunc implements JobStore.JobStatusFunctor {
+    final static class PackageUpdateFunc implements Consumer<JobStatus> {
         final int mUserId;
         final String mPackage;
         final boolean mIdle;
@@ -77,7 +74,8 @@
             mIdle = idle;
         }
 
-        @Override public void process(JobStatus jobStatus) {
+        @Override
+        public void accept(JobStatus jobStatus) {
             if (jobStatus.getSourcePackageName().equals(mPackage)
                     && jobStatus.getSourceUserId() == mUserId) {
                 if (jobStatus.setAppNotIdleConstraintSatisfied(!mIdle)) {
@@ -89,21 +87,10 @@
                 }
             }
         }
-    };
-
-    public static AppIdleController get(JobSchedulerService service) {
-        synchronized (sCreationLock) {
-            if (sController == null) {
-                sController = new AppIdleController(service, service.getContext(),
-                        service.getLock());
-            }
-            return sController;
-        }
     }
 
-    private AppIdleController(JobSchedulerService service, Context context, Object lock) {
-        super(service, context, lock);
-        mJobSchedulerService = service;
+    public AppIdleController(JobSchedulerService service) {
+        super(service);
         mUsageStatsInternal = LocalServices.getService(UsageStatsManagerInternal.class);
         mAppIdleParoleOn = true;
         mUsageStatsInternal.addAppIdleStateChangeListener(new AppIdleStateChangeListener());
@@ -131,56 +118,46 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(final PrintWriter pw, final int filterUid) {
-        pw.print("AppIdle: parole on = ");
-        pw.println(mAppIdleParoleOn);
-        mJobSchedulerService.getJobStore().forEachJob(new JobStore.JobStatusFunctor() {
-            @Override public void process(JobStatus jobStatus) {
-                // Skip printing details if the caller requested a filter
-                if (!jobStatus.shouldDump(filterUid)) {
-                    return;
-                }
-                pw.print("  #");
-                jobStatus.printUniqueId(pw);
-                pw.print(" from ");
-                UserHandle.formatUid(pw, jobStatus.getSourceUid());
-                pw.print(": ");
-                pw.print(jobStatus.getSourcePackageName());
-                if ((jobStatus.satisfiedConstraints&JobStatus.CONSTRAINT_APP_NOT_IDLE) != 0) {
-                    pw.println(" RUNNABLE");
-                } else {
-                    pw.println(" WAITING");
-                }
+    public void dumpControllerStateLocked(final IndentingPrintWriter pw,
+            final Predicate<JobStatus> predicate) {
+        pw.println("Parole on: " + mAppIdleParoleOn);
+        pw.println();
+
+        mService.getJobStore().forEachJob(predicate, (jobStatus) -> {
+            pw.print("#");
+            jobStatus.printUniqueId(pw);
+            pw.print(" from ");
+            UserHandle.formatUid(pw, jobStatus.getSourceUid());
+            pw.print(": ");
+            pw.print(jobStatus.getSourcePackageName());
+            if ((jobStatus.satisfiedConstraints&JobStatus.CONSTRAINT_APP_NOT_IDLE) != 0) {
+                pw.println(" RUNNABLE");
+            } else {
+                pw.println(" WAITING");
             }
         });
     }
 
     @Override
-    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
+            Predicate<JobStatus> predicate) {
         final long token = proto.start(fieldId);
         final long mToken = proto.start(StateControllerProto.APP_IDLE);
 
         proto.write(StateControllerProto.AppIdleController.IS_PAROLE_ON, mAppIdleParoleOn);
 
-        mJobSchedulerService.getJobStore().forEachJob(new JobStore.JobStatusFunctor() {
-            @Override public void process(JobStatus js) {
-                // Skip printing details if the caller requested a filter
-                if (!js.shouldDump(filterUid)) {
-                    return;
-                }
-
-                final long jsToken =
-                        proto.start(StateControllerProto.AppIdleController.TRACKED_JOBS);
-                js.writeToShortProto(proto, StateControllerProto.AppIdleController.TrackedJob.INFO);
-                proto.write(StateControllerProto.AppIdleController.TrackedJob.SOURCE_UID,
-                        js.getSourceUid());
-                proto.write(StateControllerProto.AppIdleController.TrackedJob.SOURCE_PACKAGE_NAME,
-                        js.getSourcePackageName());
-                proto.write(
-                        StateControllerProto.AppIdleController.TrackedJob.ARE_CONSTRAINTS_SATISFIED,
-                        (js.satisfiedConstraints & JobStatus.CONSTRAINT_APP_NOT_IDLE) != 0);
-                proto.end(jsToken);
-            }
+        mService.getJobStore().forEachJob(predicate, (js) -> {
+            final long jsToken =
+                    proto.start(StateControllerProto.AppIdleController.TRACKED_JOBS);
+            js.writeToShortProto(proto, StateControllerProto.AppIdleController.TrackedJob.INFO);
+            proto.write(StateControllerProto.AppIdleController.TrackedJob.SOURCE_UID,
+                    js.getSourceUid());
+            proto.write(StateControllerProto.AppIdleController.TrackedJob.SOURCE_PACKAGE_NAME,
+                    js.getSourcePackageName());
+            proto.write(
+                    StateControllerProto.AppIdleController.TrackedJob.ARE_CONSTRAINTS_SATISFIED,
+                    (js.satisfiedConstraints & JobStatus.CONSTRAINT_APP_NOT_IDLE) != 0);
+            proto.end(jsToken);
         });
 
         proto.end(mToken);
@@ -196,7 +173,7 @@
             }
             mAppIdleParoleOn = isAppIdleParoleOn;
             GlobalUpdateFunc update = new GlobalUpdateFunc();
-            mJobSchedulerService.getJobStore().forEachJob(update);
+            mService.getJobStore().forEachJob(update);
             if (update.mChanged) {
                 changed = true;
             }
@@ -217,7 +194,7 @@
                 }
 
                 PackageUpdateFunc update = new PackageUpdateFunc(userId, packageName, idle);
-                mJobSchedulerService.getJobStore().forEachJob(update);
+                mService.getJobStore().forEachJob(update);
                 if (update.mChanged) {
                     changed = true;
                 }
diff --git a/services/core/java/com/android/server/job/controllers/BackgroundJobsController.java b/services/core/java/com/android/server/job/controllers/BackgroundJobsController.java
index 46ec5e5..36e75115 100644
--- a/services/core/java/com/android/server/job/controllers/BackgroundJobsController.java
+++ b/services/core/java/com/android/server/job/controllers/BackgroundJobsController.java
@@ -16,50 +16,33 @@
 
 package com.android.server.job.controllers;
 
-import android.content.Context;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.Log;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
 import com.android.server.AppStateTracker;
 import com.android.server.AppStateTracker.Listener;
 import com.android.server.LocalServices;
 import com.android.server.job.JobSchedulerService;
-import com.android.server.job.JobStore;
 import com.android.server.job.StateControllerProto;
 import com.android.server.job.StateControllerProto.BackgroundJobsController.TrackedJob;
 
-import java.io.PrintWriter;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
 
 public final class BackgroundJobsController extends StateController {
     private static final String TAG = "JobScheduler.Background";
     private static final boolean DEBUG = JobSchedulerService.DEBUG
             || Log.isLoggable(TAG, Log.DEBUG);
 
-    // Singleton factory
-    private static final Object sCreationLock = new Object();
-    private static volatile BackgroundJobsController sController;
-
-    private final JobSchedulerService mJobSchedulerService;
-
     private final AppStateTracker mAppStateTracker;
 
-    public static BackgroundJobsController get(JobSchedulerService service) {
-        synchronized (sCreationLock) {
-            if (sController == null) {
-                sController = new BackgroundJobsController(service, service.getContext(),
-                        service.getLock());
-            }
-            return sController;
-        }
-    }
-
-    private BackgroundJobsController(JobSchedulerService service, Context context, Object lock) {
-        super(service, context, lock);
-        mJobSchedulerService = service;
+    public BackgroundJobsController(JobSchedulerService service) {
+        super(service);
 
         mAppStateTracker = Preconditions.checkNotNull(
                 LocalServices.getService(AppStateTracker.class));
@@ -77,19 +60,15 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(final PrintWriter pw, final int filterUid) {
-        pw.println("BackgroundJobsController");
+    public void dumpControllerStateLocked(final IndentingPrintWriter pw,
+            final Predicate<JobStatus> predicate) {
+        mAppStateTracker.dump(pw);
+        pw.println();
 
-        mAppStateTracker.dump(pw, "");
-
-        pw.println("Job state:");
-        mJobSchedulerService.getJobStore().forEachJob((jobStatus) -> {
-            if (!jobStatus.shouldDump(filterUid)) {
-                return;
-            }
+        mService.getJobStore().forEachJob(predicate, (jobStatus) -> {
             final int uid = jobStatus.getSourceUid();
             final String sourcePkg = jobStatus.getSourcePackageName();
-            pw.print("  #");
+            pw.print("#");
             jobStatus.printUniqueId(pw);
             pw.print(" from ");
             UserHandle.formatUid(pw, uid);
@@ -115,17 +94,15 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
+            Predicate<JobStatus> predicate) {
         final long token = proto.start(fieldId);
         final long mToken = proto.start(StateControllerProto.BACKGROUND);
 
         mAppStateTracker.dumpProto(proto,
                 StateControllerProto.BackgroundJobsController.FORCE_APP_STANDBY_TRACKER);
 
-        mJobSchedulerService.getJobStore().forEachJob((jobStatus) -> {
-            if (!jobStatus.shouldDump(filterUid)) {
-                return;
-            }
+        mService.getJobStore().forEachJob(predicate, (jobStatus) -> {
             final long jsToken =
                     proto.start(StateControllerProto.BackgroundJobsController.TRACKED_JOBS);
 
@@ -176,7 +153,7 @@
 
         final long start = DEBUG ? SystemClock.elapsedRealtimeNanos() : 0;
 
-        mJobSchedulerService.getJobStore().forEachJob(updateTrackedJobs);
+        mService.getJobStore().forEachJob(updateTrackedJobs);
 
         final long time = DEBUG ? (SystemClock.elapsedRealtimeNanos() - start) : 0;
         if (DEBUG) {
@@ -205,7 +182,7 @@
         return jobStatus.setBackgroundNotRestrictedConstraintSatisfied(canRun);
     }
 
-    private final class UpdateJobFunctor implements JobStore.JobStatusFunctor {
+    private final class UpdateJobFunctor implements Consumer<JobStatus> {
         private final int mFilterUid;
 
         boolean mChanged = false;
@@ -217,7 +194,7 @@
         }
 
         @Override
-        public void process(JobStatus jobStatus) {
+        public void accept(JobStatus jobStatus) {
             mTotalCount++;
             if ((mFilterUid > 0) && (mFilterUid != jobStatus.getSourceUid())) {
                 return;
diff --git a/services/core/java/com/android/server/job/controllers/BatteryController.java b/services/core/java/com/android/server/job/controllers/BatteryController.java
index 263d99b..46658ad 100644
--- a/services/core/java/com/android/server/job/controllers/BatteryController.java
+++ b/services/core/java/com/android/server/job/controllers/BatteryController.java
@@ -31,12 +31,12 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
 import com.android.server.job.JobSchedulerService;
-import com.android.server.job.StateChangedListener;
 import com.android.server.job.StateControllerProto;
 
-import java.io.PrintWriter;
+import java.util.function.Predicate;
 
 /**
  * Simple controller that tracks whether the phone is charging or not. The phone is considered to
@@ -48,36 +48,16 @@
     private static final boolean DEBUG = JobSchedulerService.DEBUG
             || Log.isLoggable(TAG, Log.DEBUG);
 
-    private static final Object sCreationLock = new Object();
-    private static volatile BatteryController sController;
-
     private final ArraySet<JobStatus> mTrackedTasks = new ArraySet<>();
     private ChargingTracker mChargeTracker;
 
-    public static BatteryController get(JobSchedulerService taskManagerService) {
-        synchronized (sCreationLock) {
-            if (sController == null) {
-                sController = new BatteryController(taskManagerService,
-                        taskManagerService.getContext(), taskManagerService.getLock());
-            }
-        }
-        return sController;
-    }
-
     @VisibleForTesting
     public ChargingTracker getTracker() {
         return mChargeTracker;
     }
 
-    @VisibleForTesting
-    public static BatteryController getForTesting(StateChangedListener stateChangedListener,
-                                           Context context) {
-        return new BatteryController(stateChangedListener, context, new Object());
-    }
-
-    private BatteryController(StateChangedListener stateChangedListener, Context context,
-            Object lock) {
-        super(stateChangedListener, context, lock);
+    public BatteryController(JobSchedulerService service) {
+        super(service);
         mChargeTracker = new ChargingTracker();
         mChargeTracker.startTracking();
     }
@@ -244,24 +224,23 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
-        pw.print("Battery: stable power = ");
-        pw.print(mChargeTracker.isOnStablePower());
-        pw.print(", not low = ");
-        pw.println(mChargeTracker.isBatteryNotLow());
+    public void dumpControllerStateLocked(IndentingPrintWriter pw,
+            Predicate<JobStatus> predicate) {
+        pw.println("Stable power: " + mChargeTracker.isOnStablePower());
+        pw.println("Not low: " + mChargeTracker.isBatteryNotLow());
+
         if (mChargeTracker.isMonitoring()) {
             pw.print("MONITORING: seq=");
             pw.println(mChargeTracker.getSeq());
         }
-        pw.print("Tracking ");
-        pw.print(mTrackedTasks.size());
-        pw.println(":");
+        pw.println();
+
         for (int i = 0; i < mTrackedTasks.size(); i++) {
             final JobStatus js = mTrackedTasks.valueAt(i);
-            if (!js.shouldDump(filterUid)) {
+            if (!predicate.test(js)) {
                 continue;
             }
-            pw.print("  #");
+            pw.print("#");
             js.printUniqueId(pw);
             pw.print(" from ");
             UserHandle.formatUid(pw, js.getSourceUid());
@@ -270,7 +249,8 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
+            Predicate<JobStatus> predicate) {
         final long token = proto.start(fieldId);
         final long mToken = proto.start(StateControllerProto.BATTERY);
 
@@ -286,7 +266,7 @@
 
         for (int i = 0; i < mTrackedTasks.size(); i++) {
             final JobStatus js = mTrackedTasks.valueAt(i);
-            if (!js.shouldDump(filterUid)) {
+            if (!predicate.test(js)) {
                 continue;
             }
             final long jsToken = proto.start(StateControllerProto.BatteryController.TRACKED_JOBS);
diff --git a/services/core/java/com/android/server/job/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
index d7ef124..abe55bb 100644
--- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
@@ -21,7 +21,6 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
 
 import android.app.job.JobInfo;
-import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
 import android.net.INetworkPolicyListener;
@@ -41,12 +40,13 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.job.JobSchedulerService;
+import com.android.server.job.JobSchedulerService.Constants;
 import com.android.server.job.JobServiceContext;
-import com.android.server.job.StateChangedListener;
 import com.android.server.job.StateControllerProto;
 
-import java.io.PrintWriter;
+import java.util.function.Predicate;
 
 /**
  * Handles changes in connectivity.
@@ -68,22 +68,8 @@
     @GuardedBy("mLock")
     private final ArraySet<JobStatus> mTrackedJobs = new ArraySet<>();
 
-    /** Singleton. */
-    private static ConnectivityController sSingleton;
-    private static Object sCreationLock = new Object();
-
-    public static ConnectivityController get(JobSchedulerService jms) {
-        synchronized (sCreationLock) {
-            if (sSingleton == null) {
-                sSingleton = new ConnectivityController(jms, jms.getContext(), jms.getLock());
-            }
-            return sSingleton;
-        }
-    }
-
-    private ConnectivityController(StateChangedListener stateChangedListener, Context context,
-            Object lock) {
-        super(stateChangedListener, context, lock);
+    public ConnectivityController(JobSchedulerService service) {
+        super(service);
 
         mConnManager = mContext.getSystemService(ConnectivityManager.class);
         mNetPolicyManager = mContext.getSystemService(NetworkPolicyManager.class);
@@ -122,7 +108,7 @@
      */
     @SuppressWarnings("unused")
     private static boolean isInsane(JobStatus jobStatus, Network network,
-            NetworkCapabilities capabilities) {
+            NetworkCapabilities capabilities, Constants constants) {
         final long estimatedBytes = jobStatus.getEstimatedNetworkBytes();
         if (estimatedBytes == JobInfo.NETWORK_BYTES_UNKNOWN) {
             // We don't know how large the job is; cross our fingers!
@@ -153,11 +139,11 @@
 
     @SuppressWarnings("unused")
     private static boolean isCongestionDelayed(JobStatus jobStatus, Network network,
-            NetworkCapabilities capabilities) {
+            NetworkCapabilities capabilities, Constants constants) {
         // If network is congested, and job is less than 50% through the
         // developer-requested window, then we're okay delaying the job.
         if (!capabilities.hasCapability(NET_CAPABILITY_NOT_CONGESTED)) {
-            return jobStatus.getFractionRunTime() < 0.5;
+            return jobStatus.getFractionRunTime() < constants.CONN_CONGESTION_DELAY_FRAC;
         } else {
             return false;
         }
@@ -165,14 +151,14 @@
 
     @SuppressWarnings("unused")
     private static boolean isStrictSatisfied(JobStatus jobStatus, Network network,
-            NetworkCapabilities capabilities) {
+            NetworkCapabilities capabilities, Constants constants) {
         return jobStatus.getJob().getRequiredNetwork().networkCapabilities
                 .satisfiedByNetworkCapabilities(capabilities);
     }
 
     @SuppressWarnings("unused")
     private static boolean isRelaxedSatisfied(JobStatus jobStatus, Network network,
-            NetworkCapabilities capabilities) {
+            NetworkCapabilities capabilities, Constants constants) {
         // Only consider doing this for prefetching jobs
         if ((jobStatus.getJob().getFlags() & JobInfo.FLAG_IS_PREFETCH) == 0) {
             return false;
@@ -184,7 +170,7 @@
                         .removeCapability(NET_CAPABILITY_NOT_METERED);
         if (relaxed.satisfiedByNetworkCapabilities(capabilities)) {
             // TODO: treat this as "maybe" response; need to check quotas
-            return jobStatus.getFractionRunTime() > 0.5;
+            return jobStatus.getFractionRunTime() > constants.CONN_PREFETCH_RELAX_FRAC;
         } else {
             return false;
         }
@@ -192,21 +178,21 @@
 
     @VisibleForTesting
     static boolean isSatisfied(JobStatus jobStatus, Network network,
-            NetworkCapabilities capabilities) {
+            NetworkCapabilities capabilities, Constants constants) {
         // Zeroth, we gotta have a network to think about being satisfied
         if (network == null || capabilities == null) return false;
 
         // First, are we insane?
-        if (isInsane(jobStatus, network, capabilities)) return false;
+        if (isInsane(jobStatus, network, capabilities, constants)) return false;
 
         // Second, is the network congested?
-        if (isCongestionDelayed(jobStatus, network, capabilities)) return false;
+        if (isCongestionDelayed(jobStatus, network, capabilities, constants)) return false;
 
         // Third, is the network a strict match?
-        if (isStrictSatisfied(jobStatus, network, capabilities)) return true;
+        if (isStrictSatisfied(jobStatus, network, capabilities, constants)) return true;
 
         // Third, is the network a relaxed match?
-        if (isRelaxedSatisfied(jobStatus, network, capabilities)) return true;
+        if (isRelaxedSatisfied(jobStatus, network, capabilities, constants)) return true;
 
         return false;
     }
@@ -222,7 +208,7 @@
         final NetworkCapabilities capabilities = mConnManager.getNetworkCapabilities(network);
 
         final boolean connected = (info != null) && info.isConnected();
-        final boolean satisfied = isSatisfied(jobStatus, network, capabilities);
+        final boolean satisfied = isSatisfied(jobStatus, network, capabilities, mConstants);
 
         final boolean changed = jobStatus
                 .setConnectivityConstraintSatisfied(connected && satisfied);
@@ -331,18 +317,15 @@
 
     @GuardedBy("mLock")
     @Override
-    public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
-        pw.print("Connectivity: connected=");
-        pw.println(mConnected);
-
-        pw.print("Tracking ");
-        pw.print(mTrackedJobs.size());
-        pw.println(" jobs");
+    public void dumpControllerStateLocked(IndentingPrintWriter pw,
+            Predicate<JobStatus> predicate) {
+        pw.println("System connected: " + mConnected);
+        pw.println();
 
         for (int i = 0; i < mTrackedJobs.size(); i++) {
             final JobStatus js = mTrackedJobs.valueAt(i);
-            if (js.shouldDump(filterUid)) {
-                pw.print("  #");
+            if (predicate.test(js)) {
+                pw.print("#");
                 js.printUniqueId(pw);
                 pw.print(" from ");
                 UserHandle.formatUid(pw, js.getSourceUid());
@@ -355,7 +338,8 @@
 
     @GuardedBy("mLock")
     @Override
-    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
+            Predicate<JobStatus> predicate) {
         final long token = proto.start(fieldId);
         final long mToken = proto.start(StateControllerProto.CONNECTIVITY);
 
@@ -363,7 +347,7 @@
 
         for (int i = 0; i < mTrackedJobs.size(); i++) {
             final JobStatus js = mTrackedJobs.valueAt(i);
-            if (!js.shouldDump(filterUid)) {
+            if (!predicate.test(js)) {
                 continue;
             }
             final long jsToken = proto.start(StateControllerProto.ConnectivityController.TRACKED_JOBS);
diff --git a/services/core/java/com/android/server/job/controllers/ContentObserverController.java b/services/core/java/com/android/server/job/controllers/ContentObserverController.java
index 90edde9..a775cf5 100644
--- a/services/core/java/com/android/server/job/controllers/ContentObserverController.java
+++ b/services/core/java/com/android/server/job/controllers/ContentObserverController.java
@@ -18,7 +18,6 @@
 
 import android.annotation.UserIdInt;
 import android.app.job.JobInfo;
-import android.content.Context;
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Handler;
@@ -31,14 +30,13 @@
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
 
-import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.job.JobSchedulerService;
-import com.android.server.job.StateChangedListener;
 import com.android.server.job.StateControllerProto;
 import com.android.server.job.StateControllerProto.ContentObserverController.Observer.TriggerContentData;
 
-import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.function.Predicate;
 
 /**
  * Controller for monitoring changes to content URIs through a ContentObserver.
@@ -60,9 +58,6 @@
      */
     private static final int URIS_URGENT_THRESHOLD = 40;
 
-    private static final Object sCreationLock = new Object();
-    private static volatile ContentObserverController sController;
-
     final private ArraySet<JobStatus> mTrackedTasks = new ArraySet<>();
     /**
      * Per-userid {@link JobInfo.TriggerContentUri} keyed ContentObserver cache.
@@ -71,26 +66,9 @@
             new SparseArray<>();
     final Handler mHandler;
 
-    public static ContentObserverController get(JobSchedulerService taskManagerService) {
-        synchronized (sCreationLock) {
-            if (sController == null) {
-                sController = new ContentObserverController(taskManagerService,
-                        taskManagerService.getContext(), taskManagerService.getLock());
-            }
-        }
-        return sController;
-    }
-
-    @VisibleForTesting
-    public static ContentObserverController getForTesting(StateChangedListener stateChangedListener,
-                                           Context context) {
-        return new ContentObserverController(stateChangedListener, context, new Object());
-    }
-
-    private ContentObserverController(StateChangedListener stateChangedListener, Context context,
-                Object lock) {
-        super(stateChangedListener, context, lock);
-        mHandler = new Handler(context.getMainLooper());
+    public ContentObserverController(JobSchedulerService service) {
+        super(service);
+        mHandler = new Handler(mContext.getMainLooper());
     }
 
     @Override
@@ -375,22 +353,25 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
-        pw.println("Content:");
+    public void dumpControllerStateLocked(IndentingPrintWriter pw,
+            Predicate<JobStatus> predicate) {
         for (int i = 0; i < mTrackedTasks.size(); i++) {
             JobStatus js = mTrackedTasks.valueAt(i);
-            if (!js.shouldDump(filterUid)) {
+            if (!predicate.test(js)) {
                 continue;
             }
-            pw.print("  #");
+            pw.print("#");
             js.printUniqueId(pw);
             pw.print(" from ");
             UserHandle.formatUid(pw, js.getSourceUid());
             pw.println();
         }
+        pw.println();
+
         int N = mObservers.size();
         if (N > 0) {
-            pw.println("  Observers:");
+            pw.println("Observers:");
+            pw.increaseIndent();
             for (int userIdx = 0; userIdx < N; userIdx++) {
                 final int userId = mObservers.keyAt(userIdx);
                 ArrayMap<JobInfo.TriggerContentUri, ObserverInstance> observersOfUser =
@@ -402,7 +383,7 @@
                     boolean shouldDump = false;
                     for (int j = 0; j < M; j++) {
                         JobInstance inst = obs.mJobs.valueAt(j);
-                        if (inst.mJobStatus.shouldDump(filterUid)) {
+                        if (predicate.test(inst.mJobStatus)) {
                             shouldDump = true;
                             break;
                         }
@@ -410,7 +391,6 @@
                     if (!shouldDump) {
                         continue;
                     }
-                    pw.print("    ");
                     JobInfo.TriggerContentUri trigger = observersOfUser.keyAt(observerIdx);
                     pw.print(trigger.getUri());
                     pw.print(" 0x");
@@ -418,17 +398,20 @@
                     pw.print(" (");
                     pw.print(System.identityHashCode(obs));
                     pw.println("):");
-                    pw.println("      Jobs:");
+                    pw.increaseIndent();
+                    pw.println("Jobs:");
+                    pw.increaseIndent();
                     for (int j = 0; j < M; j++) {
                         JobInstance inst = obs.mJobs.valueAt(j);
-                        pw.print("        #");
+                        pw.print("#");
                         inst.mJobStatus.printUniqueId(pw);
                         pw.print(" from ");
                         UserHandle.formatUid(pw, inst.mJobStatus.getSourceUid());
                         if (inst.mChangedAuthorities != null) {
                             pw.println(":");
+                            pw.increaseIndent();
                             if (inst.mTriggerPending) {
-                                pw.print("          Trigger pending: update=");
+                                pw.print("Trigger pending: update=");
                                 TimeUtils.formatDuration(
                                         inst.mJobStatus.getTriggerContentUpdateDelay(), pw);
                                 pw.print(", max=");
@@ -436,35 +419,38 @@
                                         inst.mJobStatus.getTriggerContentMaxDelay(), pw);
                                 pw.println();
                             }
-                            pw.println("          Changed Authorities:");
+                            pw.println("Changed Authorities:");
                             for (int k = 0; k < inst.mChangedAuthorities.size(); k++) {
-                                pw.print("          ");
                                 pw.println(inst.mChangedAuthorities.valueAt(k));
                             }
                             if (inst.mChangedUris != null) {
                                 pw.println("          Changed URIs:");
                                 for (int k = 0; k < inst.mChangedUris.size(); k++) {
-                                    pw.print("          ");
                                     pw.println(inst.mChangedUris.valueAt(k));
                                 }
                             }
+                            pw.decreaseIndent();
                         } else {
                             pw.println();
                         }
                     }
+                    pw.decreaseIndent();
+                    pw.decreaseIndent();
                 }
             }
+            pw.decreaseIndent();
         }
     }
 
     @Override
-    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
+            Predicate<JobStatus> predicate) {
         final long token = proto.start(fieldId);
         final long mToken = proto.start(StateControllerProto.CONTENT_OBSERVER);
 
         for (int i = 0; i < mTrackedTasks.size(); i++) {
             JobStatus js = mTrackedTasks.valueAt(i);
-            if (!js.shouldDump(filterUid)) {
+            if (!predicate.test(js)) {
                 continue;
             }
             final long jsToken =
@@ -493,7 +479,7 @@
                 boolean shouldDump = false;
                 for (int j = 0; j < m; j++) {
                     JobInstance inst = obs.mJobs.valueAt(j);
-                    if (inst.mJobStatus.shouldDump(filterUid)) {
+                    if (predicate.test(inst.mJobStatus)) {
                         shouldDump = true;
                         break;
                     }
diff --git a/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java b/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java
index 323a126..127a5c8 100644
--- a/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java
+++ b/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java
@@ -33,15 +33,16 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.DeviceIdleController;
 import com.android.server.LocalServices;
 import com.android.server.job.JobSchedulerService;
-import com.android.server.job.JobStore;
 import com.android.server.job.StateControllerProto;
 import com.android.server.job.StateControllerProto.DeviceIdleJobsController.TrackedJob;
 
-import java.io.PrintWriter;
 import java.util.Arrays;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
 
 /**
  * When device is dozing, set constraint for all jobs, except whitelisted apps, as not satisfied.
@@ -56,10 +57,6 @@
 
     static final int PROCESS_BACKGROUND_JOBS = 1;
 
-    // Singleton factory
-    private static Object sCreationLock = new Object();
-    private static DeviceIdleJobsController sController;
-
     /**
      * These are jobs added with a special flag to indicate that they should be exempted from doze
      * when the app is temp whitelisted or in the foreground.
@@ -68,7 +65,6 @@
     private final SparseBooleanArray mForegroundUids;
     private final DeviceIdleUpdateFunctor mDeviceIdleUpdateFunctor;
     private final DeviceIdleJobsDelayHandler mHandler;
-    private final JobSchedulerService mJobSchedulerService;
     private final PowerManager mPowerManager;
     private final DeviceIdleController.LocalService mLocalDeviceIdleController;
 
@@ -79,19 +75,6 @@
     private int[] mDeviceIdleWhitelistAppIds;
     private int[] mPowerSaveTempWhitelistAppIds;
 
-    /**
-     * Returns a singleton for the DeviceIdleJobsController
-     */
-    public static DeviceIdleJobsController get(JobSchedulerService service) {
-        synchronized (sCreationLock) {
-            if (sController == null) {
-                sController = new DeviceIdleJobsController(service, service.getContext(),
-                        service.getLock());
-            }
-            return sController;
-        }
-    }
-
     // onReceive
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
@@ -133,12 +116,10 @@
         }
     };
 
-    private DeviceIdleJobsController(JobSchedulerService jobSchedulerService, Context context,
-            Object lock) {
-        super(jobSchedulerService, context, lock);
+    public DeviceIdleJobsController(JobSchedulerService service) {
+        super(service);
 
-        mJobSchedulerService = jobSchedulerService;
-        mHandler = new DeviceIdleJobsDelayHandler(context.getMainLooper());
+        mHandler = new DeviceIdleJobsDelayHandler(mContext.getMainLooper());
         // Register for device idle mode changes
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mLocalDeviceIdleController =
@@ -168,13 +149,13 @@
             if (DEBUG) Slog.d(TAG, "mDeviceIdleMode=" + mDeviceIdleMode);
             if (enabled) {
                 mHandler.removeMessages(PROCESS_BACKGROUND_JOBS);
-                mJobSchedulerService.getJobStore().forEachJob(mDeviceIdleUpdateFunctor);
+                mService.getJobStore().forEachJob(mDeviceIdleUpdateFunctor);
             } else {
                 // When coming out of doze, process all foreground uids immediately, while others
                 // will be processed after a delay of 3 seconds.
                 for (int i = 0; i < mForegroundUids.size(); i++) {
                     if (mForegroundUids.valueAt(i)) {
-                        mJobSchedulerService.getJobStore().forEachJobForSourceUid(
+                        mService.getJobStore().forEachJobForSourceUid(
                                 mForegroundUids.keyAt(i), mDeviceIdleUpdateFunctor);
                     }
                 }
@@ -200,7 +181,7 @@
         }
         mForegroundUids.put(uid, active);
         mDeviceIdleUpdateFunctor.mChanged = false;
-        mJobSchedulerService.getJobStore().forEachJobForSourceUid(uid, mDeviceIdleUpdateFunctor);
+        mService.getJobStore().forEachJobForSourceUid(uid, mDeviceIdleUpdateFunctor);
         if (mDeviceIdleUpdateFunctor.mChanged) {
             mStateChangedListener.onControllerStateChanged();
         }
@@ -247,71 +228,64 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(final PrintWriter pw, final int filterUid) {
-        pw.println("DeviceIdleJobsController");
-        pw.println("mDeviceIdleMode=" + mDeviceIdleMode);
-        mJobSchedulerService.getJobStore().forEachJob(new JobStore.JobStatusFunctor() {
-            @Override public void process(JobStatus jobStatus) {
-                if (!jobStatus.shouldDump(filterUid)) {
-                    return;
-                }
-                pw.print("  #");
-                jobStatus.printUniqueId(pw);
-                pw.print(" from ");
-                UserHandle.formatUid(pw, jobStatus.getSourceUid());
-                pw.print(": ");
-                pw.print(jobStatus.getSourcePackageName());
-                pw.print((jobStatus.satisfiedConstraints
-                        & JobStatus.CONSTRAINT_DEVICE_NOT_DOZING) != 0
-                                ? " RUNNABLE" : " WAITING");
-                if (jobStatus.dozeWhitelisted) {
-                    pw.print(" WHITELISTED");
-                }
-                if (mAllowInIdleJobs.contains(jobStatus)) {
-                    pw.print(" ALLOWED_IN_DOZE");
-                }
-                pw.println();
+    public void dumpControllerStateLocked(final IndentingPrintWriter pw,
+            final Predicate<JobStatus> predicate) {
+        pw.println("Idle mode: " + mDeviceIdleMode);
+        pw.println();
+
+        mService.getJobStore().forEachJob(predicate, (jobStatus) -> {
+            pw.print("#");
+            jobStatus.printUniqueId(pw);
+            pw.print(" from ");
+            UserHandle.formatUid(pw, jobStatus.getSourceUid());
+            pw.print(": ");
+            pw.print(jobStatus.getSourcePackageName());
+            pw.print((jobStatus.satisfiedConstraints
+                    & JobStatus.CONSTRAINT_DEVICE_NOT_DOZING) != 0
+                            ? " RUNNABLE" : " WAITING");
+            if (jobStatus.dozeWhitelisted) {
+                pw.print(" WHITELISTED");
             }
+            if (mAllowInIdleJobs.contains(jobStatus)) {
+                pw.print(" ALLOWED_IN_DOZE");
+            }
+            pw.println();
         });
     }
 
     @Override
-    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
+            Predicate<JobStatus> predicate) {
         final long token = proto.start(fieldId);
         final long mToken = proto.start(StateControllerProto.DEVICE_IDLE);
 
         proto.write(StateControllerProto.DeviceIdleJobsController.IS_DEVICE_IDLE_MODE,
                 mDeviceIdleMode);
-        mJobSchedulerService.getJobStore().forEachJob(new JobStore.JobStatusFunctor() {
-            @Override public void process(JobStatus jobStatus) {
-                if (!jobStatus.shouldDump(filterUid)) {
-                    return;
-                }
-                final long jsToken =
-                        proto.start(StateControllerProto.DeviceIdleJobsController.TRACKED_JOBS);
+        mService.getJobStore().forEachJob(predicate, (jobStatus) -> {
+            final long jsToken =
+                    proto.start(StateControllerProto.DeviceIdleJobsController.TRACKED_JOBS);
 
-                jobStatus.writeToShortProto(proto, TrackedJob.INFO);
-                proto.write(TrackedJob.SOURCE_UID, jobStatus.getSourceUid());
-                proto.write(TrackedJob.SOURCE_PACKAGE_NAME, jobStatus.getSourcePackageName());
-                proto.write(TrackedJob.ARE_CONSTRAINTS_SATISFIED,
-                        (jobStatus.satisfiedConstraints &
-                            JobStatus.CONSTRAINT_DEVICE_NOT_DOZING) != 0);
-                proto.write(TrackedJob.IS_DOZE_WHITELISTED, jobStatus.dozeWhitelisted);
-                proto.write(TrackedJob.IS_ALLOWED_IN_DOZE, mAllowInIdleJobs.contains(jobStatus));
+            jobStatus.writeToShortProto(proto, TrackedJob.INFO);
+            proto.write(TrackedJob.SOURCE_UID, jobStatus.getSourceUid());
+            proto.write(TrackedJob.SOURCE_PACKAGE_NAME, jobStatus.getSourcePackageName());
+            proto.write(TrackedJob.ARE_CONSTRAINTS_SATISFIED,
+                    (jobStatus.satisfiedConstraints &
+                        JobStatus.CONSTRAINT_DEVICE_NOT_DOZING) != 0);
+            proto.write(TrackedJob.IS_DOZE_WHITELISTED, jobStatus.dozeWhitelisted);
+            proto.write(TrackedJob.IS_ALLOWED_IN_DOZE, mAllowInIdleJobs.contains(jobStatus));
 
-                proto.end(jsToken);
-            }
+            proto.end(jsToken);
         });
 
         proto.end(mToken);
         proto.end(token);
     }
 
-    final class DeviceIdleUpdateFunctor implements JobStore.JobStatusFunctor {
+    final class DeviceIdleUpdateFunctor implements Consumer<JobStatus> {
         boolean mChanged;
 
         @Override
-        public void process(JobStatus jobStatus) {
+        public void accept(JobStatus jobStatus) {
             mChanged |= updateTaskStateLocked(jobStatus);
         }
     }
@@ -328,7 +302,7 @@
                     // Just process all the jobs, the ones in foreground should already be running.
                     synchronized (mLock) {
                         mDeviceIdleUpdateFunctor.mChanged = false;
-                        mJobSchedulerService.getJobStore().forEachJob(mDeviceIdleUpdateFunctor);
+                        mService.getJobStore().forEachJob(mDeviceIdleUpdateFunctor);
                         if (mDeviceIdleUpdateFunctor.mChanged) {
                             mStateChangedListener.onControllerStateChanged();
                         }
diff --git a/services/core/java/com/android/server/job/controllers/IdleController.java b/services/core/java/com/android/server/job/controllers/IdleController.java
index 78284e5..1dbcfd6 100644
--- a/services/core/java/com/android/server/job/controllers/IdleController.java
+++ b/services/core/java/com/android/server/job/controllers/IdleController.java
@@ -30,12 +30,12 @@
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.am.ActivityManagerService;
 import com.android.server.job.JobSchedulerService;
-import com.android.server.job.StateChangedListener;
 import com.android.server.job.StateControllerProto;
 
-import java.io.PrintWriter;
+import java.util.function.Predicate;
 
 public final class IdleController extends StateController {
     private static final String TAG = "JobScheduler.Idle";
@@ -49,22 +49,8 @@
     final ArraySet<JobStatus> mTrackedTasks = new ArraySet<>();
     IdlenessTracker mIdleTracker;
 
-    // Singleton factory
-    private static Object sCreationLock = new Object();
-    private static volatile IdleController sController;
-
-    public static IdleController get(JobSchedulerService service) {
-        synchronized (sCreationLock) {
-            if (sController == null) {
-                sController = new IdleController(service, service.getContext(), service.getLock());
-            }
-            return sController;
-        }
-    }
-
-    private IdleController(StateChangedListener stateChangedListener, Context context,
-                Object lock) {
-        super(stateChangedListener, context, lock);
+    public IdleController(JobSchedulerService service) {
+        super(service);
         initIdleStateTracking();
     }
 
@@ -203,18 +189,17 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
-        pw.print("Idle: ");
-        pw.println(mIdleTracker.isIdle());
-        pw.print("Tracking ");
-        pw.print(mTrackedTasks.size());
-        pw.println(":");
+    public void dumpControllerStateLocked(IndentingPrintWriter pw,
+            Predicate<JobStatus> predicate) {
+        pw.println("Currently idle: " + mIdleTracker.isIdle());
+        pw.println();
+
         for (int i = 0; i < mTrackedTasks.size(); i++) {
             final JobStatus js = mTrackedTasks.valueAt(i);
-            if (!js.shouldDump(filterUid)) {
+            if (!predicate.test(js)) {
                 continue;
             }
-            pw.print("  #");
+            pw.print("#");
             js.printUniqueId(pw);
             pw.print(" from ");
             UserHandle.formatUid(pw, js.getSourceUid());
@@ -223,7 +208,8 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
+            Predicate<JobStatus> predicate) {
         final long token = proto.start(fieldId);
         final long mToken = proto.start(StateControllerProto.IDLE);
 
@@ -231,7 +217,7 @@
 
         for (int i = 0; i < mTrackedTasks.size(); i++) {
             final JobStatus js = mTrackedTasks.valueAt(i);
-            if (!js.shouldDump(filterUid)) {
+            if (!predicate.test(js)) {
                 continue;
             }
             final long jsToken = proto.start(StateControllerProto.IdleController.TRACKED_JOBS);
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index d1bb63a..5616197 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -888,11 +888,6 @@
         return mLastFailedRunTime;
     }
 
-    public boolean shouldDump(int filterUid) {
-        return filterUid == -1 || UserHandle.getAppId(getUid()) == filterUid
-                || UserHandle.getAppId(getSourceUid()) == filterUid;
-    }
-
     /**
      * @return Whether or not this job is ready to run, based on its requirements. This is true if
      * the constraints are satisfied <strong>or</strong> the deadline on the job has expired.
diff --git a/services/core/java/com/android/server/job/controllers/StateController.java b/services/core/java/com/android/server/job/controllers/StateController.java
index 88d6bea..495109d 100644
--- a/services/core/java/com/android/server/job/controllers/StateController.java
+++ b/services/core/java/com/android/server/job/controllers/StateController.java
@@ -19,10 +19,12 @@
 import android.content.Context;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.job.JobSchedulerService;
+import com.android.server.job.JobSchedulerService.Constants;
 import com.android.server.job.StateChangedListener;
 
-import java.io.PrintWriter;
+import java.util.function.Predicate;
 
 /**
  * Incorporates shared controller logic between the various controllers of the JobManager.
@@ -30,15 +32,18 @@
  * are ready to run, or whether they must be stopped.
  */
 public abstract class StateController {
+    protected final JobSchedulerService mService;
+    protected final StateChangedListener mStateChangedListener;
     protected final Context mContext;
     protected final Object mLock;
-    protected final StateChangedListener mStateChangedListener;
+    protected final Constants mConstants;
 
-    public StateController(StateChangedListener stateChangedListener, Context context,
-            Object lock) {
-        mStateChangedListener = stateChangedListener;
-        mContext = context;
-        mLock = lock;
+    StateController(JobSchedulerService service) {
+        mService = service;
+        mStateChangedListener = service;
+        mContext = service.getContext();
+        mLock = service.getLock();
+        mConstants = service.getConstants();
     }
 
     /**
@@ -64,7 +69,8 @@
     public void rescheduleForFailureLocked(JobStatus newJob, JobStatus failureToReschedule) {
     }
 
-    public abstract void dumpControllerStateLocked(PrintWriter pw, int filterUid);
+    public abstract void dumpControllerStateLocked(IndentingPrintWriter pw,
+            Predicate<JobStatus> predicate);
     public abstract void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
-            int filterUid);
+            Predicate<JobStatus> predicate);
 }
diff --git a/services/core/java/com/android/server/job/controllers/StorageController.java b/services/core/java/com/android/server/job/controllers/StorageController.java
index 5b79f39..c2ae53f 100644
--- a/services/core/java/com/android/server/job/controllers/StorageController.java
+++ b/services/core/java/com/android/server/job/controllers/StorageController.java
@@ -29,12 +29,12 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.job.JobSchedulerService;
-import com.android.server.job.StateChangedListener;
 import com.android.server.job.StateControllerProto;
 import com.android.server.storage.DeviceStorageMonitorService;
 
-import java.io.PrintWriter;
+import java.util.function.Predicate;
 
 /**
  * Simple controller that tracks the status of the device's storage.
@@ -44,36 +44,16 @@
     private static final boolean DEBUG = JobSchedulerService.DEBUG
             || Log.isLoggable(TAG, Log.DEBUG);
 
-    private static final Object sCreationLock = new Object();
-    private static volatile StorageController sController;
-
     private final ArraySet<JobStatus> mTrackedTasks = new ArraySet<JobStatus>();
-    private StorageTracker mStorageTracker;
-
-    public static StorageController get(JobSchedulerService taskManagerService) {
-        synchronized (sCreationLock) {
-            if (sController == null) {
-                sController = new StorageController(taskManagerService,
-                        taskManagerService.getContext(), taskManagerService.getLock());
-            }
-        }
-        return sController;
-    }
+    private final StorageTracker mStorageTracker;
 
     @VisibleForTesting
     public StorageTracker getTracker() {
         return mStorageTracker;
     }
 
-    @VisibleForTesting
-    public static StorageController getForTesting(StateChangedListener stateChangedListener,
-            Context context) {
-        return new StorageController(stateChangedListener, context, new Object());
-    }
-
-    private StorageController(StateChangedListener stateChangedListener, Context context,
-            Object lock) {
-        super(stateChangedListener, context, lock);
+    public StorageController(JobSchedulerService service) {
+        super(service);
         mStorageTracker = new StorageTracker();
         mStorageTracker.startTracking();
     }
@@ -175,20 +155,18 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
-        pw.print("Storage: not low = ");
-        pw.print(mStorageTracker.isStorageNotLow());
-        pw.print(", seq=");
-        pw.println(mStorageTracker.getSeq());
-        pw.print("Tracking ");
-        pw.print(mTrackedTasks.size());
-        pw.println(":");
+    public void dumpControllerStateLocked(IndentingPrintWriter pw,
+            Predicate<JobStatus> predicate) {
+        pw.println("Not low: " + mStorageTracker.isStorageNotLow());
+        pw.println("Sequence: " + mStorageTracker.getSeq());
+        pw.println();
+
         for (int i = 0; i < mTrackedTasks.size(); i++) {
             final JobStatus js = mTrackedTasks.valueAt(i);
-            if (!js.shouldDump(filterUid)) {
+            if (!predicate.test(js)) {
                 continue;
             }
-            pw.print("  #");
+            pw.print("#");
             js.printUniqueId(pw);
             pw.print(" from ");
             UserHandle.formatUid(pw, js.getSourceUid());
@@ -197,7 +175,8 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
+            Predicate<JobStatus> predicate) {
         final long token = proto.start(fieldId);
         final long mToken = proto.start(StateControllerProto.STORAGE);
 
@@ -208,7 +187,7 @@
 
         for (int i = 0; i < mTrackedTasks.size(); i++) {
             final JobStatus js = mTrackedTasks.valueAt(i);
-            if (!js.shouldDump(filterUid)) {
+            if (!predicate.test(js)) {
                 continue;
             }
             final long jsToken = proto.start(StateControllerProto.StorageController.TRACKED_JOBS);
diff --git a/services/core/java/com/android/server/job/controllers/TimeController.java b/services/core/java/com/android/server/job/controllers/TimeController.java
index cdafc3b..fa48b5e 100644
--- a/services/core/java/com/android/server/job/controllers/TimeController.java
+++ b/services/core/java/com/android/server/job/controllers/TimeController.java
@@ -30,15 +30,15 @@
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.job.JobSchedulerService;
-import com.android.server.job.StateChangedListener;
 import com.android.server.job.StateControllerProto;
 
-import java.io.PrintWriter;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
+import java.util.function.Predicate;
 
 /**
  * This class sets an alarm for the next expiring job, and determines whether a job's minimum
@@ -62,23 +62,13 @@
     private AlarmManager mAlarmService = null;
     /** List of tracked jobs, sorted asc. by deadline */
     private final List<JobStatus> mTrackedJobs = new LinkedList<>();
-    /** Singleton. */
-    private static TimeController mSingleton;
 
-    public static synchronized TimeController get(JobSchedulerService jms) {
-        if (mSingleton == null) {
-            mSingleton = new TimeController(jms, jms.getContext(), jms.getLock());
-        }
-        return mSingleton;
-    }
-
-    private TimeController(StateChangedListener stateChangedListener, Context context,
-                Object lock) {
-        super(stateChangedListener, context, lock);
+    public TimeController(JobSchedulerService service) {
+        super(service);
 
         mNextJobExpiredElapsedMillis = Long.MAX_VALUE;
         mNextDelayExpiredElapsedMillis = Long.MAX_VALUE;
-        mChainedAttributionEnabled = WorkSource.isChainedBatteryAttributionEnabled(context);
+        mChainedAttributionEnabled = WorkSource.isChainedBatteryAttributionEnabled(mContext);
     }
 
     /**
@@ -348,25 +338,24 @@
     };
 
     @Override
-    public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
+    public void dumpControllerStateLocked(IndentingPrintWriter pw,
+            Predicate<JobStatus> predicate) {
         final long nowElapsed = sElapsedRealtimeClock.millis();
-        pw.print("Alarms: now=");
-        pw.print(nowElapsed);
-        pw.println();
+        pw.println("Elapsed clock: " + nowElapsed);
+
         pw.print("Next delay alarm in ");
         TimeUtils.formatDuration(mNextDelayExpiredElapsedMillis, nowElapsed, pw);
         pw.println();
         pw.print("Next deadline alarm in ");
         TimeUtils.formatDuration(mNextJobExpiredElapsedMillis, nowElapsed, pw);
         pw.println();
-        pw.print("Tracking ");
-        pw.print(mTrackedJobs.size());
-        pw.println(":");
+        pw.println();
+
         for (JobStatus ts : mTrackedJobs) {
-            if (!ts.shouldDump(filterUid)) {
+            if (!predicate.test(ts)) {
                 continue;
             }
-            pw.print("  #");
+            pw.print("#");
             ts.printUniqueId(pw);
             pw.print(" from ");
             UserHandle.formatUid(pw, ts.getSourceUid());
@@ -387,7 +376,8 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
+            Predicate<JobStatus> predicate) {
         final long token = proto.start(fieldId);
         final long mToken = proto.start(StateControllerProto.TIME);
 
@@ -399,7 +389,7 @@
                 mNextJobExpiredElapsedMillis - nowElapsed);
 
         for (JobStatus ts : mTrackedJobs) {
-            if (!ts.shouldDump(filterUid)) {
+            if (!predicate.test(ts)) {
                 continue;
             }
             final long tsToken = proto.start(StateControllerProto.TimeController.TRACKED_JOBS);
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 0dab528..5267f54 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -1704,7 +1704,6 @@
             mStarted = false;
             mSingleShot = false;
             native_stop();
-            mTimeToFirstFix = 0;
             mLastFixTime = 0;
 
             // reset SV count to zero
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index bd9ec55..f29e0bb 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -28,6 +28,11 @@
 import static android.content.Intent.ACTION_USER_ADDED;
 import static android.content.Intent.ACTION_USER_REMOVED;
 import static android.content.Intent.EXTRA_UID;
+import static android.content.pm.PackageManager.MATCH_ANY_USER;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
+import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
+import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
@@ -61,9 +66,7 @@
 import static android.net.NetworkPolicyManager.resolveNetworkId;
 import static android.net.NetworkPolicyManager.uidPoliciesToString;
 import static android.net.NetworkPolicyManager.uidRulesToString;
-import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER;
-import static android.net.NetworkTemplate.MATCH_MOBILE_4G;
-import static android.net.NetworkTemplate.MATCH_MOBILE_ALL;
+import static android.net.NetworkTemplate.MATCH_MOBILE;
 import static android.net.NetworkTemplate.MATCH_WIFI;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
 import static android.net.TrafficStats.MB_IN_BYTES;
@@ -71,7 +74,6 @@
 import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
 import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT;
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-import static android.text.format.DateUtils.DAY_IN_MILLIS;
 
 import static com.android.internal.util.ArrayUtils.appendInt;
 import static com.android.internal.util.Preconditions.checkNotNull;
@@ -139,15 +141,16 @@
 import android.net.NetworkRequest;
 import android.net.NetworkSpecifier;
 import android.net.NetworkState;
+import android.net.NetworkStats;
 import android.net.NetworkTemplate;
 import android.net.StringNetworkSpecifier;
 import android.net.TrafficStats;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
+import android.os.BestClock;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Environment;
-import android.os.BestClock;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IDeviceIdleController;
@@ -359,7 +362,7 @@
 
     private final Context mContext;
     private final IActivityManager mActivityManager;
-    private final INetworkStatsService mNetworkStats;
+    private NetworkStatsManagerInternal mNetworkStats;
     private final INetworkManagementService mNetworkManager;
     private UsageStatsManagerInternal mUsageStats;
     private final Clock mClock;
@@ -516,10 +519,9 @@
     // TODO: migrate notifications to SystemUI
 
     public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
-            INetworkStatsService networkStats, INetworkManagementService networkManagement) {
-        this(context, activityManager, networkStats, networkManagement,
-                AppGlobals.getPackageManager(), getDefaultClock(), getDefaultSystemDir(),
-                false);
+            INetworkManagementService networkManagement) {
+        this(context, activityManager, networkManagement, AppGlobals.getPackageManager(),
+                getDefaultClock(), getDefaultSystemDir(), false);
     }
 
     private static @NonNull File getDefaultSystemDir() {
@@ -532,11 +534,10 @@
     }
 
     public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
-            INetworkStatsService networkStats, INetworkManagementService networkManagement,
-            IPackageManager pm, Clock clock, File systemDir, boolean suppressDefaultPolicy) {
+            INetworkManagementService networkManagement, IPackageManager pm, Clock clock,
+            File systemDir, boolean suppressDefaultPolicy) {
         mContext = checkNotNull(context, "missing context");
         mActivityManager = checkNotNull(activityManager, "missing activityManager");
-        mNetworkStats = checkNotNull(networkStats, "missing networkStats");
         mNetworkManager = checkNotNull(networkManagement, "missing networkManagement");
         mDeviceIdleController = IDeviceIdleController.Stub.asInterface(ServiceManager.getService(
                 Context.DEVICE_IDLE_CONTROLLER));
@@ -660,6 +661,7 @@
             }
 
             mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
+            mNetworkStats = LocalServices.getService(NetworkStatsManagerInternal.class);
 
             synchronized (mUidRulesFirstLock) {
                 synchronized (mNetworkPoliciesSecondLock) {
@@ -1063,9 +1065,9 @@
             if (policy.isOverLimit(totalBytes)) {
                 final boolean snoozedThisCycle = policy.lastLimitSnooze >= cycleStart;
                 if (snoozedThisCycle) {
-                    enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes);
+                    enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes, null);
                 } else {
-                    enqueueNotification(policy, TYPE_LIMIT, totalBytes);
+                    enqueueNotification(policy, TYPE_LIMIT, totalBytes, null);
                     notifyOverLimitNL(policy.template);
                 }
 
@@ -1074,7 +1076,7 @@
 
                 final boolean snoozedThisCycle = policy.lastWarningSnooze >= cycleStart;
                 if (policy.isOverWarning(totalBytes) && !snoozedThisCycle) {
-                    enqueueNotification(policy, TYPE_WARNING, totalBytes);
+                    enqueueNotification(policy, TYPE_WARNING, totalBytes, null);
                 }
             }
 
@@ -1082,7 +1084,9 @@
             // far past the plan limits.
             if (policy.limitBytes != LIMIT_DISABLED) {
                 final long recentDuration = TimeUnit.DAYS.toMillis(4);
-                final long recentBytes = getTotalBytes(policy.template, now - recentDuration, now);
+                final long recentStart = now - recentDuration;
+                final long recentEnd = now;
+                final long recentBytes = getTotalBytes(policy.template, recentStart, recentEnd);
 
                 final long cycleDuration = cycleEnd - cycleStart;
                 final long projectedBytes = (recentBytes * cycleDuration) / recentDuration;
@@ -1096,7 +1100,8 @@
                 final boolean snoozedRecently = policy.lastRapidSnooze >= now
                         - DateUtils.DAY_IN_MILLIS;
                 if (projectedBytes > alertBytes && !snoozedRecently) {
-                    enqueueNotification(policy, TYPE_RAPID, 0);
+                    enqueueNotification(policy, TYPE_RAPID, 0,
+                            findRapidBlame(policy.template, recentStart, recentEnd));
                 }
             }
         }
@@ -1111,6 +1116,45 @@
     }
 
     /**
+     * Attempt to find a specific app to blame for rapid data usage during the
+     * given time period.
+     */
+    private @Nullable ApplicationInfo findRapidBlame(NetworkTemplate template,
+            long start, long end) {
+        long totalBytes = 0;
+        long maxBytes = 0;
+        int maxUid = 0;
+
+        final NetworkStats stats = getNetworkUidBytes(template, start, end);
+        NetworkStats.Entry entry = null;
+        for (int i = 0; i < stats.size(); i++) {
+            entry = stats.getValues(i, entry);
+            final long bytes = entry.rxBytes + entry.txBytes;
+            totalBytes += bytes;
+            if (bytes > maxBytes) {
+                maxBytes = bytes;
+                maxUid = entry.uid;
+            }
+        }
+
+        // Only point blame if the majority of usage was done by a single app.
+        // TODO: support shared UIDs
+        if (maxBytes > 0 && maxBytes > totalBytes / 2) {
+            final String[] packageNames = mContext.getPackageManager().getPackagesForUid(maxUid);
+            if (packageNames.length == 1) {
+                try {
+                    return mContext.getPackageManager().getApplicationInfo(packageNames[0],
+                            MATCH_ANY_USER | MATCH_DISABLED_COMPONENTS | MATCH_DIRECT_BOOT_AWARE
+                                    | MATCH_DIRECT_BOOT_UNAWARE | MATCH_UNINSTALLED_PACKAGES);
+                } catch (NameNotFoundException ignored) {
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
      * Test if given {@link NetworkTemplate} is relevant to user based on
      * current device state, such as when
      * {@link TelephonyManager#getSubscriberId()} matches. This is regardless of
@@ -1157,7 +1201,8 @@
      * Show notification for combined {@link NetworkPolicy} and specific type,
      * like {@link #TYPE_LIMIT}. Okay to call multiple times.
      */
-    private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes) {
+    private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes,
+            ApplicationInfo rapidBlame) {
         final NotificationId notificationId = new NotificationId(policy, type);
         final Notification.Builder builder =
                 new Notification.Builder(mContext, SystemNotificationChannels.NETWORK_ALERTS);
@@ -1167,16 +1212,15 @@
                 com.android.internal.R.color.system_notification_accent_color));
 
         final Resources res = mContext.getResources();
-        CharSequence body = null;
+        final CharSequence title;
+        final CharSequence body;
         switch (type) {
             case TYPE_WARNING: {
-                final CharSequence title = res.getText(R.string.data_usage_warning_title);
-                body = res.getString(R.string.data_usage_warning_body);
+                title = res.getText(R.string.data_usage_warning_title);
+                body = res.getString(R.string.data_usage_warning_body,
+                        Formatter.formatFileSize(mContext, totalBytes));
 
                 builder.setSmallIcon(R.drawable.stat_notify_error);
-                builder.setTicker(title);
-                builder.setContentTitle(title);
-                builder.setContentText(body);
 
                 final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template);
                 builder.setDeleteIntent(PendingIntent.getBroadcast(
@@ -1189,34 +1233,20 @@
                 break;
             }
             case TYPE_LIMIT: {
-                body = res.getText(R.string.data_usage_limit_body);
-
-                final CharSequence title;
-                int icon = R.drawable.stat_notify_disabled_data;
                 switch (policy.template.getMatchRule()) {
-                    case MATCH_MOBILE_3G_LOWER:
-                        title = res.getText(R.string.data_usage_3g_limit_title);
-                        break;
-                    case MATCH_MOBILE_4G:
-                        title = res.getText(R.string.data_usage_4g_limit_title);
-                        break;
-                    case MATCH_MOBILE_ALL:
+                    case MATCH_MOBILE:
                         title = res.getText(R.string.data_usage_mobile_limit_title);
                         break;
                     case MATCH_WIFI:
                         title = res.getText(R.string.data_usage_wifi_limit_title);
-                        icon = R.drawable.stat_notify_error;
                         break;
                     default:
-                        title = null;
-                        break;
+                        return;
                 }
+                body = res.getText(R.string.data_usage_limit_body);
 
                 builder.setOngoing(true);
-                builder.setSmallIcon(icon);
-                builder.setTicker(title);
-                builder.setContentTitle(title);
-                builder.setContentText(body);
+                builder.setSmallIcon(R.drawable.stat_notify_disabled_data);
 
                 final Intent intent = buildNetworkOverLimitIntent(res, policy.template);
                 builder.setContentIntent(PendingIntent.getActivity(
@@ -1224,34 +1254,22 @@
                 break;
             }
             case TYPE_LIMIT_SNOOZED: {
-                final long overBytes = totalBytes - policy.limitBytes;
-                body = res.getString(R.string.data_usage_limit_snoozed_body,
-                        Formatter.formatFileSize(mContext, overBytes));
-
-                final CharSequence title;
                 switch (policy.template.getMatchRule()) {
-                    case MATCH_MOBILE_3G_LOWER:
-                        title = res.getText(R.string.data_usage_3g_limit_snoozed_title);
-                        break;
-                    case MATCH_MOBILE_4G:
-                        title = res.getText(R.string.data_usage_4g_limit_snoozed_title);
-                        break;
-                    case MATCH_MOBILE_ALL:
+                    case MATCH_MOBILE:
                         title = res.getText(R.string.data_usage_mobile_limit_snoozed_title);
                         break;
                     case MATCH_WIFI:
                         title = res.getText(R.string.data_usage_wifi_limit_snoozed_title);
                         break;
                     default:
-                        title = null;
-                        break;
+                        return;
                 }
+                final long overBytes = totalBytes - policy.limitBytes;
+                body = res.getString(R.string.data_usage_limit_snoozed_body,
+                        Formatter.formatFileSize(mContext, overBytes));
 
                 builder.setOngoing(true);
                 builder.setSmallIcon(R.drawable.stat_notify_error);
-                builder.setTicker(title);
-                builder.setContentTitle(title);
-                builder.setContentText(body);
                 builder.setChannelId(SystemNotificationChannels.NETWORK_STATUS);
 
                 final Intent intent = buildViewDataUsageIntent(res, policy.template);
@@ -1260,13 +1278,15 @@
                 break;
             }
             case TYPE_RAPID: {
-                final CharSequence title = res.getText(R.string.data_usage_rapid_title);
-                body = res.getText(R.string.data_usage_rapid_body);
+                title = res.getText(R.string.data_usage_rapid_title);
+                if (rapidBlame != null) {
+                    body = res.getString(R.string.data_usage_rapid_app_body,
+                            rapidBlame.loadLabel(mContext.getPackageManager()));
+                } else {
+                    body = res.getString(R.string.data_usage_rapid_body);
+                }
 
                 builder.setSmallIcon(R.drawable.stat_notify_error);
-                builder.setTicker(title);
-                builder.setContentTitle(title);
-                builder.setContentText(body);
 
                 final Intent snoozeIntent = buildSnoozeRapidIntent(policy.template);
                 builder.setDeleteIntent(PendingIntent.getBroadcast(
@@ -1277,11 +1297,15 @@
                         mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT));
                 break;
             }
+            default: {
+                return;
+            }
         }
 
-        if (!TextUtils.isEmpty(body)) {
-            builder.setStyle(new Notification.BigTextStyle().bigText(body));
-        }
+        builder.setTicker(title);
+        builder.setContentTitle(title);
+        builder.setContentText(body);
+        builder.setStyle(new Notification.BigTextStyle().bigText(body));
 
         mContext.getSystemService(NotificationManager.class).notifyAsUser(notificationId.getTag(),
                 notificationId.getId(), builder.build(), UserHandle.ALL);
@@ -1537,7 +1561,7 @@
         // TODO: reach into ConnectivityManager to proactively disable bringing
         // up this network, since we know that traffic will be blocked.
 
-        if (template.getMatchRule() == MATCH_MOBILE_ALL) {
+        if (template.getMatchRule() == MATCH_MOBILE) {
             // If mobile data usage hits the limit or if the user resumes the data, we need to
             // notify telephony.
             final SubscriptionManager sm = mContext.getSystemService(SubscriptionManager.class);
@@ -1954,9 +1978,7 @@
                             metered = readBooleanAttribute(in, ATTR_METERED);
                         } else {
                             switch (networkTemplate) {
-                                case MATCH_MOBILE_3G_LOWER:
-                                case MATCH_MOBILE_4G:
-                                case MATCH_MOBILE_ALL:
+                                case MATCH_MOBILE:
                                     metered = true;
                                     break;
                                 default:
@@ -3243,8 +3265,6 @@
         }
         try {
             mNetworkStats.setUidForeground(uid, uidForeground);
-        } catch (RemoteException e) {
-            // ignored; service lives in system_server
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
         }
@@ -4028,13 +4048,9 @@
 
                     synchronized (mNetworkPoliciesSecondLock) {
                         if (mMeteredIfaces.contains(iface)) {
-                            try {
-                                // force stats update to make sure we have
-                                // numbers that caused alert to trigger.
-                                mNetworkStats.forceUpdate();
-                            } catch (RemoteException e) {
-                                // ignored; service lives in system_server
-                            }
+                            // force stats update to make sure we have
+                            // numbers that caused alert to trigger.
+                            mNetworkStats.forceUpdate();
 
                             updateNetworkEnabledNL();
                             updateNotificationsNL();
@@ -4075,14 +4091,10 @@
                 }
                 case MSG_ADVISE_PERSIST_THRESHOLD: {
                     final long lowestRule = (Long) msg.obj;
-                    try {
-                        // make sure stats are recorded frequently enough; we aim
-                        // for 2MB threshold for 2GB/month rules.
-                        final long persistThreshold = lowestRule / 1000;
-                        mNetworkStats.advisePersistThreshold(persistThreshold);
-                    } catch (RemoteException e) {
-                        // ignored; service lives in system_server
-                    }
+                    // make sure stats are recorded frequently enough; we aim
+                    // for 2MB threshold for 2GB/month rules.
+                    final long persistThreshold = lowestRule / 1000;
+                    mNetworkStats.advisePersistThreshold(persistThreshold);
                     return true;
                 }
                 case MSG_UPDATE_INTERFACE_QUOTA: {
@@ -4366,15 +4378,26 @@
         }
     }
 
+    @Deprecated
     private long getTotalBytes(NetworkTemplate template, long start, long end) {
+        return getNetworkTotalBytes(template, start, end);
+    }
+
+    private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
         try {
             return mNetworkStats.getNetworkTotalBytes(template, start, end);
         } catch (RuntimeException e) {
-            Slog.w(TAG, "problem reading network stats: " + e);
+            Slog.w(TAG, "Failed to read network stats: " + e);
             return 0;
-        } catch (RemoteException e) {
-            // ignored; service lives in system_server
-            return 0;
+        }
+    }
+
+    private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
+        try {
+            return mNetworkStats.getNetworkUidBytes(template, start, end);
+        } catch (RuntimeException e) {
+            Slog.w(TAG, "Failed to read network stats: " + e);
+            return new NetworkStats(SystemClock.elapsedRealtime(), 0);
         }
     }
 
diff --git a/services/core/java/com/android/server/net/NetworkStatsCollection.java b/services/core/java/com/android/server/net/NetworkStatsCollection.java
index 3cc4d83..a5f8dc7 100644
--- a/services/core/java/com/android/server/net/NetworkStatsCollection.java
+++ b/services/core/java/com/android/server/net/NetworkStatsCollection.java
@@ -106,6 +106,10 @@
         reset();
     }
 
+    public void clear() {
+        reset();
+    }
+
     public void reset() {
         mStats.clear();
         mStartMillis = Long.MAX_VALUE;
diff --git a/services/core/java/com/android/server/net/NetworkStatsManagerInternal.java b/services/core/java/com/android/server/net/NetworkStatsManagerInternal.java
new file mode 100644
index 0000000..4843ede
--- /dev/null
+++ b/services/core/java/com/android/server/net/NetworkStatsManagerInternal.java
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+package com.android.server.net;
+
+import android.net.NetworkStats;
+import android.net.NetworkTemplate;
+
+public abstract class NetworkStatsManagerInternal {
+    /** Return network layer usage total for traffic that matches template. */
+    public abstract long getNetworkTotalBytes(NetworkTemplate template, long start, long end);
+
+    /** Return network layer usage per-UID for traffic that matches template. */
+    public abstract NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end);
+
+    /** Mark given UID as being in foreground for stats purposes. */
+    public abstract void setUidForeground(int uid, boolean uidForeground);
+
+    /** Advise persistance threshold; may be overridden internally. */
+    public abstract void advisePersistThreshold(long thresholdBytes);
+
+    /** Force update of statistics. */
+    public abstract void forceUpdate();
+}
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 32e15c9..93c04fe 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -49,7 +49,6 @@
 import static android.provider.Settings.Global.NETSTATS_GLOBAL_ALERT_BYTES;
 import static android.provider.Settings.Global.NETSTATS_POLL_INTERVAL;
 import static android.provider.Settings.Global.NETSTATS_SAMPLE_ENABLED;
-import static android.provider.Settings.Global.NETSTATS_TIME_CACHE_MAX_AGE;
 import static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION;
 import static android.provider.Settings.Global.NETSTATS_UID_DELETE_AGE;
 import static android.provider.Settings.Global.NETSTATS_UID_PERSIST_BYTES;
@@ -95,10 +94,10 @@
 import android.net.NetworkStatsHistory;
 import android.net.NetworkTemplate;
 import android.net.TrafficStats;
+import android.os.BestClock;
 import android.os.Binder;
 import android.os.DropBoxManager;
 import android.os.Environment;
-import android.os.BestClock;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
@@ -134,6 +133,7 @@
 import com.android.internal.util.FileRotator;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.EventLogTags;
+import com.android.server.LocalServices;
 import com.android.server.connectivity.Tethering;
 
 import java.io.File;
@@ -333,6 +333,9 @@
         mStatsObservers = checkNotNull(statsObservers, "missing NetworkStatsObservers");
         mSystemDir = checkNotNull(systemDir, "missing systemDir");
         mBaseDir = checkNotNull(baseDir, "missing baseDir");
+
+        LocalServices.addService(NetworkStatsManagerInternal.class,
+                new NetworkStatsManagerInternalImpl());
     }
 
     @VisibleForTesting
@@ -640,7 +643,7 @@
     private SubscriptionPlan resolveSubscriptionPlan(NetworkTemplate template, int flags) {
         SubscriptionPlan plan = null;
         if ((flags & NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN) != 0
-                && (template.getMatchRule() == NetworkTemplate.MATCH_MOBILE_ALL)
+                && (template.getMatchRule() == NetworkTemplate.MATCH_MOBILE)
                 && mSettings.getAugmentEnabled()) {
             if (LOGD) Slog.d(TAG, "Resolving plan for " + template);
             final long token = Binder.clearCallingIdentity();
@@ -701,12 +704,8 @@
         }
     }
 
-    @Override
-    public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
-        // Special case - since this is for internal use only, don't worry about
-        // a full access level check and just require the signature/privileged
-        // permission.
-        mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
+    private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
+        assertSystemReady();
         assertBandwidthControlEnabled();
 
         // NOTE: if callers want to get non-augmented data, they should go
@@ -716,6 +715,18 @@
                 NetworkStatsAccess.Level.DEVICE, Binder.getCallingUid()).getTotalBytes();
     }
 
+    private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
+        assertSystemReady();
+        assertBandwidthControlEnabled();
+
+        final NetworkStatsCollection uidComplete;
+        synchronized (mStatsLock) {
+            uidComplete = mUidRecorder.getOrLoadCompleteLocked();
+        }
+        return uidComplete.getSummary(template, start, end, NetworkStatsAccess.Level.DEVICE,
+                android.os.Process.SYSTEM_UID);
+    }
+
     @Override
     public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException {
         if (Binder.getCallingUid() != uid) {
@@ -777,10 +788,8 @@
         }
     }
 
-    @Override
-    public void setUidForeground(int uid, boolean uidForeground) {
-        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-
+    @VisibleForTesting
+    void setUidForeground(int uid, boolean uidForeground) {
         synchronized (mStatsLock) {
             final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT;
             final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT);
@@ -817,9 +826,7 @@
         }
     }
 
-    @Override
-    public void advisePersistThreshold(long thresholdBytes) {
-        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+    private void advisePersistThreshold(long thresholdBytes) {
         assertBandwidthControlEnabled();
 
         // clamp threshold into safe range
@@ -1330,6 +1337,33 @@
         removeUidsLocked(uids);
     }
 
+    private class NetworkStatsManagerInternalImpl extends NetworkStatsManagerInternal {
+        @Override
+        public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
+            return NetworkStatsService.this.getNetworkTotalBytes(template, start, end);
+        }
+
+        @Override
+        public NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
+            return NetworkStatsService.this.getNetworkUidBytes(template, start, end);
+        }
+
+        @Override
+        public void setUidForeground(int uid, boolean uidForeground) {
+            NetworkStatsService.this.setUidForeground(uid, uidForeground);
+        }
+
+        @Override
+        public void advisePersistThreshold(long thresholdBytes) {
+            NetworkStatsService.this.advisePersistThreshold(thresholdBytes);
+        }
+
+        @Override
+        public void forceUpdate() {
+            NetworkStatsService.this.forceUpdate();
+        }
+    }
+
     @Override
     protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, rawWriter)) return;
@@ -1550,6 +1584,12 @@
         }
     }
 
+    private void assertSystemReady() {
+        if (!mSystemReady) {
+            throw new IllegalStateException("System not ready");
+        }
+    }
+
     private void assertBandwidthControlEnabled() {
         if (!isBandwidthControlEnabled()) {
             throw new IllegalStateException("Bandwidth module disabled");
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 7467954..fd51be5 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -64,6 +64,8 @@
 import com.android.server.pm.Installer;
 import com.android.server.pm.UserManagerService;
 
+import libcore.util.EmptyArray;
+
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.File;
@@ -303,10 +305,10 @@
         schedulePersistSettings();
     }
 
-    private static Set<String> getDefaultOverlayPackages() {
+    private static String[] getDefaultOverlayPackages() {
         final String str = SystemProperties.get(DEFAULT_OVERLAYS_PROP);
         if (TextUtils.isEmpty(str)) {
-            return Collections.emptySet();
+            return EmptyArray.STRING;
         }
 
         final ArraySet<String> defaultPackages = new ArraySet<>();
@@ -315,7 +317,7 @@
                 defaultPackages.add(packageName);
             }
         }
-        return defaultPackages;
+        return defaultPackages.toArray(new String[defaultPackages.size()]);
     }
 
     private final class PackageReceiver extends BroadcastReceiver {
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index 43b1708..74eb2ea 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -60,13 +60,13 @@
     private final PackageManagerHelper mPackageManager;
     private final IdmapManager mIdmapManager;
     private final OverlayManagerSettings mSettings;
-    private final Set<String> mDefaultOverlays;
+    private final String[] mDefaultOverlays;
     private final OverlayChangeListener mListener;
 
     OverlayManagerServiceImpl(@NonNull final PackageManagerHelper packageManager,
             @NonNull final IdmapManager idmapManager,
             @NonNull final OverlayManagerSettings settings,
-            @NonNull final Set<String> defaultOverlays,
+            @NonNull final String[] defaultOverlays,
             @NonNull final OverlayChangeListener listener) {
         mPackageManager = packageManager;
         mIdmapManager = idmapManager;
@@ -104,31 +104,27 @@
         for (int i = 0; i < overlayPackagesSize; i++) {
             final PackageInfo overlayPackage = overlayPackages.get(i);
             final OverlayInfo oi = storedOverlayInfos.get(overlayPackage.packageName);
-            if (oi == null || !oi.targetPackageName.equals(overlayPackage.overlayTarget)
-                    || !Objects.equals(oi.category, overlayPackage.overlayCategory)) {
-                // Update the overlay if it didn't exist or had the wrong target package.
+            if (oi == null || !oi.targetPackageName.equals(overlayPackage.overlayTarget)) {
+                // Reset the overlay if it didn't exist or had the wrong target package.
                 mSettings.init(overlayPackage.packageName, newUserId,
                         overlayPackage.overlayTarget,
                         overlayPackage.applicationInfo.getBaseCodePath(),
-                        overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority,
+                        overlayPackage.isStaticOverlayPackage(),
+                        overlayPackage.overlayPriority,
                         overlayPackage.overlayCategory);
 
-                if (oi == null) {
-                    // This overlay does not exist in our settings.
-                    if (overlayPackage.isStaticOverlayPackage() ||
-                            mDefaultOverlays.contains(overlayPackage.packageName)) {
-                        // Enable this overlay by default.
-                        if (DEBUG) {
-                            Slog.d(TAG, "Enabling overlay " + overlayPackage.packageName
-                                    + " for user " + newUserId + " by default");
-                        }
-                        mSettings.setEnabled(overlayPackage.packageName, newUserId, true);
-                    }
-                } else {
+                if (oi != null) {
                     // The targetPackageName we have stored doesn't match the overlay's target.
                     // Queue the old target for an update as well.
                     packagesToUpdateAssets.add(oi.targetPackageName);
                 }
+            } else {
+                // Update all other components of an overlay that don't require a hard reset.
+                if (!Objects.equals(oi.category, overlayPackage.overlayCategory)) {
+                    // When changing categories, it is ok just to update our internal state.
+                    mSettings.setCategory(overlayPackage.packageName, newUserId,
+                            overlayPackage.overlayCategory);
+                }
             }
 
             try {
@@ -160,6 +156,42 @@
                 iter.remove();
             }
         }
+
+        // Collect all of the categories in which we have at least one overlay enabled.
+        final ArraySet<String> enabledCategories = new ArraySet<>();
+        final ArrayMap<String, List<OverlayInfo>> userOverlays =
+                mSettings.getOverlaysForUser(newUserId);
+        final int userOverlayTargetCount = userOverlays.size();
+        for (int i = 0; i < userOverlayTargetCount; i++) {
+            final List<OverlayInfo> overlayList = userOverlays.valueAt(i);
+            final int overlayCount = overlayList != null ? overlayList.size() : 0;
+            for (int j = 0; j < overlayCount; j++) {
+                final OverlayInfo oi = overlayList.get(j);
+                if (oi.isEnabled()) {
+                    enabledCategories.add(oi.category);
+                }
+            }
+        }
+
+        // Enable the default overlay if its category does not have a single overlay enabled.
+        for (final String defaultOverlay : mDefaultOverlays) {
+            try {
+                final OverlayInfo oi = mSettings.getOverlayInfo(defaultOverlay, newUserId);
+                if (!enabledCategories.contains(oi.category)) {
+                    Slog.w(TAG, "Enabling default overlay '" + defaultOverlay + "' for target '"
+                            + oi.targetPackageName + "' in category '" + oi.category + "' for user "
+                            + newUserId);
+                    mSettings.setEnabled(oi.packageName, newUserId, true);
+                    if (updateState(oi.targetPackageName, oi.packageName, newUserId, 0)) {
+                        packagesToUpdateAssets.add(oi.targetPackageName);
+                    }
+                }
+            } catch (OverlayManagerSettings.BadKeyException e) {
+                Slog.e(TAG, "Failed to set default overlay '" + defaultOverlay + "' for user "
+                        + newUserId, e);
+            }
+        }
+
         return new ArrayList<>(packagesToUpdateAssets);
     }
 
@@ -325,6 +357,11 @@
                 mSettings.init(packageName, userId, pkg.overlayTarget,
                         pkg.applicationInfo.getBaseCodePath(), pkg.isStaticOverlayPackage(),
                         pkg.overlayPriority, pkg.overlayCategory);
+            } else {
+                if (!Objects.equals(oldOi.category, pkg.overlayCategory)) {
+                    // Update the category in-place.
+                    mSettings.setCategory(packageName, userId, pkg.overlayCategory);
+                }
             }
 
             if (updateState(pkg.overlayTarget, packageName, userId, 0)) {
diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java
index e57fa0b..0b9412b 100644
--- a/services/core/java/com/android/server/om/OverlayManagerSettings.java
+++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java
@@ -20,6 +20,7 @@
 import static com.android.server.om.OverlayManagerService.TAG;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.om.OverlayInfo;
 import android.util.ArrayMap;
 import android.util.Slog;
@@ -39,6 +40,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -70,6 +72,9 @@
                 new SettingsItem(packageName, userId, targetPackageName, baseCodePath,
                         isStatic, priority, overlayCategory);
         if (isStatic) {
+            // All static overlays are always enabled.
+            item.setEnabled(true);
+
             int i;
             for (i = mItems.size() - 1; i >= 0; i--) {
                 SettingsItem parentItem = mItems.get(i);
@@ -122,6 +127,15 @@
         return mItems.get(idx).setBaseCodePath(path);
     }
 
+    boolean setCategory(@NonNull final String packageName, final int userId,
+            @Nullable String category) throws BadKeyException {
+        final int idx = select(packageName, userId);
+        if (idx < 0) {
+            throw new BadKeyException(packageName, userId);
+        }
+        return mItems.get(idx).setCategory(category);
+    }
+
     boolean getEnabled(@NonNull final String packageName, final int userId) throws BadKeyException {
         final int idx = select(packageName, userId);
         if (idx < 0) {
@@ -420,7 +434,7 @@
         private OverlayInfo mCache;
         private boolean mIsStatic;
         private int mPriority;
-        private final String mCategory;
+        private String mCategory;
 
         SettingsItem(@NonNull final String packageName, final int userId,
                 @NonNull final String targetPackageName, @NonNull final String baseCodePath,
@@ -431,7 +445,7 @@
             mTargetPackageName = targetPackageName;
             mBaseCodePath = baseCodePath;
             mState = state;
-            mIsEnabled = isEnabled;
+            mIsEnabled = isEnabled || isStatic;
             mCategory = category;
             mCache = null;
             mIsStatic = isStatic;
@@ -483,7 +497,11 @@
             return mIsEnabled;
         }
 
-        private boolean setEnabled(final boolean enable) {
+        private boolean setEnabled(boolean enable) {
+            if (mIsStatic) {
+                return false;
+            }
+
             if (mIsEnabled != enable) {
                 mIsEnabled = enable;
                 invalidateCache();
@@ -492,6 +510,15 @@
             return false;
         }
 
+        private boolean setCategory(String category) {
+            if (!Objects.equals(mCategory, category)) {
+                mCategory = category.intern();
+                invalidateCache();
+                return true;
+            }
+            return false;
+        }
+
         private OverlayInfo getOverlayInfo() {
             if (mCache == null) {
                 mCache = new OverlayInfo(mPackageName, mTargetPackageName, mCategory, mBaseCodePath,
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 7a5a6c5..e40dc4f 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2655,6 +2655,11 @@
                         | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
                 attrs.flags &= ~WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
                 break;
+            case TYPE_DREAM:
+                // Dreams don't have an app window token and can thus not be letterboxed.
+                // Hence always let them extend under the cutout.
+                attrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+                break;
             case TYPE_STATUS_BAR:
 
                 // If the Keyguard is in a hidden state (occluded by another window), we force to
@@ -5244,9 +5249,7 @@
         final boolean attachedInParent = attached != null && !layoutInScreen;
         // Ensure that windows with a DEFAULT or NEVER display cutout mode are laid out in
         // the cutout safe zone.
-        // Windows that are attached to a parent and laid out in said parent are already avoiding
-        // the cutout according to that parent and don't need to be further constrained.
-        if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS && !attachedInParent) {
+        if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
             final Rect displayCutoutSafeExceptMaybeTop = mTmpRect;
             displayCutoutSafeExceptMaybeTop.set(displayFrames.mDisplayCutoutSafe);
             if (layoutInScreen && layoutInsetDecor && !requestedFullscreen
@@ -5257,7 +5260,14 @@
                 // the window from that area.
                 displayCutoutSafeExceptMaybeTop.top = Integer.MIN_VALUE;
             }
-            pf.intersectUnchecked(displayCutoutSafeExceptMaybeTop);
+            // Windows that are attached to a parent and laid out in said parent are already
+            // avoidingthe cutout according to that parent and don't need to be further constrained.
+            if (!attachedInParent) {
+                pf.intersectUnchecked(displayCutoutSafeExceptMaybeTop);
+            }
+            // Make sure that NO_LIMITS windows clipped to the display don't extend into the display
+            // don't extend under the cutout.
+            df.intersectUnchecked(displayCutoutSafeExceptMaybeTop);
         }
 
         // Content should never appear in the cutout.
@@ -6695,7 +6705,7 @@
             mWindowManagerDrawComplete = false;
             mScreenOnListener = screenOnListener;
 
-            if (mKeyguardDelegate != null) {
+            if (mKeyguardDelegate != null && mKeyguardDelegate.hasKeyguard()) {
                 mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
                 mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT,
                         getKeyguardDrawnTimeout());
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 18f4a3c..58e8f77 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -242,6 +242,10 @@
         return false;
     }
 
+    public boolean hasKeyguard() {
+        return mKeyguardState.deviceHasKeyguard;
+    }
+
     public boolean isInputRestricted() {
         if (mKeyguardService != null) {
             mKeyguardState.inputRestricted = mKeyguardService.isInputRestricted();
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
index efcadad..941cd44 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
@@ -19,8 +19,6 @@
 import android.app.ActivityManager;
 import android.content.Context;
 import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.security.IKeystoreService;
 import android.util.Slog;
 
 import com.android.internal.policy.IKeyguardService;
@@ -53,16 +51,11 @@
     private final LockPatternUtils mLockPatternUtils;
     private final StateCallback mCallback;
 
-    IKeystoreService mKeystoreService;
-
     public KeyguardStateMonitor(Context context, IKeyguardService service, StateCallback callback) {
         mLockPatternUtils = new LockPatternUtils(context);
         mCurrentUserId = ActivityManager.getCurrentUser();
         mCallback = callback;
 
-        mKeystoreService = IKeystoreService.Stub.asInterface(ServiceManager
-                .getService("android.security.keystore"));
-
         try {
             service.addStateMonitorCallback(this);
         } catch (RemoteException e) {
@@ -93,12 +86,6 @@
     @Override // Binder interface
     public void onShowingStateChanged(boolean showing) {
         mIsShowing = showing;
-
-        if (showing) try {
-            mKeystoreService.lock(mCurrentUserId); // as long as this doesn't recur...
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Error locking keystore", e);
-        }
     }
 
     @Override // Binder interface
diff --git a/services/core/java/com/android/server/slice/PinnedSliceState.java b/services/core/java/com/android/server/slice/PinnedSliceState.java
index 8da16d7..f9a4ea2 100644
--- a/services/core/java/com/android/server/slice/PinnedSliceState.java
+++ b/services/core/java/com/android/server/slice/PinnedSliceState.java
@@ -16,7 +16,6 @@
 
 import static android.app.slice.SliceManager.PERMISSION_GRANTED;
 
-import android.app.slice.ISliceListener;
 import android.app.slice.Slice;
 import android.app.slice.SliceProvider;
 import android.app.slice.SliceSpec;
@@ -106,10 +105,6 @@
         setSlicePinned(false);
     }
 
-    public void onChange() {
-        mService.getHandler().post(this::handleBind);
-    }
-
     private void setSlicePinned(boolean pinned) {
         synchronized (mLock) {
             if (mSlicePinned == pinned) return;
@@ -122,45 +117,23 @@
         }
     }
 
-    public void addSliceListener(ISliceListener listener, String pkg, SliceSpec[] specs,
-            boolean hasPermission) {
+    public void pin(String pkg, SliceSpec[] specs, IBinder token) {
         synchronized (mLock) {
-            if (mListeners.size() == 0) {
-                mService.listen(mUri);
-            }
+            mListeners.put(token, new ListenerInfo(token, pkg, true,
+                    Binder.getCallingUid(), Binder.getCallingPid()));
             try {
-                listener.asBinder().linkToDeath(mDeathRecipient, 0);
+                token.linkToDeath(mDeathRecipient, 0);
             } catch (RemoteException e) {
             }
-            mListeners.put(listener.asBinder(), new ListenerInfo(listener, pkg, hasPermission,
-                    Binder.getCallingUid(), Binder.getCallingPid()));
             mergeSpecs(specs);
-            setSlicePinned(hasPermission);
-        }
-    }
-
-    public boolean removeSliceListener(ISliceListener listener) {
-        synchronized (mLock) {
-            listener.asBinder().unlinkToDeath(mDeathRecipient, 0);
-            if (mListeners.containsKey(listener.asBinder()) && mListeners.size() == 1) {
-                mService.unlisten(mUri);
-            }
-            mListeners.remove(listener.asBinder());
-        }
-        return !hasPinOrListener();
-    }
-
-    public void pin(String pkg, SliceSpec[] specs) {
-        synchronized (mLock) {
             setSlicePinned(true);
-            mPinnedPkgs.add(pkg);
-            mergeSpecs(specs);
         }
     }
 
-    public boolean unpin(String pkg) {
+    public boolean unpin(String pkg, IBinder token) {
         synchronized (mLock) {
-            mPinnedPkgs.remove(pkg);
+            token.unlinkToDeath(mDeathRecipient, 0);
+            mListeners.remove(token);
         }
         return !hasPinOrListener();
     }
@@ -171,30 +144,6 @@
         }
     }
 
-    public void recheckPackage(String pkg) {
-        synchronized (mLock) {
-            for (int i = 0; i < mListeners.size(); i++) {
-                ListenerInfo info = mListeners.valueAt(i);
-                if (!info.hasPermission && Objects.equals(info.pkg, pkg)) {
-                    mService.getHandler().post(() -> {
-                        // This bind lets the app itself participate in the permission grant.
-                        Slice s = doBind(info);
-                        if (mService.checkAccess(info.pkg, mUri, info.callingUid, info.callingPid)
-                                == PERMISSION_GRANTED) {
-                            info.hasPermission = true;
-                            setSlicePinned(true);
-                            try {
-                                info.listener.onSliceUpdated(s);
-                            } catch (RemoteException e) {
-                                checkSelfRemove();
-                            }
-                        }
-                    });
-                }
-            }
-        }
-    }
-
     @VisibleForTesting
     public boolean hasPinOrListener() {
         synchronized (mLock) {
@@ -213,7 +162,6 @@
     private void checkSelfRemove() {
         if (!hasPinOrListener()) {
             // All the listeners died, remove from pinned state.
-            mService.unlisten(mUri);
             mService.removePinnedSlice(mUri);
         }
     }
@@ -223,7 +171,7 @@
         synchronized (mLock) {
             for (int i = mListeners.size() - 1; i >= 0; i--) {
                 ListenerInfo l = mListeners.valueAt(i);
-                if (!l.listener.asBinder().isBinderAlive()) {
+                if (!l.token.isBinderAlive()) {
                     mListeners.removeAt(i);
                 }
             }
@@ -231,62 +179,6 @@
         }
     }
 
-    private void handleBind() {
-        Slice cachedSlice = doBind(null);
-        synchronized (mLock) {
-            if (!hasPinOrListener()) return;
-            for (int i = mListeners.size() - 1; i >= 0; i--) {
-                ListenerInfo info = mListeners.valueAt(i);
-                Slice s = cachedSlice;
-                if (s == null || s.hasHint(Slice.HINT_CALLER_NEEDED)
-                        || !info.hasPermission) {
-                    s = doBind(info);
-                }
-                if (s == null) {
-                    mListeners.removeAt(i);
-                    continue;
-                }
-                try {
-                    info.listener.onSliceUpdated(s);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Unable to notify slice " + mUri, e);
-                    mListeners.removeAt(i);
-                    continue;
-                }
-            }
-            checkSelfRemove();
-        }
-    }
-
-    private Slice doBind(ListenerInfo info) {
-        try (ContentProviderClient client = getClient()) {
-            if (client == null) return null;
-            Bundle extras = new Bundle();
-            extras.putParcelable(SliceProvider.EXTRA_BIND_URI, mUri);
-            extras.putParcelableArrayList(SliceProvider.EXTRA_SUPPORTED_SPECS,
-                    new ArrayList<>(Arrays.asList(mSupportedSpecs)));
-            if (info != null) {
-                extras.putString(SliceProvider.EXTRA_OVERRIDE_PKG, info.pkg);
-                extras.putInt(SliceProvider.EXTRA_OVERRIDE_UID, info.callingUid);
-                extras.putInt(SliceProvider.EXTRA_OVERRIDE_PID, info.callingPid);
-            }
-            final Bundle res;
-            try {
-                res = client.call(SliceProvider.METHOD_SLICE, null, extras);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Unable to bind slice " + mUri, e);
-                return null;
-            }
-            if (res == null) return null;
-            Bundle.setDefusable(res, true);
-            return res.getParcelable(SliceProvider.EXTRA_SLICE);
-        } catch (Throwable t) {
-            // Calling out of the system process, make sure they don't throw anything at us.
-            Log.e(TAG, "Caught throwable while binding " + mUri, t);
-            return null;
-        }
-    }
-
     private void handleSendPinned() {
         try (ContentProviderClient client = getClient()) {
             if (client == null) return;
@@ -315,15 +207,15 @@
 
     private class ListenerInfo {
 
-        private ISliceListener listener;
+        private IBinder token;
         private String pkg;
         private boolean hasPermission;
         private int callingUid;
         private int callingPid;
 
-        public ListenerInfo(ISliceListener listener, String pkg, boolean hasPermission,
+        public ListenerInfo(IBinder token, String pkg, boolean hasPermission,
                 int callingUid, int callingPid) {
-            this.listener = listener;
+            this.token = token;
             this.pkg = pkg;
             this.hasPermission = hasPermission;
             this.callingUid = callingUid;
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index a1def44..51e4709 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -28,7 +28,6 @@
 import android.app.AppOpsManager;
 import android.app.ContentProviderHolder;
 import android.app.IActivityManager;
-import android.app.slice.ISliceListener;
 import android.app.slice.ISliceManager;
 import android.app.slice.SliceManager;
 import android.app.slice.SliceSpec;
@@ -39,7 +38,6 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.ResolveInfo;
-import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Environment;
@@ -52,7 +50,6 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
-import android.util.Log;
 import android.util.Slog;
 import android.util.Xml.Encoding;
 
@@ -94,7 +91,6 @@
     @GuardedBy("mLock")
     private final ArraySet<SliceGrant> mUserGrants = new ArraySet<>();
     private final Handler mHandler;
-    private final ContentObserver mObserver;
     @GuardedBy("mSliceAccessFile")
     private final AtomicFile mSliceAccessFile;
     @GuardedBy("mAccessList")
@@ -113,16 +109,6 @@
         mAssistUtils = new AssistUtils(context);
         mHandler = new Handler(looper);
 
-        mObserver = new ContentObserver(mHandler) {
-            @Override
-            public void onChange(boolean selfChange, Uri uri, int userId) {
-                try {
-                    getPinnedSlice(maybeAddUserId(uri, userId)).onChange();
-                } catch (IllegalStateException e) {
-                    Log.e(TAG, "Received change for unpinned slice " + uri, e);
-                }
-            }
-        };
         final File systemDir = new File(Environment.getDataDirectory(), "system");
         mSliceAccessFile = new AtomicFile(new File(systemDir, "slice_access.xml"));
         mAccessList = new SliceFullAccessList(mContext);
@@ -163,40 +149,19 @@
 
     ///  ----- ISliceManager stuff -----
     @Override
-    public void addSliceListener(Uri uri, String pkg, ISliceListener listener, SliceSpec[] specs)
-            throws RemoteException {
+    public void pinSlice(String pkg, Uri uri, SliceSpec[] specs, IBinder token) throws RemoteException {
         verifyCaller(pkg);
+        enforceAccess(pkg, uri);
         uri = maybeAddUserId(uri, Binder.getCallingUserHandle().getIdentifier());
-        enforceCrossUser(pkg, uri);
-        getOrCreatePinnedSlice(uri).addSliceListener(listener, pkg, specs,
-                checkAccess(pkg, uri, Binder.getCallingUid(), Binder.getCallingUid())
-                == PERMISSION_GRANTED);
+        getOrCreatePinnedSlice(uri).pin(pkg, specs, token);
     }
 
     @Override
-    public void removeSliceListener(Uri uri, String pkg, ISliceListener listener)
-            throws RemoteException {
+    public void unpinSlice(String pkg, Uri uri, IBinder token) throws RemoteException {
         verifyCaller(pkg);
+        enforceAccess(pkg, uri);
         uri = maybeAddUserId(uri, Binder.getCallingUserHandle().getIdentifier());
-        if (getPinnedSlice(uri).removeSliceListener(listener)) {
-            removePinnedSlice(uri);
-        }
-    }
-
-    @Override
-    public void pinSlice(String pkg, Uri uri, SliceSpec[] specs) throws RemoteException {
-        verifyCaller(pkg);
-        enforceFullAccess(pkg, "pinSlice", uri);
-        uri = maybeAddUserId(uri, Binder.getCallingUserHandle().getIdentifier());
-        getOrCreatePinnedSlice(uri).pin(pkg, specs);
-    }
-
-    @Override
-    public void unpinSlice(String pkg, Uri uri) throws RemoteException {
-        verifyCaller(pkg);
-        enforceFullAccess(pkg, "unpinSlice", uri);
-        uri = maybeAddUserId(uri, Binder.getCallingUserHandle().getIdentifier());
-        if (getPinnedSlice(uri).unpin(pkg)) {
+        if (getPinnedSlice(uri).unpin(pkg, token)) {
             removePinnedSlice(uri);
         }
     }
@@ -253,11 +218,6 @@
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
-        synchronized (mLock) {
-            for (PinnedSliceState p : mPinnedSlicesByUri.values()) {
-                p.recheckPackage(pkg);
-            }
-        }
     }
 
     // Backup/restore interface
@@ -457,21 +417,6 @@
         return cn.getPackageName().equals(pkg);
     }
 
-    public void listen(Uri uri) {
-        mContext.getContentResolver().registerContentObserver(uri, true, mObserver);
-    }
-
-    public void unlisten(Uri uri) {
-        mContext.getContentResolver().unregisterContentObserver(mObserver);
-        synchronized (mLock) {
-            mPinnedSlicesByUri.forEach((u, s) -> {
-                if (s.isListening()) {
-                    listen(u);
-                }
-            });
-        }
-    }
-
     private boolean isDefaultHomeApp(String pkg, int userId) {
         String defaultHome = getDefaultHome(userId);
 
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 13357b8..75a6338 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1211,7 +1211,7 @@
         if (rotation == ROTATION_0) {
             return cutout.computeSafeInsets(mInitialDisplayWidth, mInitialDisplayHeight);
         }
-        final boolean rotated = (rotation == ROTATION_90 || mRotation == ROTATION_270);
+        final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
         final Path bounds = cutout.getBounds().getBoundaryPath();
         transformPhysicalToLogicalCoordinates(rotation, mInitialDisplayWidth, mInitialDisplayHeight,
                 mTmpMatrix);
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 5c8fadb..46c59c5 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -242,7 +242,7 @@
             final int appWidth = mService.mPolicy.getNonDecorDisplayWidth(dw, dh, rotation,
                 baseConfig.uiMode, displayId, displayCutout);
             final int appHeight = mService.mPolicy.getNonDecorDisplayHeight(dw, dh, rotation,
-                baseConfig.uiMode, displayId, mDisplayContent.getDisplayInfo().displayCutout);
+                baseConfig.uiMode, displayId, displayCutout);
             mService.mPolicy.getNonDecorInsetsLw(rotation, dw, dh, displayCutout, mTmpRect);
             final int leftInset = mTmpRect.left;
             final int topInset = mTmpRect.top;
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 7d970d9..2e86351 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -687,11 +687,12 @@
         pw.println(doublePrefix + "mTempInsetBounds=" + mTempInsetBounds.toShortString());
 
         final String triplePrefix = doublePrefix + "  ";
+        final String quadruplePrefix = triplePrefix + "  ";
 
         for (int i = mChildren.size() - 1; i >= 0; i--) {
             final AppWindowToken wtoken = mChildren.get(i);
             pw.println(triplePrefix + "Activity #" + i + " " + wtoken);
-            wtoken.dump(pw, triplePrefix, dumpAll);
+            wtoken.dump(pw, quadruplePrefix, dumpAll);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 26ac79e..be1aa46 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -50,6 +50,7 @@
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
@@ -1913,6 +1914,11 @@
                     // No move or resize, but the controller checks for title changes as well
                     mAccessibilityController.onSomeWindowResizedOrMovedLocked();
                 }
+
+                if ((flagChanges & PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) {
+                    updateNonSystemOverlayWindowsVisibilityIfNeeded(
+                            win, win.mWinAnimator.getShown());
+                }
             }
 
             if (DEBUG_LAYOUT) Slog.v(TAG_WM, "Relayout " + win + ": viewVisibility=" + viewVisibility
@@ -1960,15 +1966,36 @@
             win.setDisplayLayoutNeeded();
             win.mGivenInsetsPending = (flags & WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
 
-            // We may be deferring layout passes at the moment, but since the client is interested
-            // in the new out values right now we need to force a layout.
-            mWindowPlacerLocked.performSurfacePlacement(true /* force */);
-
             // We should only relayout if the view is visible, it is a starting window, or the
             // associated appToken is not hidden.
             final boolean shouldRelayout = viewVisibility == View.VISIBLE &&
-                (win.mAppToken == null || win.mAttrs.type == TYPE_APPLICATION_STARTING
-                    || !win.mAppToken.isClientHidden());
+                    (win.mAppToken == null || win.mAttrs.type == TYPE_APPLICATION_STARTING
+                            || !win.mAppToken.isClientHidden());
+
+            // If we are not currently running the exit animation, we need to see about starting
+            // one.
+            // We don't want to animate visibility of windows which are pending replacement.
+            // In the case of activity relaunch child windows could request visibility changes as
+            // they are detached from the main application window during the tear down process.
+            // If we satisfied these visibility changes though, we would cause a visual glitch
+            // hiding the window before it's replacement was available. So we just do nothing on
+            // our side.
+            // This must be called before the call to performSurfacePlacement.
+            if (!shouldRelayout && winAnimator.hasSurface() && !win.mAnimatingExit) {
+                if (DEBUG_VISIBILITY) {
+                    Slog.i(TAG_WM,
+                            "Relayout invis " + win + ": mAnimatingExit=" + win.mAnimatingExit);
+                }
+                result |= RELAYOUT_RES_SURFACE_CHANGED;
+                if (!win.mWillReplaceWindow) {
+                    focusMayChange = tryStartExitingAnimation(win, winAnimator, isDefaultDisplay,
+                            focusMayChange);
+                }
+            }
+
+            // We may be deferring layout passes at the moment, but since the client is interested
+            // in the new out values right now we need to force a layout.
+            mWindowPlacerLocked.performSurfacePlacement(true /* force */);
 
             if (shouldRelayout) {
                 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: viewVisibility_1");
@@ -2001,24 +2028,6 @@
                 winAnimator.mEnterAnimationPending = false;
                 winAnimator.mEnteringAnimation = false;
 
-                if (winAnimator.hasSurface() && !win.mAnimatingExit) {
-                    if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Relayout invis " + win
-                            + ": mAnimatingExit=" + win.mAnimatingExit);
-                    // If we are not currently running the exit animation, we
-                    // need to see about starting one.
-                    // We don't want to animate visibility of windows which are pending
-                    // replacement. In the case of activity relaunch child windows
-                    // could request visibility changes as they are detached from the main
-                    // application window during the tear down process. If we satisfied
-                    // these visibility changes though, we would cause a visual glitch
-                    // hiding the window before it's replacement was available.
-                    // So we just do nothing on our side.
-                    if (!win.mWillReplaceWindow) {
-                        focusMayChange = tryStartExitingAnimation(
-                                win, winAnimator, isDefaultDisplay, focusMayChange);
-                    }
-                    result |= RELAYOUT_RES_SURFACE_CHANGED;
-                }
                 if (viewVisibility == View.VISIBLE && winAnimator.hasSurface()) {
                     // We already told the client to go invisible, but the message may not be
                     // handled yet, or it might want to draw a last frame. If we already have a
@@ -7397,7 +7406,8 @@
     }
 
     void updateNonSystemOverlayWindowsVisibilityIfNeeded(WindowState win, boolean surfaceShown) {
-        if (!win.hideNonSystemOverlayWindowsWhenVisible()) {
+        if (!win.hideNonSystemOverlayWindowsWhenVisible()
+                && !mHidingNonSystemOverlayWindows.contains(win)) {
             return;
         }
         final boolean systemAlertWindowsHidden = !mHidingNonSystemOverlayWindows.isEmpty();
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index d24b3ee..5b5de0e 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1088,8 +1088,8 @@
 
             traceBeginAndSlog("StartNetworkPolicyManagerService");
             try {
-                networkPolicy = new NetworkPolicyManagerService(context,
-                    mActivityManagerService, networkStats, networkManagement);
+                networkPolicy = new NetworkPolicyManagerService(context, mActivityManagerService,
+                        networkManagement);
                 ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
             } catch (Throwable e) {
                 reportWtf("starting NetworkPolicy Service", e);
diff --git a/services/net/java/android/net/ip/IpClient.java b/services/net/java/android/net/ip/IpClient.java
index d3a97b3..1f370a5 100644
--- a/services/net/java/android/net/ip/IpClient.java
+++ b/services/net/java/android/net/ip/IpClient.java
@@ -72,6 +72,7 @@
 import java.util.List;
 import java.util.Set;
 import java.util.StringJoiner;
+import java.util.concurrent.CountDownLatch;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
@@ -100,6 +101,11 @@
 
     /**
      * Callbacks for handling IpClient events.
+     *
+     * These methods are called by IpClient on its own thread. Implementations
+     * of this class MUST NOT carry out long-running computations or hold locks
+     * for which there might be contention with other code calling public
+     * methods of the same IpClient instance.
      */
     public static class Callback {
         // In order to receive onPreDhcpAction(), call #withPreDhcpAction()
@@ -545,6 +551,7 @@
     private final String mClatInterfaceName;
     @VisibleForTesting
     protected final Callback mCallback;
+    private final CountDownLatch mShutdownLatch;
     private final INetworkManagementService mNwService;
     private final NetlinkTracker mNetlinkTracker;
     private final WakeupMessage mProvisioningTimeoutAlarm;
@@ -597,6 +604,7 @@
         mInterfaceName = ifName;
         mClatInterfaceName = CLAT_PREFIX + ifName;
         mCallback = new LoggingCallbackWrapper(callback);
+        mShutdownLatch = new CountDownLatch(1);
         mNwService = nwService;
 
         mLog = new SharedLog(MAX_LOG_RECORDS, mTag);
@@ -704,6 +712,7 @@
     @Override
     protected void onQuitting() {
         mCallback.onQuit();
+        mShutdownLatch.countDown();
     }
 
     // Shut down this IpClient instance altogether.
@@ -712,6 +721,17 @@
         sendMessage(CMD_TERMINATE_AFTER_STOP);
     }
 
+    // In order to avoid deadlock, this method MUST NOT be called on the
+    // IpClient instance's thread. This prohibition includes code executed by
+    // when methods on the passed-in IpClient.Callback instance are called.
+    public void awaitShutdown() {
+        try {
+            mShutdownLatch.await();
+        } catch (InterruptedException e) {
+            mLog.e("Interrupted while awaiting shutdown: " + e);
+        }
+    }
+
     public static ProvisioningConfiguration.Builder buildProvisioningConfiguration() {
         return new ProvisioningConfiguration.Builder();
     }
diff --git a/services/print/java/com/android/server/print/UserState.java b/services/print/java/com/android/server/print/UserState.java
index 84c1bb2..3c09cb1 100644
--- a/services/print/java/com/android/server/print/UserState.java
+++ b/services/print/java/com/android/server/print/UserState.java
@@ -38,7 +38,6 @@
 import android.content.pm.ResolveInfo;
 import android.graphics.drawable.Icon;
 import android.net.Uri;
-import android.os.AsyncTask;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
@@ -236,15 +235,6 @@
             return null;
         }
 
-        // Spin the spooler to add the job and show the config UI.
-        new AsyncTask<Void, Void, Void>() {
-            @Override
-            protected Void doInBackground(Void... params) {
-                mSpooler.createPrintJob(printJob);
-                return null;
-            }
-        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
-
         final long identity = Binder.clearCallingIdentity();
         try {
             Intent intent = new Intent(PrintManager.ACTION_PRINT_DIALOG);
diff --git a/services/robotests/Android.mk b/services/robotests/Android.mk
index d825533..cd8163d 100644
--- a/services/robotests/Android.mk
+++ b/services/robotests/Android.mk
@@ -58,14 +58,14 @@
 LOCAL_SRC_FILES := \
     $(call all-java-files-under, src) \
     $(call all-Iaidl-files-under, $(INTERNAL_BACKUP)) \
+    $(call all-java-files-under, ../../core/java/android/app/backup) \
+    $(call all-Iaidl-files-under, ../../core/java/android/app/backup) \
     ../../core/java/android/content/pm/PackageInfo.java \
-    ../../core/java/android/app/backup/BackupAgent.java \
-    ../../core/java/android/app/backup/BackupDataOutput.java \
-    ../../core/java/android/app/backup/FullBackupDataOutput.java \
     ../../core/java/android/app/IBackupAgent.aidl
 
 LOCAL_AIDL_INCLUDES := \
     $(call all-Iaidl-files-under, $(INTERNAL_BACKUP)) \
+    $(call all-Iaidl-files-under, ../../core/java/android/app/backup) \
     ../../core/java/android/app/IBackupAgent.aidl
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
diff --git a/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java b/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
index d0e6658..60704e7 100644
--- a/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
+++ b/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
@@ -112,11 +112,8 @@
         ShadowQueuedWork.class
     }
 )
-@SystemLoaderPackages({"com.android.server.backup"})
+@SystemLoaderPackages({"com.android.server.backup", "android.app.backup"})
 @SystemLoaderClasses({
-    BackupDataOutput.class,
-    FullBackupDataOutput.class,
-    BackupAgent.class,
     IBackupTransport.class,
     IBackupAgent.class,
     PackageInfo.class
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index e1b4422..d31d550 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -26,6 +26,9 @@
 import static android.net.NetworkPolicyManager.POLICY_NONE;
 import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
 import static android.net.NetworkPolicyManager.uidPoliciesToString;
+import static android.net.NetworkStats.IFACE_ALL;
+import static android.net.NetworkStats.SET_ALL;
+import static android.net.NetworkStats.TAG_ALL;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
 import static android.net.TrafficStats.MB_IN_BYTES;
 import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
@@ -42,8 +45,6 @@
 import static com.android.server.net.NetworkPolicyManagerService.TYPE_RAPID;
 import static com.android.server.net.NetworkPolicyManagerService.TYPE_WARNING;
 
-import static com.google.common.truth.Truth.assertThat;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -86,7 +87,6 @@
 import android.net.IConnectivityManager;
 import android.net.INetworkManagementEventObserver;
 import android.net.INetworkPolicyListener;
-import android.net.INetworkStatsService;
 import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkCapabilities;
@@ -105,6 +105,7 @@
 import android.os.PowerSaveState;
 import android.os.RemoteException;
 import android.os.SimpleClock;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
@@ -125,6 +126,7 @@
 import com.android.internal.util.test.BroadcastInterceptingContext.FutureIntent;
 import com.android.server.net.NetworkPolicyManagerInternal;
 import com.android.server.net.NetworkPolicyManagerService;
+import com.android.server.net.NetworkStatsManagerInternal;
 
 import libcore.io.IoUtils;
 import libcore.io.Streams;
@@ -214,7 +216,6 @@
     private String mNetpolicyXml;
 
     private @Mock IActivityManager mActivityManager;
-    private @Mock INetworkStatsService mStatsService;
     private @Mock INetworkManagementService mNetworkManager;
     private @Mock IConnectivityManager mConnManager;
     private @Mock NotificationManager mNotifManager;
@@ -224,7 +225,8 @@
     private @Mock CarrierConfigManager mCarrierConfigManager;
     private @Mock TelephonyManager mTelephonyManager;
 
-    private static ActivityManagerInternal mActivityManagerInternal;
+    private ActivityManagerInternal mActivityManagerInternal;
+    private NetworkStatsManagerInternal mStatsService;
 
     private IUidObserver mUidObserver;
     private INetworkManagementEventObserver mNetworkObserver;
@@ -264,6 +266,8 @@
     private static final int UID_F = UserHandle.getUid(USER_ID, APP_ID_F);
 
     private static final String PKG_NAME_A = "name.is.A,pkg.A";
+    private static final String PKG_NAME_B = "name.is.B,pkg.B";
+    private static final String PKG_NAME_C = "name.is.C,pkg.C";
 
     public final @Rule NetPolicyMethodRule mNetPolicyXmlRule = new NetPolicyMethodRule();
 
@@ -287,6 +291,8 @@
                 .setBatterySaverEnabled(false).build();
         final PowerManagerInternal pmInternal = addLocalServiceMock(PowerManagerInternal.class);
         when(pmInternal.getLowPowerState(anyInt())).thenReturn(state);
+
+        mStatsService = addLocalServiceMock(NetworkStatsManagerInternal.class);
     }
 
     @Before
@@ -347,7 +353,7 @@
                 eq(ActivityManager.PROCESS_STATE_UNKNOWN), isNull(String.class));
 
         mFutureIntent = newRestrictBackgroundChangedFuture();
-        mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager, mStatsService,
+        mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager,
                 mNetworkManager, mIpm, mClock, mPolicyDir, true);
         mService.bindConnectivityManager(mConnManager);
         mPolicyListener = new NetworkPolicyListenerAnswer(mService);
@@ -375,6 +381,14 @@
         when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
                 .thenReturn(new ApplicationInfo());
         when(mPackageManager.getPackagesForUid(UID_A)).thenReturn(new String[] {PKG_NAME_A});
+        when(mPackageManager.getPackagesForUid(UID_B)).thenReturn(new String[] {PKG_NAME_B});
+        when(mPackageManager.getPackagesForUid(UID_C)).thenReturn(new String[] {PKG_NAME_C});
+        when(mPackageManager.getApplicationInfo(eq(PKG_NAME_A), anyInt()))
+                .thenReturn(buildApplicationInfo(PKG_NAME_A));
+        when(mPackageManager.getApplicationInfo(eq(PKG_NAME_B), anyInt()))
+                .thenReturn(buildApplicationInfo(PKG_NAME_B));
+        when(mPackageManager.getApplicationInfo(eq(PKG_NAME_C), anyInt()))
+                .thenReturn(buildApplicationInfo(PKG_NAME_C));
         when(mNetworkManager.isBandwidthControlEnabled()).thenReturn(true);
         when(mNetworkManager.setDataSaverModeEnabled(anyBoolean())).thenReturn(true);
 
@@ -409,6 +423,7 @@
         LocalServices.removeServiceForTest(PowerManagerInternal.class);
         LocalServices.removeServiceForTest(DeviceIdleController.LocalService.class);
         LocalServices.removeServiceForTest(UsageStatsManagerInternal.class);
+        LocalServices.removeServiceForTest(NetworkStatsManagerInternal.class);
     }
 
     @After
@@ -515,7 +530,7 @@
         mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
 
         // RestrictBackground should be on even though battery saver want to turn it off
-        assertThat(mService.getRestrictBackground()).isTrue();
+        assertTrue(mService.getRestrictBackground());
 
         PowerSaveState stateOff = new PowerSaveState.Builder()
                 .setGlobalBatterySaverEnabled(false)
@@ -524,7 +539,7 @@
         mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
 
         // RestrictBackground should be on, following its previous state
-        assertThat(mService.getRestrictBackground()).isTrue();
+        assertTrue(mService.getRestrictBackground());
     }
 
     @Test
@@ -539,7 +554,7 @@
         mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
 
         // RestrictBackground should be turned on because of battery saver
-        assertThat(mService.getRestrictBackground()).isTrue();
+        assertTrue(mService.getRestrictBackground());
 
         PowerSaveState stateOff = new PowerSaveState.Builder()
                 .setGlobalBatterySaverEnabled(false)
@@ -548,7 +563,7 @@
         mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
 
         // RestrictBackground should be off, following its previous state
-        assertThat(mService.getRestrictBackground()).isFalse();
+        assertFalse(mService.getRestrictBackground());
     }
 
     @Test
@@ -562,7 +577,7 @@
         mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
 
         // RestrictBackground should still be on
-        assertThat(mService.getRestrictBackground()).isTrue();
+        assertTrue(mService.getRestrictBackground());
 
         // User turns off RestrictBackground manually
         setRestrictBackground(false);
@@ -571,7 +586,7 @@
         mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
 
         // RestrictBackground should be off because user changes it manually
-        assertThat(mService.getRestrictBackground()).isFalse();
+        assertFalse(mService.getRestrictBackground());
     }
 
     private void removeRestrictBackgroundWhitelist(boolean expectIntent) throws Exception {
@@ -974,6 +989,7 @@
     public void testNotificationWarningLimitSnooze() throws Exception {
         // Create a place to store fake usage
         final NetworkStatsHistory history = new NetworkStatsHistory(TimeUnit.HOURS.toMillis(1));
+        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
         when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
                 .thenAnswer(new Answer<Long>() {
                     @Override
@@ -983,6 +999,13 @@
                         return entry.rxBytes + entry.txBytes;
                     }
                 });
+        when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
+                .thenAnswer(new Answer<NetworkStats>() {
+                    @Override
+                    public NetworkStats answer(InvocationOnMock invocation) throws Throwable {
+                        return stats;
+                    }
+                });
 
         // Get active mobile network in place
         expectMobileDefaults();
@@ -1003,7 +1026,7 @@
 
         // Normal usage means no notification
         {
-            history.removeBucketsBefore(Long.MAX_VALUE);
+            history.clear();
             history.recordData(start, end,
                     new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(360), 0L, 0L, 0L, 0));
 
@@ -1020,7 +1043,7 @@
 
         // Push over warning
         {
-            history.removeBucketsBefore(Long.MAX_VALUE);
+            history.clear();
             history.recordData(start, end,
                     new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1799), 0L, 0L, 0L, 0));
 
@@ -1038,7 +1061,7 @@
 
         // Push over limit
         {
-            history.removeBucketsBefore(Long.MAX_VALUE);
+            history.clear();
             history.recordData(start, end,
                     new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1810), 0L, 0L, 0L, 0));
 
@@ -1073,6 +1096,7 @@
     public void testNotificationRapid() throws Exception {
         // Create a place to store fake usage
         final NetworkStatsHistory history = new NetworkStatsHistory(TimeUnit.HOURS.toMillis(1));
+        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
         when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
                 .thenAnswer(new Answer<Long>() {
                     @Override
@@ -1082,6 +1106,13 @@
                         return entry.rxBytes + entry.txBytes;
                     }
                 });
+        when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
+                .thenAnswer(new Answer<NetworkStats>() {
+                    @Override
+                    public NetworkStats answer(InvocationOnMock invocation) throws Throwable {
+                        return stats;
+                    }
+                });
 
         // Get active mobile network in place
         expectMobileDefaults();
@@ -1102,7 +1133,7 @@
 
         // Using 20% data in 20% time is normal
         {
-            history.removeBucketsBefore(Long.MAX_VALUE);
+            history.clear();
             history.recordData(start, end,
                     new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(360), 0L, 0L, 0L, 0));
 
@@ -1111,16 +1142,58 @@
             verify(mNotifManager, never()).notifyAsUser(any(), anyInt(), any(), any());
         }
 
-        // Using 80% data in 20% time is alarming
+        // Using 80% data in 20% time is alarming; but spread equally among
+        // three UIDs means we get generic alert
         {
-            history.removeBucketsBefore(Long.MAX_VALUE);
+            history.clear();
             history.recordData(start, end,
                     new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0));
+            stats.clear();
+            stats.addValues(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
+                    DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
+            stats.addValues(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
+                    DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
+            stats.addValues(IFACE_ALL, UID_C, SET_ALL, TAG_ALL,
+                    DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
 
             reset(mNotifManager);
             mService.updateNetworks();
+
+            final ArgumentCaptor<Notification> notif = ArgumentCaptor.forClass(Notification.class);
             verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_RAPID),
-                    isA(Notification.class), eq(UserHandle.ALL));
+                    notif.capture(), eq(UserHandle.ALL));
+
+            final String text = notif.getValue().extras.getCharSequence(Notification.EXTRA_TEXT)
+                    .toString();
+            assertFalse(text.contains(PKG_NAME_A));
+            assertFalse(text.contains(PKG_NAME_B));
+            assertFalse(text.contains(PKG_NAME_C));
+        }
+
+        // Using 80% data in 20% time is alarming; but mostly done by one UID
+        // means we get specific alert
+        {
+            history.clear();
+            history.recordData(start, end,
+                    new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0));
+            stats.clear();
+            stats.addValues(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
+                    DataUnit.MEGABYTES.toBytes(960), 0, 0, 0, 0);
+            stats.addValues(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
+                    DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
+
+            reset(mNotifManager);
+            mService.updateNetworks();
+
+            final ArgumentCaptor<Notification> notif = ArgumentCaptor.forClass(Notification.class);
+            verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_RAPID),
+                    notif.capture(), eq(UserHandle.ALL));
+
+            final String text = notif.getValue().extras.getCharSequence(Notification.EXTRA_TEXT)
+                    .toString();
+            assertTrue(text.contains(PKG_NAME_A));
+            assertFalse(text.contains(PKG_NAME_B));
+            assertFalse(text.contains(PKG_NAME_C));
         }
     }
 
@@ -1411,6 +1484,12 @@
                 true);
     }
 
+    private ApplicationInfo buildApplicationInfo(String label) {
+        final ApplicationInfo ai = new ApplicationInfo();
+        ai.nonLocalizedLabel = label;
+        return ai;
+    }
+
     private NetworkInfo buildNetworkInfo() {
         final NetworkInfo ni = new NetworkInfo(ConnectivityManager.TYPE_MOBILE,
                 TelephonyManager.NETWORK_TYPE_LTE, null, null);
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
index d3df924..5161114 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
@@ -22,6 +22,8 @@
 import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
 import static android.view.Display.DEFAULT_DISPLAY;
 
+import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
+import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
 import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
 import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
 import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
@@ -119,20 +121,20 @@
             }
             return null;
         }).when(mActivity.app.thread).scheduleTransaction(any());
-        mActivity.state = STOPPED;
+        mActivity.setState(STOPPED, "testPausingWhenVisibleFromStopped");
 
         mActivity.makeVisibleIfNeeded(null /* starting */);
 
-        assertEquals(mActivity.state, PAUSING);
+        assertTrue(mActivity.isState(PAUSING));
 
         assertTrue(pauseFound.value);
 
         // Make sure that the state does not change for current non-stopping states.
-        mActivity.state = INITIALIZING;
+        mActivity.setState(INITIALIZING, "testPausingWhenVisibleFromStopped");
 
         mActivity.makeVisibleIfNeeded(null /* starting */);
 
-        assertEquals(mActivity.state, INITIALIZING);
+        assertTrue(mActivity.isState(INITIALIZING));
     }
 
     @Test
@@ -197,7 +199,23 @@
         record.canBeLaunchedOnDisplay(DEFAULT_DISPLAY);
 
 
-        verify(mService.mStackSupervisor, times(1)).canPlaceEntityOnDisplay(anyInt(), eq(expected), anyInt(), anyInt(),
-                eq(record.info));
+        verify(mService.mStackSupervisor, times(1)).canPlaceEntityOnDisplay(anyInt(), eq(expected),
+                anyInt(), anyInt(), eq(record.info));
+    }
+
+    @Test
+    public void testFinishingAfterDestroying() throws Exception {
+        assertFalse(mActivity.finishing);
+        mActivity.setState(DESTROYING, "testFinishingAfterDestroying");
+        assertTrue(mActivity.isState(DESTROYING));
+        assertTrue(mActivity.finishing);
+    }
+
+    @Test
+    public void testFinishingAfterDestroyed() throws Exception {
+        assertFalse(mActivity.finishing);
+        mActivity.setState(DESTROYED, "testFinishingAfterDestroyed");
+        assertTrue(mActivity.isState(DESTROYED));
+        assertTrue(mActivity.finishing);
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/appops/AppOpsServiceTest.java b/services/tests/servicestests/src/com/android/server/appops/AppOpsServiceTest.java
new file mode 100644
index 0000000..ad21a78
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/appops/AppOpsServiceTest.java
@@ -0,0 +1,228 @@
+/*
+ * 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.
+ */
+package com.android.server;
+
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.MODE_ERRORED;
+import static android.app.AppOpsManager.OP_READ_SMS;
+import static android.app.AppOpsManager.OP_WRITE_SMS;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.app.AppOpsManager.OpEntry;
+import android.app.AppOpsManager.PackageOps;
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Process;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Unit tests for AppOpsService. Covers functionality that is difficult to test using CTS tests
+ * or for which we can write more detailed unit tests than CTS tests (because the internal APIs are
+ * more finegrained data than the public ones).
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AppOpsServiceTest {
+
+    private static final String TAG = AppOpsServiceTest.class.getSimpleName();
+    // State will be persisted into this XML file.
+    private static final String APP_OPS_FILENAME = "appops-service-test.xml";
+
+    private File mAppOpsFile;
+    private Context mContext;
+    private Handler mHandler;
+    private AppOpsService mAppOpsService;
+    private String mMyPackageName;
+    private int mMyUid;
+    private long mTestStartMillis;
+
+    @Before
+    public void setUp() {
+        mContext = InstrumentationRegistry.getTargetContext();
+        mAppOpsFile = new File(mContext.getFilesDir(), APP_OPS_FILENAME);
+        if (mAppOpsFile.exists()) {
+            // Start with a clean state (persisted into XML).
+            mAppOpsFile.delete();
+        }
+
+        HandlerThread handlerThread = new HandlerThread(TAG);
+        handlerThread.start();
+        mHandler = new Handler(handlerThread.getLooper());
+        mMyPackageName = mContext.getOpPackageName();
+        mMyUid = Process.myUid();
+
+        mAppOpsService = new AppOpsService(mAppOpsFile, mHandler);
+        mAppOpsService.mContext = mContext;
+        mTestStartMillis = System.currentTimeMillis();
+    }
+
+    @Test
+    public void testGetOpsForPackage_noOpsLogged() {
+        assertThat(getLoggedOps()).isNull();
+    }
+
+    @Test
+    public void testNoteOperationAndGetOpsForPackage() {
+        mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED);
+        mAppOpsService.setMode(OP_WRITE_SMS, mMyUid, mMyPackageName, MODE_ERRORED);
+
+        // Note an op that's allowed.
+        mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName);
+        List<PackageOps> loggedOps = getLoggedOps();
+        assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
+
+        // Note another op that's not allowed.
+        mAppOpsService.noteOperation(OP_WRITE_SMS, mMyUid, mMyPackageName);
+        loggedOps = getLoggedOps();
+        assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
+        assertContainsOp(loggedOps, OP_WRITE_SMS, -1, mTestStartMillis, MODE_ERRORED);
+    }
+
+    // Tests the dumping and restoring of the in-memory state to/from XML.
+    @Test
+    public void testStatePersistence() {
+        mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED);
+        mAppOpsService.setMode(OP_WRITE_SMS, mMyUid, mMyPackageName, MODE_ERRORED);
+        mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName);
+        mAppOpsService.noteOperation(OP_WRITE_SMS, mMyUid, mMyPackageName);
+        mAppOpsService.writeState();
+
+        // Create a new app ops service, and initialize its state from XML.
+        mAppOpsService = new AppOpsService(mAppOpsFile, mHandler);
+        mAppOpsService.mContext = mContext;
+        mAppOpsService.readState();
+
+        // Query the state of the 2nd service.
+        List<PackageOps> loggedOps = getLoggedOps();
+        assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
+        assertContainsOp(loggedOps, OP_WRITE_SMS, -1, mTestStartMillis, MODE_ERRORED);
+    }
+
+    // Tests that ops are persisted during shutdown.
+    @Test
+    public void testShutdown() {
+        mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED);
+        mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName);
+        mAppOpsService.shutdown();
+
+        // Create a new app ops service, and initialize its state from XML.
+        mAppOpsService = new AppOpsService(mAppOpsFile, mHandler);
+        mAppOpsService.mContext = mContext;
+        mAppOpsService.readState();
+
+        // Query the state of the 2nd service.
+        List<PackageOps> loggedOps = getLoggedOps();
+        assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
+    }
+
+    @Test
+    public void testGetOpsForPackage() {
+        mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED);
+        mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName);
+
+        // Query all ops
+        List<PackageOps> loggedOps = mAppOpsService.getOpsForPackage(
+                mMyUid, mMyPackageName, null /* all ops */);
+        assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
+
+        // Query specific ops
+        loggedOps = mAppOpsService.getOpsForPackage(
+                mMyUid, mMyPackageName, new int[]{OP_READ_SMS, OP_WRITE_SMS});
+        assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
+
+        // Query unknown UID
+        loggedOps = mAppOpsService.getOpsForPackage(mMyUid + 1, mMyPackageName, null /* all ops */);
+        assertThat(loggedOps).isNull();
+
+        // Query unknown package name
+        loggedOps = mAppOpsService.getOpsForPackage(mMyUid, "fake.package", null /* all ops */);
+        assertThat(loggedOps).isNull();
+
+        // Query op code that's not been logged
+        loggedOps = mAppOpsService.getOpsForPackage(mMyUid, mMyPackageName,
+                new int[]{OP_WRITE_SMS});
+        assertThat(loggedOps).isNull();
+    }
+
+    @Test
+    public void testPackageRemoved() {
+        mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED);
+        mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName);
+
+        List<PackageOps> loggedOps = getLoggedOps();
+        assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
+
+        mAppOpsService.packageRemoved(mMyUid, mMyPackageName);
+        assertThat(getLoggedOps()).isNull();
+    }
+
+    @Test
+    public void testUidRemoved() {
+        mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED);
+        mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName);
+
+        List<PackageOps> loggedOps = getLoggedOps();
+        assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
+
+        mAppOpsService.uidRemoved(mMyUid);
+        assertThat(getLoggedOps()).isNull();
+    }
+
+    private List<PackageOps> getLoggedOps() {
+        return mAppOpsService.getOpsForPackage(mMyUid, mMyPackageName, null /* all ops */);
+    }
+
+    private void assertContainsOp(List<PackageOps> loggedOps, int opCode, long minMillis,
+            long minRejectMillis, int mode) {
+
+        boolean opLogged = false;
+        for (PackageOps pkgOps : loggedOps) {
+            assertWithMessage("Unexpected UID").that(mMyUid).isEqualTo(pkgOps.getUid());
+            assertWithMessage("Unexpected package name").that(mMyPackageName).isEqualTo(
+                    pkgOps.getPackageName());
+
+            for (OpEntry opEntry : pkgOps.getOps()) {
+                if (opCode != opEntry.getOp()) {
+                    continue;
+                }
+                opLogged = true;
+
+                assertWithMessage("Unexpected mode").that(mode).isEqualTo(opEntry.getMode());
+                if (minMillis > 0) {
+                    assertWithMessage("Unexpected timestamp")
+                            .that(opEntry.getTime()).isAtLeast(minMillis);
+                }
+                if (minRejectMillis > 0) {
+                    assertWithMessage("Unexpected rejection timestamp")
+                            .that(opEntry.getRejectTime()).isAtLeast(minRejectMillis);
+                }
+            }
+        }
+        assertWithMessage("Op was not logged").that(opLogged).isTrue();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java b/services/tests/servicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
index 35cba18..8874894 100644
--- a/services/tests/servicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
@@ -33,12 +33,14 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.os.Build;
+import android.os.Handler;
 import android.os.SystemClock;
 import android.support.test.runner.AndroidJUnit4;
 import android.util.DataUnit;
 
 import com.android.server.LocalServices;
 import com.android.server.job.JobSchedulerService;
+import com.android.server.job.JobSchedulerService.Constants;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -49,6 +51,8 @@
 
 @RunWith(AndroidJUnit4.class)
 public class ConnectivityControllerTest {
+    private Constants mConstants;
+
     @Before
     public void setUp() throws Exception {
         // Assume all packages are current SDK
@@ -65,23 +69,26 @@
                 Clock.fixed(SystemClock.uptimeMillisClock().instant(), ZoneOffset.UTC);
         JobSchedulerService.sElapsedRealtimeClock =
                 Clock.fixed(SystemClock.elapsedRealtimeClock().instant(), ZoneOffset.UTC);
+
+        // Assume default constants for now
+        mConstants = new Constants();
     }
 
     @Test
     public void testInsane() throws Exception {
-        final Network network = new Network(101);
+        final Network net = new Network(101);
         final JobInfo.Builder job = createJob()
                 .setEstimatedNetworkBytes(DataUnit.MEBIBYTES.toBytes(1))
                 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
 
         // Slow network is too slow
-        assertFalse(ConnectivityController.isSatisfied(createJobStatus(job), network,
+        assertFalse(ConnectivityController.isSatisfied(createJobStatus(job), net,
                 createCapabilities().setLinkUpstreamBandwidthKbps(1)
-                        .setLinkDownstreamBandwidthKbps(1)));
+                        .setLinkDownstreamBandwidthKbps(1), mConstants));
         // Fast network looks great
-        assertTrue(ConnectivityController.isSatisfied(createJobStatus(job), network,
+        assertTrue(ConnectivityController.isSatisfied(createJobStatus(job), net,
                 createCapabilities().setLinkUpstreamBandwidthKbps(1024)
-                        .setLinkDownstreamBandwidthKbps(1024)));
+                        .setLinkDownstreamBandwidthKbps(1024), mConstants));
     }
 
     @Test
@@ -95,19 +102,19 @@
 
         // Uncongested network is whenever
         {
-            final Network network = new Network(101);
-            final NetworkCapabilities capabilities = createCapabilities()
+            final Network net = new Network(101);
+            final NetworkCapabilities caps = createCapabilities()
                     .addCapability(NET_CAPABILITY_NOT_CONGESTED);
-            assertTrue(ConnectivityController.isSatisfied(early, network, capabilities));
-            assertTrue(ConnectivityController.isSatisfied(late, network, capabilities));
+            assertTrue(ConnectivityController.isSatisfied(early, net, caps, mConstants));
+            assertTrue(ConnectivityController.isSatisfied(late, net, caps, mConstants));
         }
 
         // Congested network is more selective
         {
-            final Network network = new Network(101);
-            final NetworkCapabilities capabilities = createCapabilities();
-            assertFalse(ConnectivityController.isSatisfied(early, network, capabilities));
-            assertTrue(ConnectivityController.isSatisfied(late, network, capabilities));
+            final Network net = new Network(101);
+            final NetworkCapabilities caps = createCapabilities();
+            assertFalse(ConnectivityController.isSatisfied(early, net, caps, mConstants));
+            assertTrue(ConnectivityController.isSatisfied(late, net, caps, mConstants));
         }
     }
 
@@ -126,25 +133,25 @@
 
         // Unmetered network is whenever
         {
-            final Network network = new Network(101);
-            final NetworkCapabilities capabilities = createCapabilities()
+            final Network net = new Network(101);
+            final NetworkCapabilities caps = createCapabilities()
                     .addCapability(NET_CAPABILITY_NOT_CONGESTED)
                     .addCapability(NET_CAPABILITY_NOT_METERED);
-            assertTrue(ConnectivityController.isSatisfied(early, network, capabilities));
-            assertTrue(ConnectivityController.isSatisfied(late, network, capabilities));
-            assertTrue(ConnectivityController.isSatisfied(earlyPrefetch, network, capabilities));
-            assertTrue(ConnectivityController.isSatisfied(latePrefetch, network, capabilities));
+            assertTrue(ConnectivityController.isSatisfied(early, net, caps, mConstants));
+            assertTrue(ConnectivityController.isSatisfied(late, net, caps, mConstants));
+            assertTrue(ConnectivityController.isSatisfied(earlyPrefetch, net, caps, mConstants));
+            assertTrue(ConnectivityController.isSatisfied(latePrefetch, net, caps, mConstants));
         }
 
         // Metered network is only when prefetching and late
         {
-            final Network network = new Network(101);
-            final NetworkCapabilities capabilities = createCapabilities()
+            final Network net = new Network(101);
+            final NetworkCapabilities caps = createCapabilities()
                     .addCapability(NET_CAPABILITY_NOT_CONGESTED);
-            assertFalse(ConnectivityController.isSatisfied(early, network, capabilities));
-            assertFalse(ConnectivityController.isSatisfied(late, network, capabilities));
-            assertFalse(ConnectivityController.isSatisfied(earlyPrefetch, network, capabilities));
-            assertTrue(ConnectivityController.isSatisfied(latePrefetch, network, capabilities));
+            assertFalse(ConnectivityController.isSatisfied(early, net, caps, mConstants));
+            assertFalse(ConnectivityController.isSatisfied(late, net, caps, mConstants));
+            assertFalse(ConnectivityController.isSatisfied(earlyPrefetch, net, caps, mConstants));
+            assertTrue(ConnectivityController.isSatisfied(latePrefetch, net, caps, mConstants));
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java
index 293f9af..c6800be 100644
--- a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java
+++ b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java
@@ -77,6 +77,7 @@
         assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+        assertInsetBy(mAppWindow.displayFrame, 0, 0, 0, 0);
     }
 
     @Test
@@ -91,6 +92,7 @@
         assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.decorFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.displayFrame, 0, NAV_BAR_HEIGHT);
     }
 
     @Test
@@ -106,6 +108,7 @@
         assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.decorFrame, 0, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.displayFrame, 0, NAV_BAR_HEIGHT);
     }
 
     @Test
@@ -130,6 +133,7 @@
         assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+        assertInsetByTopBottom(mAppWindow.displayFrame, 0, 0);
     }
 
     @Test
@@ -146,6 +150,7 @@
         assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+        assertInsetByTopBottom(mAppWindow.displayFrame, STATUS_BAR_HEIGHT, 0);
     }
 
     @Test
@@ -162,6 +167,7 @@
         assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+        assertInsetBy(mAppWindow.displayFrame, 0, 0, 0, 0);
     }
 
     @Test
@@ -178,6 +184,7 @@
         assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+        assertInsetByTopBottom(mAppWindow.displayFrame, STATUS_BAR_HEIGHT, 0);
     }
 
     @Test
@@ -195,6 +202,7 @@
         assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+        assertInsetByTopBottom(mAppWindow.displayFrame, 0, 0);
     }
 
 
@@ -212,6 +220,7 @@
         assertInsetBy(mAppWindow.contentFrame,
                 DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
         assertInsetBy(mAppWindow.decorFrame, 0, 0, 0, 0);
+        assertInsetBy(mAppWindow.displayFrame, DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
     }
 
     @Test
@@ -228,6 +237,7 @@
         assertInsetBy(mAppWindow.contentFrame,
                 NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, 0);
         assertInsetBy(mAppWindow.decorFrame, 0, 0, 0, 0);
+        assertInsetBy(mAppWindow.displayFrame, 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
     }
 
     @Test
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java b/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
index cfd155e..1052e8f 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
@@ -71,6 +71,7 @@
     private PinnedSliceState mPinnedSliceManager;
     private IContentProvider mIContentProvider;
     private ContentProvider mContentProvider;
+    private IBinder mToken = new Binder();
 
     @Before
     public void setup() {
@@ -108,7 +109,7 @@
         TestableLooper.get(this).processAllMessages();
 
         // When pinned for the first time, a pinned message should be sent.
-        mPinnedSliceManager.pin("pkg", FIRST_SPECS);
+        mPinnedSliceManager.pin("pkg", FIRST_SPECS, mToken);
         TestableLooper.get(this).processAllMessages();
 
         verify(mIContentProvider).call(anyString(), eq(SliceProvider.METHOD_PIN), eq(null),
@@ -119,112 +120,27 @@
     }
 
     @Test
-    public void testSendPinnedOnListen() throws RemoteException {
-        TestableLooper.get(this).processAllMessages();
-
-        // When a listener is added for the first time, a pinned message should be sent.
-        ISliceListener listener = mock(ISliceListener.class);
-        when(listener.asBinder()).thenReturn(new Binder());
-
-        mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
-                true);
-        TestableLooper.get(this).processAllMessages();
-
-        verify(mIContentProvider).call(anyString(), eq(SliceProvider.METHOD_PIN), eq(null),
-                argThat(b -> {
-                    assertEquals(TEST_URI, b.getParcelable(SliceProvider.EXTRA_BIND_URI));
-                    return true;
-                }));
-    }
-
-    @Test
-    public void testNoSendPinnedWithoutPermission() throws RemoteException {
-        TestableLooper.get(this).processAllMessages();
-
-        // When a listener is added for the first time, a pinned message should be sent.
-        ISliceListener listener = mock(ISliceListener.class);
-        when(listener.asBinder()).thenReturn(new Binder());
-
-        mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
-                false);
-        TestableLooper.get(this).processAllMessages();
-
-        verify(mIContentProvider, never()).call(anyString(), eq(SliceProvider.METHOD_PIN), eq(null),
-                any());
-    }
-
-    @Test
-    public void testSendUnpinnedOnDestroy() throws RemoteException {
-        TestableLooper.get(this).processAllMessages();
-        clearInvocations(mIContentProvider);
-
-        mPinnedSliceManager.pin("pkg", FIRST_SPECS);
-        mPinnedSliceManager.destroy();
-        TestableLooper.get(this).processAllMessages();
-
-        verify(mIContentProvider).call(anyString(), eq(SliceProvider.METHOD_UNPIN), eq(null),
-                argThat(b -> {
-                    assertEquals(TEST_URI, b.getParcelable(SliceProvider.EXTRA_BIND_URI));
-                    return true;
-                }));
-    }
-
-    @Test
     public void testPkgPin() {
         assertFalse(mPinnedSliceManager.hasPinOrListener());
 
-        mPinnedSliceManager.pin("pkg", FIRST_SPECS);
+        mPinnedSliceManager.pin("pkg", FIRST_SPECS, mToken);
         assertTrue(mPinnedSliceManager.hasPinOrListener());
 
-        assertTrue(mPinnedSliceManager.unpin("pkg"));
+        assertTrue(mPinnedSliceManager.unpin("pkg", mToken));
         assertFalse(mPinnedSliceManager.hasPinOrListener());
     }
 
     @Test
     public void testMultiPkgPin() {
+        IBinder t2 = new Binder();
         assertFalse(mPinnedSliceManager.hasPinOrListener());
 
-        mPinnedSliceManager.pin("pkg", FIRST_SPECS);
+        mPinnedSliceManager.pin("pkg", FIRST_SPECS, mToken);
         assertTrue(mPinnedSliceManager.hasPinOrListener());
-        mPinnedSliceManager.pin("pkg2", FIRST_SPECS);
+        mPinnedSliceManager.pin("pkg2", FIRST_SPECS, t2);
 
-        assertFalse(mPinnedSliceManager.unpin("pkg"));
-        assertTrue(mPinnedSliceManager.unpin("pkg2"));
-        assertFalse(mPinnedSliceManager.hasPinOrListener());
-    }
-
-    @Test
-    public void testListenerPin() {
-        ISliceListener listener = mock(ISliceListener.class);
-        when(listener.asBinder()).thenReturn(new Binder());
-        assertFalse(mPinnedSliceManager.hasPinOrListener());
-
-        mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
-                true);
-        assertTrue(mPinnedSliceManager.hasPinOrListener());
-
-        assertTrue(mPinnedSliceManager.removeSliceListener(listener));
-        assertFalse(mPinnedSliceManager.hasPinOrListener());
-    }
-
-    @Test
-    public void testMultiListenerPin() {
-        ISliceListener listener = mock(ISliceListener.class);
-        Binder value = new Binder();
-        when(listener.asBinder()).thenReturn(value);
-        ISliceListener listener2 = mock(ISliceListener.class);
-        Binder value2 = new Binder();
-        when(listener2.asBinder()).thenReturn(value2);
-        assertFalse(mPinnedSliceManager.hasPinOrListener());
-
-        mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
-                true);
-        assertTrue(mPinnedSliceManager.hasPinOrListener());
-        mPinnedSliceManager.addSliceListener(listener2, mContext.getPackageName(), FIRST_SPECS,
-                true);
-
-        assertFalse(mPinnedSliceManager.removeSliceListener(listener));
-        assertTrue(mPinnedSliceManager.removeSliceListener(listener2));
+        assertFalse(mPinnedSliceManager.unpin("pkg", mToken));
+        assertTrue(mPinnedSliceManager.unpin("pkg2", t2));
         assertFalse(mPinnedSliceManager.hasPinOrListener());
     }
 
@@ -236,8 +152,7 @@
         when(listener.asBinder()).thenReturn(binder);
         assertFalse(mPinnedSliceManager.hasPinOrListener());
 
-        mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
-                true);
+        mPinnedSliceManager.pin(mContext.getPackageName(), FIRST_SPECS, binder);
         assertTrue(mPinnedSliceManager.hasPinOrListener());
 
         ArgumentCaptor<DeathRecipient> arg = ArgumentCaptor.forClass(DeathRecipient.class);
@@ -246,79 +161,7 @@
         when(binder.isBinderAlive()).thenReturn(false);
         arg.getValue().binderDied();
 
-        verify(mSliceService).unlisten(eq(TEST_URI));
         verify(mSliceService).removePinnedSlice(eq(TEST_URI));
         assertFalse(mPinnedSliceManager.hasPinOrListener());
     }
-
-    @Test
-    public void testPkgListenerPin() {
-        ISliceListener listener = mock(ISliceListener.class);
-        when(listener.asBinder()).thenReturn(new Binder());
-        assertFalse(mPinnedSliceManager.hasPinOrListener());
-
-        mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
-                true);
-        assertTrue(mPinnedSliceManager.hasPinOrListener());
-        mPinnedSliceManager.pin("pkg", FIRST_SPECS);
-
-        assertFalse(mPinnedSliceManager.removeSliceListener(listener));
-        assertTrue(mPinnedSliceManager.unpin("pkg"));
-        assertFalse(mPinnedSliceManager.hasPinOrListener());
-    }
-
-    @Test
-    public void testBind() throws RemoteException {
-        TestableLooper.get(this).processAllMessages();
-        clearInvocations(mIContentProvider);
-
-        ISliceListener listener = mock(ISliceListener.class);
-        when(listener.asBinder()).thenReturn(new Binder());
-        Slice s = new Slice.Builder(TEST_URI).build();
-        Bundle b = new Bundle();
-        b.putParcelable(SliceProvider.EXTRA_SLICE, s);
-        when(mIContentProvider.call(anyString(), eq(SliceProvider.METHOD_SLICE), eq(null),
-                any())).thenReturn(b);
-
-        assertFalse(mPinnedSliceManager.hasPinOrListener());
-
-        mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
-                true);
-
-        mPinnedSliceManager.onChange();
-        TestableLooper.get(this).processAllMessages();
-
-        verify(mIContentProvider).call(anyString(), eq(SliceProvider.METHOD_SLICE), eq(null),
-                argThat(bundle -> {
-                    assertEquals(TEST_URI, bundle.getParcelable(SliceProvider.EXTRA_BIND_URI));
-                    return true;
-                }));
-        verify(listener).onSliceUpdated(eq(s));
-    }
-
-    @Test
-    public void testRecheckPackage() throws RemoteException {
-        TestableLooper.get(this).processAllMessages();
-
-        ISliceListener listener = mock(ISliceListener.class);
-        when(listener.asBinder()).thenReturn(new Binder());
-
-        mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
-                false);
-        TestableLooper.get(this).processAllMessages();
-
-        verify(mIContentProvider, never()).call(anyString(), eq(SliceProvider.METHOD_PIN), eq(null),
-                any());
-
-        when(mSliceService.checkAccess(any(), any(), anyInt(), anyInt()))
-                .thenReturn(PERMISSION_GRANTED);
-        mPinnedSliceManager.recheckPackage(mContext.getPackageName());
-        TestableLooper.get(this).processAllMessages();
-
-        verify(mIContentProvider).call(anyString(), eq(SliceProvider.METHOD_PIN), eq(null),
-                argThat(b -> {
-                    assertEquals(TEST_URI, b.getParcelable(SliceProvider.EXTRA_BIND_URI));
-                    return true;
-                }));
-    }
 }
\ No newline at end of file
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
index fe9ea7a..6fc3009 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
@@ -32,6 +32,8 @@
 import android.app.slice.SliceSpec;
 import android.content.pm.PackageManagerInternal;
 import android.net.Uri;
+import android.os.Binder;
+import android.os.IBinder;
 import android.os.RemoteException;
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
@@ -59,6 +61,7 @@
 
     private SliceManagerService mService;
     private PinnedSliceState mCreatedSliceState;
+    private IBinder mToken = new Binder();
 
     @Before
     public void setup() {
@@ -77,43 +80,11 @@
     }
 
     @Test
-    public void testAddListenerCreatesPinned() throws RemoteException {
-        mService.addSliceListener(TEST_URI, "pkg", mock(ISliceListener.class), EMPTY_SPECS);
-        verify(mService, times(1)).createPinnedSlice(eq(TEST_URI));
-    }
-
-    @Test
-    public void testAddListenerCreatesOnePinned() throws RemoteException {
-        mService.addSliceListener(TEST_URI, "pkg", mock(ISliceListener.class), EMPTY_SPECS);
-        mService.addSliceListener(TEST_URI, "pkg", mock(ISliceListener.class), EMPTY_SPECS);
-        verify(mService, times(1)).createPinnedSlice(eq(TEST_URI));
-    }
-
-    @Test
-    public void testRemoveListenerDestroysPinned() throws RemoteException {
-        ISliceListener listener = mock(ISliceListener.class);
-        mService.addSliceListener(TEST_URI, "pkg", listener, EMPTY_SPECS);
-
-        when(mCreatedSliceState.removeSliceListener(eq(listener))).thenReturn(false);
-        mService.removeSliceListener(TEST_URI, "pkg", listener);
-        verify(mCreatedSliceState, never()).destroy();
-
-        when(mCreatedSliceState.removeSliceListener(eq(listener))).thenReturn(true);
-        mService.removeSliceListener(TEST_URI, "pkg", listener);
-        verify(mCreatedSliceState).destroy();
-    }
-
-    @Test(expected = IllegalStateException.class)
-    public void testUnrecognizedThrows() throws RemoteException {
-        mService.removeSliceListener(TEST_URI, "pkg", mock(ISliceListener.class));
-    }
-
-    @Test
     public void testAddPinCreatesPinned() throws RemoteException {
         doReturn("pkg").when(mService).getDefaultHome(anyInt());
 
-        mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS);
-        mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS);
+        mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken);
+        mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken);
         verify(mService, times(1)).createPinnedSlice(eq(TEST_URI));
     }
 
@@ -121,15 +92,11 @@
     public void testRemovePinDestroysPinned() throws RemoteException {
         doReturn("pkg").when(mService).getDefaultHome(anyInt());
 
-        mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS);
+        mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken);
 
-        when(mCreatedSliceState.unpin(eq("pkg"))).thenReturn(false);
-        mService.unpinSlice("pkg", TEST_URI);
+        when(mCreatedSliceState.unpin(eq("pkg"), eq(mToken))).thenReturn(false);
+        mService.unpinSlice("pkg", TEST_URI, mToken);
         verify(mCreatedSliceState, never()).destroy();
-
-        when(mCreatedSliceState.unpin(eq("pkg"))).thenReturn(true);
-        mService.unpinSlice("pkg", TEST_URI);
-        verify(mCreatedSliceState).destroy();
     }
 
 }
\ No newline at end of file
diff --git a/services/usage/java/com/android/server/usage/AppIdleHistory.java b/services/usage/java/com/android/server/usage/AppIdleHistory.java
index f26c2ae..8e5a418 100644
--- a/services/usage/java/com/android/server/usage/AppIdleHistory.java
+++ b/services/usage/java/com/android/server/usage/AppIdleHistory.java
@@ -25,6 +25,7 @@
 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE;
 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
 
+import android.app.usage.AppStandbyInfo;
 import android.app.usage.UsageStatsManager;
 import android.os.SystemClock;
 import android.util.ArrayMap;
@@ -37,8 +38,6 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.LocalServices;
-import com.android.server.job.JobSchedulerInternal;
 
 import libcore.io.IoUtils;
 
@@ -53,8 +52,7 @@
 import java.io.FileReader;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.ArrayList;
 
 /**
  * Keeps track of recent active state changes in apps.
@@ -384,14 +382,13 @@
         return appUsageHistory.currentBucket;
     }
 
-    public Map<String, Integer> getAppStandbyBuckets(int userId, long elapsedRealtime,
-            boolean appIdleEnabled) {
+    public ArrayList<AppStandbyInfo> getAppStandbyBuckets(int userId, boolean appIdleEnabled) {
         ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
         int size = userHistory.size();
-        HashMap<String, Integer> buckets = new HashMap<>(size);
+        ArrayList<AppStandbyInfo> buckets = new ArrayList<>(size);
         for (int i = 0; i < size; i++) {
-            buckets.put(userHistory.keyAt(i),
-                    appIdleEnabled ? userHistory.valueAt(i).currentBucket : STANDBY_BUCKET_ACTIVE);
+            buckets.add(new AppStandbyInfo(userHistory.keyAt(i),
+                    appIdleEnabled ? userHistory.valueAt(i).currentBucket : STANDBY_BUCKET_ACTIVE));
         }
         return buckets;
     }
diff --git a/services/usage/java/com/android/server/usage/AppStandbyController.java b/services/usage/java/com/android/server/usage/AppStandbyController.java
index c31809e..f40aa5b 100644
--- a/services/usage/java/com/android/server/usage/AppStandbyController.java
+++ b/services/usage/java/com/android/server/usage/AppStandbyController.java
@@ -33,6 +33,7 @@
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.AppGlobals;
+import android.app.usage.AppStandbyInfo;
 import android.app.usage.UsageStatsManager.StandbyBuckets;
 import android.app.usage.UsageEvents;
 import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
@@ -954,9 +955,9 @@
         }
     }
 
-    public Map<String, Integer> getAppStandbyBuckets(int userId, long elapsedRealtime) {
+    public List<AppStandbyInfo> getAppStandbyBuckets(int userId) {
         synchronized (mAppIdleLock) {
-            return mAppIdleHistory.getAppStandbyBuckets(userId, elapsedRealtime, mAppIdleEnabled);
+            return mAppIdleHistory.getAppStandbyBuckets(userId, mAppIdleEnabled);
         }
     }
 
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 3b0fd1f..dedf967 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -20,6 +20,7 @@
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.app.IUidObserver;
+import android.app.usage.AppStandbyInfo;
 import android.app.usage.ConfigurationStats;
 import android.app.usage.IUsageStatsManager;
 import android.app.usage.UsageEvents;
@@ -758,7 +759,8 @@
         }
 
         @Override
-        public Map getAppStandbyBuckets(String callingPackageName, int userId) {
+        public ParceledListSlice<AppStandbyInfo> getAppStandbyBuckets(String callingPackageName,
+                int userId) {
             final int callingUid = Binder.getCallingUid();
             try {
                 userId = ActivityManager.getService().handleIncomingUser(
@@ -773,15 +775,17 @@
             }
             final long token = Binder.clearCallingIdentity();
             try {
-                return mAppStandby.getAppStandbyBuckets(userId,
-                        SystemClock.elapsedRealtime());
+                final List<AppStandbyInfo> standbyBucketList =
+                        mAppStandby.getAppStandbyBuckets(userId);
+                return (standbyBucketList == null) ? ParceledListSlice.emptyList()
+                        : new ParceledListSlice<>(standbyBucketList);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
-        public void setAppStandbyBuckets(Map appBuckets, int userId) {
+        public void setAppStandbyBuckets(ParceledListSlice appBuckets, int userId) {
             getContext().enforceCallingPermission(Manifest.permission.CHANGE_APP_IDLE_STATE,
                     "No permission to change app standby state");
 
@@ -800,10 +804,10 @@
             final long token = Binder.clearCallingIdentity();
             try {
                 final long elapsedRealtime = SystemClock.elapsedRealtime();
-                Map<String, Integer> buckets = (Map<String, Integer>) appBuckets;
-                for (Map.Entry<String, Integer> entry: buckets.entrySet()) {
-                    String packageName = entry.getKey();
-                    int bucket = entry.getValue();
+                List<AppStandbyInfo> bucketList = appBuckets.getList();
+                for (AppStandbyInfo bucketInfo : bucketList) {
+                    final String packageName = bucketInfo.mPackageName;
+                    final int bucket = bucketInfo.mStandbyBucket;
                     if (bucket < UsageStatsManager.STANDBY_BUCKET_ACTIVE
                             || bucket > UsageStatsManager.STANDBY_BUCKET_NEVER) {
                         throw new IllegalArgumentException(
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index ec12da2..8afc511 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -24,6 +24,7 @@
 import android.content.res.Configuration;
 import android.os.SystemClock;
 import android.content.Context;
+import android.text.format.DateFormat;
 import android.text.format.DateUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -474,25 +475,25 @@
         mDatabase.checkinDailyFiles(new UsageStatsDatabase.CheckinAction() {
             @Override
             public boolean checkin(IntervalStats stats) {
-                printIntervalStats(pw, stats, false, null);
+                printIntervalStats(pw, stats, true, null);
                 return true;
             }
         });
     }
 
     void dump(IndentingPrintWriter pw, String pkg) {
-        // This is not a check-in, only dump in-memory stats.
+        printLast24HrEvents(pw, true, pkg);
         for (int interval = 0; interval < mCurrentStats.length; interval++) {
             pw.print("In-memory ");
             pw.print(intervalToString(interval));
             pw.println(" stats");
-            printIntervalStats(pw, mCurrentStats[interval], true, pkg);
+            printIntervalStats(pw, mCurrentStats[interval], false, pkg);
         }
     }
 
     private String formatDateTime(long dateTime, boolean pretty) {
         if (pretty) {
-            return "\"" + DateUtils.formatDateTime(mContext, dateTime, sDateFormatFlags) + "\"";
+            return "\"" + DateFormat.format("yyyy-MM-dd HH:mm:ss", dateTime).toString() + "\"";
         }
         return Long.toString(dateTime);
     }
@@ -504,8 +505,82 @@
         return Long.toString(elapsedTime);
     }
 
+
+    void printEvent(IndentingPrintWriter pw, UsageEvents.Event event, boolean prettyDates) {
+        pw.printPair("time", formatDateTime(event.mTimeStamp, prettyDates));
+        pw.printPair("type", eventToString(event.mEventType));
+        pw.printPair("package", event.mPackage);
+        if (event.mClass != null) {
+            pw.printPair("class", event.mClass);
+        }
+        if (event.mConfiguration != null) {
+            pw.printPair("config", Configuration.resourceQualifierString(event.mConfiguration));
+        }
+        if (event.mShortcutId != null) {
+            pw.printPair("shortcutId", event.mShortcutId);
+        }
+        if (event.mEventType == UsageEvents.Event.STANDBY_BUCKET_CHANGED) {
+            pw.printPair("standbyBucket", event.mBucket);
+        }
+        pw.printHexPair("flags", event.mFlags);
+        pw.println();
+    }
+
+    void printLast24HrEvents(IndentingPrintWriter pw, boolean prettyDates, final String pkg) {
+        final long endTime = System.currentTimeMillis();
+        UnixCalendar yesterday = new UnixCalendar(endTime);
+        yesterday.addDays(-1);
+
+        final long beginTime = yesterday.getTimeInMillis();
+
+        List<UsageEvents.Event> events = queryStats(UsageStatsManager.INTERVAL_DAILY,
+                beginTime, endTime, new StatCombiner<UsageEvents.Event>() {
+                    @Override
+                    public void combine(IntervalStats stats, boolean mutable,
+                            List<UsageEvents.Event> accumulatedResult) {
+                        if (stats.events == null) {
+                            return;
+                        }
+
+                        final int startIndex = stats.events.closestIndexOnOrAfter(beginTime);
+                        if (startIndex < 0) {
+                            return;
+                        }
+
+                        final int size = stats.events.size();
+                        for (int i = startIndex; i < size; i++) {
+                            if (stats.events.keyAt(i) >= endTime) {
+                                return;
+                            }
+
+                            UsageEvents.Event event = stats.events.valueAt(i);
+                            if (pkg != null && !pkg.equals(event.mPackage)) {
+                                continue;
+                            }
+                            accumulatedResult.add(event);
+                        }
+                    }
+                });
+
+        pw.print("Last 24 hour events (");
+        if (prettyDates) {
+            pw.printPair("timeRange", "\"" + DateUtils.formatDateRange(mContext,
+                    beginTime, endTime, sDateFormatFlags) + "\"");
+        } else {
+            pw.printPair("beginTime", beginTime);
+            pw.printPair("endTime", endTime);
+        }
+        pw.println(")");
+        pw.increaseIndent();
+        for (UsageEvents.Event event : events) {
+            printEvent(pw, event, prettyDates);
+        }
+        pw.decreaseIndent();
+    }
+
     void printIntervalStats(IndentingPrintWriter pw, IntervalStats stats,
-            boolean prettyDates, String pkg) {
+            boolean checkin, String pkg) {
+        boolean prettyDates = !checkin;
         if (prettyDates) {
             pw.printPair("timeRange", "\"" + DateUtils.formatDateRange(mContext,
                     stats.beginTime, stats.endTime, sDateFormatFlags) + "\"");
@@ -578,35 +653,23 @@
             pw.decreaseIndent();
         }
 
-        pw.println("events");
-        pw.increaseIndent();
-        final TimeSparseArray<UsageEvents.Event> events = stats.events;
-        final int eventCount = events != null ? events.size() : 0;
-        for (int i = 0; i < eventCount; i++) {
-            final UsageEvents.Event event = events.valueAt(i);
-            if (pkg != null && !pkg.equals(event.mPackage)) {
-                continue;
+        // The last 24 hours of events is already printed in the non checkin dump
+        // No need to repeat here.
+        if (checkin) {
+            pw.println("events");
+            pw.increaseIndent();
+            final TimeSparseArray<UsageEvents.Event> events = stats.events;
+            final int eventCount = events != null ? events.size() : 0;
+            for (int i = 0; i < eventCount; i++) {
+                final UsageEvents.Event event = events.valueAt(i);
+                if (pkg != null && !pkg.equals(event.mPackage)) {
+                    continue;
+                }
+                printEvent(pw, event, prettyDates);
             }
-            pw.printPair("time", formatDateTime(event.mTimeStamp, prettyDates));
-            pw.printPair("type", eventToString(event.mEventType));
-            pw.printPair("package", event.mPackage);
-            if (event.mClass != null) {
-                pw.printPair("class", event.mClass);
-            }
-            if (event.mConfiguration != null) {
-                pw.printPair("config", Configuration.resourceQualifierString(event.mConfiguration));
-            }
-            if (event.mShortcutId != null) {
-                pw.printPair("shortcutId", event.mShortcutId);
-            }
-            if (event.mEventType == UsageEvents.Event.STANDBY_BUCKET_CHANGED) {
-                pw.printPair("standbyBucket", event.mBucket);
-            }
-            pw.printHexPair("flags", event.mFlags);
-            pw.println();
+            pw.decreaseIndent();
         }
         pw.decreaseIndent();
-        pw.decreaseIndent();
     }
 
     private static String intervalToString(int interval) {
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 63263bd..e7f0cc2 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -2732,6 +2732,7 @@
          * This should be spread to other technologies,
          * but is currently only used for LTE (14) and eHRPD (13).
          * <P>Type: INTEGER</P>
+         * @deprecated this column is no longer supported, use {@link #NETWORK_TYPE_BITMASK} instead
          */
         @Deprecated
         public static final String BEARER = "bearer";
@@ -2744,13 +2745,14 @@
          * Bitmask for a radio tech R is (1 << (R - 1))
          * <P>Type: INTEGER</P>
          * @hide
+         * @deprecated this column is no longer supported, use {@link #NETWORK_TYPE_BITMASK} instead
          */
         @Deprecated
         public static final String BEARER_BITMASK = "bearer_bitmask";
 
         /**
          * Radio technology (network type) bitmask.
-         * To check what values can be contained, refer to
+         * To check what values can be contained, refer to the NETWORK_TYPE_ constants in
          * {@link android.telephony.TelephonyManager}.
          * Bitmask for a radio tech R is (1 << (R - 1))
          * <P>Type: INTEGER</P>
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index ec348df..b6be3c5 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -178,7 +178,6 @@
 
     /**
      * Number of radio technologies for GSM, UMTS and CDMA.
-     * @hide
      */
     private static final int NEXT_RIL_RADIO_TECHNOLOGY = 20;
 
@@ -340,6 +339,8 @@
         mIsEmergencyOnly = s.mIsEmergencyOnly;
         mIsDataRoamingFromRegistration = s.mIsDataRoamingFromRegistration;
         mIsUsingCarrierAggregation = s.mIsUsingCarrierAggregation;
+        mChannelNumber = s.mChannelNumber;
+        mCellBandwidths = Arrays.copyOf(s.mCellBandwidths, s.mCellBandwidths.length);
         mLteEarfcnRsrpBoost = s.mLteEarfcnRsrpBoost;
         mNetworkRegistrationStates = new ArrayList<>(s.mNetworkRegistrationStates);
     }
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 28f8122..2aea1d7 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -914,8 +914,10 @@
                 mock(INetworkPolicyManager.class),
                 mock(IpConnectivityLog.class));
 
-        mService.systemReady();
+        // Create local CM before sending system ready so that we can answer
+        // getSystemService() correctly.
         mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService);
+        mService.systemReady();
         mCm.bindProcessToNetwork(null);
 
         // Ensure that the default setting for Captive Portals is used for most tests
@@ -3412,8 +3414,10 @@
 
     @Test
     public void testNetworkCallbackMaximum() {
-        final int MAX_REQUESTS = 100;
-        final int CALLBACKS = 90;
+        // We can only have 99 callbacks, because MultipathPolicyTracker is
+        // already one of them.
+        final int MAX_REQUESTS = 99;
+        final int CALLBACKS = 89;
         final int INTENTS = 10;
         assertEquals(MAX_REQUESTS, CALLBACKS + INTENTS);
 
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index b1b05e8..49b2643 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -95,6 +95,7 @@
 
 import com.android.internal.net.VpnInfo;
 import com.android.internal.util.test.BroadcastInterceptingContext;
+import com.android.server.LocalServices;
 import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
 import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
 
@@ -221,6 +222,9 @@
 
     @After
     public void tearDown() throws Exception {
+        // Registered by NetworkStatsService's constructor.
+        LocalServices.removeServiceForTest(NetworkStatsManagerInternal.class);
+
         IoUtils.deleteContents(mStatsDir);
 
         mServiceContext = null;