Merge "strings.xml: Resources to post notification for network suggestions"
diff --git a/Android.bp b/Android.bp
index 4762cba..32bd408 100644
--- a/Android.bp
+++ b/Android.bp
@@ -104,6 +104,7 @@
         "core/java/android/app/backup/IRestoreObserver.aidl",
         "core/java/android/app/backup/IRestoreSession.aidl",
         "core/java/android/app/backup/ISelectBackupTransportCallback.aidl",
+        "core/java/android/app/role/IOnRoleHoldersChangedListener.aidl",
         "core/java/android/app/role/IRoleManager.aidl",
         "core/java/android/app/role/IRoleManagerCallback.aidl",
         "core/java/android/app/slice/ISliceManager.aidl",
@@ -690,7 +691,6 @@
             "frameworks/av/media/libaudioclient/aidl",
             "frameworks/native/aidl/gui",
             "system/core/storaged/binder",
-            "system/netd/server/binder",
             "system/vold/binder",
             "system/bt/binder",
             "system/security/keystore/binder",
diff --git a/apct-tests/perftests/core/src/android/os/BinderCallsStatsPerfTest.java b/apct-tests/perftests/core/src/android/os/BinderCallsStatsPerfTest.java
index 5be0cb0..99e4ba1 100644
--- a/apct-tests/perftests/core/src/android/os/BinderCallsStatsPerfTest.java
+++ b/apct-tests/perftests/core/src/android/os/BinderCallsStatsPerfTest.java
@@ -39,6 +39,7 @@
 @LargeTest
 public class BinderCallsStatsPerfTest {
     private static final int DEFAULT_BUCKET_SIZE = 1000;
+    private static final int WORKSOURCE_UID = 1;
     static class FakeCpuTimeBinderCallsStats extends BinderCallsStats {
         private int mTimeMs;
 
@@ -117,8 +118,8 @@
         Binder b = new Binder();
         while (state.keepRunning()) {
             for (int i = 0; i < 10000; i++) {
-                CallSession s = mBinderCallsStats.callStarted(b, i % maxBucketSize);
-                mBinderCallsStats.callEnded(s, 0, 0);
+                CallSession s = mBinderCallsStats.callStarted(b, i % maxBucketSize, WORKSOURCE_UID);
+                mBinderCallsStats.callEnded(s, 0, 0, WORKSOURCE_UID);
             }
         }
     }
diff --git a/api/current.txt b/api/current.txt
index de5a0b1..c893840 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23060,6 +23060,7 @@
     method public deprecated boolean isBluetoothA2dpOn();
     method public boolean isBluetoothScoAvailableOffCall();
     method public boolean isBluetoothScoOn();
+    method public static boolean isHapticPlaybackSupported();
     method public boolean isMicrophoneMute();
     method public boolean isMusicActive();
     method public static boolean isOffloadedPlaybackSupported(android.media.AudioFormat);
@@ -37454,6 +37455,8 @@
     field public static final java.lang.String EXTRA_ORIENTATION = "android.provider.extra.ORIENTATION";
     field public static final java.lang.String EXTRA_PROMPT = "android.provider.extra.PROMPT";
     field public static final java.lang.String METADATA_EXIF = "android:documentExif";
+    field public static final java.lang.String METADATA_TREE_COUNT = "android:metadataTreeCount";
+    field public static final java.lang.String METADATA_TREE_SIZE = "android:metadataTreeSize";
     field public static final java.lang.String METADATA_TYPES = "android:documentMetadataTypes";
     field public static final java.lang.String PROVIDER_INTERFACE = "android.content.action.DOCUMENTS_PROVIDER";
     field public static final java.lang.String QUERY_ARG_DISPLAY_NAME = "android:query-arg-display-name";
@@ -37830,6 +37833,7 @@
 
   public static final class MediaStore.Downloads implements android.provider.MediaStore.DownloadColumns {
     method public static android.net.Uri getContentUri(java.lang.String);
+    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/download";
     field public static final android.net.Uri EXTERNAL_CONTENT_URI;
     field public static final android.net.Uri INTERNAL_CONTENT_URI;
   }
@@ -40569,6 +40573,7 @@
   public final class UserData implements android.os.Parcelable {
     method public int describeContents();
     method public java.lang.String getFieldClassificationAlgorithm();
+    method public java.lang.String getFieldClassificationAlgorithmForCategory(java.lang.String);
     method public java.lang.String getId();
     method public static int getMaxCategoryCount();
     method public static int getMaxFieldClassificationIdsSize();
@@ -40584,6 +40589,7 @@
     method public android.service.autofill.UserData.Builder add(java.lang.String, java.lang.String);
     method public android.service.autofill.UserData build();
     method public android.service.autofill.UserData.Builder setFieldClassificationAlgorithm(java.lang.String, android.os.Bundle);
+    method public android.service.autofill.UserData.Builder setFieldClassificationAlgorithmForCategory(java.lang.String, java.lang.String, android.os.Bundle);
   }
 
   public abstract interface Validator {
@@ -44101,12 +44107,14 @@
     method public static int getSlotIndex(int);
     method public int[] getSubscriptionIds(int);
     method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int);
+    method public java.util.List<android.telephony.SubscriptionInfo> getSubscriptionsInGroup(int);
     method public boolean isActiveSubscriptionId(int);
     method public boolean isNetworkRoaming(int);
     method public static boolean isUsableSubscriptionId(int);
     method public static boolean isValidSubscriptionId(int);
     method public void removeOnOpportunisticSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener);
     method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
+    method public boolean removeSubscriptionsFromGroup(int[]);
     method public java.lang.String setSubscriptionGroup(int[]);
     method public void setSubscriptionOverrideCongested(int, boolean, long);
     method public void setSubscriptionOverrideUnmetered(int, boolean, long);
diff --git a/api/removed.txt b/api/removed.txt
index f7106d2..e3e8b63 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -508,6 +508,21 @@
     field public static final deprecated java.lang.String TIMESTAMP = "timestamp";
   }
 
+  public final class DocumentsContract {
+    method public static android.net.Uri copyDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException;
+    method public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
+    method public static android.content.IntentSender createWebLinkIntent(android.content.ContentResolver, android.net.Uri, android.os.Bundle) throws java.io.FileNotFoundException;
+    method public static boolean deleteDocument(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException;
+    method public static void ejectRoot(android.content.ContentResolver, android.net.Uri);
+    method public static android.provider.DocumentsContract.Path findDocumentPath(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException;
+    method public static android.os.Bundle getDocumentMetadata(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException;
+    method public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentResolver, android.net.Uri, android.graphics.Point, android.os.CancellationSignal) throws java.io.FileNotFoundException;
+    method public static boolean isChildDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException;
+    method public static android.net.Uri moveDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException;
+    method public static boolean removeDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException;
+    method public static android.net.Uri renameDocument(android.content.ContentResolver, android.net.Uri, java.lang.String) throws java.io.FileNotFoundException;
+  }
+
   public static final class Settings.Global extends android.provider.Settings.NameValueTable {
     field public static final deprecated java.lang.String CONTACT_METADATA_SYNC = "contact_metadata_sync";
   }
diff --git a/api/system-current.txt b/api/system-current.txt
index e6e252c..6db4ec7 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -136,6 +136,7 @@
     field public static final java.lang.String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP";
     field public static final java.lang.String NOTIFY_TV_INPUTS = "android.permission.NOTIFY_TV_INPUTS";
     field public static final java.lang.String OBSERVE_APP_USAGE = "android.permission.OBSERVE_APP_USAGE";
+    field public static final java.lang.String OBSERVE_ROLE_HOLDERS = "android.permission.OBSERVE_ROLE_HOLDERS";
     field public static final java.lang.String OVERRIDE_WIFI_CONFIG = "android.permission.OVERRIDE_WIFI_CONFIG";
     field public static final java.lang.String PACKAGE_USAGE_STATS = "android.permission.PACKAGE_USAGE_STATS";
     field public static final java.lang.String PACKAGE_VERIFICATION_AGENT = "android.permission.PACKAGE_VERIFICATION_AGENT";
@@ -173,6 +174,7 @@
     field public static final java.lang.String REGISTER_CONNECTION_MANAGER = "android.permission.REGISTER_CONNECTION_MANAGER";
     field public static final java.lang.String REGISTER_SIM_SUBSCRIPTION = "android.permission.REGISTER_SIM_SUBSCRIPTION";
     field public static final java.lang.String REMOVE_DRM_CERTIFICATES = "android.permission.REMOVE_DRM_CERTIFICATES";
+    field public static final java.lang.String REMOVE_TASKS = "android.permission.REMOVE_TASKS";
     field public static final java.lang.String RESET_PASSWORD = "android.permission.RESET_PASSWORD";
     field public static final java.lang.String RESTRICTED_VR_ACCESS = "android.permission.RESTRICTED_VR_ACCESS";
     field public static final java.lang.String RETRIEVE_WINDOW_CONTENT = "android.permission.RETRIEVE_WINDOW_CONTENT";
@@ -599,6 +601,8 @@
     method public boolean isDeviceManaged();
     method public boolean isDeviceProvisioned();
     method public boolean isDeviceProvisioningConfigApplied();
+    method public boolean isManagedKiosk();
+    method public boolean isUnattendedManagedKiosk();
     method public void notifyPendingSystemUpdate(long);
     method public void notifyPendingSystemUpdate(long, boolean);
     method public boolean packageHasActiveAdmins(java.lang.String);
@@ -885,12 +889,18 @@
 
 package android.app.role {
 
+  public abstract interface OnRoleHoldersChangedListener {
+    method public abstract void onRoleHoldersChanged(java.lang.String, android.os.UserHandle);
+  }
+
   public final class RoleManager {
+    method public void addOnRoleHoldersChangedListenerAsUser(java.util.concurrent.Executor, android.app.role.OnRoleHoldersChangedListener, android.os.UserHandle);
     method public void addRoleHolderAsUser(java.lang.String, java.lang.String, android.os.UserHandle, java.util.concurrent.Executor, android.app.role.RoleManagerCallback);
     method public boolean addRoleHolderFromController(java.lang.String, java.lang.String);
     method public void clearRoleHoldersAsUser(java.lang.String, android.os.UserHandle, java.util.concurrent.Executor, android.app.role.RoleManagerCallback);
     method public java.util.List<java.lang.String> getRoleHolders(java.lang.String);
     method public java.util.List<java.lang.String> getRoleHoldersAsUser(java.lang.String, android.os.UserHandle);
+    method public void removeOnRoleHoldersChangedListenerAsUser(android.app.role.OnRoleHoldersChangedListener, android.os.UserHandle);
     method public void removeRoleHolderAsUser(java.lang.String, java.lang.String, android.os.UserHandle, java.util.concurrent.Executor, android.app.role.RoleManagerCallback);
     method public boolean removeRoleHolderFromController(java.lang.String, java.lang.String);
     method public void setRoleNamesFromController(java.util.List<java.lang.String>);
@@ -1363,6 +1373,7 @@
 
   public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
     field public static final int FLAG_REMOVED = 2; // 0x2
+    field public static final int PROTECTION_FLAG_DOCUMENTER = 262144; // 0x40000
     field public static final int PROTECTION_FLAG_OEM = 16384; // 0x4000
     field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000
     field public static final int PROTECTION_FLAG_WELLBEING = 131072; // 0x20000
@@ -4573,11 +4584,6 @@
     field public static final int FLAG_REMOVABLE_USB = 524288; // 0x80000
   }
 
-  public final class MediaStore {
-    method public static void deleteContributedMedia(android.content.Context, java.lang.String);
-    method public static long getContributedMediaSize(android.content.Context, java.lang.String);
-  }
-
   public abstract class SearchIndexableData {
     ctor public SearchIndexableData();
     ctor public SearchIndexableData(android.content.Context);
@@ -4922,7 +4928,10 @@
 
   public abstract class AutofillFieldClassificationService extends android.app.Service {
     method public android.os.IBinder onBind(android.content.Intent);
-    method public float[][] onGetScores(java.lang.String, android.os.Bundle, java.util.List<android.view.autofill.AutofillValue>, java.util.List<java.lang.String>);
+    method public float[][] onCalculateScores(java.util.List<android.view.autofill.AutofillValue>, java.util.List<java.lang.String>, java.util.List<java.lang.String>, java.lang.String, android.os.Bundle, java.util.Map, java.util.Map);
+    method public deprecated float[][] onGetScores(java.lang.String, android.os.Bundle, java.util.List<android.view.autofill.AutofillValue>, java.util.List<java.lang.String>);
+    field public static final java.lang.String REQUIRED_ALGORITHM_EDIT_DISTANCE = "EDIT_DISTANCE";
+    field public static final java.lang.String REQUIRED_ALGORITHM_EXACT_MATCH = "EXACT_MATCH";
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutofillFieldClassificationService";
     field public static final java.lang.String SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS = "android.autofill.field_classification.available_algorithms";
     field public static final java.lang.String SERVICE_META_DATA_KEY_DEFAULT_ALGORITHM = "android.autofill.field_classification.default_algorithm";
@@ -6846,12 +6855,6 @@
     method public android.telephony.ims.ImsSsInfo.Builder setProvisionStatus(int);
   }
 
-  public static abstract class ImsSsInfo.ClirInterrogationStatus implements java.lang.annotation.Annotation {
-  }
-
-  public static abstract class ImsSsInfo.ClirOutgoingState implements java.lang.annotation.Annotation {
-  }
-
   public final class ImsStreamMediaProfile implements android.os.Parcelable {
     ctor public ImsStreamMediaProfile(int, int, int, int, int);
     method public void copyFrom(android.telephony.ims.ImsStreamMediaProfile);
diff --git a/api/test-current.txt b/api/test-current.txt
index 7ef58f1..4717969 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -10,6 +10,8 @@
     field public static final java.lang.String FORCE_STOP_PACKAGES = "android.permission.FORCE_STOP_PACKAGES";
     field public static final java.lang.String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS";
     field public static final java.lang.String READ_CELL_BROADCASTS = "android.permission.READ_CELL_BROADCASTS";
+    field public static final java.lang.String REMOVE_TASKS = "android.permission.REMOVE_TASKS";
+    field public static final java.lang.String WRITE_OBB = "android.permission.WRITE_OBB";
   }
 
 }
@@ -372,6 +374,7 @@
   }
 
   public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
+    field public static final int PROTECTION_FLAG_DOCUMENTER = 262144; // 0x40000
     field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000
     field public static final int PROTECTION_FLAG_VENDOR_PRIVILEGED = 32768; // 0x8000
     field public static final int PROTECTION_FLAG_WELLBEING = 131072; // 0x20000
@@ -1006,8 +1009,8 @@
   }
 
   public final class MediaStore {
-    method public static void deleteContributedMedia(android.content.Context, java.lang.String);
-    method public static long getContributedMediaSize(android.content.Context, java.lang.String);
+    method public static void deleteContributedMedia(android.content.Context, java.lang.String, android.os.UserHandle) throws java.io.IOException;
+    method public static long getContributedMediaSize(android.content.Context, java.lang.String, android.os.UserHandle) throws java.io.IOException;
   }
 
   public final class Settings {
@@ -1093,6 +1096,15 @@
 
 package android.service.autofill {
 
+  public abstract class AutofillFieldClassificationService extends android.app.Service {
+    method public android.os.IBinder onBind(android.content.Intent);
+    field public static final java.lang.String REQUIRED_ALGORITHM_EDIT_DISTANCE = "EDIT_DISTANCE";
+    field public static final java.lang.String REQUIRED_ALGORITHM_EXACT_MATCH = "EXACT_MATCH";
+    field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutofillFieldClassificationService";
+    field public static final java.lang.String SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS = "android.autofill.field_classification.available_algorithms";
+    field public static final java.lang.String SERVICE_META_DATA_KEY_DEFAULT_ALGORITHM = "android.autofill.field_classification.default_algorithm";
+  }
+
   public final class CharSequenceTransformation extends android.service.autofill.InternalTransformation implements android.os.Parcelable android.service.autofill.Transformation {
     method public void apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int) throws java.lang.Exception;
   }
@@ -1149,6 +1161,10 @@
     method public android.view.autofill.AutofillValue sanitize(android.view.autofill.AutofillValue);
   }
 
+  public final class UserData implements android.os.Parcelable {
+    method public android.util.ArrayMap<java.lang.String, java.lang.String> getFieldClassificationAlgorithms();
+  }
+
   public abstract interface ValueFinder {
     method public default java.lang.String findByAutofillId(android.view.autofill.AutofillId);
     method public abstract android.view.autofill.AutofillValue findRawValueByAutofillId(android.view.autofill.AutofillId);
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index 3723fce..e3748f1 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -201,7 +201,7 @@
 
     private void doEnabled(@UserIdInt int userId) {
         try {
-            boolean isEnabled = mBmgr.isBackupEnabled();
+            boolean isEnabled = mBmgr.isBackupEnabledForUser(userId);
             System.out.println("Backup Manager currently "
                     + enableToString(isEnabled));
         } catch (RemoteException e) {
@@ -219,7 +219,7 @@
 
         try {
             boolean enable = Boolean.parseBoolean(arg);
-            mBmgr.setBackupEnabled(enable);
+            mBmgr.setBackupEnabledForUser(userId, enable);
             System.out.println("Backup Manager now " + enableToString(enable));
         } catch (NumberFormatException e) {
             showUsage();
@@ -232,7 +232,7 @@
 
     void doRun(@UserIdInt int userId) {
         try {
-            mBmgr.backupNow();
+            mBmgr.backupNowForUser(userId);
         } catch (RemoteException e) {
             System.err.println(e.toString());
             System.err.println(BMGR_NOT_RUNNING_ERR);
@@ -416,7 +416,8 @@
                     (monitorState != Monitor.OFF)
                             ? new BackupMonitor(monitorState == Monitor.VERBOSE)
                             : null;
-            int err = mBmgr.requestBackup(
+            int err = mBmgr.requestBackupForUser(
+                    userId,
                     packages.toArray(new String[packages.size()]),
                     observer,
                     monitor,
@@ -477,7 +478,7 @@
         String arg = nextArg();
         if ("backups".equals(arg)) {
             try {
-                mBmgr.cancelBackups();
+                mBmgr.cancelBackupsForUser(userId);
             } catch (RemoteException e) {
                 System.err.println(e.toString());
                 System.err.println(BMGR_NOT_RUNNING_ERR);
diff --git a/cmds/incident_helper/tests/KernelWakesParser_test.cpp b/cmds/incident_helper/tests/KernelWakesParser_test.cpp
index f92d813..573ca4f 100644
--- a/cmds/incident_helper/tests/KernelWakesParser_test.cpp
+++ b/cmds/incident_helper/tests/KernelWakesParser_test.cpp
@@ -84,9 +84,9 @@
     record1->set_event_count(8);
     record1->set_wakeup_count(0);
     record1->set_expire_count(0);
-    record1->set_active_since(0l);
-    record1->set_total_time(0l);
-    record1->set_max_time(0l);
+    record1->set_active_since(0L);
+    record1->set_total_time(0L);
+    record1->set_max_time(0L);
     record1->set_last_change(131348LL);
     record1->set_prevent_suspend_time(0LL);
 
@@ -96,9 +96,9 @@
     record2->set_event_count(143);
     record2->set_wakeup_count(0);
     record2->set_expire_count(0);
-    record2->set_active_since(0l);
-    record2->set_total_time(123l);
-    record2->set_max_time(3l);
+    record2->set_active_since(0L);
+    record2->set_total_time(123L);
+    record2->set_max_time(3L);
     record2->set_last_change(2067286206LL);
     record2->set_prevent_suspend_time(0LL);
 
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 78d8e29..f58caff 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -1217,6 +1217,12 @@
     optional bool has_audio = 3;
     optional bool has_hid = 4;
     optional bool has_storage = 5;
+    enum State {
+        STATE_DISCONNECTED = 0;
+        STATE_CONNECTED = 1;
+    }
+    optional State state = 6;
+    optional int64 last_connect_duration_ms = 7;
 }
 
 
@@ -1265,14 +1271,18 @@
  * Logs when something is plugged into or removed from the USB-C connector.
  *
  * Logged from:
- *  Vendor USB HAL.
+ *  UsbService
  */
 message UsbConnectorStateChanged {
     enum State {
-      DISCONNECTED = 0;
-      CONNECTED = 1;
+        STATE_DISCONNECTED = 0;
+        STATE_CONNECTED = 1;
     }
     optional State state = 1;
+    optional string id = 2;
+    // Last active session in ms.
+    // 0 when the port is in connected state.
+    optional int64 last_connect_duration_millis = 3;
 }
 
 /**
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index f25520b..1f22a6a 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -432,6 +432,26 @@
     return false;
 }
 
+bool ValueMetricProducer::hitFullBucketGuardRailLocked(const MetricDimensionKey& newKey) {
+    // ===========GuardRail==============
+    // 1. Report the tuple count if the tuple count > soft limit
+    if (mCurrentFullBucket.find(newKey) != mCurrentFullBucket.end()) {
+        return false;
+    }
+    if (mCurrentFullBucket.size() > mDimensionSoftLimit - 1) {
+        size_t newTupleCount = mCurrentFullBucket.size() + 1;
+        // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
+        if (newTupleCount > mDimensionHardLimit) {
+            ALOGE("ValueMetric %lld dropping data for full bucket dimension key %s",
+                  (long long)mMetricId,
+                  newKey.toString().c_str());
+            return true;
+        }
+    }
+
+    return false;
+}
+
 bool getDoubleOrLong(const LogEvent& event, const Matcher& matcher, Value& ret) {
     for (const FieldValue& value : event.getValues()) {
         if (value.mField.matches(matcher)) {
@@ -496,6 +516,7 @@
             VLOG("Failed to get value %d from event %s", i, event.ToString().c_str());
             return;
         }
+        interval.seenNewData = true;
 
         if (mUseDiff) {
             if (!interval.hasBase) {
@@ -648,6 +669,9 @@
         // Accumulate partial buckets with current value and then send to anomaly tracker.
         if (mCurrentFullBucket.size() > 0) {
             for (const auto& slice : mCurrentSlicedBucket) {
+                if (hitFullBucketGuardRailLocked(slice.first)) {
+                    continue;
+                }
                 // TODO: fix this when anomaly can accept double values
                 mCurrentFullBucket[slice.first] += slice.second[0].value.long_value;
             }
@@ -679,11 +703,21 @@
         }
     }
 
-    // Reset counters
-    for (auto& slice : mCurrentSlicedBucket) {
-        for (auto& interval : slice.second) {
+    for (auto it = mCurrentSlicedBucket.begin(); it != mCurrentSlicedBucket.end();) {
+        bool obsolete = true;
+        for (auto& interval : it->second) {
             interval.hasValue = false;
             interval.sampleSize = 0;
+            if (interval.seenNewData) {
+                obsolete = false;
+            }
+            interval.seenNewData = false;
+        }
+
+        if (obsolete) {
+            it = mCurrentSlicedBucket.erase(it);
+        } else {
+            it++;
         }
     }
 }
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index 36ae214..4991af4 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -128,7 +128,9 @@
         int sampleSize;
         // If this dimension has any non-tainted value. If not, don't report the
         // dimension.
-        bool hasValue;
+        bool hasValue = false;
+        // Whether new data is seen in the bucket.
+        bool seenNewData = false;
     } Interval;
 
     std::unordered_map<MetricDimensionKey, std::vector<Interval>> mCurrentSlicedBucket;
@@ -146,6 +148,8 @@
     // Util function to check whether the specified dimension hits the guardrail.
     bool hitGuardRailLocked(const MetricDimensionKey& newKey);
 
+    bool hitFullBucketGuardRailLocked(const MetricDimensionKey& newKey);
+
     void pullAndMatchEventsLocked(const int64_t timestampNs);
 
     // Reset diff base and mHasGlobalBase
@@ -202,6 +206,7 @@
     FRIEND_TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput);
     FRIEND_TEST(ValueMetricProducerTest, TestUseZeroDefaultBase);
     FRIEND_TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures);
+    FRIEND_TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index 1bd34f5..5524503 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -1469,7 +1469,7 @@
 }
 
 /*
- * Tests pulled atoms with no conditions
+ * Tests zero default base.
  */
 TEST(ValueMetricProducerTest, TestUseZeroDefaultBase) {
     ValueMetric metric;
@@ -1554,7 +1554,7 @@
 }
 
 /*
- * Tests pulled atoms with no conditions
+ * Tests using zero default base with failed pull.
  */
 TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures) {
     ValueMetric metric;
@@ -1681,6 +1681,129 @@
     EXPECT_EQ(2UL, valueProducer.mPastBuckets.size());
 }
 
+/*
+ * Tests trim unused dimension key if no new data is seen in an entire bucket.
+ */
+TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) {
+    ValueMetric metric;
+    metric.set_id(metricId);
+    metric.set_bucket(ONE_MINUTE);
+    metric.mutable_value_field()->set_field(tagId);
+    metric.mutable_value_field()->add_child()->set_field(2);
+    metric.mutable_dimensions_in_what()->set_field(tagId);
+    metric.mutable_dimensions_in_what()->add_child()->set_field(1);
+
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard =
+            new EventMatcherWizard({new SimpleLogMatchingTracker(
+                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
+    EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+            .WillOnce(Invoke([](int tagId, int64_t timeNs,
+                                vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
+                event->write(1);
+                event->write(3);
+                event->init();
+                data->push_back(event);
+                return true;
+            }));
+
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+                                      logEventMatcherIndex, eventMatcherWizard, tagId,
+                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    auto iter = valueProducer.mCurrentSlicedBucket.begin();
+    auto& interval1 = iter->second[0];
+    EXPECT_EQ(1, iter->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
+    EXPECT_EQ(true, interval1.hasBase);
+    EXPECT_EQ(3, interval1.base.long_value);
+    EXPECT_EQ(false, interval1.hasValue);
+    EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+    vector<shared_ptr<LogEvent>> allData;
+
+    allData.clear();
+    shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
+    event1->write(2);
+    event1->write(4);
+    event1->init();
+    shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
+    event2->write(1);
+    event2->write(11);
+    event2->init();
+    allData.push_back(event1);
+    allData.push_back(event2);
+
+    valueProducer.onDataPulled(allData);
+    EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
+    EXPECT_EQ(true, interval1.hasBase);
+    EXPECT_EQ(11, interval1.base.long_value);
+    EXPECT_EQ(true, interval1.hasValue);
+    EXPECT_EQ(8, interval1.value.long_value);
+    EXPECT_TRUE(interval1.seenNewData);
+
+    auto it = valueProducer.mCurrentSlicedBucket.begin();
+    for (; it != valueProducer.mCurrentSlicedBucket.end(); it++) {
+        if (it != iter) {
+            break;
+        }
+    }
+    EXPECT_TRUE(it != iter);
+    auto& interval2 = it->second[0];
+    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
+    EXPECT_EQ(true, interval2.hasBase);
+    EXPECT_EQ(4, interval2.base.long_value);
+    EXPECT_EQ(false, interval2.hasValue);
+    EXPECT_TRUE(interval2.seenNewData);
+    EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+
+    // next pull somehow did not happen, skip to end of bucket 3
+    allData.clear();
+    event1 = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
+    event1->write(2);
+    event1->write(5);
+    event1->init();
+    allData.push_back(event1);
+    valueProducer.onDataPulled(allData);
+
+    EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
+
+    EXPECT_EQ(false, interval1.hasBase);
+    EXPECT_EQ(false, interval1.hasValue);
+    EXPECT_EQ(8, interval1.value.long_value);
+    // on probation now
+    EXPECT_FALSE(interval1.seenNewData);
+
+    EXPECT_EQ(true, interval2.hasBase);
+    EXPECT_EQ(5, interval2.base.long_value);
+    EXPECT_EQ(false, interval2.hasValue);
+    // back to good status
+    EXPECT_TRUE(interval2.seenNewData);
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+
+    allData.clear();
+    event1 = make_shared<LogEvent>(tagId, bucket5StartTimeNs + 1);
+    event1->write(2);
+    event1->write(13);
+    event1->init();
+    allData.push_back(event1);
+    valueProducer.onDataPulled(allData);
+
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    EXPECT_EQ(true, interval2.hasBase);
+    EXPECT_EQ(13, interval2.base.long_value);
+    EXPECT_EQ(true, interval2.hasValue);
+    EXPECT_EQ(8, interval2.value.long_value);
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+}
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/telecom/src/com/android/commands/telecom/Telecom.java b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
index f3bf6e7..a39f5e3 100644
--- a/cmds/telecom/src/com/android/commands/telecom/Telecom.java
+++ b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
@@ -46,6 +46,7 @@
     private static final String COMMAND_SET_PHONE_ACCOUNT_DISABLED = "set-phone-account-disabled";
     private static final String COMMAND_REGISTER_PHONE_ACCOUNT = "register-phone-account";
     private static final String COMMAND_REGISTER_SIM_PHONE_ACCOUNT = "register-sim-phone-account";
+    private static final String COMMAND_SET_TEST_CALL_REDIRECTION_APP = "set-test-call-redirection-app";
     private static final String COMMAND_SET_TEST_CALL_SCREENING_APP = "set-test-call-screening-app";
     private static final String COMMAND_ADD_OR_REMOVE_CALL_COMPANION_APP =
             "add-or-remove-call-companion-app";
@@ -68,6 +69,7 @@
                 "usage: telecom set-phone-account-enabled <COMPONENT> <ID> <USER_SN>\n" +
                 "usage: telecom set-phone-account-disabled <COMPONENT> <ID> <USER_SN>\n" +
                 "usage: telecom register-phone-account <COMPONENT> <ID> <USER_SN> <LABEL>\n" +
+                "usage: telecom set-test-call-redirection-app <PACKAGE>\n" +
                 "usage: telecom set-test-call-screening-app <PACKAGE>\n" +
                 "usage: telecom set-test-auto-mode-app <PACKAGE>\n" +
                 "usage: telecom add-or-remove-call-companion-app <PACKAGE> <1/0>\n" +
@@ -120,6 +122,9 @@
             case COMMAND_REGISTER_PHONE_ACCOUNT:
                 runRegisterPhoneAccount();
                 break;
+            case COMMAND_SET_TEST_CALL_REDIRECTION_APP:
+                runSetTestCallRedirectionApp();
+                break;
             case COMMAND_SET_TEST_CALL_SCREENING_APP:
                 runSetTestCallScreeningApp();
                 break;
@@ -189,6 +194,11 @@
         System.out.println("Success - " + handle + " registered.");
     }
 
+    private void runSetTestCallRedirectionApp() throws RemoteException {
+        final String packageName = nextArg();
+        mTelecomService.setTestDefaultCallRedirectionApp(packageName);
+    }
+
     private void runSetTestCallScreeningApp() throws RemoteException {
         final String packageName = nextArg();
         mTelecomService.setTestDefaultCallScreeningApp(packageName);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 61b9d55..5e445d14 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -6755,8 +6755,8 @@
                 case "--autofill":
                     dumpAutofillManager(prefix, writer);
                     return;
-                case "--intelligence":
-                    dumpIntelligenceManager(prefix, writer);
+                case "--contentcapture":
+                    dumpContentCaptureManager(prefix, writer);
                     return;
             }
         }
@@ -6788,7 +6788,7 @@
         mHandler.getLooper().dump(new PrintWriterPrinter(writer), prefix);
 
         dumpAutofillManager(prefix, writer);
-        dumpIntelligenceManager(prefix, writer);
+        dumpContentCaptureManager(prefix, writer);
 
         ResourcesManager.getInstance().dump(prefix, writer);
     }
@@ -6804,12 +6804,12 @@
         }
     }
 
-    void dumpIntelligenceManager(String prefix, PrintWriter writer) {
-        final ContentCaptureManager im = getContentCaptureManager();
-        if (im != null) {
-            im.dump(prefix, writer);
+    void dumpContentCaptureManager(String prefix, PrintWriter writer) {
+        final ContentCaptureManager cm = getContentCaptureManager();
+        if (cm != null) {
+            cm.dump(prefix, writer);
         } else {
-            writer.print(prefix); writer.println("No IntelligenceManager");
+            writer.print(prefix); writer.println("No ContentCaptureManager");
         }
     }
 
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 8e54961..81eac5a 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -10239,4 +10239,73 @@
         }
         return Collections.emptySet();
     }
+
+    /**
+     * Returns whether the device is being used as a managed kiosk, as defined in the CDD. As of
+     * this release, these requirements are as follows:
+     * <ul>
+     *     <li>The device is in Lock Task (therefore there is also a Device Owner app on the
+     *     device)</li>
+     *     <li>The Lock Task feature {@link DevicePolicyManager#LOCK_TASK_FEATURE_SYSTEM_INFO} is
+     *     not enabled, so the system info in the status bar is not visible</li>
+     *     <li>The device does not have a secure lock screen (e.g. it has no lock screen or has
+     *     swipe-to-unlock)</li>
+     *     <li>The device is not in the middle of an ephemeral user session</li>
+     * </ul>
+     *
+     * <p>Publicly-accessible dedicated devices don't have the same privacy model as
+     * personally-used devices. In particular, user consent popups don't make sense as a barrier to
+     * accessing persistent data on these devices since the user giving consent and the user whose
+     * data is on the device are unlikely to be the same. These consent popups prevent the true
+     * remote management of these devices.
+     *
+     * <p>This condition is not sufficient to cover APIs that would access data that only lives for
+     * the duration of the user's session, since the user has an expectation of privacy in these
+     * conditions that more closely resembles use of a personal device. In those cases, see {@link
+     * #isUnattendedManagedKiosk()}.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
+    public boolean isManagedKiosk() {
+        throwIfParentInstance("isManagedKiosk");
+        if (mService != null) {
+            try {
+                return mService.isManagedKiosk();
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns whether the device is being used as an unattended managed kiosk, as defined in the
+     * CDD. As of this release, these requirements are as follows:
+     * <ul>
+     *     <li>The device is being used as a managed kiosk, as defined in the CDD and verified at
+     *     {@link #isManagedKiosk()}</li>
+     *     <li>The device has not received user input for at least 30 minutes</li>
+     * </ul>
+     *
+     * <p>See {@link #isManagedKiosk()} for context. This is a stronger requirement that also
+     * ensures that the device hasn't been interacted with recently, making it an appropriate check
+     * for privacy-sensitive APIs that wouldn't be appropriate during an active user session.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
+    public boolean isUnattendedManagedKiosk() {
+        throwIfParentInstance("isUnattendedManagedKiosk");
+        if (mService != null) {
+            try {
+                return mService.isUnattendedManagedKiosk();
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+        return false;
+    }
 }
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 1148685..1ff4146 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -428,4 +428,7 @@
     List<String> getCrossProfileCalendarPackages(in ComponentName admin);
     boolean isPackageAllowedToAccessCalendarForUser(String packageName, int userHandle);
     List<String> getCrossProfileCalendarPackagesForUser(int userHandle);
+
+    boolean isManagedKiosk();
+    boolean isUnattendedManagedKiosk();
 }
diff --git a/core/java/android/app/backup/IBackupManager.aidl b/core/java/android/app/backup/IBackupManager.aidl
index 3e20748..0afb98f 100644
--- a/core/java/android/app/backup/IBackupManager.aidl
+++ b/core/java/android/app/backup/IBackupManager.aidl
@@ -91,6 +91,15 @@
      * at some point in the future.
      *
      * <p>Callers must hold the android.permission.BACKUP permission to use this method.
+     * If {@code userId} is different from the calling user id, then the caller must hold the
+     * android.permission.INTERACT_ACROSS_USERS_FULL permission.
+     *
+     * @param userId User id for which backup service should be enabled/disabled.
+     */
+    void setBackupEnabledForUser(int userId, boolean isEnabled);
+
+    /**
+     * {@link android.app.backup.IBackupManager.setBackupEnabledForUser} for the calling user id.
      */
     void setBackupEnabled(boolean isEnabled);
 
@@ -120,6 +129,15 @@
      * Report whether the backup mechanism is currently enabled.
      *
      * <p>Callers must hold the android.permission.BACKUP permission to use this method.
+     * If {@code userId} is different from the calling user id, then the caller must hold the
+     * android.permission.INTERACT_ACROSS_USERS_FULL permission.
+     *
+     * @param userId User id for which the backup service status should be reported.
+     */
+    boolean isBackupEnabledForUser(int userId);
+
+    /**
+     * {@link android.app.backup.IBackupManager.isBackupEnabledForUser} for the calling user id.
      */
     boolean isBackupEnabled();
 
@@ -149,6 +167,15 @@
      * method.
      *
      * <p>Callers must hold the android.permission.BACKUP permission to use this method.
+     * If {@code userId} is different from the calling user id, then the caller must hold the
+     * android.permission.INTERACT_ACROSS_USERS_FULL permission.
+     *
+     * @param userId User id for which an immediate backup should be scheduled.
+     */
+    void backupNowForUser(int userId);
+
+    /**
+     * {@link android.app.backup.IBackupManager.backupNowForUser} for the calling user id.
      */
     void backupNow();
 
@@ -432,6 +459,12 @@
      * <p>If this method returns zero (meaning success), the OS will attempt to backup all provided
      * packages using the remote transport.
      *
+     * <p>Callers must hold the android.permission.BACKUP permission to use this method.
+     * If {@code userId} is different from the calling user id, then the caller must hold the
+     * android.permission.INTERACT_ACROSS_USERS_FULL permission.
+     *
+     * @param userId User id for which an immediate backup should be requested.
+
      * @param observer The {@link BackupObserver} to receive callbacks during the backup
      * operation.
      *
@@ -442,12 +475,29 @@
      *
      * @return Zero on success; nonzero on error.
      */
+    int requestBackupForUser(int userId, in String[] packages, IBackupObserver observer,
+        IBackupManagerMonitor monitor, int flags);
+
+    /**
+     * {@link android.app.backup.IBackupManager.requestBackupForUser} for the calling user id.
+     */
     int requestBackup(in String[] packages, IBackupObserver observer, IBackupManagerMonitor monitor,
         int flags);
 
     /**
      * Cancel all running backups. After this call returns, no currently running backups will
      * interact with the selected transport.
+     *
+     * <p>Callers must hold the android.permission.BACKUP permission to use this method.
+     * If {@code userId} is different from the calling user id, then the caller must hold the
+     * android.permission.INTERACT_ACROSS_USERS_FULL permission.
+     *
+     * @param userId User id for which backups should be cancelled.
+     */
+    void cancelBackupsForUser(int userId);
+
+    /**
+     * {@link android.app.backup.IBackupManager.cancelBackups} for the calling user id.
      */
     void cancelBackups();
 }
diff --git a/core/java/android/app/role/IOnRoleHoldersChangedListener.aidl b/core/java/android/app/role/IOnRoleHoldersChangedListener.aidl
new file mode 100644
index 0000000..6cf961f
--- /dev/null
+++ b/core/java/android/app/role/IOnRoleHoldersChangedListener.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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.role;
+
+/**
+ * @hide
+ */
+oneway interface IOnRoleHoldersChangedListener {
+
+    void onRoleHoldersChanged(String roleName, int userId);
+}
diff --git a/core/java/android/app/role/IRoleManager.aidl b/core/java/android/app/role/IRoleManager.aidl
index 3ca8ec0..4ce0f31 100644
--- a/core/java/android/app/role/IRoleManager.aidl
+++ b/core/java/android/app/role/IRoleManager.aidl
@@ -16,6 +16,7 @@
 
 package android.app.role;
 
+import android.app.role.IOnRoleHoldersChangedListener;
 import android.app.role.IRoleManagerCallback;
 
 /**
@@ -37,6 +38,11 @@
 
     void clearRoleHoldersAsUser(in String roleName, int userId, in IRoleManagerCallback callback);
 
+    void addOnRoleHoldersChangedListenerAsUser(IOnRoleHoldersChangedListener listener, int userId);
+
+    void removeOnRoleHoldersChangedListenerAsUser(IOnRoleHoldersChangedListener listener,
+            int userId);
+
     void setRoleNamesFromController(in List<String> roleNames);
 
     boolean addRoleHolderFromController(in String roleName, in String packageName);
diff --git a/core/java/android/app/role/OnRoleHoldersChangedListener.java b/core/java/android/app/role/OnRoleHoldersChangedListener.java
new file mode 100644
index 0000000..5958deb
--- /dev/null
+++ b/core/java/android/app/role/OnRoleHoldersChangedListener.java
@@ -0,0 +1,38 @@
+/*
+ * 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.role;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.UserHandle;
+
+/**
+ * Listener for role holder changes.
+ *
+ * @hide
+ */
+@SystemApi
+public interface OnRoleHoldersChangedListener {
+
+    /**
+     * Called when the holders of roles are changed.
+     *
+     * @param roleName the name of the role whose holders are changed
+     * @param user the user for this role holder change
+     */
+    void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user);
+}
diff --git a/core/java/android/app/role/RoleManager.java b/core/java/android/app/role/RoleManager.java
index f3b2153..5d101ab 100644
--- a/core/java/android/app/role/RoleManager.java
+++ b/core/java/android/app/role/RoleManager.java
@@ -23,6 +23,7 @@
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
+import android.annotation.UserIdInt;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Binder;
@@ -30,8 +31,12 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.util.ArrayMap;
+import android.util.SparseArray;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.Preconditions;
+import com.android.internal.util.function.pooled.PooledLambda;
 
 import java.util.List;
 import java.util.concurrent.Executor;
@@ -125,6 +130,13 @@
     @NonNull
     private final IRoleManager mService;
 
+    @GuardedBy("mListenersLock")
+    @NonNull
+    private final SparseArray<ArrayMap<OnRoleHoldersChangedListener,
+            OnRoleHoldersChangedListenerDelegate>> mListeners = new SparseArray<>();
+    @NonNull
+    private final Object mListenersLock = new Object();
+
     /**
      * @hide
      */
@@ -146,8 +158,6 @@
      * @param roleName the name of requested role
      *
      * @return the {@code Intent} to prompt user to grant the role
-     *
-     * @throws IllegalArgumentException if {@code role} is {@code null} or empty
      */
     @NonNull
     public Intent createRequestRoleIntent(@NonNull String roleName) {
@@ -164,8 +174,6 @@
      * @param roleName the name of role to checking for
      *
      * @return whether the role is available in the system
-     *
-     * @throws IllegalArgumentException if the role name is {@code null} or empty
      */
     public boolean isRoleAvailable(@NonNull String roleName) {
         Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
@@ -182,8 +190,6 @@
      * @param roleName the name of the role to check for
      *
      * @return whether the calling application is holding the role
-     *
-     * @throws IllegalArgumentException if the role name is {@code null} or empty.
      */
     public boolean isRoleHeld(@NonNull String roleName) {
         Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
@@ -204,8 +210,6 @@
      *
      * @return a list of package names of the role holders, or an empty list if none.
      *
-     * @throws IllegalArgumentException if the role name is {@code null} or empty.
-     *
      * @see #getRoleHoldersAsUser(String, UserHandle)
      *
      * @hide
@@ -230,8 +234,6 @@
      *
      * @return a list of package names of the role holders, or an empty list if none.
      *
-     * @throws IllegalArgumentException if the role name is {@code null} or empty.
-     *
      * @see #addRoleHolderAsUser(String, String, UserHandle, Executor, RoleManagerCallback)
      * @see #removeRoleHolderAsUser(String, String, UserHandle, Executor, RoleManagerCallback)
      * @see #clearRoleHoldersAsUser(String, UserHandle, Executor, RoleManagerCallback)
@@ -266,8 +268,6 @@
      * @param executor the {@code Executor} to run the callback on.
      * @param callback the callback for whether this call is successful
      *
-     * @throws IllegalArgumentException if the role name or package name is {@code null} or empty.
-     *
      * @see #getRoleHoldersAsUser(String, UserHandle)
      * @see #removeRoleHolderAsUser(String, String, UserHandle, Executor, RoleManagerCallback)
      * @see #clearRoleHoldersAsUser(String, UserHandle, Executor, RoleManagerCallback)
@@ -306,8 +306,6 @@
      * @param executor the {@code Executor} to run the callback on.
      * @param callback the callback for whether this call is successful
      *
-     * @throws IllegalArgumentException if the role name or package name is {@code null} or empty.
-     *
      * @see #getRoleHoldersAsUser(String, UserHandle)
      * @see #addRoleHolderAsUser(String, String, UserHandle, Executor, RoleManagerCallback)
      * @see #clearRoleHoldersAsUser(String, UserHandle, Executor, RoleManagerCallback)
@@ -345,8 +343,6 @@
      * @param executor the {@code Executor} to run the callback on.
      * @param callback the callback for whether this call is successful
      *
-     * @throws IllegalArgumentException if the role name is {@code null} or empty.
-     *
      * @see #getRoleHoldersAsUser(String, UserHandle)
      * @see #addRoleHolderAsUser(String, String, UserHandle, Executor, RoleManagerCallback)
      * @see #removeRoleHolderAsUser(String, String, UserHandle, Executor, RoleManagerCallback)
@@ -371,6 +367,96 @@
     }
 
     /**
+     * Add a listener to observe role holder changes
+     * <p>
+     * <strong>Note:</strong> Using this API requires holding
+     * {@code android.permission.OBSERVE_ROLE_HOLDERS} and if the user id is not the current user
+     * {@code android.permission.INTERACT_ACROSS_USERS_FULL}.
+     *
+     * @param executor the {@code Executor} to call the listener on.
+     * @param listener the listener to be added
+     * @param user the user to add the listener for
+     *
+     * @see #removeOnRoleHoldersChangedListenerAsUser(OnRoleHoldersChangedListener, UserHandle)
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS)
+    @SystemApi
+    public void addOnRoleHoldersChangedListenerAsUser(@CallbackExecutor @NonNull Executor executor,
+            @NonNull OnRoleHoldersChangedListener listener, @NonNull UserHandle user) {
+        Preconditions.checkNotNull(executor, "executor cannot be null");
+        Preconditions.checkNotNull(listener, "listener cannot be null");
+        Preconditions.checkNotNull(user, "user cannot be null");
+        int userId = user.getIdentifier();
+        synchronized (mListenersLock) {
+            ArrayMap<OnRoleHoldersChangedListener, OnRoleHoldersChangedListenerDelegate> listeners =
+                    mListeners.get(userId);
+            if (listeners == null) {
+                listeners = new ArrayMap<>();
+                mListeners.put(userId, listeners);
+            } else {
+                if (listeners.containsKey(listener)) {
+                    return;
+                }
+            }
+            OnRoleHoldersChangedListenerDelegate listenerDelegate =
+                    new OnRoleHoldersChangedListenerDelegate(executor, listener);
+            try {
+                mService.addOnRoleHoldersChangedListenerAsUser(listenerDelegate, userId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+            listeners.put(listener, listenerDelegate);
+        }
+    }
+
+    /**
+     * Remove a listener observing role holder changes
+     * <p>
+     * <strong>Note:</strong> Using this API requires holding
+     * {@code android.permission.OBSERVE_ROLE_HOLDERS} and if the user id is not the current user
+     * {@code android.permission.INTERACT_ACROSS_USERS_FULL}.
+     *
+     * @param listener the listener to be removed
+     * @param user the user to remove the listener for
+     *
+     * @see #addOnRoleHoldersChangedListenerAsUser(Executor, OnRoleHoldersChangedListener,
+     *                                             UserHandle)
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS)
+    @SystemApi
+    public void removeOnRoleHoldersChangedListenerAsUser(
+            @NonNull OnRoleHoldersChangedListener listener, @NonNull UserHandle user) {
+        Preconditions.checkNotNull(listener, "listener cannot be null");
+        Preconditions.checkNotNull(user, "user cannot be null");
+        int userId = user.getIdentifier();
+        synchronized (mListenersLock) {
+            ArrayMap<OnRoleHoldersChangedListener, OnRoleHoldersChangedListenerDelegate> listeners =
+                    mListeners.get(userId);
+            if (listeners == null) {
+                return;
+            }
+            OnRoleHoldersChangedListenerDelegate listenerDelegate = listeners.get(listener);
+            if (listenerDelegate == null) {
+                return;
+            }
+            try {
+                mService.removeOnRoleHoldersChangedListenerAsUser(listenerDelegate,
+                        user.getIdentifier());
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+            listeners.remove(listener);
+            if (listeners.isEmpty()) {
+                mListeners.remove(userId);
+            }
+        }
+    }
+
+    /**
      * Set the names of all the available roles. Should only be called from
      * {@link android.rolecontrollerservice.RoleControllerService}.
      * <p>
@@ -379,8 +465,6 @@
      *
      * @param roleNames the names of all the available roles
      *
-     * @throws IllegalArgumentException if the list of role names is {@code null}.
-     *
      * @hide
      */
     @RequiresPermission(PERMISSION_MANAGE_ROLES_FROM_CONTROLLER)
@@ -408,8 +492,6 @@
      * @return whether the operation was successful, and will also be {@code true} if a matching
      *         role holder is already found.
      *
-     * @throws IllegalArgumentException if the role name or package name is {@code null} or empty.
-     *
      * @see #getRoleHolders(String)
      * @see #removeRoleHolderFromController(String, String)
      *
@@ -442,8 +524,6 @@
      * @return whether the operation was successful, and will also be {@code true} if no matching
      *         role holder was found to remove.
      *
-     * @throws IllegalArgumentException if the role name or package name is {@code null} or empty.
-     *
      * @see #getRoleHolders(String)
      * @see #addRoleHolderFromController(String, String)
      *
@@ -495,4 +575,31 @@
             }
         }
     }
+
+    private static class OnRoleHoldersChangedListenerDelegate
+            extends IOnRoleHoldersChangedListener.Stub {
+
+        @NonNull
+        private final Executor mExecutor;
+        @NonNull
+        private final OnRoleHoldersChangedListener mListener;
+
+        OnRoleHoldersChangedListenerDelegate(@NonNull Executor executor,
+                @NonNull OnRoleHoldersChangedListener listener) {
+            mExecutor = executor;
+            mListener = listener;
+        }
+
+        @Override
+        public void onRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId) {
+            long token = Binder.clearCallingIdentity();
+            try {
+                mExecutor.execute(PooledLambda.obtainRunnable(
+                        OnRoleHoldersChangedListener::onRoleHoldersChanged, mListener, roleName,
+                        UserHandle.of(userId)));
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+    }
 }
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 0150f6a..da39b63 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1399,6 +1399,16 @@
     public static final int DELETE_DONT_KILL_APP = 0x00000008;
 
     /**
+     * Flag parameter for {@link #deletePackage} to indicate that any
+     * contributed media should also be deleted during this uninstall. The
+     * meaning of "contributed" means it won't automatically be deleted when the
+     * app is uninstalled.
+     *
+     * @hide
+     */
+    public static final int DELETE_CONTRIBUTED_MEDIA = 0x00000010;
+
+    /**
      * Flag parameter for {@link #deletePackage} to indicate that package deletion
      * should be chatty.
      *
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 43c0222..5db9f50 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -54,6 +54,7 @@
     public static final int PACKAGE_SYSTEM_TEXT_CLASSIFIER = 5;
     public static final int PACKAGE_PERMISSION_CONTROLLER = 6;
     public static final int PACKAGE_WELLBEING = 7;
+    public static final int PACKAGE_DOCUMENTER = 8;
     @IntDef(value = {
         PACKAGE_SYSTEM,
         PACKAGE_SETUP_WIZARD,
@@ -63,6 +64,7 @@
         PACKAGE_SYSTEM_TEXT_CLASSIFIER,
         PACKAGE_PERMISSION_CONTROLLER,
         PACKAGE_WELLBEING,
+        PACKAGE_DOCUMENTER,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface KnownPackage {}
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index 20997d6..bb8c92d 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -192,6 +192,17 @@
     @TestApi
     public static final int PROTECTION_FLAG_WELLBEING = 0x20000;
 
+    /**
+     * Additional flag for {@link #protectionLevel}, corresponding to the
+     * {@code documenter} value of {@link android.R.attr#protectionLevel}.
+     *
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    public static final int PROTECTION_FLAG_DOCUMENTER = 0x40000;
+
+
     /** @hide */
     @IntDef(flag = true, prefix = { "PROTECTION_FLAG_" }, value = {
             PROTECTION_FLAG_PRIVILEGED,
@@ -209,6 +220,7 @@
             PROTECTION_FLAG_VENDOR_PRIVILEGED,
             PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER,
             PROTECTION_FLAG_WELLBEING,
+            PROTECTION_FLAG_DOCUMENTER,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ProtectionFlags {}
@@ -401,6 +413,9 @@
         if ((level & PermissionInfo.PROTECTION_FLAG_WELLBEING) != 0) {
             protLevel += "|wellbeing";
         }
+        if ((level & PermissionInfo.PROTECTION_FLAG_DOCUMENTER) != 0) {
+            protLevel += "|documenter";
+        }
         return protLevel;
     }
 
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 0c44a56..8a5f43d 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -931,7 +931,7 @@
      * Returns a transport-specific information container. The application may cast this
      * container to a concrete sub-class based on its knowledge of the network request. The
      * application should be able to deal with a {@code null} return value or an invalid case,
-     * e.g. use {@code instanceof} operation to verify expected type.
+     * e.g. use {@code instanceof} operator to verify expected type.
      *
      * @return A concrete implementation of the {@link TransportInfo} class or null if not
      * available for the network.
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 2ae796c..d45fa11 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -916,23 +916,49 @@
     private static native long getNativeBBinderHolder();
     private static native long getFinalizer();
 
+    /**
+     * By default, we use the calling uid since we can always trust it.
+     */
+    private static volatile BinderInternal.WorkSourceProvider sWorkSourceProvider =
+            Binder::getCallingUid;
+
+    /**
+     * Sets the work source provider.
+     *
+     * <li>The callback is global. Only fast operations should be done to avoid thread
+     * contentions.
+     * <li>The callback implementation needs to handle synchronization if needed. The methods on the
+     * callback can be called concurrently.
+     * <li>The callback is called on the critical path of the binder transaction so be careful about
+     * performance.
+     * <li>Never execute another binder transaction inside the callback.
+     * @hide
+     */
+    public static void setWorkSourceProvider(BinderInternal.WorkSourceProvider workSourceProvider) {
+        if (workSourceProvider == null) {
+            throw new IllegalArgumentException("workSourceProvider cannot be null");
+        }
+        sWorkSourceProvider = workSourceProvider;
+    }
+
     // Entry point from android_util_Binder.cpp's onTransact
     private boolean execTransact(int code, long dataObj, long replyObj,
             int flags) {
-        final long origWorkSource = ThreadLocalWorkSource.setUid(Binder.getCallingUid());
+        final int workSourceUid = sWorkSourceProvider.resolveWorkSourceUid();
+        final long origWorkSource = ThreadLocalWorkSource.setUid(workSourceUid);
         try {
-            return execTransactInternal(code, dataObj, replyObj, flags);
+            return execTransactInternal(code, dataObj, replyObj, flags, workSourceUid);
         } finally {
             ThreadLocalWorkSource.restore(origWorkSource);
         }
     }
 
     private boolean execTransactInternal(int code, long dataObj, long replyObj,
-            int flags) {
+            int flags, int workSourceUid) {
         // Make sure the observer won't change while processing a transaction.
         final BinderInternal.Observer observer = sObserver;
         final CallSession callSession =
-                observer != null ? observer.callStarted(this, code) : null;
+                observer != null ? observer.callStarted(this, code, workSourceUid) : null;
         Parcel data = Parcel.obtain(dataObj);
         Parcel reply = Parcel.obtain(replyObj);
         // theoretically, we should call transact, which will call onTransact,
@@ -971,10 +997,11 @@
             if (tracingEnabled) {
                 Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
             }
+            if (observer != null) {
+                observer.callEnded(callSession, data.dataSize(), reply.dataSize(), workSourceUid);
+            }
         }
         checkParcel(this, code, reply, "Unreasonably large binder reply buffer");
-        int replySizeBytes = reply.dataSize();
-        int requestSizeBytes = data.dataSize();
         reply.recycle();
         data.recycle();
 
@@ -984,9 +1011,6 @@
         // to the main transaction loop to wait for another incoming transaction.  Either
         // way, strict mode begone!
         StrictMode.clearGatheredViolations();
-        if (observer != null) {
-            observer.callEnded(callSession, requestSizeBytes, replySizeBytes);
-        }
         return res;
     }
 }
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 28ea553..567efa7 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -66,6 +66,9 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.charset.StandardCharsets;
+import java.security.DigestInputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.Objects;
@@ -717,6 +720,57 @@
     }
 
     /**
+     * Compute the digest of the given file using the requested algorithm.
+     *
+     * @param algorithm Any valid algorithm accepted by
+     *            {@link MessageDigest#getInstance(String)}.
+     * @hide
+     */
+    public static byte[] digest(@NonNull File file, @NonNull String algorithm)
+            throws IOException, NoSuchAlgorithmException {
+        try (FileInputStream in = new FileInputStream(file)) {
+            return digest(in, algorithm);
+        }
+    }
+
+    /**
+     * Compute the digest of the given file using the requested algorithm.
+     *
+     * @param algorithm Any valid algorithm accepted by
+     *            {@link MessageDigest#getInstance(String)}.
+     * @hide
+     */
+    public static byte[] digest(@NonNull InputStream in, @NonNull String algorithm)
+            throws IOException, NoSuchAlgorithmException {
+        // TODO: implement kernel optimizations
+        return digestInternalUserspace(in, algorithm);
+    }
+
+    /**
+     * Compute the digest of the given file using the requested algorithm.
+     *
+     * @param algorithm Any valid algorithm accepted by
+     *            {@link MessageDigest#getInstance(String)}.
+     * @hide
+     */
+    public static byte[] digest(FileDescriptor fd, String algorithm)
+            throws IOException, NoSuchAlgorithmException {
+        // TODO: implement kernel optimizations
+        return digestInternalUserspace(new FileInputStream(fd), algorithm);
+    }
+
+    private static byte[] digestInternalUserspace(InputStream in, String algorithm)
+            throws IOException, NoSuchAlgorithmException {
+        final MessageDigest digest = MessageDigest.getInstance(algorithm);
+        try (DigestInputStream digestStream = new DigestInputStream(in, digest)) {
+            final byte[] buffer = new byte[8192];
+            while (digestStream.read(buffer) != -1) {
+            }
+        }
+        return digest.digest();
+    }
+
+    /**
      * Delete older files in a directory until only those matching the given
      * constraints remain.
      *
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index c9c4205..be8cf0e 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -18,7 +18,6 @@
 package android.os;
 
 import android.net.InterfaceConfiguration;
-import android.net.INetd;
 import android.net.INetworkManagementEventObserver;
 import android.net.ITetheringStatsProvider;
 import android.net.Network;
@@ -47,11 +46,6 @@
     void unregisterObserver(INetworkManagementEventObserver obs);
 
     /**
-     * Retrieve an INetd to talk to netd.
-     */
-    INetd getNetdService();
-
-    /**
      * Returns a list of currently known network interfaces
      */
     String[] listInterfaces();
diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java
index 2cb5aee..d55489a 100644
--- a/core/java/android/os/PowerManagerInternal.java
+++ b/core/java/android/os/PowerManagerInternal.java
@@ -200,4 +200,7 @@
      * PowerHint defined in android/hardware/power/<version 1.0 & up>/IPower.h
      */
     public abstract void powerHint(int hintId, int data);
+
+    /** Returns whether there hasn't been a user activity event for the given number of ms. */
+    public abstract boolean wasDeviceIdleFor(long ms);
 }
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index ff77228..a8726e9 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -244,18 +244,34 @@
      * Get string array identifies the type or types of metadata returned
      * using DocumentsContract#getDocumentMetadata.
      *
-     * @see #getDocumentMetadata(ContentResolver, Uri)
+     * @see #getDocumentMetadata(ContentInterface, Uri)
      */
     public static final String METADATA_TYPES = "android:documentMetadataTypes";
 
     /**
      * Get Exif information using DocumentsContract#getDocumentMetadata.
      *
-     * @see #getDocumentMetadata(ContentResolver, Uri)
+     * @see #getDocumentMetadata(ContentInterface, Uri)
      */
     public static final String METADATA_EXIF = "android:documentExif";
 
     /**
+     * Get total count of all documents currently stored under the given
+     * directory tree. Only valid for {@link Document#MIME_TYPE_DIR} documents.
+     *
+     * @see #getDocumentMetadata(ContentInterface, Uri)
+     */
+    public static final String METADATA_TREE_COUNT = "android:metadataTreeCount";
+
+    /**
+     * Get total size of all documents currently stored under the given
+     * directory tree. Only valid for {@link Document#MIME_TYPE_DIR} documents.
+     *
+     * @see #getDocumentMetadata(ContentInterface, Uri)
+     */
+    public static final String METADATA_TREE_SIZE = "android:metadataTreeSize";
+
+    /**
      * Constants related to a document, including {@link Cursor} column names
      * and flags.
      * <p>
@@ -519,7 +535,7 @@
          * using DocumentsContract#getDocumentMetadata
          *
          * @see #COLUMN_FLAGS
-         * @see DocumentsContract#getDocumentMetadata(ContentResolver, Uri)
+         * @see DocumentsContract#getDocumentMetadata(ContentInterface, Uri)
          */
         public static final int FLAG_SUPPORTS_METADATA = 1 << 14;
     }
@@ -1259,6 +1275,12 @@
         }
     }
 
+    /** @removed */
+    public static Bitmap getDocumentThumbnail(ContentResolver content, Uri documentUri, Point size,
+            CancellationSignal signal) throws FileNotFoundException {
+        return getDocumentThumbnail((ContentInterface) content, documentUri, size, signal);
+    }
+
     /**
      * Create a new document with given MIME type and display name.
      *
@@ -1285,6 +1307,11 @@
         }
     }
 
+    /** @removed */
+    public static Uri createDocument(ContentResolver content, Uri parentDocumentUri,
+            String mimeType, String displayName) throws FileNotFoundException {
+        return createDocument((ContentInterface) content, parentDocumentUri, mimeType, displayName);
+    }
 
     /**
      * Test if a document is descendant (child, grandchild, etc) from the given
@@ -1318,6 +1345,12 @@
         }
     }
 
+    /** @removed */
+    public static boolean isChildDocument(ContentResolver content, Uri parentDocumentUri,
+            Uri childDocumentUri) throws FileNotFoundException {
+        return isChildDocument((ContentInterface) content, parentDocumentUri, childDocumentUri);
+    }
+
     /**
      * Change the display name of an existing document.
      * <p>
@@ -1349,6 +1382,12 @@
         }
     }
 
+    /** @removed */
+    public static Uri renameDocument(ContentResolver content, Uri documentUri,
+            String displayName) throws FileNotFoundException {
+        return renameDocument((ContentInterface) content, documentUri, displayName);
+    }
+
     /**
      * Delete the given document.
      *
@@ -1371,6 +1410,12 @@
         }
     }
 
+    /** @removed */
+    public static boolean deleteDocument(ContentResolver content, Uri documentUri)
+            throws FileNotFoundException {
+        return deleteDocument((ContentInterface) content, documentUri);
+    }
+
     /**
      * Copies the given document.
      *
@@ -1396,6 +1441,12 @@
         }
     }
 
+    /** @removed */
+    public static Uri copyDocument(ContentResolver content, Uri sourceDocumentUri,
+            Uri targetParentDocumentUri) throws FileNotFoundException {
+        return copyDocument((ContentInterface) content, sourceDocumentUri, targetParentDocumentUri);
+    }
+
     /**
      * Moves the given document under a new parent.
      *
@@ -1423,6 +1474,13 @@
         }
     }
 
+    /** @removed */
+    public static Uri moveDocument(ContentResolver content, Uri sourceDocumentUri,
+            Uri sourceParentDocumentUri, Uri targetParentDocumentUri) throws FileNotFoundException {
+        return moveDocument((ContentInterface) content, sourceDocumentUri, sourceParentDocumentUri,
+                targetParentDocumentUri);
+    }
+
     /**
      * Removes the given document from a parent directory.
      *
@@ -1450,6 +1508,12 @@
         }
     }
 
+    /** @removed */
+    public static boolean removeDocument(ContentResolver content, Uri documentUri,
+            Uri parentDocumentUri) throws FileNotFoundException {
+        return removeDocument((ContentInterface) content, documentUri, parentDocumentUri);
+    }
+
     /**
      * Ejects the given root. It throws {@link IllegalStateException} when ejection failed.
      *
@@ -1467,6 +1531,11 @@
         }
     }
 
+    /** @removed */
+    public static void ejectRoot(ContentResolver content, Uri rootUri) {
+        ejectRoot((ContentInterface) content, rootUri);
+    }
+
     /**
      * Returns metadata associated with the document. The type of metadata returned
      * is specific to the document type. For example the data returned for an image
@@ -1512,6 +1581,12 @@
         }
     }
 
+    /** @removed */
+    public static Bundle getDocumentMetadata(ContentResolver content, Uri documentUri)
+            throws FileNotFoundException {
+        return getDocumentMetadata((ContentInterface) content, documentUri);
+    }
+
     /**
      * Finds the canonical path from the top of the document tree.
      *
@@ -1543,6 +1618,12 @@
         }
     }
 
+    /** @removed */
+    public static Path findDocumentPath(ContentResolver content, Uri treeUri)
+            throws FileNotFoundException {
+        return findDocumentPath((ContentInterface) content, treeUri);
+    }
+
     /**
      * Creates an intent for obtaining a web link for the specified document.
      *
@@ -1616,6 +1697,12 @@
         }
     }
 
+    /** @removed */
+    public static IntentSender createWebLinkIntent(ContentResolver content, Uri uri,
+            Bundle options) throws FileNotFoundException {
+        return createWebLinkIntent((ContentInterface) content, uri, options);
+    }
+
     /**
      * Open the given image for thumbnail purposes, using any embedded EXIF
      * thumbnail if available, and providing orientation hints from the parent
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 1451165..f38f740 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -23,7 +23,6 @@
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.app.Activity;
@@ -50,6 +49,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.os.storage.StorageManager;
 import android.os.storage.StorageVolume;
 import android.os.storage.VolumeInfo;
@@ -70,6 +70,7 @@
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
+import java.util.regex.Pattern;
 
 /**
  * The Media provider contains meta data for all available media on both internal
@@ -1046,6 +1047,20 @@
                 getContentUri("external");
 
         /**
+         * The MIME type for this table.
+         */
+        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/download";
+
+        /**
+         * Regex that matches paths that needs to be considered part of downloads collection.
+         * @hide
+         */
+        public static final Pattern PATTERN_DOWNLOADS_FILE = Pattern.compile(
+                "(?i)^/storage/[^/]+/(?:[0-9]+/)?(?:Android/sandbox/[^/]+/)?Download/.+");
+        private static final Pattern PATTERN_DOWNLOADS_DIRECTORY = Pattern.compile(
+                "(?i)^/storage/[^/]+/(?:[0-9]+/)?(?:Android/sandbox/[^/]+/)?Download/?");
+
+        /**
          * Get the content:// style URI for the downloads table on the
          * given volume.
          *
@@ -1061,6 +1076,16 @@
         public static Uri getContentUriForPath(@NonNull String path) {
             return getContentUri(getVolumeNameForPath(path));
         }
+
+        /** @hide */
+        public static boolean isDownload(@NonNull String path) {
+            return PATTERN_DOWNLOADS_FILE.matcher(path).matches();
+        }
+
+        /** @hide */
+        public static boolean isDownloadDir(@NonNull String path) {
+            return PATTERN_DOWNLOADS_DIRECTORY.matcher(path).matches();
+        }
     }
 
     private static String getVolumeNameForPath(@NonNull String path) {
@@ -2882,18 +2907,24 @@
      *
      * @hide
      */
-    @SystemApi
     @TestApi
     @RequiresPermission(android.Manifest.permission.CLEAR_APP_USER_DATA)
-    public static @BytesLong long getContributedMediaSize(Context context, String packageName) {
-        try (ContentProviderClient client = context.getContentResolver()
-                .acquireContentProviderClient(AUTHORITY)) {
-            final Bundle in = new Bundle();
-            in.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
-            final Bundle out = client.call(GET_CONTRIBUTED_MEDIA_CALL, null, in);
-            return out.getLong(Intent.EXTRA_INDEX);
-        } catch (RemoteException e) {
-            throw e.rethrowAsRuntimeException();
+    public static @BytesLong long getContributedMediaSize(Context context, String packageName,
+            UserHandle user) throws IOException {
+        final UserManager um = context.getSystemService(UserManager.class);
+        if (um.isUserUnlocked(user) && um.isUserRunning(user)) {
+            try {
+                final ContentResolver resolver = context
+                        .createPackageContextAsUser(packageName, 0, user).getContentResolver();
+                final Bundle in = new Bundle();
+                in.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
+                final Bundle out = resolver.call(AUTHORITY, GET_CONTRIBUTED_MEDIA_CALL, null, in);
+                return out.getLong(Intent.EXTRA_INDEX);
+            } catch (Exception e) {
+                throw new IOException(e);
+            }
+        } else {
+            throw new IOException("User " + user + " must be unlocked and running");
         }
     }
 
@@ -2904,17 +2935,23 @@
      *
      * @hide
      */
-    @SystemApi
     @TestApi
     @RequiresPermission(android.Manifest.permission.CLEAR_APP_USER_DATA)
-    public static void deleteContributedMedia(Context context, String packageName) {
-        try (ContentProviderClient client = context.getContentResolver()
-                .acquireContentProviderClient(AUTHORITY)) {
-            final Bundle in = new Bundle();
-            in.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
-            client.call(DELETE_CONTRIBUTED_MEDIA_CALL, null, in);
-        } catch (RemoteException e) {
-            throw e.rethrowAsRuntimeException();
+    public static void deleteContributedMedia(Context context, String packageName,
+            UserHandle user) throws IOException {
+        final UserManager um = context.getSystemService(UserManager.class);
+        if (um.isUserUnlocked(user) && um.isUserRunning(user)) {
+            try {
+                final ContentResolver resolver = context
+                        .createPackageContextAsUser(packageName, 0, user).getContentResolver();
+                final Bundle in = new Bundle();
+                in.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
+                resolver.call(AUTHORITY, DELETE_CONTRIBUTED_MEDIA_CALL, null, in);
+            } catch (Exception e) {
+                throw new IOException(e);
+            }
+        } else {
+            throw new IOException("User " + user + " must be unlocked and running");
         }
     }
 }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 9380695..93a5950 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -13933,13 +13933,6 @@
         /**
          * Store a name/value pair into the database.
          * <p>
-         * The method takes an optional tag to associate with the setting which can be used to clear
-         * only settings made by your package and associated with this tag by passing the tag to
-         * {@link #resetToDefaults(ContentResolver, String)}. The value of this setting can be
-         * overridden by future calls to this or other put methods, and the tag provided in those
-         * calls, which may be null, will override the tag provided in this call. Any call to a put
-         * method which does not accept a tag will effectively set the tag to null.
-         * </p><p>
          * Also the method takes an argument whether to make the value the default for this setting.
          * If the system already specified a default value, then the one passed in here will
          * <strong>not</strong> be set as the default.
@@ -13948,46 +13941,47 @@
          * @param resolver to access the database with.
          * @param name to store.
          * @param value to associate with the name.
-         * @param tag to associated with the setting.
          * @param makeDefault whether to make the value the default one.
          * @return true if the value was set, false on database errors.
          *
-         * @see #resetToDefaults(ContentResolver, String)
+         * @see #resetToDefaults(ContentResolver, int, String)
          *
          * @hide
          */
         // TODO(b/117663715): require a new write permission restricted to a single source
         @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
-        static boolean putString(@NonNull ContentResolver resolver,
-                @NonNull String name, @Nullable String value, @Nullable String tag,
-                boolean makeDefault) {
-            return sNameValueCache.putStringForUser(resolver, name, value, tag, makeDefault,
+        static boolean putString(@NonNull ContentResolver resolver, @NonNull String name,
+                @Nullable String value, boolean makeDefault) {
+            return sNameValueCache.putStringForUser(resolver, name, value, null, makeDefault,
                     resolver.getUserId());
         }
 
         /**
-         * Reset the settings to their defaults. This would reset <strong>only</strong> settings set
-         * by the caller's package. Passing in the optional tag will reset only settings changed by
-         * your package and associated with this tag.
+         * Reset the values to their defaults.
+         * <p>
+         * The method accepts an optional prefix parameter. If provided, only pairs with a name that
+         * starts with the exact prefix will be reset. Otherwise all will be reset.
          *
          * @param resolver Handle to the content resolver.
-         * @param tag Optional tag which should be associated with the settings to reset.
+         * @param resetMode The reset mode to use.
+         * @param prefix Optionally, to limit which which pairs are reset.
          *
-         * @see #putString(ContentResolver, String, String, String, boolean)
+         * @see #putString(ContentResolver, String, String, boolean)
          *
          * @hide
          */
         // TODO(b/117663715): require a new write permission restricted to a single source
         @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
-        static void resetToDefaults(@NonNull ContentResolver resolver,
-                @Nullable String tag) {
+        static void resetToDefaults(@NonNull ContentResolver resolver, @ResetMode int resetMode,
+                @Nullable String prefix) {
             try {
                 Bundle arg = new Bundle();
                 arg.putInt(CALL_METHOD_USER_KEY, resolver.getUserId());
-                if (tag != null) {
-                    arg.putString(CALL_METHOD_TAG_KEY, tag);
+                arg.putInt(Settings.CALL_METHOD_RESET_MODE_KEY, resetMode);
+                if (prefix != null) {
+                    arg.putString(Settings.CALL_METHOD_PREFIX_KEY, prefix);
                 }
-                arg.putInt(CALL_METHOD_RESET_MODE_KEY, RESET_MODE_PACKAGE_DEFAULTS);
+                arg.putInt(CALL_METHOD_RESET_MODE_KEY, resetMode);
                 IContentProvider cp = sProviderHolder.getProvider(resolver);
                 cp.call(resolver.getPackageName(), sProviderHolder.mUri.getAuthority(),
                         CALL_METHOD_RESET_CONFIG, null, arg);
diff --git a/core/java/android/service/autofill/AutofillFieldClassificationService.java b/core/java/android/service/autofill/AutofillFieldClassificationService.java
index bd3c3d3..2612917 100644
--- a/core/java/android/service/autofill/AutofillFieldClassificationService.java
+++ b/core/java/android/service/autofill/AutofillFieldClassificationService.java
@@ -20,6 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.app.Service;
 import android.content.Intent;
 import android.os.Bundle;
@@ -35,6 +36,7 @@
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 
 /**
  * A service that calculates field classification scores.
@@ -51,6 +53,7 @@
  * {@hide}
  */
 @SystemApi
+@TestApi
 public abstract class AutofillFieldClassificationService extends Service {
 
     private static final String TAG = "AutofillFieldClassificationService";
@@ -75,17 +78,32 @@
     public static final String SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS =
             "android.autofill.field_classification.available_algorithms";
 
+    /**
+     * Field classification algorithm that computes the edit distance between two Strings.
+     *
+     * <p>Service implementation must provide this algorithm.</p>
+     */
+    public static final String REQUIRED_ALGORITHM_EDIT_DISTANCE = "EDIT_DISTANCE";
+
+    /**
+     * Field classification algorithm that computes whether the last four digits between two
+     * Strings match exactly.
+     *
+     * <p>Service implementation must provide this algorithm.</p>
+     */
+    public static final String REQUIRED_ALGORITHM_EXACT_MATCH = "EXACT_MATCH";
 
     /** {@hide} **/
     public static final String EXTRA_SCORES = "scores";
 
     private AutofillFieldClassificationServiceWrapper mWrapper;
 
-    private void getScores(RemoteCallback callback, String algorithmName, Bundle algorithmArgs,
-            List<AutofillValue> actualValues, String[] userDataValues) {
+    private void calculateScores(RemoteCallback callback, List<AutofillValue> actualValues,
+            String[] userDataValues, String[] categoryIds, String defaultAlgorithm,
+            Bundle defaultArgs, Map algorithms, Map args) {
         final Bundle data = new Bundle();
-        final float[][] scores = onGetScores(algorithmName, algorithmArgs, actualValues,
-                Arrays.asList(userDataValues));
+        final float[][] scores = onCalculateScores(actualValues, Arrays.asList(userDataValues),
+                Arrays.asList(categoryIds), defaultAlgorithm, defaultArgs, algorithms, args);
         if (scores != null) {
             data.putParcelable(EXTRA_SCORES, new Scores(scores));
         }
@@ -169,9 +187,12 @@
      * @return the calculated scores of {@code actualValues} x {@code userDataValues}.
      *
      * {@hide}
+     *
+     * @deprecated Use {@link AutofillFieldClassificationService#onCalculateScores} instead.
      */
     @Nullable
     @SystemApi
+    @Deprecated
     public float[][] onGetScores(@Nullable String algorithm,
             @Nullable Bundle algorithmOptions, @NonNull List<AutofillValue> actualValues,
             @NonNull List<String> userDataValues) {
@@ -179,16 +200,98 @@
         return null;
     }
 
+    /**
+     * Calculates field classification scores in a batch.
+     *
+     * <p>A field classification score is a {@code float} representing how well an
+     * {@link AutofillValue} matches a expected value predicted by an autofill service
+     * &mdash;a full match is {@code 1.0} (representing 100%), while a full mismatch is {@code 0.0}.
+     *
+     * <p>The exact score depends on the algorithm used to calculate it&mdash;the service must
+     * provide at least one default algorithm (which is used when the algorithm is not specified
+     * or is invalid), but it could provide more (in which case the algorithm name should be
+     * specified by the caller when calculating the scores).
+     *
+     * <p>For example, if the service provides an algorithm named {@code EXACT_MATCH} that
+     * returns {@code 1.0} if all characters match or {@code 0.0} otherwise, a call to:
+     *
+     * <pre>
+     * HashMap algorithms = new HashMap<>();
+     * algorithms.put("email", "EXACT_MATCH");
+     * algorithms.put("phone", "EXACT_MATCH");
+     *
+     * HashMap args = new HashMap<>();
+     * args.put("email", null);
+     * args.put("phone", null);
+     *
+     * service.onCalculateScores(Arrays.asList(AutofillValue.forText("email1"),
+     * AutofillValue.forText("PHONE1")), Arrays.asList("email1", "phone1"),
+     * Array.asList("email", "phone"), algorithms, args);
+     * </pre>
+     *
+     * <p>Returns:
+     *
+     * <pre>
+     * [
+     *   [1.0, 0.0], // "email1" compared against ["email1", "phone1"]
+     *   [0.0, 0.0]  // "PHONE1" compared against ["email1", "phone1"]
+     * ];
+     * </pre>
+     *
+     * <p>If the same algorithm allows the caller to specify whether the comparisons should be
+     * case sensitive by passing a boolean option named {@code "case_sensitive"}, then a call to:
+     *
+     * <pre>
+     * Bundle algorithmOptions = new Bundle();
+     * algorithmOptions.putBoolean("case_sensitive", false);
+     * args.put("phone", algorithmOptions);
+     *
+     * service.onCalculateScores(Arrays.asList(AutofillValue.forText("email1"),
+     * AutofillValue.forText("PHONE1")), Arrays.asList("email1", "phone1"),
+     * Array.asList("email", "phone"), algorithms, args);
+     * </pre>
+     *
+     * <p>Returns:
+     *
+     * <pre>
+     * [
+     *   [1.0, 0.0], // "email1" compared against ["email1", "phone1"]
+     *   [0.0, 1.0]  // "PHONE1" compared against ["email1", "phone1"]
+     * ];
+     * </pre>
+     *
+     * @param actualValues values entered by the user.
+     * @param userDataValues values predicted from the user data.
+     * @param categoryIds category Ids correspoinding to userDataValues
+     * @param defaultAlgorithm default field classification algorithm
+     * @param algorithms array of field classification algorithms
+     * @return the calculated scores of {@code actualValues} x {@code userDataValues}.
+     *
+     * {@hide}
+     */
+    @Nullable
+    @SystemApi
+    public float[][] onCalculateScores(@NonNull List<AutofillValue> actualValues,
+            @NonNull List<String> userDataValues, @NonNull List<String> categoryIds,
+            @Nullable String defaultAlgorithm, @Nullable Bundle defaultArgs,
+            @Nullable Map algorithms, @Nullable Map args) {
+        Log.e(TAG, "service implementation (" + getClass()
+                + " does not implement onCalculateScore()");
+        return null;
+    }
+
     private final class AutofillFieldClassificationServiceWrapper
             extends IAutofillFieldClassificationService.Stub {
         @Override
-        public void getScores(RemoteCallback callback, String algorithmName, Bundle algorithmArgs,
-                List<AutofillValue> actualValues, String[] userDataValues)
-                        throws RemoteException {
+        public void calculateScores(RemoteCallback callback, List<AutofillValue> actualValues,
+                String[] userDataValues, String[] categoryIds, String defaultAlgorithm,
+                Bundle defaultArgs, Map algorithms, Map args)
+                throws RemoteException {
             mHandler.sendMessage(obtainMessage(
-                    AutofillFieldClassificationService::getScores,
+                    AutofillFieldClassificationService::calculateScores,
                     AutofillFieldClassificationService.this,
-                    callback, algorithmName, algorithmArgs, actualValues, userDataValues));
+                    callback, actualValues, userDataValues, categoryIds, defaultAlgorithm,
+                    defaultArgs, algorithms, args));
         }
     }
 
diff --git a/core/java/android/service/autofill/IAutofillFieldClassificationService.aidl b/core/java/android/service/autofill/IAutofillFieldClassificationService.aidl
index 398557d..2cd24f9 100644
--- a/core/java/android/service/autofill/IAutofillFieldClassificationService.aidl
+++ b/core/java/android/service/autofill/IAutofillFieldClassificationService.aidl
@@ -20,6 +20,7 @@
 import android.os.RemoteCallback;
 import android.view.autofill.AutofillValue;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Service used to calculate match scores for Autofill Field Classification.
@@ -27,6 +28,8 @@
  * @hide
  */
 oneway interface IAutofillFieldClassificationService {
-    void getScores(in RemoteCallback callback, String algorithmName, in Bundle algorithmArgs,
-                   in List<AutofillValue> actualValues, in String[] userDataValues);
+    void calculateScores(in RemoteCallback callback, in List<AutofillValue> actualValues,
+                         in String[] userDataValues, in String[] categoryIds,
+                         in String defaultAlgorithm, in Bundle defaultArgs,
+                         in Map algorithms, in Map args);
 }
diff --git a/core/java/android/service/autofill/UserData.java b/core/java/android/service/autofill/UserData.java
index fccb85b..37f1923 100644
--- a/core/java/android/service/autofill/UserData.java
+++ b/core/java/android/service/autofill/UserData.java
@@ -24,6 +24,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.app.ActivityThread;
 import android.content.ContentResolver;
 import android.os.Bundle;
@@ -32,6 +33,7 @@
 import android.provider.Settings;
 import android.service.autofill.FieldClassification.Match;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
 import android.view.autofill.AutofillManager;
@@ -57,28 +59,57 @@
     private static final int DEFAULT_MAX_VALUE_LENGTH = 100;
 
     private final String mId;
-    private final String mAlgorithm;
-    private final Bundle mAlgorithmArgs;
     private final String[] mCategoryIds;
     private final String[] mValues;
 
+    private final String mDefaultAlgorithm;
+    private final Bundle mDefaultArgs;
+    private final ArrayMap<String, String> mCategoryAlgorithms;
+    private final ArrayMap<String, Bundle> mCategoryArgs;
+
     private UserData(Builder builder) {
         mId = builder.mId;
-        mAlgorithm = builder.mAlgorithm;
-        mAlgorithmArgs = builder.mAlgorithmArgs;
         mCategoryIds = new String[builder.mCategoryIds.size()];
         builder.mCategoryIds.toArray(mCategoryIds);
         mValues = new String[builder.mValues.size()];
         builder.mValues.toArray(mValues);
+        builder.mValues.toArray(mValues);
+
+        mDefaultAlgorithm = builder.mDefaultAlgorithm;
+        mDefaultArgs = builder.mDefaultArgs;
+        mCategoryAlgorithms = builder.mCategoryAlgorithms;
+        mCategoryArgs = builder.mCategoryArgs;
     }
 
     /**
-     * Gets the name of the algorithm that is used to calculate
-     * {@link Match#getScore() match scores}.
+     * Gets the name of the default algorithm that is used to calculate
+     * {@link Match#getScore()} match scores}.
      */
     @Nullable
     public String getFieldClassificationAlgorithm() {
-        return mAlgorithm;
+        return mDefaultAlgorithm;
+    }
+
+    /** @hide */
+    public Bundle getDefaultFieldClassificationArgs() {
+        return mDefaultArgs;
+    }
+
+    /**
+     * Gets the name of the algorithm corresponding to the specific autofill category
+     * that is used to calculate {@link Match#getScore() match scores}
+     *
+     * @param categoryId autofill field category
+     *
+     * @return String name of algorithm, null if none found.
+     */
+    @Nullable
+    public String getFieldClassificationAlgorithmForCategory(@NonNull String categoryId) {
+        Preconditions.checkNotNull(categoryId);
+        if (mCategoryAlgorithms == null || !mCategoryAlgorithms.containsKey(categoryId)) {
+            return null;
+        }
+        return mCategoryAlgorithms.get(categoryId);
     }
 
     /**
@@ -89,11 +120,6 @@
     }
 
     /** @hide */
-    public Bundle getAlgorithmArgs() {
-        return mAlgorithmArgs;
-    }
-
-    /** @hide */
     public String[] getCategoryIds() {
         return mCategoryIds;
     }
@@ -104,11 +130,29 @@
     }
 
     /** @hide */
+    @TestApi
+    public ArrayMap<String, String> getFieldClassificationAlgorithms() {
+        return mCategoryAlgorithms;
+    }
+
+    /** @hide */
+    public ArrayMap<String, Bundle> getFieldClassificationArgs() {
+        return mCategoryArgs;
+    }
+
+    /** @hide */
     public void dump(String prefix, PrintWriter pw) {
         pw.print(prefix); pw.print("id: "); pw.print(mId);
-        pw.print(prefix); pw.print("Algorithm: "); pw.print(mAlgorithm);
-        pw.print(" Args: "); pw.println(mAlgorithmArgs);
-
+        pw.print(prefix); pw.print("Default Algorithm: "); pw.print(mDefaultAlgorithm);
+        pw.print(prefix); pw.print("Default Args"); pw.print(mDefaultArgs);
+        if (mCategoryAlgorithms != null && mCategoryAlgorithms.size() > 0) {
+            pw.print(prefix); pw.print("Algorithms per category: ");
+            for (int i = 0; i < mCategoryAlgorithms.size(); i++) {
+                pw.print(prefix); pw.print(prefix); pw.print(mCategoryAlgorithms.keyAt(i));
+                pw.print(": "); pw.println(Helper.getRedacted(mCategoryAlgorithms.valueAt(i)));
+                pw.print("args="); pw.print(mCategoryArgs.get(mCategoryAlgorithms.keyAt(i)));
+            }
+        }
         // Cannot disclose field ids or values because they could contain PII
         pw.print(prefix); pw.print("Field ids size: "); pw.println(mCategoryIds.length);
         for (int i = 0; i < mCategoryIds.length; i++) {
@@ -139,8 +183,13 @@
         private final String mId;
         private final ArrayList<String> mCategoryIds;
         private final ArrayList<String> mValues;
-        private String mAlgorithm;
-        private Bundle mAlgorithmArgs;
+        private String mDefaultAlgorithm;
+        private Bundle mDefaultArgs;
+
+        // Map of autofill field categories to fleid classification algorithms and args
+        private ArrayMap<String, String> mCategoryAlgorithms;
+        private ArrayMap<String, Bundle> mCategoryArgs;
+
         private boolean mDestroyed;
 
         // Non-persistent array used to limit the number of unique ids.
@@ -148,7 +197,6 @@
         // Non-persistent array used to ignore duplaicated value/category pairs.
         private final ArraySet<String> mUniqueValueCategoryPairs;
 
-
         /**
          * Creates a new builder for the user data used for <a href="#FieldClassification">field
          * classification</a>.
@@ -169,7 +217,7 @@
          * {@link AutofillManager#getUserData()}).
          *
          * @param value value of the user data.
-         * @param categoryId string used to identify the category the value is associated with.
+         * @param categoryId autofill field category.
          *
          * @throws IllegalArgumentException if any of the following occurs:
          * <ul>
@@ -189,13 +237,15 @@
             mCategoryIds = new ArrayList<>(maxUserDataSize);
             mValues = new ArrayList<>(maxUserDataSize);
             mUniqueValueCategoryPairs = new ArraySet<>(maxUserDataSize);
+
             mUniqueCategoryIds = new ArraySet<>(getMaxCategoryCount());
 
             addMapping(value, categoryId);
         }
 
         /**
-         * Sets the algorithm used for <a href="#FieldClassification">field classification</a>.
+         * Sets the default algorithm used for
+         * <a href="#FieldClassification">field classification</a>.
          *
          * <p>The currently available algorithms can be retrieve through
          * {@link AutofillManager#getAvailableFieldClassificationAlgorithms()}.
@@ -212,8 +262,40 @@
         public Builder setFieldClassificationAlgorithm(@Nullable String name,
                 @Nullable Bundle args) {
             throwIfDestroyed();
-            mAlgorithm = name;
-            mAlgorithmArgs = args;
+            mDefaultAlgorithm = name;
+            mDefaultArgs = args;
+            return this;
+        }
+
+        /**
+         * Sets the algorithm used for <a href="#FieldClassification">field classification</a>
+         * for the specified category.
+         *
+         * <p>The currently available algorithms can be retrieved through
+         * {@link AutofillManager#getAvailableFieldClassificationAlgorithms()}.
+         *
+         * <p>If not set, the
+         * {@link AutofillManager#getDefaultFieldClassificationAlgorithm() default algorithm} is
+         * used instead.
+         *
+         * @param categoryId autofill field category.
+         * @param name name of the algorithm or {@code null} to used default.
+         * @param args optional arguments to the algorithm.
+         *
+         * @return this builder
+         */
+        public Builder setFieldClassificationAlgorithmForCategory(@NonNull String categoryId,
+                @Nullable String name, @Nullable Bundle args) {
+            throwIfDestroyed();
+            Preconditions.checkNotNull(categoryId);
+            if (mCategoryAlgorithms == null) {
+                mCategoryAlgorithms = new ArrayMap<>(getMaxCategoryCount());
+            }
+            if (mCategoryArgs == null) {
+                mCategoryArgs = new ArrayMap<>(getMaxCategoryCount());
+            }
+            mCategoryAlgorithms.put(categoryId, name);
+            mCategoryArgs.put(categoryId, args);
             return this;
         }
 
@@ -317,8 +399,7 @@
     public String toString() {
         if (!sDebug) return super.toString();
 
-        final StringBuilder builder = new StringBuilder("UserData: [id=").append(mId)
-                .append(", algorithm=").append(mAlgorithm);
+        final StringBuilder builder = new StringBuilder("UserData: [id=").append(mId);
         // Cannot disclose category ids or values because they could contain PII
         builder.append(", categoryIds=");
         Helper.appendRedacted(builder, mCategoryIds);
@@ -341,8 +422,10 @@
         parcel.writeString(mId);
         parcel.writeStringArray(mCategoryIds);
         parcel.writeStringArray(mValues);
-        parcel.writeString(mAlgorithm);
-        parcel.writeBundle(mAlgorithmArgs);
+        parcel.writeString(mDefaultAlgorithm);
+        parcel.writeBundle(mDefaultArgs);
+        parcel.writeMap(mCategoryAlgorithms);
+        parcel.writeMap(mCategoryArgs);
     }
 
     public static final Parcelable.Creator<UserData> CREATOR =
@@ -355,10 +438,28 @@
             final String id = parcel.readString();
             final String[] categoryIds = parcel.readStringArray();
             final String[] values = parcel.readStringArray();
+            final String defaultAlgorithm = parcel.readString();
+            final Bundle defaultArgs = parcel.readBundle();
+            final ArrayMap<String, String> categoryAlgorithms = new ArrayMap<>();
+            parcel.readMap(categoryAlgorithms, String.class.getClassLoader());
+            final ArrayMap<String, Bundle> categoryArgs = new ArrayMap<>();
+            parcel.readMap(categoryArgs, Bundle.class.getClassLoader());
+
             final Builder builder = new Builder(id, values[0], categoryIds[0])
-                    .setFieldClassificationAlgorithm(parcel.readString(), parcel.readBundle());
+                    .setFieldClassificationAlgorithm(defaultAlgorithm, defaultArgs);
+
             for (int i = 1; i < categoryIds.length; i++) {
-                builder.add(values[i], categoryIds[i]);
+                String categoryId = categoryIds[i];
+                builder.add(values[i], categoryId);
+            }
+
+            final int size = categoryAlgorithms.size();
+            if (size > 0) {
+                for (int i = 0; i < size; i++) {
+                    final String categoryId = categoryAlgorithms.keyAt(i);
+                    builder.setFieldClassificationAlgorithmForCategory(categoryId,
+                            categoryAlgorithms.valueAt(i), categoryArgs.get(categoryId));
+                }
             }
             return builder.build();
         }
diff --git a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
index 68a86f3..9aff281 100644
--- a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
+++ b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
@@ -32,7 +32,6 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.SystemClock;
-import android.service.autofill.augmented.AugmentedAutofillService.AutofillProxy;
 import android.service.autofill.augmented.PresentationParams.SystemPopupPresentationParams;
 import android.util.Log;
 import android.util.Pair;
@@ -172,7 +171,9 @@
             mAutofillProxies.put(sessionId,  proxy);
         } else {
             // TODO(b/111330312): figure out if it's ok to reuse the proxy; add logging
+            // TODO(b/111330312): also make sure to cover scenario on CTS test
             if (DEBUG) Log.d(TAG, "Reusing proxy for session " + sessionId);
+            proxy.update(focusedId, focusedValue);
         }
         // TODO(b/111330312): set cancellation signal
         final CancellationSignal cancellationSignal = null;
@@ -248,8 +249,10 @@
         private final IFillCallback mCallback;
         public final int taskId;
         public final ComponentName componentName;
-        public final AutofillId focusedId;
-        public final AutofillValue focusedValue;
+        @GuardedBy("mLock")
+        private AutofillId mFocusedId;
+        @GuardedBy("mLock")
+        private AutofillValue mFocusedValue;
 
         // Objects used to log metrics
         private final long mRequestTime;
@@ -272,8 +275,8 @@
             mCallback = callback;
             this.taskId = taskId;
             this.componentName = componentName;
-            this.focusedId = focusedId;
-            this.focusedValue = focusedValue;
+            this.mFocusedId = focusedId;
+            this.mFocusedValue = focusedValue;
             this.mRequestTime = requestTime;
             // TODO(b/111330312): linkToDeath
         }
@@ -286,13 +289,13 @@
                 }
                 Rect rect;
                 try {
-                    rect = mClient.getViewCoordinates(focusedId);
+                    rect = mClient.getViewCoordinates(mFocusedId);
                 } catch (RemoteException e) {
-                    Log.w(TAG, "Could not get coordinates for " + focusedId);
+                    Log.w(TAG, "Could not get coordinates for " + mFocusedId);
                     return null;
                 }
                 if (rect == null) {
-                    if (DEBUG) Log.d(TAG, "getViewCoordinates(" + focusedId + ") returned null");
+                    if (DEBUG) Log.d(TAG, "getViewCoordinates(" + mFocusedId + ") returned null");
                     return null;
                 }
                 mSmartSuggestion = new SystemPopupPresentationParams(this, rect);
@@ -325,6 +328,28 @@
             }
         }
 
+        private void update(@NonNull AutofillId focusedId, @NonNull AutofillValue focusedValue) {
+            synchronized (mLock) {
+                // TODO(b/111330312): should we close the popupwindow if the focused id changed?
+                mFocusedId = focusedId;
+                mFocusedValue = focusedValue;
+            }
+        }
+
+        @NonNull
+        public AutofillId getFocusedId() {
+            synchronized (mLock) {
+                return mFocusedId;
+            }
+        }
+
+        @NonNull
+        public AutofillValue getFocusedValue() {
+            synchronized (mLock) {
+                return mFocusedValue;
+            }
+        }
+
         // Used (mostly) for metrics.
         public void report(@ReportEvent int event) {
             switch (event) {
@@ -372,9 +397,9 @@
             pw.print(prefix); pw.print("taskId: "); pw.println(taskId);
             pw.print(prefix); pw.print("component: ");
             pw.println(componentName.flattenToShortString());
-            pw.print(prefix); pw.print("focusedId: "); pw.println(focusedId);
-            if (focusedValue != null) {
-                pw.print(prefix); pw.print("focusedValue: "); pw.println(focusedValue);
+            pw.print(prefix); pw.print("focusedId: "); pw.println(mFocusedId);
+            if (mFocusedValue != null) {
+                pw.print(prefix); pw.print("focusedValue: "); pw.println(mFocusedValue);
             }
             pw.print(prefix); pw.print("client: "); pw.println(mClient);
             final String prefix2 = prefix + "  ";
diff --git a/core/java/android/service/autofill/augmented/FillCallback.java b/core/java/android/service/autofill/augmented/FillCallback.java
index 0546465..620ec59 100644
--- a/core/java/android/service/autofill/augmented/FillCallback.java
+++ b/core/java/android/service/autofill/augmented/FillCallback.java
@@ -15,10 +15,13 @@
  */
 package android.service.autofill.augmented;
 
+import static android.service.autofill.augmented.AugmentedAutofillService.DEBUG;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.service.autofill.augmented.AugmentedAutofillService.AutofillProxy;
+import android.util.Log;
 
 /**
  * Callback used to indicate at {@link FillRequest} has been fulfilled.
@@ -27,6 +30,9 @@
  */
 @SystemApi
 public final class FillCallback {
+
+    private static final String TAG = FillCallback.class.getSimpleName();
+
     private final AutofillProxy mProxy;
 
     FillCallback(@NonNull AutofillProxy proxy) {
@@ -40,7 +46,11 @@
      * could not provide autofill for the request.
      */
     public void onSuccess(@Nullable FillResponse response) {
+        if (DEBUG) Log.d(TAG, "onSuccess(): " + response);
+
         mProxy.report(AutofillProxy.REPORT_EVENT_ON_SUCCESS);
+        if (response == null) return;
+
         final FillWindow fillWindow = response.getFillWindow();
         if (fillWindow != null) {
             fillWindow.show();
diff --git a/core/java/android/service/autofill/augmented/FillRequest.java b/core/java/android/service/autofill/augmented/FillRequest.java
index fd75b15..57d2cc8 100644
--- a/core/java/android/service/autofill/augmented/FillRequest.java
+++ b/core/java/android/service/autofill/augmented/FillRequest.java
@@ -58,7 +58,7 @@
      */
     @NonNull
     public AutofillId getFocusedId() {
-        return mProxy.focusedId;
+        return mProxy.getFocusedId();
     }
 
     /**
@@ -66,7 +66,7 @@
      */
     @NonNull
     public AutofillValue getFocusedValue() {
-        return mProxy.focusedValue;
+        return mProxy.getFocusedValue();
     }
 
     /**
@@ -82,6 +82,6 @@
     @Override
     public String toString() {
         return "FillRequest[act=" + getActivityComponent().flattenToShortString()
-                + ", id=" + mProxy.focusedId + "]";
+                + ", id=" + mProxy.getFocusedId() + "]";
     }
 }
diff --git a/core/java/android/service/autofill/augmented/FillResponse.java b/core/java/android/service/autofill/augmented/FillResponse.java
index 7064b6f..1ecfab4 100644
--- a/core/java/android/service/autofill/augmented/FillResponse.java
+++ b/core/java/android/service/autofill/augmented/FillResponse.java
@@ -102,6 +102,8 @@
         // TODO(b/111330312): add methods to disable app / activity, either here or on manager
     }
 
+    // TODO(b/111330312): implement to String
+
     @Override
     public int describeContents() {
         return 0;
diff --git a/core/java/android/service/notification/Adjustment.java b/core/java/android/service/notification/Adjustment.java
index 518f8ed..de532b7 100644
--- a/core/java/android/service/notification/Adjustment.java
+++ b/core/java/android/service/notification/Adjustment.java
@@ -80,11 +80,18 @@
      * Data type: int, one of importance values e.g.
      * {@link android.app.NotificationManager#IMPORTANCE_MIN}.
      *
-     * If used from
-     * {@link NotificationAssistantService#onNotificationEnqueued(StatusBarNotification)}, it can
-     * block a notification from appearing or silence it. If used from
-     * {@link NotificationAssistantService#adjustNotification(Adjustment)}, it can visually
-     * demote a notification.
+     * <p> If used from
+     * {@link NotificationAssistantService#onNotificationEnqueued(StatusBarNotification)}, and
+     * received before the notification is posted, it can block a notification from appearing or
+     * silence it. Importance adjustments received too late from
+     * {@link NotificationAssistantService#onNotificationEnqueued(StatusBarNotification)} will be
+     * ignored.
+     * </p>
+     * <p>If used from
+     * {@link NotificationAssistantService#adjustNotification(Adjustment)}, it can
+     * visually demote or cancel a notification, but use this with care if they notification was
+     * recently posted because the notification may already have made noise.
+     * </p>
      */
     public static final String KEY_IMPORTANCE = "key_importance";
 
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index ba5340c..fb4f9c0 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -38,9 +38,14 @@
     private final InsetsState mState = new InsetsState();
     private final Rect mFrame = new Rect();
     private final SparseArray<InsetsSourceConsumer> mSourceConsumers = new SparseArray<>();
+    private final ViewRootImpl mViewRoot;
 
     private final SparseArray<InsetsSourceControl> mTmpControlArray = new SparseArray<>();
 
+    public InsetsController(ViewRootImpl viewRoot) {
+        mViewRoot = viewRoot;
+    }
+
     void onFrameChanged(Rect frame) {
         mFrame.set(frame);
     }
@@ -49,8 +54,14 @@
         return mState;
     }
 
-    public void setState(InsetsState state) {
+    boolean onStateChanged(InsetsState state) {
+        if (mState.equals(state)) {
+            return false;
+        }
         mState.set(state);
+        applyLocalVisibilityOverride();
+        mViewRoot.notifyInsetsChanged();
+        return true;
     }
 
     /**
@@ -105,17 +116,28 @@
         }
     }
 
+    private void applyLocalVisibilityOverride() {
+        for (int i = mSourceConsumers.size() - 1; i >= 0; i--) {
+            final InsetsSourceConsumer controller = mSourceConsumers.valueAt(i);
+            controller.applyLocalVisibilityOverride();
+        }
+    }
+
     @VisibleForTesting
     public @NonNull InsetsSourceConsumer getSourceConsumer(@InternalInsetType int type) {
         InsetsSourceConsumer controller = mSourceConsumers.get(type);
         if (controller != null) {
             return controller;
         }
-        controller = new InsetsSourceConsumer(type, mState, Transaction::new);
+        controller = new InsetsSourceConsumer(type, mState, Transaction::new, this);
         mSourceConsumers.put(type, controller);
         return controller;
     }
 
+    void notifyVisibilityChanged() {
+        mViewRoot.notifyInsetsChanged();
+    }
+
     void dump(String prefix, PrintWriter pw) {
         pw.println(prefix); pw.println("InsetsController:");
         mState.dump(prefix + "  ", pw);
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index e74aa8d..ec85c4c 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -33,27 +33,31 @@
     private final Supplier<Transaction> mTransactionSupplier;
     private final @InternalInsetType int mType;
     private final InsetsState mState;
-    private @Nullable InsetsSourceControl mControl;
+    private final InsetsController mController;
+    private @Nullable InsetsSourceControl mSourceControl;
     private boolean mHidden;
 
     public InsetsSourceConsumer(@InternalInsetType int type, InsetsState state,
-            Supplier<Transaction> transactionSupplier) {
+            Supplier<Transaction> transactionSupplier, InsetsController controller) {
         mType = type;
         mState = state;
         mTransactionSupplier = transactionSupplier;
+        mController = controller;
     }
 
     public void setControl(@Nullable InsetsSourceControl control) {
-        if (mControl == control) {
+        if (mSourceControl == control) {
             return;
         }
-        mControl = control;
+        mSourceControl = control;
         applyHiddenToControl();
+        applyLocalVisibilityOverride();
+        mController.notifyVisibilityChanged();
     }
 
     @VisibleForTesting
     public InsetsSourceControl getControl() {
-        return mControl;
+        return mSourceControl;
     }
 
     int getType() {
@@ -70,25 +74,36 @@
         setHidden(true);
     }
 
+    void applyLocalVisibilityOverride() {
+
+        // If we don't have control, we are not able to change the visibility.
+        if (mSourceControl == null) {
+            return;
+        }
+        mState.getSource(mType).setVisible(!mHidden);
+    }
+
     private void setHidden(boolean hidden) {
         if (mHidden == hidden) {
             return;
         }
         mHidden = hidden;
         applyHiddenToControl();
+        applyLocalVisibilityOverride();
+        mController.notifyVisibilityChanged();
     }
 
     private void applyHiddenToControl() {
-        if (mControl == null) {
+        if (mSourceControl == null) {
             return;
         }
 
         // TODO: Animation
         final Transaction t = mTransactionSupplier.get();
         if (mHidden) {
-            t.hide(mControl.getLeash());
+            t.hide(mSourceControl.getLeash());
         } else {
-            t.show(mControl.getLeash());
+            t.show(mSourceControl.getLeash());
         }
         t.apply();
     }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 4b9a2b9..e36e258 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -462,7 +462,7 @@
     final DisplayCutout.ParcelableWrapper mPendingDisplayCutout =
             new DisplayCutout.ParcelableWrapper(DisplayCutout.NO_CUTOUT);
     boolean mPendingAlwaysConsumeNavBar;
-    private InsetsState mPendingInsets = new InsetsState();
+    private InsetsState mTempInsets = new InsetsState();
     final ViewTreeObserver.InternalInsetsInfo mLastGivenInsets
             = new ViewTreeObserver.InternalInsetsInfo();
 
@@ -550,7 +550,7 @@
             InputEventConsistencyVerifier.isInstrumentationEnabled() ?
                     new InputEventConsistencyVerifier(this, 0) : null;
 
-    private final InsetsController mInsetsController = new InsetsController();
+    private final InsetsController mInsetsController = new InsetsController(this);
 
     static final class SystemUiVisibilityInfo {
         int seq;
@@ -821,7 +821,7 @@
                             getHostVisibility(), mDisplay.getDisplayId(), mTmpFrame,
                             mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
                             mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel,
-                            mInsetsController.getState());
+                            mTempInsets);
                     setFrame(mTmpFrame);
                 } catch (RemoteException e) {
                     mAdded = false;
@@ -849,7 +849,7 @@
                 mAttachInfo.mAlwaysConsumeNavBar =
                         (res & WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_NAV_BAR) != 0;
                 mPendingAlwaysConsumeNavBar = mAttachInfo.mAlwaysConsumeNavBar;
-                mPendingInsets = mInsetsController.getState();
+                mInsetsController.onStateChanged(mTempInsets);
                 if (DEBUG_LAYOUT) Log.v(mTag, "Added window " + mWindow);
                 if (res < WindowManagerGlobal.ADD_OKAY) {
                     mAttachInfo.mRootView = null;
@@ -1342,6 +1342,19 @@
         scheduleTraversals();
     }
 
+    void notifyInsetsChanged() {
+        if (!USE_NEW_INSETS) {
+            return;
+        }
+        mApplyInsetsRequested = true;
+
+        // If this changes during traversal, no need to schedule another one as it will dispatch it
+        // during the current traversal.
+        if (!mIsInTraversal) {
+            scheduleTraversals();
+        }
+    }
+
     @Override
     public void requestLayout() {
         if (!mHandlingLayoutInLayoutRequest) {
@@ -2027,9 +2040,6 @@
                 if (mPendingAlwaysConsumeNavBar != mAttachInfo.mAlwaysConsumeNavBar) {
                     insetsChanged = true;
                 }
-                if (!mPendingInsets.equals(mInsetsController.getState())) {
-                    insetsChanged = true;
-                }
                 if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT
                         || lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
                     windowSizeMayChange = true;
@@ -2223,8 +2233,6 @@
                         mAttachInfo.mStableInsets);
                 final boolean cutoutChanged = !mPendingDisplayCutout.equals(
                         mAttachInfo.mDisplayCutout);
-                final boolean insetsStateChanged = !mPendingInsets.equals(
-                        mInsetsController.getState());
                 final boolean outsetsChanged = !mPendingOutsets.equals(mAttachInfo.mOutsets);
                 final boolean surfaceSizeChanged = (relayoutResult
                         & WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED) != 0;
@@ -2262,10 +2270,6 @@
                     mAttachInfo.mAlwaysConsumeNavBar = mPendingAlwaysConsumeNavBar;
                     contentInsetsChanged = true;
                 }
-                if (insetsStateChanged) {
-                    mInsetsController.setState(mPendingInsets);
-                    contentInsetsChanged = true;
-                }
                 if (contentInsetsChanged || mLastSystemUiVisibility !=
                         mAttachInfo.mSystemUiVisibility || mApplyInsetsRequested
                         || mLastOverscanRequested != mAttachInfo.mOverscanRequested
@@ -4375,22 +4379,12 @@
                     }
                     break;
                 case MSG_INSETS_CHANGED:
-                    mPendingInsets = (InsetsState) msg.obj;
-
-                    // TODO: Full traversal not needed here.
-                    if (USE_NEW_INSETS) {
-                        requestLayout();
-                    }
+                    mInsetsController.onStateChanged((InsetsState) msg.obj);
                     break;
                 case MSG_INSETS_CONTROL_CHANGED: {
                     SomeArgs args = (SomeArgs) msg.obj;
-                    mPendingInsets = (InsetsState) args.arg1;
                     mInsetsController.onControlsChanged((InsetsSourceControl[]) args.arg2);
-
-                    // TODO: Full traversal not necessarily needed here.
-                    if (USE_NEW_INSETS) {
-                        requestLayout();
-                    }
+                    mInsetsController.onStateChanged((InsetsState) args.arg1);
                     break;
                 }
                 case MSG_WINDOW_MOVED:
@@ -6791,7 +6785,7 @@
                 insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber,
                 mTmpFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
                 mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingDisplayCutout,
-                mPendingMergedConfiguration, mSurface, mPendingInsets);
+                mPendingMergedConfiguration, mSurface, mTempInsets);
 
         mPendingAlwaysConsumeNavBar =
                 (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR) != 0;
@@ -6808,7 +6802,7 @@
             mTranslator.translateRectInScreenToAppWindow(mPendingStableInsets);
         }
         setFrame(mTmpFrame);
-
+        mInsetsController.onStateChanged(mTempInsets);
         return relayoutResult;
     }
 
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index 48831da..1889692 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -422,7 +422,7 @@
 
     /** @hide */
     public void dump(String prefix, PrintWriter pw) {
-        pw.print(prefix); pw.println("IntelligenceManager");
+        pw.print(prefix); pw.println("ContentCaptureManager");
         final String prefix2 = prefix + "  ";
         pw.print(prefix2); pw.print("mContext: "); pw.println(mContext);
         pw.print(prefix2); pw.print("user: "); pw.println(mContext.getUserId());
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 2a42232..522be81 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -10209,7 +10209,7 @@
         }
 
         // ContentCapture
-        if (isImportantForContentCapture() && isTextEditable()) {
+        if (isLaidOut() && isImportantForContentCapture() && isTextEditable()) {
             final ContentCaptureManager cm = mContext.getSystemService(ContentCaptureManager.class);
             if (cm != null && cm.isContentCaptureEnabled()) {
                 // TODO(b/111276913): pass flags when edited by user / add CTS test
diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java
index 8bc90a8..a27dbea 100644
--- a/core/java/com/android/internal/content/FileSystemProvider.java
+++ b/core/java/com/android/internal/content/FileSystemProvider.java
@@ -39,6 +39,7 @@
 import android.provider.DocumentsProvider;
 import android.provider.MediaStore;
 import android.provider.MetadataReader;
+import android.system.Int64Ref;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
@@ -53,6 +54,12 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
@@ -122,18 +129,56 @@
             throw new FileNotFoundException("Can't find the file for documentId: " + documentId);
         }
 
+        final String mimeType = getDocumentType(documentId);
+        if (Document.MIME_TYPE_DIR.equals(mimeType)) {
+            final Int64Ref treeCount = new Int64Ref(0);
+            final Int64Ref treeSize = new Int64Ref(0);
+            try {
+                final Path path = FileSystems.getDefault().getPath(file.getAbsolutePath());
+                Files.walkFileTree(path, new FileVisitor<Path>() {
+                    @Override
+                    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+                        return FileVisitResult.CONTINUE;
+                    }
+
+                    @Override
+                    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+                        treeCount.value += 1;
+                        treeSize.value += attrs.size();
+                        return FileVisitResult.CONTINUE;
+                    }
+
+                    @Override
+                    public FileVisitResult visitFileFailed(Path file, IOException exc) {
+                        return FileVisitResult.CONTINUE;
+                    }
+
+                    @Override
+                    public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
+                        return FileVisitResult.CONTINUE;
+                    }
+                });
+            } catch (IOException e) {
+                Log.e(TAG, "An error occurred retrieving the metadata", e);
+                return null;
+            }
+
+            final Bundle res = new Bundle();
+            res.putLong(DocumentsContract.METADATA_TREE_COUNT, treeCount.value);
+            res.putLong(DocumentsContract.METADATA_TREE_SIZE, treeSize.value);
+            return res;
+        }
+
         if (!file.isFile()) {
             Log.w(TAG, "Can't stream non-regular file. Returning empty metadata.");
             return null;
         }
-
         if (!file.canRead()) {
             Log.w(TAG, "Can't stream non-readable file. Returning empty metadata.");
             return null;
         }
-
-        String mimeType = getDocumentType(documentId);
         if (!MetadataReader.isSupportedMimeType(mimeType)) {
+            Log.w(TAG, "Unsupported type " + mimeType + ". Returning empty metadata.");
             return null;
         }
 
@@ -562,7 +607,8 @@
     }
 
     protected boolean typeSupportsMetadata(String mimeType) {
-        return MetadataReader.isSupportedMimeType(mimeType);
+        return MetadataReader.isSupportedMimeType(mimeType)
+                || Document.MIME_TYPE_DIR.equals(mimeType);
     }
 
     protected final File getFileForDocId(String docId) throws FileNotFoundException {
diff --git a/core/java/com/android/internal/os/AppIdToPackageMap.java b/core/java/com/android/internal/os/AppIdToPackageMap.java
new file mode 100644
index 0000000..65aa989
--- /dev/null
+++ b/core/java/com/android/internal/os/AppIdToPackageMap.java
@@ -0,0 +1,79 @@
+/*
+ * 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.internal.os;
+
+
+import android.app.AppGlobals;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.RemoteException;
+import android.os.UserHandle;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/** Maps AppIds to their package names. */
+public final class AppIdToPackageMap {
+    private final Map<Integer, String> mAppIdToPackageMap;
+
+    @VisibleForTesting
+    public AppIdToPackageMap(Map<Integer, String> appIdToPackageMap) {
+        mAppIdToPackageMap = appIdToPackageMap;
+    }
+
+    /** Creates a new {@link AppIdToPackageMap} for currently installed packages. */
+    public static AppIdToPackageMap getSnapshot() {
+        List<PackageInfo> packages;
+        try {
+            packages = AppGlobals.getPackageManager()
+                    .getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES
+                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+                                    | PackageManager.MATCH_DIRECT_BOOT_AWARE,
+                            UserHandle.USER_SYSTEM).getList();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        final Map<Integer, String> map = new HashMap<>();
+        for (PackageInfo pkg : packages) {
+            final int uid = pkg.applicationInfo.uid;
+            if (pkg.sharedUserId != null && map.containsKey(uid)) {
+                // Use sharedUserId string as package name if there are collisions
+                map.put(uid, "shared:" + pkg.sharedUserId);
+            } else {
+                map.put(uid, pkg.packageName);
+            }
+        }
+        return new AppIdToPackageMap(map);
+    }
+
+    /** Maps the AppId to a package name. */
+    public String mapAppId(int appId) {
+        String pkgName = mAppIdToPackageMap.get(appId);
+        return pkgName == null ? String.valueOf(appId) : pkgName;
+    }
+
+    /** Maps the UID to a package name. */
+    public String mapUid(int uid) {
+        final int appId = UserHandle.getAppId(uid);
+        final String pkgName = mAppIdToPackageMap.get(appId);
+        final String uidStr = UserHandle.formatUid(uid);
+        return pkgName == null ? uidStr : pkgName + '/' + uidStr;
+    }
+}
diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java
index ff34036..5465485 100644
--- a/core/java/com/android/internal/os/BinderCallsStats.java
+++ b/core/java/com/android/internal/os/BinderCallsStats.java
@@ -21,8 +21,6 @@
 import android.os.Binder;
 import android.os.Process;
 import android.os.SystemClock;
-import android.os.ThreadLocalWorkSource;
-import android.os.UserHandle;
 import android.text.format.DateFormat;
 import android.util.ArrayMap;
 import android.util.Pair;
@@ -62,7 +60,11 @@
     private static final int CALL_SESSIONS_POOL_SIZE = 100;
     private static final int MAX_EXCEPTION_COUNT_SIZE = 50;
     private static final String EXCEPTION_COUNT_OVERFLOW_NAME = "overflow";
+    // Default values for overflow entry. The work source uid does not use a default value in order
+    // to have on overflow entry per work source uid.
     private static final Class<? extends Binder> OVERFLOW_BINDER = OverflowBinder.class;
+    private static final boolean OVERFLOW_SCREEN_INTERACTIVE = false;
+    private static final int OVERFLOW_DIRECT_CALLING_UID = -1;
     private static final int OVERFLOW_TRANSACTION_CODE = -1;
 
     // Whether to collect all the data: cpu + exceptions + reply/request sizes.
@@ -106,7 +108,7 @@
 
     @Override
     @Nullable
-    public CallSession callStarted(Binder binder, int code) {
+    public CallSession callStarted(Binder binder, int code, int workSourceUid) {
         if (mDeviceState == null || mDeviceState.isCharging()) {
             return null;
         }
@@ -130,19 +132,21 @@
     }
 
     @Override
-    public void callEnded(@Nullable CallSession s, int parcelRequestSize, int parcelReplySize) {
+    public void callEnded(@Nullable CallSession s, int parcelRequestSize,
+            int parcelReplySize, int workSourceUid) {
         if (s == null) {
             return;
         }
 
-        processCallEnded(s, parcelRequestSize, parcelReplySize);
+        processCallEnded(s, parcelRequestSize, parcelReplySize, workSourceUid);
 
         if (mCallSessionsPool.size() < CALL_SESSIONS_POOL_SIZE) {
             mCallSessionsPool.add(s);
         }
     }
 
-    private void processCallEnded(CallSession s, int parcelRequestSize, int parcelReplySize) {
+    private void processCallEnded(CallSession s,
+            int parcelRequestSize, int parcelReplySize, int workSourceUid) {
         // Non-negative time signals we need to record data for this call.
         final boolean recordCall = s.cpuTimeStarted >= 0;
         final long duration;
@@ -155,7 +159,6 @@
             latencyDuration = 0;
         }
         final int callingUid = getCallingUid();
-        final int workSourceUid = getWorkSourceUid();
 
         synchronized (mLock) {
             // This was already checked in #callStart but check again while synchronized.
@@ -356,14 +359,13 @@
     }
 
     /** Writes the collected statistics to the supplied {@link PrintWriter}.*/
-    public void dump(PrintWriter pw, Map<Integer, String> appIdToPkgNameMap, boolean verbose) {
+    public void dump(PrintWriter pw, AppIdToPackageMap packageMap, boolean verbose) {
         synchronized (mLock) {
-            dumpLocked(pw, appIdToPkgNameMap, verbose);
+            dumpLocked(pw, packageMap, verbose);
         }
     }
 
-    private void dumpLocked(PrintWriter pw, Map<Integer, String> appIdToPkgNameMap,
-            boolean verbose) {
+    private void dumpLocked(PrintWriter pw, AppIdToPackageMap packageMap, boolean verbose) {
         long totalCallsCount = 0;
         long totalRecordedCallsCount = 0;
         long totalCpuTime = 0;
@@ -397,9 +399,9 @@
         for (ExportedCallStat e : exportedCallStats) {
             sb.setLength(0);
             sb.append("    ")
-                    .append(uidToString(e.callingUid, appIdToPkgNameMap))
+                    .append(packageMap.mapUid(e.callingUid))
                     .append(',')
-                    .append(uidToString(e.workSourceUid, appIdToPkgNameMap))
+                    .append(packageMap.mapUid(e.workSourceUid))
                     .append(',').append(e.className)
                     .append('#').append(e.methodName)
                     .append(',').append(e.screenInteractive)
@@ -420,7 +422,7 @@
         final List<UidEntry> summaryEntries = verbose ? entries
                 : getHighestValues(entries, value -> value.cpuTimeMicros, 0.9);
         for (UidEntry entry : summaryEntries) {
-            String uidStr = uidToString(entry.workSourceUid, appIdToPkgNameMap);
+            String uidStr = packageMap.mapUid(entry.workSourceUid);
             pw.println(String.format("  %10d %3.0f%% %8d %8d %s",
                     entry.cpuTimeMicros, 100d * entry.cpuTimeMicros / totalCpuTime,
                     entry.recordedCallCount, entry.callCount, uidStr));
@@ -448,13 +450,6 @@
         }
     }
 
-    private static String uidToString(int uid, Map<Integer, String> pkgNameMap) {
-        final int appId = UserHandle.getAppId(uid);
-        final String pkgName = pkgNameMap == null ? null : pkgNameMap.get(appId);
-        final String uidStr = UserHandle.formatUid(uid);
-        return pkgName == null ? uidStr : pkgName + '/' + uidStr;
-    }
-
     protected long getThreadTimeMicro() {
         return SystemClock.currentThreadTimeMicro();
     }
@@ -463,10 +458,6 @@
         return Binder.getCallingUid();
     }
 
-    protected int getWorkSourceUid() {
-        return ThreadLocalWorkSource.getUid();
-    }
-
     protected long getElapsedRealtimeMicro() {
         return SystemClock.elapsedRealtimeNanos() / 1000;
     }
@@ -669,14 +660,16 @@
             // Only create CallStat if it's a new entry, otherwise update existing instance.
             if (mapCallStat == null) {
                 if (maxCallStatsReached) {
-                    mapCallStat = get(callingUid, OVERFLOW_BINDER, OVERFLOW_TRANSACTION_CODE,
-                            screenInteractive);
+                    mapCallStat = get(OVERFLOW_DIRECT_CALLING_UID, OVERFLOW_BINDER,
+                            OVERFLOW_TRANSACTION_CODE, OVERFLOW_SCREEN_INTERACTIVE);
                     if (mapCallStat != null) {
                         return mapCallStat;
                     }
 
+                    callingUid = OVERFLOW_DIRECT_CALLING_UID;
                     binderClass = OVERFLOW_BINDER;
                     transactionCode = OVERFLOW_TRANSACTION_CODE;
+                    screenInteractive = OVERFLOW_SCREEN_INTERACTIVE;
                 }
 
                 mapCallStat = new CallStat(callingUid, binderClass, transactionCode,
diff --git a/core/java/com/android/internal/os/BinderInternal.java b/core/java/com/android/internal/os/BinderInternal.java
index 0155067..5b69979 100644
--- a/core/java/com/android/internal/os/BinderInternal.java
+++ b/core/java/com/android/internal/os/BinderInternal.java
@@ -22,7 +22,6 @@
 import android.os.IBinder;
 import android.os.SystemClock;
 import android.util.EventLog;
-import android.util.Log;
 import android.util.SparseIntArray;
 
 import com.android.internal.util.Preconditions;
@@ -86,6 +85,22 @@
         boolean exceptionThrown;
     }
 
+
+    /**
+     * Responsible for resolving a work source.
+     */
+    @FunctionalInterface
+    public interface WorkSourceProvider {
+        /**
+         * <p>This method is called in a critical path of the binder transaction.
+         * <p>The implementation should never execute a binder call since it is called during a
+         * binder transaction.
+         *
+         * @return the uid of the process to attribute the binder transaction to.
+         */
+        int resolveWorkSourceUid();
+    }
+
     /**
      * Allows to track various steps of an API call.
      */
@@ -95,14 +110,16 @@
          *
          * @return a CallSession to pass to the callEnded method.
          */
-        CallSession callStarted(Binder binder, int code);
+        CallSession callStarted(Binder binder, int code, int workSourceUid);
 
         /**
          * Called when a binder call stops.
          *
-         * <li>This method will be called even when an exception is thrown.
+         * <li>This method will be called even when an exception is thrown by the binder stub
+         * implementation.
          */
-        void callEnded(CallSession s, int parcelRequestSize, int parcelReplySize);
+        void callEnded(CallSession s, int parcelRequestSize, int parcelReplySize,
+                int workSourceUid);
 
         /**
          * Called if an exception is thrown while executing the binder transaction.
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 31bb1d5..8962e1d 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -132,7 +132,6 @@
         "android/graphics/GIFMovie.cpp",
         "android/graphics/GraphicBuffer.cpp",
         "android/graphics/Graphics.cpp",
-        "android/graphics/HarfBuzzNGFaceSkia.cpp",
         "android/graphics/ImageDecoder.cpp",
         "android/graphics/Interpolator.cpp",
         "android/graphics/MaskFilter.cpp",
diff --git a/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp b/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
deleted file mode 100644
index cfe742d..0000000
--- a/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (c) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define LOG_TAG "TextLayoutCache"
-
-#include "HarfBuzzNGFaceSkia.h"
-
-#include <stdlib.h>
-
-#include <log/log.h>
-
-#include <SkPaint.h>
-#include <SkPath.h>
-#include <SkPoint.h>
-#include <SkRect.h>
-#include <SkTypeface.h>
-
-#include <hb.h>
-
-namespace android {
-
-static const bool kDebugGlyphs = false;
-
-// Our implementation of the callbacks which Harfbuzz requires by using Skia
-// calls. See the Harfbuzz source for references about what these callbacks do.
-
-struct HarfBuzzFontData {
-    explicit HarfBuzzFontData(SkPaint* paint) : m_paint(paint) { }
-    SkPaint* m_paint;
-};
-
-static void SkiaGetGlyphWidthAndExtents(SkPaint* paint, hb_codepoint_t codepoint, hb_position_t* width, hb_glyph_extents_t* extents)
-{
-    ALOG_ASSERT(codepoint <= 0xFFFF);
-    paint->setTextEncoding(kGlyphID_SkTextEncoding);
-
-    SkScalar skWidth;
-    SkRect skBounds;
-    uint16_t glyph = codepoint;
-
-    paint->getTextWidths(&glyph, sizeof(glyph), &skWidth, &skBounds);
-    if (kDebugGlyphs) {
-        ALOGD("returned glyph for %i: width = %f", codepoint, skWidth);
-    }
-    if (width)
-        *width = SkScalarToHBFixed(skWidth);
-    if (extents) {
-        // Invert y-axis because Skia is y-grows-down but we set up harfbuzz to be y-grows-up.
-        extents->x_bearing = SkScalarToHBFixed(skBounds.fLeft);
-        extents->y_bearing = SkScalarToHBFixed(-skBounds.fTop);
-        extents->width = SkScalarToHBFixed(skBounds.width());
-        extents->height = SkScalarToHBFixed(-skBounds.height());
-    }
-}
-
-static hb_bool_t harfbuzzGetGlyph(hb_font_t* hbFont, void* fontData, hb_codepoint_t unicode, hb_codepoint_t variationSelector, hb_codepoint_t* glyph, void* userData)
-{
-    HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData);
-    SkPaint* paint = hbFontData->m_paint;
-    paint->setTextEncoding(kUTF32_SkTextEncoding);
-
-    if (unicode > 0x10ffff) {
-        unicode = 0xfffd;
-    }
-    SkUnichar unichar = unicode;
-
-    uint16_t glyph16;
-    paint->textToGlyphs(&unichar, sizeof(unichar), &glyph16);
-    *glyph = glyph16;
-    return !!*glyph;
-}
-
-static hb_position_t harfbuzzGetGlyphHorizontalAdvance(hb_font_t* hbFont, void* fontData, hb_codepoint_t glyph, void* userData)
-{
-    HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData);
-    hb_position_t advance = 0;
-
-    SkiaGetGlyphWidthAndExtents(hbFontData->m_paint, glyph, &advance, 0);
-    return advance;
-}
-
-static hb_bool_t harfbuzzGetGlyphHorizontalOrigin(hb_font_t* hbFont, void* fontData, hb_codepoint_t glyph, hb_position_t* x, hb_position_t* y, void* userData)
-{
-    // Just return true, following the way that Harfbuzz-FreeType
-    // implementation does.
-    return true;
-}
-
-static hb_bool_t harfbuzzGetGlyphExtents(hb_font_t* hbFont, void* fontData, hb_codepoint_t glyph, hb_glyph_extents_t* extents, void* userData)
-{
-    HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData);
-
-    SkiaGetGlyphWidthAndExtents(hbFontData->m_paint, glyph, 0, extents);
-    return true;
-}
-
-static hb_font_funcs_t* harfbuzzSkiaGetFontFuncs()
-{
-    static hb_font_funcs_t* harfbuzzSkiaFontFuncs = 0;
-
-    // We don't set callback functions which we can't support.
-    // Harfbuzz will use the fallback implementation if they aren't set.
-    if (!harfbuzzSkiaFontFuncs) {
-        harfbuzzSkiaFontFuncs = hb_font_funcs_create();
-        hb_font_funcs_set_glyph_func(harfbuzzSkiaFontFuncs, harfbuzzGetGlyph, 0, 0);
-        hb_font_funcs_set_glyph_h_advance_func(harfbuzzSkiaFontFuncs, harfbuzzGetGlyphHorizontalAdvance, 0, 0);
-        hb_font_funcs_set_glyph_h_origin_func(harfbuzzSkiaFontFuncs, harfbuzzGetGlyphHorizontalOrigin, 0, 0);
-        hb_font_funcs_set_glyph_extents_func(harfbuzzSkiaFontFuncs, harfbuzzGetGlyphExtents, 0, 0);
-        hb_font_funcs_make_immutable(harfbuzzSkiaFontFuncs);
-    }
-    return harfbuzzSkiaFontFuncs;
-}
-
-hb_blob_t* harfbuzzSkiaReferenceTable(hb_face_t* face, hb_tag_t tag, void* userData)
-{
-    SkTypeface* typeface = reinterpret_cast<SkTypeface*>(userData);
-
-    const size_t tableSize = typeface->getTableSize(tag);
-    if (!tableSize)
-        return 0;
-
-    char* buffer = reinterpret_cast<char*>(malloc(tableSize));
-    if (!buffer)
-        return 0;
-    size_t actualSize = typeface->getTableData(tag, 0, tableSize, buffer);
-    if (tableSize != actualSize) {
-        free(buffer);
-        return 0;
-    }
-
-    return hb_blob_create(const_cast<char*>(buffer), tableSize,
-                          HB_MEMORY_MODE_WRITABLE, buffer, free);
-}
-
-static void destroyHarfBuzzFontData(void* data) {
-    delete (HarfBuzzFontData*)data;
-}
-
-hb_font_t* createFont(hb_face_t* face, SkPaint* paint, float sizeX, float sizeY) {
-    hb_font_t* font = hb_font_create(face);
-    
-    // Note: this needs to be reworked when we do subpixels
-    int x_ppem = floor(sizeX + 0.5);
-    int y_ppem = floor(sizeY + 0.5);
-    hb_font_set_ppem(font, x_ppem, y_ppem); 
-    hb_font_set_scale(font, HBFloatToFixed(sizeX), HBFloatToFixed(sizeY));
-
-    HarfBuzzFontData* data = new HarfBuzzFontData(paint);
-    hb_font_set_funcs(font, harfbuzzSkiaGetFontFuncs(), data, destroyHarfBuzzFontData);
-
-    return font;
-}
-
-} // namespace android
diff --git a/core/jni/android_hardware_SoundTrigger.cpp b/core/jni/android_hardware_SoundTrigger.cpp
index 98bc735..8a28034 100644
--- a/core/jni/android_hardware_SoundTrigger.cpp
+++ b/core/jni/android_hardware_SoundTrigger.cpp
@@ -225,7 +225,8 @@
                                     gAudioFormatCstor,
                                     audioFormatFromNative(event->audio_config.format),
                                     event->audio_config.sample_rate,
-                                    inChannelMaskFromNative(event->audio_config.channel_mask));
+                                    inChannelMaskFromNative(event->audio_config.channel_mask),
+                                    (jint)0 /* channelIndexMask */);
 
     }
     if (event->type == SOUND_MODEL_TYPE_KEYPHRASE) {
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index adab8e2..283eb03 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -2061,6 +2061,12 @@
     return (jint)nativeToJavaStatus(status);
 }
 
+static jboolean
+android_media_AudioSystem_isHapticPlaybackSupported(JNIEnv *env, jobject thiz)
+{
+    return AudioSystem::isHapticPlaybackSupported();
+}
+
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod gMethods[] = {
@@ -2123,6 +2129,7 @@
     {"setSurroundFormatEnabled", "(IZ)I", (void *)android_media_AudioSystem_setSurroundFormatEnabled},
     {"setAssistantUid", "(I)I", (void *)android_media_AudioSystem_setAssistantUid},
     {"setA11yServicesUids", "([I)I", (void *)android_media_AudioSystem_setA11yServicesUids},
+    {"isHapticPlaybackSupported", "()Z", (void *)android_media_AudioSystem_isHapticPlaybackSupported},
 };
 
 static const JNINativeMethod gEventHandlerMethods[] = {
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 0286730..4aa88e7 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -276,15 +276,17 @@
     }
   }
 
-  // We don't want core dumps, though, so set the soft limit on core dump size
-  // to 0 without changing the hard limit.
-  rlimit rl;
-  if (getrlimit(RLIMIT_CORE, &rl) == -1) {
-    ALOGE("getrlimit(RLIMIT_CORE) failed");
-  } else {
-    rl.rlim_cur = 0;
-    if (setrlimit(RLIMIT_CORE, &rl) == -1) {
-      ALOGE("setrlimit(RLIMIT_CORE) failed");
+  // Set the core dump size to zero unless wanted (see also coredump_setup in build/envsetup.sh).
+  if (!GetBoolProperty("persist.zygote.core_dump", false)) {
+    // Set the soft limit on core dump size to 0 without changing the hard limit.
+    rlimit rl;
+    if (getrlimit(RLIMIT_CORE, &rl) == -1) {
+      ALOGE("getrlimit(RLIMIT_CORE) failed");
+    } else {
+      rl.rlim_cur = 0;
+      if (setrlimit(RLIMIT_CORE, &rl) == -1) {
+        ALOGE("setrlimit(RLIMIT_CORE) failed");
+      }
     }
   }
 }
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index fd64c65..514f306 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -76,5 +76,11 @@
 
     // OPEN: Settings > Developer options > Disable > Info dialog
     DIALOG_DISABLE_DEVELOPMENT_OPTIONS = 1591;
+
+    // OPEN: WifiDppConfiguratorActivity (android.settings.WIFI_DPP_CONFIGURATOR_XXX action intents)
+    SETTINGS_WIFI_DPP_CONFIGURATOR = 1595;
+
+    // OPEN: WifiDppEnrolleeActivity (android.settings.WIFI_DPP_ENROLLEE_XXX action intents)
+    SETTINGS_WIFI_DPP_ENROLLEE = 1596;
 }
 
diff --git a/core/proto/android/service/usb.proto b/core/proto/android/service/usb.proto
index ed040f4..f7dcee2 100644
--- a/core/proto/android/service/usb.proto
+++ b/core/proto/android/service/usb.proto
@@ -206,6 +206,8 @@
     optional bool can_change_mode = 3;
     optional bool can_change_power_role = 4;
     optional bool can_change_data_role = 5;
+    optional int64 connected_at_millis = 6;
+    optional int64 last_connect_duration_millis = 7;
 }
 
 message UsbPortProto {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 988eac0..9c55c75 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -897,7 +897,7 @@
         android:protectionLevel="dangerous"
         android:usageInfoRequired="true" />
 
-    <!-- @hide @SystemApi
+    <!-- @hide @SystemApi @TestApi
          Allows an application to modify OBB files visible to other apps. -->
     <permission android:name="android.permission.WRITE_OBB"
         android:protectionLevel="signature|privileged" />
@@ -2087,10 +2087,9 @@
          <p>This permission should <em>only</em> be requested by the platform
          document management app.  This permission cannot be granted to
          third-party apps.
-         <p>Protection level: signature
     -->
     <permission android:name="android.permission.MANAGE_DOCUMENTS"
-        android:protectionLevel="signature" />
+        android:protectionLevel="signature|documenter" />
 
     <!-- @hide Allows an application to cache content.
          <p>Not for use by third-party applications.
@@ -2213,9 +2212,9 @@
         android:description="@string/permdesc_reorderTasks"
         android:protectionLevel="normal" />
 
-    <!-- @hide Allows an application to change to remove/kill tasks -->
+    <!-- @SystemApi @TestApi @hide Allows an application to change to remove/kill tasks -->
     <permission android:name="android.permission.REMOVE_TASKS"
-        android:protectionLevel="signature" />
+        android:protectionLevel="signature|documenter" />
 
     <!-- @SystemApi @TestApi @hide Allows an application to create/manage/remove stacks -->
     <permission android:name="android.permission.MANAGE_ACTIVITY_STACKS"
@@ -3351,6 +3350,11 @@
     <permission android:name="android.permission.MANAGE_ROLE_HOLDERS"
                 android:protectionLevel="signature|installer" />
 
+    <!-- @SystemApi Allows an application to observe role holder changes.
+         @hide -->
+    <permission android:name="android.permission.OBSERVE_ROLE_HOLDERS"
+                android:protectionLevel="signature|installer" />
+
     <!-- @SystemApi Allows an application to use SurfaceFlinger's low level features.
          <p>Not for use by third-party applications.
          @hide
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 56c2e3e..f3b4df7 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1086,7 +1086,7 @@
     <string name="email" msgid="4560673117055050403">"ኢሜይል"</string>
     <string name="email_desc" msgid="3638665569546416795">"ለተመረጡ አድራሻዎች ኢሜይል ላክ"</string>
     <string name="dial" msgid="1253998302767701559">"ጥሪ"</string>
-    <string name="dial_desc" msgid="6573723404985517250">"ወደተመረጠውን ስልክ ቁጥር ደውል"</string>
+    <string name="dial_desc" msgid="6573723404985517250">"ወደ ተመረጠው ስልክ ቁጥር ደውል"</string>
     <string name="map" msgid="5441053548030107189">"ካርታ"</string>
     <string name="map_desc" msgid="1836995341943772348">"የተመረጠውን አድራሻ ያለበትን አግኝ"</string>
     <string name="browse" msgid="1245903488306147205">"ክፈት"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 2af43ce..a14a871 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -537,7 +537,7 @@
     <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Fingerabdruck teilweise erkannt. Bitte versuche es noch einmal."</string>
     <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Fingerabdruck konnte nicht verarbeitet werden. Bitte versuche es noch einmal."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Fingerabdrucksensor ist verschmutzt. Reinige ihn und versuche es noch einmal."</string>
-    <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Finger zu schnell bewegt. Bitte versuche es noch einmal."</string>
+    <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Finger zu schnell bewegt, bitte noch einmal versuchen"</string>
     <string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"Finger zu langsam bewegt. Bitte versuche es noch einmal."</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
@@ -549,7 +549,7 @@
     <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Zeitüberschreitung für Fingerabdruck. Bitte versuche es noch einmal."</string>
     <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Fingerabdruckvorgang abgebrochen"</string>
     <string name="fingerprint_error_user_canceled" msgid="7999639584615291494">"Vorgang der Fingerabdruckauthentifizierung vom Nutzer abgebrochen."</string>
-    <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Zu viele Versuche. Bitte versuche es später noch einmal."</string>
+    <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Zu viele Versuche, bitte später noch einmal versuchen"</string>
     <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Zu viele Versuche. Der Fingerabdrucksensor wurde deaktiviert."</string>
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Bitte versuche es noch einmal."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="7654382120628334248">"Keine Fingerabdrücke erfasst."</string>
@@ -581,7 +581,7 @@
     <string name="face_error_no_space" msgid="8224993703466381314">"Gesicht kann nicht gespeichert werden."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Gesichtserkennung abgebrochen."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Gesichtsauthentifizierung vom Nutzer abgebrochen."</string>
-    <string name="face_error_lockout" msgid="3407426963155388504">"Zu viele Versuche. Versuch es später noch einmal."</string>
+    <string name="face_error_lockout" msgid="3407426963155388504">"Zu viele Versuche, bitte später noch einmal versuchen"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Zu viele Versuche. Gesichtserkennung deaktiviert."</string>
     <string name="face_error_unable_to_process" msgid="238761109287767270">"Versuch es noch einmal."</string>
     <string name="face_error_not_enrolled" msgid="9166792142679691323">"Kein Gesicht erfasst."</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 77a8f05..e633ab4 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1084,27 +1084,27 @@
     <string name="inputMethod" msgid="1653630062304567879">"Sisestusmeetod"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstitoimingud"</string>
     <string name="email" msgid="4560673117055050403">"E-post"</string>
-    <string name="email_desc" msgid="3638665569546416795">"Valitud aadressile meili saatmine"</string>
+    <string name="email_desc" msgid="3638665569546416795">"Saada valitud aadressile meil"</string>
     <string name="dial" msgid="1253998302767701559">"Helista"</string>
-    <string name="dial_desc" msgid="6573723404985517250">"Valitud telefoninumbrile helistamine"</string>
+    <string name="dial_desc" msgid="6573723404985517250">"Helista valitud telefoninumbrile"</string>
     <string name="map" msgid="5441053548030107189">"Kaart"</string>
-    <string name="map_desc" msgid="1836995341943772348">"Valitud aadressi leidmine"</string>
+    <string name="map_desc" msgid="1836995341943772348">"Leia valitud aadress"</string>
     <string name="browse" msgid="1245903488306147205">"Ava"</string>
-    <string name="browse_desc" msgid="8220976549618935044">"Valitud URL-i avamine"</string>
+    <string name="browse_desc" msgid="8220976549618935044">"Ava valitud URL"</string>
     <string name="sms" msgid="4560537514610063430">"Saada sõnum"</string>
-    <string name="sms_desc" msgid="7526588350969638809">"Valitud telefoninumbrile sõnumi saatmine"</string>
+    <string name="sms_desc" msgid="7526588350969638809">"Saada valitud telefoninumbrile sõnum"</string>
     <string name="add_contact" msgid="7867066569670597203">"Lisa"</string>
-    <string name="add_contact_desc" msgid="4830217847004590345">"Kontaktide hulka lisamine"</string>
+    <string name="add_contact_desc" msgid="4830217847004590345">"Lisa kontaktide hulka"</string>
     <string name="view_calendar" msgid="979609872939597838">"Kuva"</string>
-    <string name="view_calendar_desc" msgid="5828320291870344584">"Valitud aja vaatamine kalendris"</string>
+    <string name="view_calendar_desc" msgid="5828320291870344584">"Kuva valitud aeg kalendris"</string>
     <string name="add_calendar_event" msgid="1953664627192056206">"Lisa ajakavasse"</string>
-    <string name="add_calendar_event_desc" msgid="4326891793260687388">"Ürituse ajastamine valitud ajale"</string>
+    <string name="add_calendar_event_desc" msgid="4326891793260687388">"Ajasta üritus valitud ajale"</string>
     <string name="view_flight" msgid="7691640491425680214">"Jälgi"</string>
-    <string name="view_flight_desc" msgid="3876322502674253506">"Valitud lennu jälgimine"</string>
+    <string name="view_flight_desc" msgid="3876322502674253506">"Jälgi valitud lendu"</string>
     <string name="translate" msgid="9218619809342576858">"Tõlgi"</string>
-    <string name="translate_desc" msgid="4502367770068777202">"Tõlkige valitud tekst"</string>
+    <string name="translate_desc" msgid="4502367770068777202">"Tõlgi valitud tekst"</string>
     <string name="define" msgid="7394820043869954211">"Defineeri"</string>
-    <string name="define_desc" msgid="7910883642444919726">"Valitud teksti defineerimine"</string>
+    <string name="define_desc" msgid="7910883642444919726">"Defineeri valitud tekst"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Talletusruum saab täis"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Mõned süsteemifunktsioonid ei pruugi töötada"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Süsteemis pole piisavalt talletusruumi. Veenduge, et seadmes oleks 250 MB vaba ruumi, ja käivitage seade uuesti."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index bc367be..3f8f0d1 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1097,7 +1097,7 @@
     <string name="add_contact_desc" msgid="4830217847004590345">"Lisää yhteystietoihin"</string>
     <string name="view_calendar" msgid="979609872939597838">"Näytä"</string>
     <string name="view_calendar_desc" msgid="5828320291870344584">"Näytä valittu aika kalenterissa"</string>
-    <string name="add_calendar_event" msgid="1953664627192056206">"Aikataulu"</string>
+    <string name="add_calendar_event" msgid="1953664627192056206">"Aikatauluta"</string>
     <string name="add_calendar_event_desc" msgid="4326891793260687388">"Ajoita tapahtuma valitulle ajalle"</string>
     <string name="view_flight" msgid="7691640491425680214">"Seuraa"</string>
     <string name="view_flight_desc" msgid="3876322502674253506">"Seuraa valittua lentoa"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index fccb289..87e1f97 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -306,7 +306,7 @@
     <string name="permgroupdesc_calllog" msgid="3006237336748283775">"कॉल लॉग की जानकारी देखना और उसमें बदलाव करना"</string>
     <string name="permgrouprequest_calllog" msgid="8487355309583773267">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; को अपने काॅल लाॅग एक्सेस करने की मंज़ूरी देना चाहते हैं?"</string>
     <string name="permgrouplab_phone" msgid="5229115638567440675">"फ़ोन"</string>
-    <string name="permgroupdesc_phone" msgid="6234224354060641055">"फ़ोन कॉल करें और प्रबंधित करें"</string>
+    <string name="permgroupdesc_phone" msgid="6234224354060641055">"फ़ोन कॉल करने और उन्हें प्रबंधित करने की अनुमति दें"</string>
     <string name="permgrouprequest_phone" msgid="9166979577750581037">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; को फ़ोन कॉल करने और उन्हें प्रबंधित करने की अनुमति दें?"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"शरीर संवेदक"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"अपने महत्वपूर्ण संकेतों के बारे में सेंसर डेटा को ऐक्सेस करें"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 69b4db2..cd2af7b 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1097,7 +1097,7 @@
     <string name="add_contact_desc" msgid="4830217847004590345">"បញ្ចូល​ទៅ​ក្នុង​ទំនាក់ទំនង"</string>
     <string name="view_calendar" msgid="979609872939597838">"មើល"</string>
     <string name="view_calendar_desc" msgid="5828320291870344584">"មើល​ពេលវេលា​ដែល​បាន​ជ្រើសរើស​នៅក្នុង​ប្រតិទិន"</string>
-    <string name="add_calendar_event" msgid="1953664627192056206">"កាលវិភាគ"</string>
+    <string name="add_calendar_event" msgid="1953664627192056206">"កំណត់​កាលវិភាគ"</string>
     <string name="add_calendar_event_desc" msgid="4326891793260687388">"កំណត់​កាលវិភាគ​ព្រឹត្តិការណ៍​សម្រាប់ពេល​វេលាដែល​បាន​ជ្រើសរើស"</string>
     <string name="view_flight" msgid="7691640491425680214">"តាម​ដាន"</string>
     <string name="view_flight_desc" msgid="3876322502674253506">"តាមដាន​ជើង​ហោះហើរ​ដែល​បាន​ជ្រើសរើស"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 2232f4d..f6e9b72 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -1083,15 +1083,15 @@
     <string name="deleteText" msgid="6979668428458199034">"Жок кылуу"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Киргизүү ыкмасы"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Текст боюнча иштер"</string>
-    <string name="email" msgid="4560673117055050403">"Электрондук почта"</string>
+    <string name="email" msgid="4560673117055050403">"Кат жөнөтүү"</string>
     <string name="email_desc" msgid="3638665569546416795">"Тандалган дарекке электрондук кат жөнөтүү"</string>
     <string name="dial" msgid="1253998302767701559">"Чалуу"</string>
     <string name="dial_desc" msgid="6573723404985517250">"Тандалган телефон номерине чалуу"</string>
-    <string name="map" msgid="5441053548030107189">"Карта"</string>
+    <string name="map" msgid="5441053548030107189">"Картадан кароо"</string>
     <string name="map_desc" msgid="1836995341943772348">"Тандалган даректи картада табуу"</string>
     <string name="browse" msgid="1245903488306147205">"Ачуу"</string>
     <string name="browse_desc" msgid="8220976549618935044">"Тандалган URL\'ди ачуу"</string>
-    <string name="sms" msgid="4560537514610063430">"Билдирүү"</string>
+    <string name="sms" msgid="4560537514610063430">"Билдирүү жазуу"</string>
     <string name="sms_desc" msgid="7526588350969638809">"Тандалган телефон номерине билдирүү жөнөтүү"</string>
     <string name="add_contact" msgid="7867066569670597203">"Кошуу"</string>
     <string name="add_contact_desc" msgid="4830217847004590345">"Байланыштарга кошуу"</string>
@@ -1103,7 +1103,7 @@
     <string name="view_flight_desc" msgid="3876322502674253506">"Тандалган аба каттамына көз салуу"</string>
     <string name="translate" msgid="9218619809342576858">"Которуу"</string>
     <string name="translate_desc" msgid="4502367770068777202">"Тандалган текстти которуу"</string>
-    <string name="define" msgid="7394820043869954211">"Төмөнкү сөздүн аныктамасын бериңиз:"</string>
+    <string name="define" msgid="7394820043869954211">"Аныктоо"</string>
     <string name="define_desc" msgid="7910883642444919726">"Тандалган текстти аныктоо"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Сактагычта орун калбай баратат"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Системанын кээ бир функциялары иштебеши мүмкүн"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index eec4b31..dd4b125 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1107,7 +1107,7 @@
     <string name="email_desc" msgid="3638665569546416795">"Nosūtīt e-pasta ziņojumu uz atlasīto adresi"</string>
     <string name="dial" msgid="1253998302767701559">"Zvanīt"</string>
     <string name="dial_desc" msgid="6573723404985517250">"Zvanīt uz atlasīto tālruņa numuru"</string>
-    <string name="map" msgid="5441053548030107189">"Maps"</string>
+    <string name="map" msgid="5441053548030107189">"Karte"</string>
     <string name="map_desc" msgid="1836995341943772348">"Atrast atlasīto adresi"</string>
     <string name="browse" msgid="1245903488306147205">"Atvērt"</string>
     <string name="browse_desc" msgid="8220976549618935044">"Atvērt atlasīto URL"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index ac28270..93f7e37 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1083,23 +1083,23 @@
     <string name="deleteText" msgid="6979668428458199034">"Устгах"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Оруулах арга"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Текст үйлдэл"</string>
-    <string name="email" msgid="4560673117055050403">"Имэйл"</string>
+    <string name="email" msgid="4560673117055050403">"Имэйл бичих"</string>
     <string name="email_desc" msgid="3638665569546416795">"Сонгосон хаяг руу имэйл илгээх"</string>
     <string name="dial" msgid="1253998302767701559">"Залгах"</string>
     <string name="dial_desc" msgid="6573723404985517250">"Сонгосон утасны дугаар руу залгах"</string>
-    <string name="map" msgid="5441053548030107189">"Газрын зураг"</string>
+    <string name="map" msgid="5441053548030107189">"Газрын зураг хийх"</string>
     <string name="map_desc" msgid="1836995341943772348">"Сонгосон хаягийг байршуулах"</string>
     <string name="browse" msgid="1245903488306147205">"Нээх"</string>
     <string name="browse_desc" msgid="8220976549618935044">"Сонгосон URL-г нээх"</string>
-    <string name="sms" msgid="4560537514610063430">"Зурвас"</string>
+    <string name="sms" msgid="4560537514610063430">"Зурвас бичих"</string>
     <string name="sms_desc" msgid="7526588350969638809">"Сонгосон утасны дугаар руу мессеж илгээх"</string>
     <string name="add_contact" msgid="7867066569670597203">"Нэмэх"</string>
     <string name="add_contact_desc" msgid="4830217847004590345">"Харилцагчид нэмэх"</string>
     <string name="view_calendar" msgid="979609872939597838">"Үзэх"</string>
     <string name="view_calendar_desc" msgid="5828320291870344584">"Календариас сонгосон огноог харах"</string>
-    <string name="add_calendar_event" msgid="1953664627192056206">"Хуваарь"</string>
+    <string name="add_calendar_event" msgid="1953664627192056206">"Хуваарь гаргах"</string>
     <string name="add_calendar_event_desc" msgid="4326891793260687388">"Aрга хэмжээг сонгосон цагт хуваарилах"</string>
-    <string name="view_flight" msgid="7691640491425680214">"Бичлэг"</string>
+    <string name="view_flight" msgid="7691640491425680214">"Хянах"</string>
     <string name="view_flight_desc" msgid="3876322502674253506">"Сонгосон нислэгийг хянах"</string>
     <string name="translate" msgid="9218619809342576858">"Орчуулах"</string>
     <string name="translate_desc" msgid="4502367770068777202">"Сонгосон текстийг орчуулах"</string>
diff --git a/core/res/res/values-mr-watch/strings.xml b/core/res/res/values-mr-watch/strings.xml
index 223f8fa..f8a5214 100644
--- a/core/res/res/values-mr-watch/strings.xml
+++ b/core/res/res/values-mr-watch/strings.xml
@@ -20,6 +20,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="1090732262010398759">"<xliff:g id="NUMBER_1">%2$d</xliff:g> पैकी <xliff:g id="NUMBER_0">%1$d</xliff:g> अॅप"</string>
+    <string name="android_upgrading_apk" msgid="1090732262010398759">"<xliff:g id="NUMBER_1">%2$d</xliff:g> पैकी <xliff:g id="NUMBER_0">%1$d</xliff:g> अ‍ॅप"</string>
     <string name="permgrouplab_sensors" msgid="202675452368612754">"सेन्सर"</string>
 </resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 9a58b38..902380b 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -183,7 +183,7 @@
     <string name="ssl_ca_cert_noti_by_administrator" msgid="3541729986326153557">"आपल्या कार्य प्रोफाइल प्रशासकाद्वारे"</string>
     <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"<xliff:g id="MANAGING_DOMAIN">%s</xliff:g> द्वारे"</string>
     <string name="work_profile_deleted" msgid="5005572078641980632">"कार्य प्रोफाईल हटविले"</string>
-    <string name="work_profile_deleted_details" msgid="6307630639269092360">"कार्य प्रोफाइल प्रशासक अॅप गहाळ आहे किंवा करप्ट आहे. परिणामी, तुमचे कार्य प्रोफाइल आणि संबंधित डेटा हटवले गेले आहेत. सहाय्यासाठी आपल्या प्रशासकाशी संपर्क साधा."</string>
+    <string name="work_profile_deleted_details" msgid="6307630639269092360">"कार्य प्रोफाइल प्रशासक अ‍ॅप गहाळ आहे किंवा करप्ट आहे. परिणामी, तुमचे कार्य प्रोफाइल आणि संबंधित डेटा हटवले गेले आहेत. सहाय्यासाठी आपल्या प्रशासकाशी संपर्क साधा."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"तुमचे कार्य प्रोफाइल आता या डिव्हाइसवर उपलब्‍ध नाही"</string>
     <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"बर्‍याचदा पासवर्ड टाकण्‍याचा प्रयत्‍न केला"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"डिव्हाइस व्यवस्थापित केले आहे"</string>
@@ -281,9 +281,9 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"स्थान"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"या डिव्हाइसच्या स्थानावर प्रवेश"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला या डिव्हाइसचे स्थान अॅक्सेस करू द्यायचे?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"तुम्ही अॅप वापरत असताना, अॅपला फक्त स्थानाचा अॅक्सेस असेल."</string>
+    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"तुम्ही अ‍ॅप वापरत असताना, अ‍ॅपला फक्त स्थानाचा अॅक्सेस असेल."</string>
     <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"या डिव्हाइसचे स्थान अॅक्सेस करण्याची &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला नेहेमी अनुमती द्यायची का?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"तुम्ही अॅप वापरत नसलात तरीही, अॅपला स्थानाचा नेहेमी अॅक्सेस असेल."</string>
+    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"तुम्ही अ‍ॅप वापरत नसलात तरीही, अ‍ॅपला स्थानाचा नेहेमी अॅक्सेस असेल."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"कॅलेंडर"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"आपल्या कॅलेंडरवर प्रवेश"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला तुमचे कॅलेंडर अॅक्सेस करू द्यायचे?"</string>
@@ -330,11 +330,11 @@
     <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"फिंगरप्रिंट जेश्चर"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="4386487962402228670">"डिव्‍हाइसच्‍या फिंगरप्रिंट सेंसरवर केलेले जेश्चर कॅप्‍चर करू शकते."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"स्टेटस बार अक्षम करा किंवा सुधारित करा"</string>
-    <string name="permdesc_statusBar" msgid="8434669549504290975">"स्टेटस बार अक्षम करण्यासाठी किंवा सिस्टम चिन्हे जोडण्यासाठी आणि काढण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"स्टेटस बार अक्षम करण्यासाठी किंवा सिस्टम चिन्हे जोडण्यासाठी आणि काढण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"स्टेटस बार होऊ द्या"</string>
-    <string name="permdesc_statusBarService" msgid="716113660795976060">"स्टेटस बार होण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_statusBarService" msgid="716113660795976060">"स्टेटस बार होण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_expandStatusBar" msgid="1148198785937489264">"स्‍टेटस बार विस्तृत करा/संकुचित करा"</string>
-    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"स्टेटस बार विस्तृत करण्यासाठी किंवा संक्षिप्त करण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"स्टेटस बार विस्तृत करण्यासाठी किंवा संक्षिप्त करण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_install_shortcut" msgid="4279070216371564234">"शॉर्टकट स्‍थापित करा"</string>
     <string name="permdesc_install_shortcut" msgid="8341295916286736996">"अनुप्रयोगाला वापरकर्ता हस्‍तक्षेपाशिवाय मुख्‍यस्‍क्रीन शॉर्टकट जोडण्‍याची अनुमती देते."</string>
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"शॉर्टकट विस्‍थापित करा"</string>
@@ -344,103 +344,103 @@
     <string name="permlab_answerPhoneCalls" msgid="4077162841226223337">"फोन कॉलचे उत्तर द्या"</string>
     <string name="permdesc_answerPhoneCalls" msgid="2901889867993572266">"येणार्‍या फोन कॉलचे उत्तर देण्यास अॅपला अनुमती देते."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"मजकूर मेसेज मिळवा (SMS)"</string>
-    <string name="permdesc_receiveSms" msgid="6424387754228766939">"SMS मेसेज प्राप्त करण्याची आणि त्यावर प्रक्रिया करण्याची अॅप ला अनुमती देते. म्हणजेच अॅप आपल्या डीव्हाइसवर पाठविलेले मेसेज तुम्हाला न दर्शवता त्यांचे परीक्षण करू किंवा ते हटवू शकतो."</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"SMS मेसेज प्राप्त करण्याची आणि त्यावर प्रक्रिया करण्याची अ‍ॅप ला अनुमती देते. म्हणजेच अ‍ॅप आपल्या डीव्हाइसवर पाठविलेले मेसेज तुम्हाला न दर्शवता त्यांचे परीक्षण करू किंवा ते हटवू शकतो."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"मजकूर मेसेज मिळवा (MMS)"</string>
-    <string name="permdesc_receiveMms" msgid="533019437263212260">"MMS मेसेज प्राप्त करण्यास आणि त्यावर प्रक्रिया करण्यास अॅप ला अनुमती देते. म्हणजेच अॅप आपल्या डिव्हाइसवर पाठविलेले मेसेज तुम्हाला न दर्शवता त्यांचे परीक्षण करू किंवा ते हटवू शकतो."</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"MMS मेसेज प्राप्त करण्यास आणि त्यावर प्रक्रिया करण्यास अ‍ॅप ला अनुमती देते. म्हणजेच अ‍ॅप आपल्या डिव्हाइसवर पाठविलेले मेसेज तुम्हाला न दर्शवता त्यांचे परीक्षण करू किंवा ते हटवू शकतो."</string>
     <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"सेल प्रसारण मेसेज वाचा"</string>
-    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"आपल्या डिव्हाइसद्वारे प्राप्त केलेले सेल प्रसारण मेसेज वाचण्यासाठी अॅप ला अनुमती देते. काही स्थानांमध्ये तुम्हाला आणीबाणीच्या परिस्थितीची चेतावणी देण्यासाठी सेल प्रसारण सूचना वितरीत केल्या जातात. आणीबाणी सेल प्रसारण प्राप्त होते तेव्हा आपल्या डिव्हाइसच्या कार्यप्रदर्शनात किंवा कार्यात दुर्भावनापूर्ण अॅप्स व्यत्यय आणू शकतात."</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"आपल्या डिव्हाइसद्वारे प्राप्त केलेले सेल प्रसारण मेसेज वाचण्यासाठी अ‍ॅप ला अनुमती देते. काही स्थानांमध्ये तुम्हाला आणीबाणीच्या परिस्थितीची चेतावणी देण्यासाठी सेल प्रसारण सूचना वितरीत केल्या जातात. आणीबाणी सेल प्रसारण प्राप्त होते तेव्हा आपल्या डिव्हाइसच्या कार्यप्रदर्शनात किंवा कार्यात दुर्भावनापूर्ण अ‍ॅप्स व्यत्यय आणू शकतात."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"सदस्यता घेतलेली फीड वाचा"</string>
-    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"सध्या संकालित केलेल्या फीडविषयी तपशील मिळविण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"सध्या संकालित केलेल्या फीडविषयी तपशील मिळविण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_sendSms" msgid="7544599214260982981">"SMS मेसेज पाठवणे आणि पाहणे"</string>
-    <string name="permdesc_sendSms" msgid="7094729298204937667">"SMS मेसेज पाठविण्यासाठी अॅप ला अनुमती देते. हे अनपेक्षित शुल्कामुळे होऊ शकते. दुर्भावनापूर्ण अॅप्स नी आपल्या पुष्टिकरणाशिवाय मेसेज पाठवल्यामुळे तुमचे पैसे खर्च होऊ शकतात."</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"SMS मेसेज पाठविण्यासाठी अ‍ॅप ला अनुमती देते. हे अनपेक्षित शुल्कामुळे होऊ शकते. दुर्भावनापूर्ण अ‍ॅप्स नी आपल्या पुष्टिकरणाशिवाय मेसेज पाठवल्यामुळे तुमचे पैसे खर्च होऊ शकतात."</string>
     <string name="permlab_readSms" msgid="8745086572213270480">"तुमचे मजकूर मेसेज वाचा (SMS किंवा MMS)"</string>
-    <string name="permdesc_readSms" product="tablet" msgid="4741697454888074891">"हा अॅप तुमच्या टॅब्लेटवर स्टोअर केलेले सर्व SMS (मजकूर) मेसेज वाचू शकतो."</string>
-    <string name="permdesc_readSms" product="tv" msgid="5796670395641116592">"हा अॅप तुमच्या टीव्हीवर स्टोअर केलेले सर्व SMS (मजकूर) मेसेज वाचू शकतो."</string>
-    <string name="permdesc_readSms" product="default" msgid="6826832415656437652">"हा अॅप तुमच्या फोनवर स्टोअर केलेले सर्व SMS (मजकूर) मेसेज वाचू शकतो."</string>
+    <string name="permdesc_readSms" product="tablet" msgid="4741697454888074891">"हा अ‍ॅप तुमच्या टॅब्लेटवर स्टोअर केलेले सर्व SMS (मजकूर) मेसेज वाचू शकतो."</string>
+    <string name="permdesc_readSms" product="tv" msgid="5796670395641116592">"हा अ‍ॅप तुमच्या टीव्हीवर स्टोअर केलेले सर्व SMS (मजकूर) मेसेज वाचू शकतो."</string>
+    <string name="permdesc_readSms" product="default" msgid="6826832415656437652">"हा अ‍ॅप तुमच्या फोनवर स्टोअर केलेले सर्व SMS (मजकूर) मेसेज वाचू शकतो."</string>
     <string name="permlab_receiveWapPush" msgid="5991398711936590410">"मजकूर मेसेज मिळवा (WAP)"</string>
-    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAP मेसेज प्राप्त करण्यास आणि त्यावर प्रक्रिया करण्यासाठी अॅप ला अनुमती देते. ही परवानगी तुम्हाला पाठविलेले मेसेज तुम्हाला न दर्शविता त्यांचे परीक्षण करण्याची आणि ते हटविण्याची क्षमता समाविष्ट करते."</string>
+    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAP मेसेज प्राप्त करण्यास आणि त्यावर प्रक्रिया करण्यासाठी अ‍ॅप ला अनुमती देते. ही परवानगी तुम्हाला पाठविलेले मेसेज तुम्हाला न दर्शविता त्यांचे परीक्षण करण्याची आणि ते हटविण्याची क्षमता समाविष्ट करते."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"चालणारे अॅप्स पुनर्प्राप्त करा"</string>
-    <string name="permdesc_getTasks" msgid="7454215995847658102">"सध्या आणि अलीकडे चालणार्‍या कार्यांविषयी माहिती पुनर्प्राप्त करण्यासाठी अॅप ला अनुमती देते. हे डिव्हाइसवर कोणते अॅप्लिकेशन वापरले जात आहेत त्याविषयी माहिती शोधण्यासाठी अॅप ला अनुमती देऊ शकतात."</string>
+    <string name="permdesc_getTasks" msgid="7454215995847658102">"सध्या आणि अलीकडे चालणार्‍या कार्यांविषयी माहिती पुनर्प्राप्त करण्यासाठी अ‍ॅप ला अनुमती देते. हे डिव्हाइसवर कोणते अ‍ॅप्लिकेशन वापरले जात आहेत त्याविषयी माहिती शोधण्यासाठी अ‍ॅप ला अनुमती देऊ शकतात."</string>
     <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"प्रोफाईल आणि डिव्हाइस मालक व्यवस्थापित करा"</string>
     <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"प्रोफाईल मालक आणि डिव्हाइस मालक सेट करण्याची अॅप्सना अनुमती द्या."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"चालणारे अॅप्स पुनर्क्रमित करा"</string>
-    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"समोर आणि पार्श्वभूमीवर कार्ये हलविण्यासाठी अॅप ला अनुमती देते. अॅप हे आपल्या इनपुटशिवाय करू शकतो."</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"समोर आणि पार्श्वभूमीवर कार्ये हलविण्यासाठी अ‍ॅप ला अनुमती देते. अ‍ॅप हे आपल्या इनपुटशिवाय करू शकतो."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"कार मोड सुरू करा"</string>
-    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"कार मोड सक्षम करण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"कार मोड सक्षम करण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"अन्य अॅप्स बंद करा"</string>
-    <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"अन्य अॅप्सच्या पार्श्वभूमी प्रक्रिया समाप्त करण्यासाठी अॅप ला अनुमती देते. यामुळे अन्य अॅप्स चालणे थांबू शकते."</string>
-    <string name="permlab_systemAlertWindow" msgid="7238805243128138690">"हा अॅप इतर अॅप्सच्या शीर्षस्थानी दिसू शकतो."</string>
-    <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"हे अॅप इतर अॅप्सच्या शीर्षस्थानी किंवा स्क्रीनच्या इतर भागांवर दिसू शकतो. हे सामान्य अॅप वापरात व्यत्यय आणू शकते किंवा इतर अॅप्सची डिस्प्ले पद्धत बदलू शकते."</string>
+    <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"अन्य अ‍ॅप्सच्या पार्श्वभूमी प्रक्रिया समाप्त करण्यासाठी अ‍ॅप ला अनुमती देते. यामुळे अन्य अ‍ॅप्स चालणे थांबू शकते."</string>
+    <string name="permlab_systemAlertWindow" msgid="7238805243128138690">"हा अ‍ॅप इतर अ‍ॅप्सच्या शीर्षस्थानी दिसू शकतो."</string>
+    <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"हे अ‍ॅप इतर अ‍ॅप्सच्या शीर्षस्थानी किंवा स्क्रीनच्या इतर भागांवर दिसू शकतो. हे सामान्य अ‍ॅप वापरात व्यत्यय आणू शकते किंवा इतर अ‍ॅप्सची डिस्प्ले पद्धत बदलू शकते."</string>
     <string name="permlab_runInBackground" msgid="7365290743781858803">"पार्श्वभूमीत चालवा"</string>
-    <string name="permdesc_runInBackground" msgid="7370142232209999824">"हे अॅप पार्श्वभूमीत चालू शकते. हे बॅटरी अधिक जलद संपवू शकते."</string>
+    <string name="permdesc_runInBackground" msgid="7370142232209999824">"हे अ‍ॅप पार्श्वभूमीत चालू शकते. हे बॅटरी अधिक जलद संपवू शकते."</string>
     <string name="permlab_useDataInBackground" msgid="8694951340794341809">"पार्श्वभूमीत डेटा वापरा"</string>
     <string name="permdesc_useDataInBackground" msgid="6049514223791806027">"हे अ‍ॅप पार्श्वभूमीत डेटा वापरू शकते. हे डेटाचा वापर वाढवू शकते."</string>
-    <string name="permlab_persistentActivity" msgid="8841113627955563938">"अॅप नेहमी चालवा"</string>
-    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"अॅप ला मेमरीमध्ये कायम असलेले त्याचे स्वतःचे भाग बनविण्यास अनुमती देते. हे टॅबलेट धीमा करून अन्य अॅप्सवर उपलब्ध असलेल्या मेमरीवर मर्यादा घालू शकते."</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"अ‍ॅप नेहमी चालवा"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"अ‍ॅप ला मेमरीमध्ये कायम असलेले त्याचे स्वतःचे भाग बनविण्यास अनुमती देते. हे टॅबलेट धीमा करून अन्य अ‍ॅप्सवर उपलब्ध असलेल्या मेमरीवर मर्यादा घालू शकते."</string>
     <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"अॅपला मेमरीमध्ये कायम असलेले त्याचे स्वतःचे भाग बनविण्यासाठी अनुमती देते. हे टीव्ही धीमा करून इतर अॅप्सवर उपलब्ध असलेली मेमरी मर्यादित करू शकते."</string>
-    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"अॅप ला मेमरीमध्ये कायम असलेले त्याचे स्वतःचे भाग बनविण्यास अनुमती देते. हे फोन धीमा करून अन्य अॅप्सवर उपलब्ध असलेल्या मेमरीवर मर्यादा घालू शकते."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"अ‍ॅप ला मेमरीमध्ये कायम असलेले त्याचे स्वतःचे भाग बनविण्यास अनुमती देते. हे फोन धीमा करून अन्य अ‍ॅप्सवर उपलब्ध असलेल्या मेमरीवर मर्यादा घालू शकते."</string>
     <string name="permlab_foregroundService" msgid="3310786367649133115">"पृष्‍ठभाग सेवा रन करा"</string>
     <string name="permdesc_foregroundService" msgid="6471634326171344622">"अ‍ॅपला पृष्‍ठभाग सेवा वापरण्याची अनुमती देते."</string>
-    <string name="permlab_getPackageSize" msgid="7472921768357981986">"अॅप संचयन स्थान मोजा"</string>
-    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"अॅप ला त्याचा कोड, डेटा आणि कॅश   आकार पुनर्प्राप्त करण्यासाठी अनुमती देते"</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"अ‍ॅप संचयन स्थान मोजा"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"अ‍ॅप ला त्याचा कोड, डेटा आणि कॅश   आकार पुनर्प्राप्त करण्यासाठी अनुमती देते"</string>
     <string name="permlab_writeSettings" msgid="2226195290955224730">"सिस्टम सेटिंग्ज सुधारित करा"</string>
-    <string name="permdesc_writeSettings" msgid="7775723441558907181">"सिस्टीमचा सेटिंग्ज डेटा सुधारित करण्यासाठी अॅप ला अनुमती देते. दुर्भावनापूर्ण अॅप्स आपल्या सिस्टीमचे कॉन्फिगरेशन दूषित करू शकतात."</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"सिस्टीमचा सेटिंग्ज डेटा सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. दुर्भावनापूर्ण अ‍ॅप्स आपल्या सिस्टीमचे कॉन्फिगरेशन दूषित करू शकतात."</string>
     <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"सुरूवातीस चालवा"</string>
-    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"जसे सिस्टम बूट करणे समाप्त करते तसे अॅप ला स्वतः प्रारंभ करण्यास अनुमती देते. यामुळे टॅबलेट प्रारंभ करण्यास वेळ लागू शकतो आणि नेहमी चालू राहून एकंदर टॅबलेटला धीमे करण्यास अॅप ला अनुमती देते."</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"जसे सिस्टम बूट करणे समाप्त करते तसे अ‍ॅप ला स्वतः प्रारंभ करण्यास अनुमती देते. यामुळे टॅबलेट प्रारंभ करण्यास वेळ लागू शकतो आणि नेहमी चालू राहून एकंदर टॅबलेटला धीमे करण्यास अ‍ॅप ला अनुमती देते."</string>
     <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"सिस्टम बूट करणे समाप्त करते तसेच अॅपने स्वतः प्रारंभ करण्यास त्याला अनुमती देते. यामुळे टीव्ही प्रारंभ करण्यासाठी त्यास जास्त वेळ लागू शकतो आणि नेहमी चालू ठेवून संपूर्ण टॅबलेट धीमे करण्यासाठी अॅपला अनुमती देते."</string>
-    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"जसे सिस्टम बूट करणे समाप्त करते तसे अॅप ला स्वतः प्रारंभ करण्यास अनुमती देते. यामुळे फोन प्रारंभ करण्यास वेळ लागू शकतो आणि नेहमी चालू राहून एकंदर फोनला धीमे करण्यास अॅप ला अनुमती देते."</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"जसे सिस्टम बूट करणे समाप्त करते तसे अ‍ॅप ला स्वतः प्रारंभ करण्यास अनुमती देते. यामुळे फोन प्रारंभ करण्यास वेळ लागू शकतो आणि नेहमी चालू राहून एकंदर फोनला धीमे करण्यास अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_broadcastSticky" msgid="7919126372606881614">"रोचक प्रसारण पाठवा"</string>
-    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"रोचक प्रसारणे पाठविण्यासाठी अॅप ला अनुमती देते, जे प्रसारण समाप्त झाल्यानंतर देखील तसेच राहते. अत्याधिक वापरामुळे बरीच मेमरी वापरली जाऊन तो टॅब्लेटला धीमा किंवा अस्थिर करू शकतो."</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"रोचक प्रसारणे पाठविण्यासाठी अ‍ॅप ला अनुमती देते, जे प्रसारण समाप्त झाल्यानंतर देखील तसेच राहते. अत्याधिक वापरामुळे बरीच मेमरी वापरली जाऊन तो टॅब्लेटला धीमा किंवा अस्थिर करू शकतो."</string>
     <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"रोचक प्रसारणे पाठविण्यास अॅपला अनुमती देते, जे प्रसारण समाप्त झाल्यानंतर तसेच रहाते. अतिरिक्त वापर टीव्ही धीमा किंवा यासाठी बरीच मेमरी वापरली जात असल्यामुळे तो अस्थिर करू शकतो."</string>
-    <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"रोचक प्रसारणे पाठविण्यासाठी अॅप ला अनुमती देते, जे प्रसारण समाप्त झाल्यानंतर देखील तसेच राहते. अत्याधिक वापरामुळे बरीच मेमरी वापरली जाऊन तो फोनला धीमा किंवा अस्थिर करू शकतो."</string>
+    <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"रोचक प्रसारणे पाठविण्यासाठी अ‍ॅप ला अनुमती देते, जे प्रसारण समाप्त झाल्यानंतर देखील तसेच राहते. अत्याधिक वापरामुळे बरीच मेमरी वापरली जाऊन तो फोनला धीमा किंवा अस्थिर करू शकतो."</string>
     <string name="permlab_readContacts" msgid="8348481131899886131">"तुमचे संपर्क वाचा"</string>
-    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"तुम्ही कॉल केलेल्या, ईमेल केलेल्या किंवा विशिष्ट लोकांशी अन्य मार्गांनी संवाद प्रस्थापित केलेल्या लोकांच्या फ्रिक्वेन्सीसह, आपल्या टॅब्लेटवर स्टोअर केलेल्या आपल्या संपर्कांविषयीचा डेटा वाचण्यासाठी अॅप ला अनुमती देते. ही परवानगी तुमचा संपर्क डेटा सेव्ह करण्याची अॅप्स ला अनुमती देते आणि दुर्भावनापूर्ण अॅप्स आपल्या माहितीशिवाय संपर्क डेटा शेअर करू शकतात."</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"तुम्ही कॉल केलेल्या, ईमेल केलेल्या किंवा विशिष्ट लोकांशी अन्य मार्गांनी संवाद प्रस्थापित केलेल्या लोकांच्या फ्रिक्वेन्सीसह, आपल्या टॅब्लेटवर स्टोअर केलेल्या आपल्या संपर्कांविषयीचा डेटा वाचण्यासाठी अ‍ॅप ला अनुमती देते. ही परवानगी तुमचा संपर्क डेटा सेव्ह करण्याची अ‍ॅप्स ला अनुमती देते आणि दुर्भावनापूर्ण अ‍ॅप्स आपल्या माहितीशिवाय संपर्क डेटा शेअर करू शकतात."</string>
     <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"तुम्ही विशिष्ट लोकांना इतर मार्गांनी कॉल केलेल्या, ईमेल केलेल्या किंवा संप्रेषित केलेल्या फ्रिक्वेन्सीसह, आपल्या टीव्हीवर स्टोअर केलेल्या आपल्या संपर्कांविषयीचा डेटा वाचण्यासाठी अॅप्सला अनुमती देतात. ही परवागनी अॅप्सला तुमचा संपर्क डेटा सेव्ह करण्यासाठी अनुमती देते आणि दुर्भावनापूर्ण अॅप्स तुम्हाला न कळविता संपर्क डेटा शेअर करू शकतात."</string>
-    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"तुम्ही कॉल केलेल्या, ईमेल केलेल्या किंवा विशिष्ट लोकांशी अन्य मार्गांनी संवाद प्रस्थापित केलेल्या लोकांच्या फ्रिक्वेन्सीसह, आपल्या फोनवर स्टोअर केलेल्या आपल्या संपर्कांविषयीचा डेटा वाचण्यासाठी अॅप ला अनुमती देते. ही परवानगी तुमचा संपर्क डेटा सेव्ह करण्याची अॅप्स ला अनुमती देते आणि दुर्भावनापूर्ण अॅप्स आपल्या माहितीशिवाय संपर्क डेटा शेअर करू शकतात."</string>
+    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"तुम्ही कॉल केलेल्या, ईमेल केलेल्या किंवा विशिष्ट लोकांशी अन्य मार्गांनी संवाद प्रस्थापित केलेल्या लोकांच्या फ्रिक्वेन्सीसह, आपल्या फोनवर स्टोअर केलेल्या आपल्या संपर्कांविषयीचा डेटा वाचण्यासाठी अ‍ॅप ला अनुमती देते. ही परवानगी तुमचा संपर्क डेटा सेव्ह करण्याची अ‍ॅप्स ला अनुमती देते आणि दुर्भावनापूर्ण अ‍ॅप्स आपल्या माहितीशिवाय संपर्क डेटा शेअर करू शकतात."</string>
     <string name="permlab_writeContacts" msgid="5107492086416793544">"तुमचे संपर्क सुधारित करा"</string>
-    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"तुम्ही विशिष्ट संपर्कांशी अन्य मार्गांनी कॉल केलेल्या, ईमेल केलेल्या किंवा संवाद प्रस्थापित केलेल्या फ्रिक्वेन्सीसह, आपल्या टॅब्लेटवर स्टोअर केलेल्या आपल्या संपर्कांविषयीचा डेटा सुधारित करण्यासाठी अॅप ला अनुमती देते. ही परवानगी संपर्क डेटा हटविण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"तुम्ही विशिष्ट संपर्कांशी अन्य मार्गांनी कॉल केलेल्या, ईमेल केलेल्या किंवा संवाद प्रस्थापित केलेल्या फ्रिक्वेन्सीसह, आपल्या टॅब्लेटवर स्टोअर केलेल्या आपल्या संपर्कांविषयीचा डेटा सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. ही परवानगी संपर्क डेटा हटविण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"तुम्ही विशिष्ट संपर्कांशी अन्य मार्गांनी कॉल केलेल्या, ईमेल केलेल्या किंवा संवाद प्रस्थापित केलेल्या फ्रिक्वेन्सीसह, आपल्या टीव्हीवर स्टोअर केलेल्या आपल्या संपर्कांविषयीचा डेटा सुधारित करण्यासाठी अॅपला अनुमती देते. ही परवानगी संपर्क डेटा हटविण्यासाठी अॅपला अनुमती देते."</string>
-    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"तुम्ही विशिष्ट संपर्कांशी अन्य मार्गांनी कॉल केलेल्या, ईमेल केलेल्या किंवा संवाद प्रस्थापित केलेल्या फ्रिक्वेन्सीसह, आपल्या फोनवर स्टोअर केलेल्या आपल्या संपर्कांविषयीचा डेटा सुधारित करण्यासाठी अॅप ला अनुमती देते. ही परवानगी संपर्क डेटा हटविण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"तुम्ही विशिष्ट संपर्कांशी अन्य मार्गांनी कॉल केलेल्या, ईमेल केलेल्या किंवा संवाद प्रस्थापित केलेल्या फ्रिक्वेन्सीसह, आपल्या फोनवर स्टोअर केलेल्या आपल्या संपर्कांविषयीचा डेटा सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. ही परवानगी संपर्क डेटा हटविण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_readCallLog" msgid="3478133184624102739">"कॉल लॉग वाचा"</string>
-    <string name="permdesc_readCallLog" msgid="3204122446463552146">"हा अॅप तुमचा कॉल इतिहास वाचू शकता."</string>
+    <string name="permdesc_readCallLog" msgid="3204122446463552146">"हा अ‍ॅप तुमचा कॉल इतिहास वाचू शकता."</string>
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"कॉल लॉग लिहा"</string>
-    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"येणार्‍या आणि केल्या जाणार्‍या कॉलविषयीच्या डेटासह, आपल्या टॅब्लेटचा कॉल लॉग सुधारित करण्यासाठी अॅप ला अनुमती देते. दुर्भावनापूर्ण अॅप्स तुमचा कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"येणार्‍या आणि केल्या जाणार्‍या कॉलविषयीच्या डेटासह, आपल्या टॅब्लेटचा कॉल लॉग सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. दुर्भावनापूर्ण अ‍ॅप्स तुमचा कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
     <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"येणार्‍या आणि केल्या जाणार्‍या कॉलविषयीच्या डेटासह, आपल्या टीव्हीचा कॉल लॉग सुधारित करण्यासाठी अॅपला अनुमती देते. दुर्भावनापूर्ण अॅप्स तुमचा कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
-    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"येणार्‍या आणि केल्या जाणार्‍या कॉलविषयीच्या डेटासह, आपल्या फोनचा कॉल लॉग सुधारित करण्यासाठी अॅप ला अनुमती देते. दुर्भावनापूर्ण अॅप्स तुमचा कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"येणार्‍या आणि केल्या जाणार्‍या कॉलविषयीच्या डेटासह, आपल्या फोनचा कॉल लॉग सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. दुर्भावनापूर्ण अ‍ॅप्स तुमचा कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
     <string name="permlab_bodySensors" msgid="4683341291818520277">"शरीर सेंसर (हृदय गती मॉनिटरसारखे) अॅक्सेस करा"</string>
     <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"हृदय गती सारख्या, आपल्या शारीरिक स्थितीचे नियंत्रण करणार्‍या सेन्सरवरून डेटामध्ये प्रवेश करण्यासाठी अॅपला अनुमती देते."</string>
     <string name="permlab_readCalendar" msgid="6716116972752441641">"कॅलेंडर इव्हेंट आणि तपशील वाचा"</string>
-    <string name="permdesc_readCalendar" product="tablet" msgid="4993979255403945892">"हा अॅप आपल्या टॅब्लेटवर स्टोअर केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि शेअर करू शकतो किंवा तुमचा कॅलेंडर डेटा सेव्ह करू शकतो."</string>
-    <string name="permdesc_readCalendar" product="tv" msgid="8837931557573064315">"हा अॅप आपल्या टीव्हीवर स्टोअर केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि शेअर करू शकतो किंवा तुमचा कॅलेंडर डेटा सेव्ह करू शकतो."</string>
-    <string name="permdesc_readCalendar" product="default" msgid="4373978642145196715">"हा अॅप आपल्या फोनवर स्टोअर केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि शेअर करू शकतो किंवा तुमचा कॅलेंडर डेटा सेव्ह करू शकतो."</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4993979255403945892">"हा अ‍ॅप आपल्या टॅब्लेटवर स्टोअर केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि शेअर करू शकतो किंवा तुमचा कॅलेंडर डेटा सेव्ह करू शकतो."</string>
+    <string name="permdesc_readCalendar" product="tv" msgid="8837931557573064315">"हा अ‍ॅप आपल्या टीव्हीवर स्टोअर केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि शेअर करू शकतो किंवा तुमचा कॅलेंडर डेटा सेव्ह करू शकतो."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="4373978642145196715">"हा अ‍ॅप आपल्या फोनवर स्टोअर केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि शेअर करू शकतो किंवा तुमचा कॅलेंडर डेटा सेव्ह करू शकतो."</string>
     <string name="permlab_writeCalendar" msgid="8438874755193825647">"कॅलेंडर इव्हेंट जोडा किंवा बदला आणि मालकाला न कळवता अतिथींना ईमेल पाठवा"</string>
-    <string name="permdesc_writeCalendar" product="tablet" msgid="1675270619903625982">"हा अॅप आपल्या टॅब्लेटवर कॅलेंडर इव्हेंट जोडू, काढू किंवा बदलू शकतो. हा अॅप कॅलेंडर मालकांकडून येत आहेत असे वाटणारे मेसेज पाठवू किंवा त्यांच्या मालकांना सूचित केल्याशिवाय इव्हेंट बदलू शकतो."</string>
-    <string name="permdesc_writeCalendar" product="tv" msgid="9017809326268135866">"हा अॅप आपल्या टीव्हीवर कॅलेंडर इव्हेंट जोडू, काढू किंवा बदलू शकतो. हा अॅप कॅलेंडर मालकांकडून येत आहेत असे वाटणारे मेसेज पाठवू किंवा त्यांच्या मालकांना सूचित केल्याशिवाय इव्हेंट बदलू शकतो."</string>
-    <string name="permdesc_writeCalendar" product="default" msgid="7592791790516943173">"हा अॅप आपल्या फोनवर कॅलेंडर इव्हेंट जोडू, काढू किंवा बदलू शकतो. हा अॅप कॅलेंडर मालकांकडून येत आहेत असे वाटणारे मेसेज पाठवू किंवा त्यांच्या मालकांना सूचित केल्याशिवाय इव्हेंट बदलू शकतो."</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="1675270619903625982">"हा अ‍ॅप आपल्या टॅब्लेटवर कॅलेंडर इव्हेंट जोडू, काढू किंवा बदलू शकतो. हा अ‍ॅप कॅलेंडर मालकांकडून येत आहेत असे वाटणारे मेसेज पाठवू किंवा त्यांच्या मालकांना सूचित केल्याशिवाय इव्हेंट बदलू शकतो."</string>
+    <string name="permdesc_writeCalendar" product="tv" msgid="9017809326268135866">"हा अ‍ॅप आपल्या टीव्हीवर कॅलेंडर इव्हेंट जोडू, काढू किंवा बदलू शकतो. हा अ‍ॅप कॅलेंडर मालकांकडून येत आहेत असे वाटणारे मेसेज पाठवू किंवा त्यांच्या मालकांना सूचित केल्याशिवाय इव्हेंट बदलू शकतो."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="7592791790516943173">"हा अ‍ॅप आपल्या फोनवर कॅलेंडर इव्हेंट जोडू, काढू किंवा बदलू शकतो. हा अ‍ॅप कॅलेंडर मालकांकडून येत आहेत असे वाटणारे मेसेज पाठवू किंवा त्यांच्या मालकांना सूचित केल्याशिवाय इव्हेंट बदलू शकतो."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"अतिरिक्त स्थान प्रदाता आदेश अॅक्सेस करा"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"अ‍ॅपला अतिरिक्त स्‍थान प्रदाता आदेशावर प्रवेश करण्‍याची अनुमती देते. हे कदाचित अ‍ॅपला GPS किंवा इतर स्‍थान स्त्रोत च्या ऑपरेशनमध्‍ये हस्तक्षेप करण्‍याची अनुमती देऊ शकते."</string>
     <string name="permlab_accessFineLocation" msgid="6265109654698562427">"फक्त फोरग्राउंडमध्ये अचूकपणे अ‍ॅक्सेस करा"</string>
     <string name="permdesc_accessFineLocation" msgid="3520508381065331098">"हे अ‍ॅप फक्त फोरग्राउंडमध्ये असतानाच तुमचे अचूक स्थान मिळवू शकते. या स्थान सेवा सुरू करणे आणि त्या वापरण्यासाठी अ‍ॅपसाठी तुमच्या फोनवर उपलब्ध करणे आवश्यक आहे, यामुळे बॅटरी वापर वाढू शकतो."</string>
     <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"फक्त फोरग्राउंडमध्ये अंदाजे स्थान (नेटवर्क आधारित) अ‍ॅक्सेस करा"</string>
-    <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"हे अ‍ॅप फक्त फोरग्राउंडमध्ये असतानाच, सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतवर आधारित तुमचे स्थान मिळवू शकते. त्या वापरण्याकरता अॅपसाठी, या स्थान सेवा सुरू करणे आणि त्या तुमच्या टॅबलेटवर उपलब्ध करणे आवश्यक आहे."</string>
-    <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"हे अ‍ॅप फक्त फोरग्राउंडमध्ये असतानाच, सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतवर आधारित तुमचे स्थान मिळवू शकते. त्या वापरण्याकरता अॅपसाठी, या स्थान सेवा सुरू करणे आणि त्या तुमच्या टीव्हीवर उपलब्ध करणे आवश्यक आहे."</string>
-    <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"हे अ‍ॅप फक्त फोरग्राउंडमध्ये असतानाच, सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतवर आधारित तुमचे स्थान मिळवू शकते. ते वापरण्याकरता अॅपसाठी, या स्थान सेवा सुरू करणे आणि त्या तुमच्या फोनवर उपलब्ध करणे आवश्यक आहे."</string>
+    <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"हे अ‍ॅप फक्त फोरग्राउंडमध्ये असतानाच, सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतवर आधारित तुमचे स्थान मिळवू शकते. त्या वापरण्याकरता अ‍ॅपसाठी, या स्थान सेवा सुरू करणे आणि त्या तुमच्या टॅबलेटवर उपलब्ध करणे आवश्यक आहे."</string>
+    <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"हे अ‍ॅप फक्त फोरग्राउंडमध्ये असतानाच, सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतवर आधारित तुमचे स्थान मिळवू शकते. त्या वापरण्याकरता अ‍ॅपसाठी, या स्थान सेवा सुरू करणे आणि त्या तुमच्या टीव्हीवर उपलब्ध करणे आवश्यक आहे."</string>
+    <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"हे अ‍ॅप फक्त फोरग्राउंडमध्ये असतानाच, सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतवर आधारित तुमचे स्थान मिळवू शकते. ते वापरण्याकरता अ‍ॅपसाठी, या स्थान सेवा सुरू करणे आणि त्या तुमच्या फोनवर उपलब्ध करणे आवश्यक आहे."</string>
     <string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"बॅकग्राउंडमध्ये स्थान अॅक्सेस करू शकतो"</string>
-    <string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"याला अंदाजे किंवा अचूक स्थान अॅक्सेस करण्यास अतिरिक्त मंजूरी दिल्यास, बॅकग्राउंडमध्ये चालतांना अॅप स्थान अॅक्सेस करू शकतो."</string>
+    <string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"याला अंदाजे किंवा अचूक स्थान अॅक्सेस करण्यास अतिरिक्त मंजूरी दिल्यास, बॅकग्राउंडमध्ये चालतांना अ‍ॅप स्थान अॅक्सेस करू शकतो."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"आपल्या ऑडिओ सेटिंग्ज बदला"</string>
-    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"व्हॉल्यूम आणि आउटपुटसाठी कोणता स्पीकर वापरला आहे यासारख्या समग्र ऑडिओ सेटिंग्ज सुधारित करण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"व्हॉल्यूम आणि आउटपुटसाठी कोणता स्पीकर वापरला आहे यासारख्या समग्र ऑडिओ सेटिंग्ज सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"ऑडिओ रेकॉर्ड"</string>
-    <string name="permdesc_recordAudio" msgid="4245930455135321433">"हा अॅप कोणत्याही वेळी मायक्रोफोन वापरून ऑडिओ रेकॉर्ड करू शकता."</string>
+    <string name="permdesc_recordAudio" msgid="4245930455135321433">"हा अ‍ॅप कोणत्याही वेळी मायक्रोफोन वापरून ऑडिओ रेकॉर्ड करू शकता."</string>
     <string name="permlab_sim_communication" msgid="2935852302216852065">"सिम वर कमांड पाठवा"</string>
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"अ‍ॅप ला सिम वर कमांड पाठविण्‍याची अनुमती देते. हे खूप धोकादायक असते."</string>
     <string name="permlab_activityRecognition" msgid="3634590230567608356">"शारीरिक अॅक्टिव्हिटी ओळखा"</string>
-    <string name="permdesc_activityRecognition" msgid="3143453925156552894">"हे अॅप तुमच्या शारीरिक अॅक्टिव्हिटी ओळखू शकते."</string>
+    <string name="permdesc_activityRecognition" msgid="3143453925156552894">"हे अ‍ॅप तुमच्या शारीरिक अॅक्टिव्हिटी ओळखू शकते."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"चित्रे आणि व्हिडिओ घ्या"</string>
-    <string name="permdesc_camera" msgid="5392231870049240670">"हा अॅप कोणत्याही वेळी कॅमेरा वापरून चित्रेे घेऊ आणि व्ह‍िडिअो रेकॉर्ड करू शकतो."</string>
+    <string name="permdesc_camera" msgid="5392231870049240670">"हा अ‍ॅप कोणत्याही वेळी कॅमेरा वापरून चित्रेे घेऊ आणि व्ह‍िडिअो रेकॉर्ड करू शकतो."</string>
     <string name="permlab_vibrate" msgid="7696427026057705834">"व्हायब्रेट नियंत्रित करा"</string>
-    <string name="permdesc_vibrate" msgid="6284989245902300945">"अॅप ला व्हायब्रेटर नियंत्रित करण्यासाठी अनुमती देते."</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"अ‍ॅप ला व्हायब्रेटर नियंत्रित करण्यासाठी अनुमती देते."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"फोन नंबरवर प्रत्यक्ष कॉल करा"</string>
-    <string name="permdesc_callPhone" msgid="3740797576113760827">"आपल्या हस्तक्षेपाशिवाय फोन नंबरवर कॉल करण्यासाठी अॅप ला अनुमती देते. यामुळे अनपेक्षित शुल्क किंवा कॉल लागू शकतात. लक्षात ठेवा की हे आणीबाणीच्या नंबरवर कॉल करण्यासाठी अॅप ला अनुमती देत नाही. दुर्भावनापूर्ण अॅप्स नी आपल्या पुष्टिकरणाशिवाय कॉल केल्यामुळे तुमचे पैसे खर्च होऊ शकतात."</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"आपल्या हस्तक्षेपाशिवाय फोन नंबरवर कॉल करण्यासाठी अ‍ॅप ला अनुमती देते. यामुळे अनपेक्षित शुल्क किंवा कॉल लागू शकतात. लक्षात ठेवा की हे आणीबाणीच्या नंबरवर कॉल करण्यासाठी अ‍ॅप ला अनुमती देत नाही. दुर्भावनापूर्ण अ‍ॅप्स नी आपल्या पुष्टिकरणाशिवाय कॉल केल्यामुळे तुमचे पैसे खर्च होऊ शकतात."</string>
     <string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS कॉल सेवा अॅक्सेस करा"</string>
     <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"आपल्‍या हस्तक्षेपाशिवाय अ‍ॅपला कॉल करण्‍यासाठी IMS सेवा वापरण्याची अनुमती देते."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"फोन स्थिती आणि ओळख वाचा"</string>
@@ -454,59 +454,59 @@
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"टॅबलेट निष्क्रिय होण्यापासून प्रतिबंधित करा"</string>
     <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"निष्क्रिय होण्यापासून प्रतिबंध करा"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"फोन निष्‍क्रिय होण्‍यापासून प्रतिबंधित करा"</string>
-    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"टॅब्लेटला निष्क्रिय होण्यापासून प्रतिबंधित करण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"टॅब्लेटला निष्क्रिय होण्यापासून प्रतिबंधित करण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permdesc_wakeLock" product="tv" msgid="3208534859208996974">"निष्क्रिय होण्यापासून टीव्हीला प्रतिबंध करण्यासाठी अॅपला अनुमती देते."</string>
-    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"फोनला निष्क्रिय होण्यापासून प्रतिबंधित करण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"फोनला निष्क्रिय होण्यापासून प्रतिबंधित करण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_transmitIr" msgid="7545858504238530105">"इन्फ्रारेड प्रक्षेपण करा"</string>
     <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"अ‍ॅप ला टॅब्‍लेटच्‍या इन्‍फ्रारेड ट्रान्‍समीटरचा वापर करण्‍याची अनुमती देते."</string>
     <string name="permdesc_transmitIr" product="tv" msgid="3926790828514867101">"टीव्हीचे इन्फ्रारेड ट्रान्समीटर वापरण्यासाठी अॅपला अनुमती देते."</string>
     <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"अ‍ॅप ला फोनच्‍या इन्‍फ्रारेड ट्रान्‍समीटरचा वापर करण्‍याची अनुमती देते."</string>
     <string name="permlab_setWallpaper" msgid="6627192333373465143">"वॉलपेपर सेट करा"</string>
-    <string name="permdesc_setWallpaper" msgid="7373447920977624745">"सिस्टम वॉलपेपर सेट करण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_setWallpaper" msgid="7373447920977624745">"सिस्टम वॉलपेपर सेट करण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"तुमचा वॉलपेपर आकार समायोजित करा"</string>
-    <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"सिस्टम वॉलपेपर आकार सूचना सेट करण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"सिस्टम वॉलपेपर आकार सूचना सेट करण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_setTimeZone" msgid="2945079801013077340">"टाइम झोन सेट करा"</string>
-    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"टॅब्लेटचा टाइम झोन बदलण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"टॅब्लेटचा टाइम झोन बदलण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"टीव्हीचा टाईम झोन बदलण्यासाठी अॅपला अनुमती देते."</string>
-    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"फोनचा टाइम झोन बदलण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"फोनचा टाइम झोन बदलण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_getAccounts" msgid="1086795467760122114">"डिव्हाइसवरील खाती शोधा"</string>
-    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"टॅब्लेटद्वारे ज्ञात खात्यांची सूची मिळवण्यासाठी अॅप ला अनुमती देते. यात तुम्ही इंस्टॉल केलेल्या अनुप्रयोगांद्वारे तयार केलेली कोणतीही खाती समाविष्ट होऊ शकतात."</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"टॅब्लेटद्वारे ज्ञात खात्यांची सूची मिळवण्यासाठी अ‍ॅप ला अनुमती देते. यात तुम्ही इंस्टॉल केलेल्या अनुप्रयोगांद्वारे तयार केलेली कोणतीही खाती समाविष्ट होऊ शकतात."</string>
     <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"टीव्हीद्वारे ज्ञात खात्यांची सूची मिळविण्यासाठी अॅपला अनुमती देतो. यात तुम्ही इंस्टॉल केलेल्या अनुप्रयोगांद्वारे तयार केलेली कोणतीही खाती समाविष्ट असू शकतात."</string>
-    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"फोनद्वारे ज्ञात खात्यांची सूची मिळवण्यासाठी अॅप ला अनुमती देते. यात तुम्ही इंस्टॉल केलेल्या अनुप्रयोगांद्वारे तयार केलेली कोणतीही खाती समाविष्ट करू शकतात."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"फोनद्वारे ज्ञात खात्यांची सूची मिळवण्यासाठी अ‍ॅप ला अनुमती देते. यात तुम्ही इंस्टॉल केलेल्या अनुप्रयोगांद्वारे तयार केलेली कोणतीही खाती समाविष्ट करू शकतात."</string>
     <string name="permlab_accessNetworkState" msgid="4951027964348974773">"नेटवर्क कनेक्शन पहा"</string>
-    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"कोणती नेटवर्क अस्तित्वात आहेत आणि कनेक्ट केलेली आहेत यासारख्या नेटवर्क कनेक्शनविषयीची माहिती पाहण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"कोणती नेटवर्क अस्तित्वात आहेत आणि कनेक्ट केलेली आहेत यासारख्या नेटवर्क कनेक्शनविषयीची माहिती पाहण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_createNetworkSockets" msgid="7934516631384168107">"पूर्ण नेटवर्क प्रवेश आहे"</string>
-    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"नेटवर्क सॉकेट तयार करण्यासाठी आणि कस्टम नेटवर्क प्रोटोकॉल वापरण्यासाठी अॅप ला अनुमती देते. ब्राउझर आणि अन्य अॅप्लिकेशन म्हणजे इंटरनेटवर डेटा पाठवण्याचा मार्ग, म्हणजे इंटरनेटवर डेटा पाठविण्यासाठी परवानगीची आवश्यकता नसते."</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"नेटवर्क सॉकेट तयार करण्यासाठी आणि कस्टम नेटवर्क प्रोटोकॉल वापरण्यासाठी अ‍ॅप ला अनुमती देते. ब्राउझर आणि अन्य अ‍ॅप्लिकेशन म्हणजे इंटरनेटवर डेटा पाठवण्याचा मार्ग, म्हणजे इंटरनेटवर डेटा पाठविण्यासाठी परवानगीची आवश्यकता नसते."</string>
     <string name="permlab_changeNetworkState" msgid="958884291454327309">"नेटवर्क कनेक्टिव्हिटी बदला"</string>
-    <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"नेटवर्क कनेक्टिव्हिटीची स्थिती बदलण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"नेटवर्क कनेक्टिव्हिटीची स्थिती बदलण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_changeTetherState" msgid="5952584964373017960">"टिथर केलेली कनेक्टिव्हिटी बदला"</string>
-    <string name="permdesc_changeTetherState" msgid="1524441344412319780">"टेदर केलेल्या नेटवर्क कनेक्टिव्हिटीची स्थिती बदलण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_changeTetherState" msgid="1524441344412319780">"टेदर केलेल्या नेटवर्क कनेक्टिव्हिटीची स्थिती बदलण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_accessWifiState" msgid="5202012949247040011">"वाय-फाय कनेक्शन पहा"</string>
-    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"वाय-फाय सक्षम केले आहे किंवा नाही आणि कनेक्ट केलेल्या वाय-फाय डीव्हाइसचे नाव यासारख्या, वाय-फाय नेटवर्किंग विषयीची माहिती पाहण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"वाय-फाय सक्षम केले आहे किंवा नाही आणि कनेक्ट केलेल्या वाय-फाय डीव्हाइसचे नाव यासारख्या, वाय-फाय नेटवर्किंग विषयीची माहिती पाहण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_changeWifiState" msgid="6550641188749128035">"वाय-फाय वरून कनेक्ट करा आणि डिस्कनेक्ट करा"</string>
     <string name="permdesc_changeWifiState" msgid="7137950297386127533">"वाय-फाय अॅक्सेस बिंदूंवर कनेक्ट करण्यासाठी आणि त्यावरून डिस्कनेक्ट करण्यासाठी आणि वाय-फाय नेटवर्कसाठी डिव्हाइस कॉंफिगरेशनमध्ये बदल करण्यासाठी अॅपला अनुमती देते."</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"वाय-फाय मल्‍टिकास्‍ट रिसेप्‍शनला अनुमती द्या"</string>
-    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"मल्टिकास्ट पत्ते वापरून फक्त तुमच्या टॅब्लेटवर नाही, तर वाय-फाय नेटवर्कवरील सर्व डीव्हाइसवर पाठविलेले पॅकेट प्राप्त करण्यासाठी अॅप ला अनुमती देते. हे मल्टिकास्टखेरिज इतर मोडसाठी अधिक पॉवर वापरते."</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"मल्टिकास्ट पत्ते वापरून फक्त तुमच्या टॅब्लेटवर नाही, तर वाय-फाय नेटवर्कवरील सर्व डीव्हाइसवर पाठविलेले पॅकेट प्राप्त करण्यासाठी अ‍ॅप ला अनुमती देते. हे मल्टिकास्टखेरिज इतर मोडसाठी अधिक पॉवर वापरते."</string>
     <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"केवळ तुमचा टीव्ही न वापरता, एकाधिक पत्ते वापरून एका वाय-फाय नेटवकवरील सर्व डीव्हाइसवर पाठविलेली पॅकेट प्राप्त करण्यासाठी अॅपला अनुमती देते."</string>
-    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"मल्टिकास्ट पत्ते वापरून फक्त तुमच्या फोनवर नाही, तर वाय-फाय नेटवर्कवरील सर्व डीव्हाइसवर पाठविलेले पॅकेट प्राप्त करण्यासाठी अॅप ला अनुमती देते. हे मल्टिकास्टखेरिज इतर मोडसाठी अधिक पॉवर वापरते."</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"मल्टिकास्ट पत्ते वापरून फक्त तुमच्या फोनवर नाही, तर वाय-फाय नेटवर्कवरील सर्व डीव्हाइसवर पाठविलेले पॅकेट प्राप्त करण्यासाठी अ‍ॅप ला अनुमती देते. हे मल्टिकास्टखेरिज इतर मोडसाठी अधिक पॉवर वापरते."</string>
     <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"ब्लूटूथ सेटिंग्ज अॅक्सेस करा"</string>
-    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"स्थानिक ब्लूटूथ टॅबलेट कॉंफिगर करण्याकरिता आणि दूरस्थ डिव्हाइस शोधण्यासाठी आणि त्यासह जोडण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"स्थानिक ब्लूटूथ टॅबलेट कॉंफिगर करण्याकरिता आणि दूरस्थ डिव्हाइस शोधण्यासाठी आणि त्यासह जोडण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"स्थानिक ब्लूटूथ टीव्ही कॉंफिगर करण्यासाठी आणि दूरस्थ डीव्हाइससह शोधण्यासाठी आणि जोडण्यासाठी अॅपला अनुमती देते."</string>
-    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"स्थानिक ब्लूटूथ फोन कॉंफिगर करण्याकरिता आणि दूरस्थ डिव्हाइस शोधण्यासाठी आणि त्यासह जोडण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"स्थानिक ब्लूटूथ फोन कॉंफिगर करण्याकरिता आणि दूरस्थ डिव्हाइस शोधण्यासाठी आणि त्यासह जोडण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_accessWimaxState" msgid="4195907010610205703">"WiMAX कनेक्ट करा आणि त्यावरून डिस्कनेक्ट करा"</string>
-    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"WiMAX सक्षम केले आहे किंवा नाही आणि कनेक्ट केलेल्या कोणत्याही WiMAX नेटवर्क विषयीची माहिती निर्धारित करण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"WiMAX सक्षम केले आहे किंवा नाही आणि कनेक्ट केलेल्या कोणत्याही WiMAX नेटवर्क विषयीची माहिती निर्धारित करण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_changeWimaxState" msgid="340465839241528618">"WiMAX स्थिती बदला"</string>
-    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"WiMAX नेटवर्कवर टॅबलेट कनेक्ट करण्यास आणि त्यावरून टॅबलेट डिस्कनेक्ट करण्यास अॅप ला अनुमती देते."</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"WiMAX नेटवर्कवर टॅबलेट कनेक्ट करण्यास आणि त्यावरून टॅबलेट डिस्कनेक्ट करण्यास अ‍ॅप ला अनुमती देते."</string>
     <string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"WiMAX नेटवर्कवरून टीव्ही कनेक्ट करण्यासाठी आणि त्यावरून टीव्ही डिस्कनेक्ट करण्यासाठी अॅपला अनुमती देते."</string>
-    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"WiMAX नेटवर्कवर फोन कनेक्ट करण्यास आणि त्यावरून फोन डिस्कनेक्ट करण्यास अॅप ला अनुमती देते."</string>
+    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"WiMAX नेटवर्कवर फोन कनेक्ट करण्यास आणि त्यावरून फोन डिस्कनेक्ट करण्यास अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_bluetooth" msgid="6127769336339276828">"ब्लूटूथ डीव्हाइससह जोडा"</string>
-    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"टॅबलेटवर ब्लूटूथ चे कॉंफिगरेशन पाहण्यासाठी आणि पेअर केलेल्या डीव्हाइससह कनेक्शन इंस्टॉल करण्यासाठी आणि स्वीकारण्यासाठी, अॅप ला अनुमती देते."</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"टॅबलेटवर ब्लूटूथ चे कॉंफिगरेशन पाहण्यासाठी आणि पेअर केलेल्या डीव्हाइससह कनेक्शन इंस्टॉल करण्यासाठी आणि स्वीकारण्यासाठी, अ‍ॅप ला अनुमती देते."</string>
     <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"टीव्हीवर ब्लूटूथचे कॉंफिगरेशन पाहण्यासाठी आणि जोडलेल्या डीव्हाइससह कनेक्शन इंस्टॉल करण्यासाठी आणि स्वीकारण्यासाठी अॅपला अनुमती देते."</string>
-    <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"फोनवर ब्लूटूथ चे कॉंफिगरेशन पाहण्यासाठी आणि पेअर केलेल्या डीव्हाइससह कनेक्शन इंस्टॉल करण्यासाठी आणि स्वीकारण्यासाठी, अॅप ला अनुमती देते."</string>
+    <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"फोनवर ब्लूटूथ चे कॉंफिगरेशन पाहण्यासाठी आणि पेअर केलेल्या डीव्हाइससह कनेक्शन इंस्टॉल करण्यासाठी आणि स्वीकारण्यासाठी, अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"फील्ड जवळील कम्युनिकेशन नियंत्रित करा"</string>
     <string name="permdesc_nfc" msgid="7120611819401789907">"फील्ड जवळील कम्युनिकेशन (NFC) टॅग, कार्डे आणि वाचक यांच्यासह संवाद करण्यासाठी अॅपला अनुमती देते."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"तुमचे स्क्रीन लॉक अक्षम करा"</string>
-    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"कीलॉक आणि कोणतीही संबद्ध पासवर्ड सुरक्षितता अक्षम करण्यासाठी अॅप ला अनुमती देते. उदाहरणार्थ, येणारा फोन कॉल प्राप्त करताना फोन कीलॉक अक्षम करतो, नंतर जेव्हा कॉल समाप्त होतो तेव्हा तो कीलॉक पुन्हा-सक्षम करतो."</string>
+    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"कीलॉक आणि कोणतीही संबद्ध पासवर्ड सुरक्षितता अक्षम करण्यासाठी अ‍ॅप ला अनुमती देते. उदाहरणार्थ, येणारा फोन कॉल प्राप्त करताना फोन कीलॉक अक्षम करतो, नंतर जेव्हा कॉल समाप्त होतो तेव्हा तो कीलॉक पुन्हा-सक्षम करतो."</string>
     <string name="permlab_useBiometric" msgid="8837753668509919318">"बायोमेट्रिक हार्डवेअर वापरा"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"ऑथेंटिकेशनसाठी बायोमेट्रिक हार्डवेअरचा वापर करण्याची अॅपला अनुमती देते"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"फिंगरप्रिंट हार्डवेअर व्यवस्थापित करा"</string>
@@ -591,11 +591,11 @@
   </string-array>
     <string name="face_icon_content_description" msgid="4024817159806482191">"चेहरा आयकन"</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"सिंक सेटिंग्‍ज वाचा"</string>
-    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"खात्याच्या सिंक सेटिंग्ज वाचण्यासाठी अॅप ला अनुमती देते. उदाहरणार्थ, हे खात्यासह लोकांचा अॅप संकालित केला आहे किंवा नाही हे निर्धारित करू शकते."</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"खात्याच्या सिंक सेटिंग्ज वाचण्यासाठी अ‍ॅप ला अनुमती देते. उदाहरणार्थ, हे खात्यासह लोकांचा अ‍ॅप संकालित केला आहे किंवा नाही हे निर्धारित करू शकते."</string>
     <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"सिंक चालू आणि बंद करा टॉगल करा"</string>
-    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"खात्यासाठी सिंक सेटिंग्ज सुधारित करण्यासाठी अॅप ला अनुमती देते. उदाहरणार्थ, हे खात्यासह लोकांच्या अॅप चे सिंक सक्षम करण्यासाठी वापरले जाऊ शकते."</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"खात्यासाठी सिंक सेटिंग्ज सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. उदाहरणार्थ, हे खात्यासह लोकांच्या अ‍ॅप चे सिंक सक्षम करण्यासाठी वापरले जाऊ शकते."</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"सिंक आकडेवारी वाचा"</string>
-    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"सिंक इव्हेंटचा इतिहास आणि किती डेटाचे सिंक केले आहे यासह, खात्याची सिंक स्थिती वाचण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"सिंक इव्हेंटचा इतिहास आणि किती डेटाचे सिंक केले आहे यासह, खात्याची सिंक स्थिती वाचण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_sdcardRead" msgid="1438933556581438863">"तुमच्या शेअर केलेल्या स्टोरेजचे आशय वाचते"</string>
     <string name="permdesc_sdcardRead" msgid="1804941689051236391">"अॅपला तुमच्या शेअर केलेल्या स्टोरेजचे आशय वाचण्याची अनुमती देते."</string>
     <string name="permlab_sdcardWrite" msgid="9220937740184960897">"तुमच्या शेअर केलेल्या स्टोरेजच्या आशयांमध्ये सुधारणा करा किंवा हटवा"</string>
@@ -607,17 +607,17 @@
     <string name="permlab_register_call_provider" msgid="108102120289029841">"नवीन टेलिकॉम कनेक्शनची नोंदणी करा"</string>
     <string name="permdesc_register_call_provider" msgid="7034310263521081388">"नवीन टेलिकॉम कनेक्शनची नोंदणी करण्यासाठी अॅपला अनुमती देते."</string>
     <string name="permlab_connection_manager" msgid="1116193254522105375">"टेलिकॉम कनेक्शन व्यवस्थापित करा"</string>
-    <string name="permdesc_connection_manager" msgid="5925480810356483565">"टेलिकॉम कनेक्शन व्यवस्थापित करण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_connection_manager" msgid="5925480810356483565">"टेलिकॉम कनेक्शन व्यवस्थापित करण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_bind_incall_service" msgid="6773648341975287125">"कॉल-मधील स्‍क्रीनशी परस्‍परसंवाद करा"</string>
     <string name="permdesc_bind_incall_service" msgid="8343471381323215005">"वापरकर्ता कॉल-मधील स्‍क्रीन केव्‍हा आणि कशी पाहतो ते नियंत्रित करण्‍याची अ‍ॅपला अनुमती देते."</string>
     <string name="permlab_bind_connection_service" msgid="3557341439297014940">"टेलिफोनी सेवांशी परस्परसंवाद साधा"</string>
-    <string name="permdesc_bind_connection_service" msgid="4008754499822478114">"कॉल करण्यासाठी/घेण्यासाठी टेलिफोनी सेवांशी परस्परसंवाद साधण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_bind_connection_service" msgid="4008754499822478114">"कॉल करण्यासाठी/घेण्यासाठी टेलिफोनी सेवांशी परस्परसंवाद साधण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_control_incall_experience" msgid="9061024437607777619">"एक कॉल-मधील वापरकर्ता अनुभव प्रदान करा"</string>
     <string name="permdesc_control_incall_experience" msgid="915159066039828124">"अ‍ॅप्सला कॉल-मधील वापरकर्ता अनुभव प्रदान करण्‍याची अनुमती देते."</string>
     <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"ऐतिहासिक नेटवर्क वापर वाचा"</string>
     <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"विशिष्ट नेटवर्क आणि अ‍ॅप्सकरिता ऐतिहासिक नेटवर्क वापराचे वाचन करण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"नेटवर्क धोरण व्यवस्थापित करा"</string>
-    <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"नेटवर्क धोरणे व्यवस्थापित करण्यासाठी आणि अॅप-विशिष्ट नियम परिभाषित करण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"नेटवर्क धोरणे व्यवस्थापित करण्यासाठी आणि अ‍ॅप-विशिष्ट नियम परिभाषित करण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"नेटवर्क वापर हिशोब सुधारित करा"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"अॅप्स वर नेटवर्क वापराचा हिशोब कसा घेतला जातो हे सुधारित करण्यासाठी अॅप्स ला अनुमती देते. सामान्य अॅप्सद्वारे वापरण्यासाठी नाही."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"प्रवेश सूचना"</string>
@@ -633,7 +633,7 @@
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"नेटवर्क स्‍थितींवरील निरीक्षणांसाठी ऐका"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"अनु्प्रयोगाला नेटवर्क स्‍थितींवरील निरीक्षणे ऐकण्‍यासाठी अनुमती देते. सामान्‍य अ‍ॅप्‍ससाठी कधीही आवश्‍यक नसावे."</string>
     <string name="permlab_setInputCalibration" msgid="4902620118878467615">"इनपुट डिव्हाइस कॅलिब्रेशन बदला"</string>
-    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"स्पर्श स्क्रीनची कॅलिब्रेशन प्राचले सुधारित करण्यासाठी अॅप ला अनुमती देते. सामान्य अॅप्स साठी कधीही आवश्यक नसते."</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"स्पर्श स्क्रीनची कॅलिब्रेशन प्राचले सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. सामान्य अ‍ॅप्स साठी कधीही आवश्यक नसते."</string>
     <string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM प्रमाणपत्रे अॅक्सेस करा"</string>
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"DRM प्रमाणपत्रांची तरतूद करण्यासाठी आणि वापरण्यासाठी अनुप्रयोगास अनुमती देते. सामान्य अॅप्सकरिता कधीही आवश्यकता नसते."</string>
     <string name="permlab_handoverStatus" msgid="7820353257219300883">"Android बीम स्थानांतरण स्थिती प्राप्त करा"</string>
@@ -672,7 +672,7 @@
     <string name="policylab_expirePassword" msgid="5610055012328825874">"स्क्रीन लॉक पासवर्ड कालबाह्यता सेट करा"</string>
     <string name="policydesc_expirePassword" msgid="5367525762204416046">"लॉक-स्क्रीन पासवर्ड किती वारंवार बदलणे आवश्यक आहे ते बदला."</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"स्टोरेज एंक्रिप्शन सेट करा"</string>
-    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"स्टोअर केलेला अॅप डेटा एंक्रिप्ट केला जाणे आवश्यक आहे."</string>
+    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"स्टोअर केलेला अ‍ॅप डेटा एंक्रिप्ट केला जाणे आवश्यक आहे."</string>
     <string name="policylab_disableCamera" msgid="6395301023152297826">"कॅमेरे अक्षम करा"</string>
     <string name="policydesc_disableCamera" msgid="2306349042834754597">"सर्व डिव्हाइस कॅमेर्‍यांचा वापर प्रतिबंधित करा."</string>
     <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"काही स्क्रीन लॉक वैशिष्‍ट्ये अक्षम करा"</string>
@@ -897,7 +897,7 @@
     <string name="granularity_label_link" msgid="5815508880782488267">"लिंक"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"रेखा"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"फॅक्टरी चाचणी अयशस्वी"</string>
-    <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST क्रिया फक्त /सिस्टम/अॅप मध्ये इंस्टॉल केलेल्या पॅकेजसाठी समर्थित आहे."</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST क्रिया फक्त /सिस्टम/अ‍ॅप मध्ये इंस्टॉल केलेल्या पॅकेजसाठी समर्थित आहे."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST क्रिया प्रदान करणारे कोणतेही पॅकेज आढळले नाही."</string>
     <string name="factorytest_reboot" msgid="6320168203050791643">"रीबूट करा"</string>
     <string name="js_dialog_title" msgid="1987483977834603872">"\"<xliff:g id="TITLE">%s</xliff:g>\" वरील पृष्ठ हे म्हणते:"</string>
@@ -928,17 +928,17 @@
     <string name="autofill_area" msgid="3547409050889952423">"क्षेत्र"</string>
     <string name="autofill_emirate" msgid="2893880978835698818">"अमिरात"</string>
     <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"तुमचे वेब बुकमार्क आणि इतिहास वाचा"</string>
-    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"ब्राउझरने भेट दिलेल्या सर्व URL चा इतिहास आणि ब्राउझरचे सर्व बुकमार्क वाचण्यास अॅप ला अनुमती देते. टीप: या परवानगीची तृतीय-पक्ष ब्राउझरद्वारे किंवा वेब ब्राउझिंग क्षमता असलेल्या अन्य अनुप्रयोगांद्वारे अंमलबजावणी करू शकत नाही."</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"ब्राउझरने भेट दिलेल्या सर्व URL चा इतिहास आणि ब्राउझरचे सर्व बुकमार्क वाचण्यास अ‍ॅप ला अनुमती देते. टीप: या परवानगीची तृतीय-पक्ष ब्राउझरद्वारे किंवा वेब ब्राउझिंग क्षमता असलेल्या अन्य अनुप्रयोगांद्वारे अंमलबजावणी करू शकत नाही."</string>
     <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"वेब बुकमार्क आणि इतिहास लिहा"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"तुमच्या टॅब्लेटवर स्टोअर केलेला ब्राउझरचा इतिहास किंवा बुकमार्क सुधारित करण्यासाठी अॅप ला अनुमती देते. हे ब्राउझर डेटा मिटविण्यासाठी किंवा सुधारित करण्यासाठी अॅप ला अनुमती देते. टीप: ही परवानगी तृतीय पक्ष ब्राउझरद्वारे किंवा वेब ब्राउझिंग क्षमतांसह अन्य अॅप्लिकेशनद्वारे अंमलबजावणी करण्याची टीप देऊ शकते."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"तुमच्या टॅब्लेटवर स्टोअर केलेला ब्राउझरचा इतिहास किंवा बुकमार्क सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. हे ब्राउझर डेटा मिटविण्यासाठी किंवा सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. टीप: ही परवानगी तृतीय पक्ष ब्राउझरद्वारे किंवा वेब ब्राउझिंग क्षमतांसह अन्य अ‍ॅप्लिकेशनद्वारे अंमलबजावणी करण्याची टीप देऊ शकते."</string>
     <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"तुमच्या टीव्हीवर स्टोअर केलेला ब्राउझरचा इतिहास किंवा बुकमार्क सुधारित करण्यासाठी अॅपला अनुमती देते. हे ब्राउझर डेटा मिटविण्यासाठी किंवा सुधारित करण्यासाठी अॅपला अनुमती देऊ शकते. टीप: या परवानगीची अंमलबजावणी वेब ब्राउझिंग क्षमता असलेल्या तृतीय-पक्ष ब्राउझरद्वारे किंवा इतर अॅप्लिकेशनद्वारे केली जाऊ शकत नाही."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"तुमच्या फोनवर स्टोअर केलेला ब्राउझरचा इतिहास किंवा बुकमार्क सुधारित करण्यासाठी अॅप ला अनुमती देते. हे ब्राउझर डेटा मिटविण्यासाठी किंवा सुधारित करण्यासाठी अॅप ला अनुमती देते. टीप: ही परवानगी तृतीय पक्ष ब्राउझरद्वारे किंवा वेब ब्राउझिंग क्षमतांसह अन्य अॅप्लिकेशनद्वारे अंमलबजावणी करण्याची टीप देऊ शकते."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"तुमच्या फोनवर स्टोअर केलेला ब्राउझरचा इतिहास किंवा बुकमार्क सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. हे ब्राउझर डेटा मिटविण्यासाठी किंवा सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. टीप: ही परवानगी तृतीय पक्ष ब्राउझरद्वारे किंवा वेब ब्राउझिंग क्षमतांसह अन्य अ‍ॅप्लिकेशनद्वारे अंमलबजावणी करण्याची टीप देऊ शकते."</string>
     <string name="permlab_setAlarm" msgid="1379294556362091814">"अलार्म सेट करा"</string>
     <string name="permdesc_setAlarm" msgid="316392039157473848">"इंस्टॉल केलेल्या अलार्म घड्याळ अॅपमध्ये अलार्म सेट करण्यासाठी अॅपला अनुमती देते. काही अलार्म घड्याळ अॅप्समध्ये हे वैशिष्ट्य नसू शकते."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"व्हॉइसमेल जोडा"</string>
-    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"आपल्या व्हॉइसमेल इनबॉक्समध्ये मेसेज जोडण्यासाठी अॅप ला अनुमती देते."</string>
+    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"आपल्या व्हॉइसमेल इनबॉक्समध्ये मेसेज जोडण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"ब्राउझर भौगोलिक स्थान परवानग्या सुधारित करा"</string>
-    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"ब्राउझरच्या भौगोलिक स्थान परवानग्या सुधारित करण्यासाठी अॅप ला अनुमती देते. दुर्भावनापूर्ण अॅप्स यादृच्छिक वेबसाइटवर स्थान माहिती पाठविण्यास अनुमती देण्यासाठी याचा वापर करू शकतात."</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"ब्राउझरच्या भौगोलिक स्थान परवानग्या सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. दुर्भावनापूर्ण अ‍ॅप्स यादृच्छिक वेबसाइटवर स्थान माहिती पाठविण्यास अनुमती देण्यासाठी याचा वापर करू शकतात."</string>
     <string name="save_password_message" msgid="767344687139195790">"ब्राउझरने हा पासवर्ड लक्षात ठेवावा असे तुम्ही इच्छिता?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"आत्ता नाही"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"लक्षात ठेवा"</string>
@@ -1083,25 +1083,25 @@
     <string name="deleteText" msgid="6979668428458199034">"हटवा"</string>
     <string name="inputMethod" msgid="1653630062304567879">"इनपुट पद्धत"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"मजकूर क्रिया"</string>
-    <string name="email" msgid="4560673117055050403">"ईमेल"</string>
+    <string name="email" msgid="4560673117055050403">"ईमेल करा"</string>
     <string name="email_desc" msgid="3638665569546416795">"निवडलेल्या अॅड्रेसवर ईमेल करा"</string>
     <string name="dial" msgid="1253998302767701559">"कॉल करा"</string>
     <string name="dial_desc" msgid="6573723404985517250">"निवडलेल्या फोन नंबरवर कॉल करा"</string>
-    <string name="map" msgid="5441053548030107189">"नकाशा"</string>
+    <string name="map" msgid="5441053548030107189">"नकाशा उघडा"</string>
     <string name="map_desc" msgid="1836995341943772348">"निवडलेला पत्ता शोधा"</string>
     <string name="browse" msgid="1245903488306147205">"उघडा"</string>
     <string name="browse_desc" msgid="8220976549618935044">"निवडलेली URL उघडा"</string>
-    <string name="sms" msgid="4560537514610063430">"मेसेज"</string>
+    <string name="sms" msgid="4560537514610063430">"मेसेज करा"</string>
     <string name="sms_desc" msgid="7526588350969638809">"निवडलेल्या फोन नंबरवर एसएमएस करा"</string>
     <string name="add_contact" msgid="7867066569670597203">"जोडा"</string>
     <string name="add_contact_desc" msgid="4830217847004590345">"संपर्कांमध्ये जोडा"</string>
-    <string name="view_calendar" msgid="979609872939597838">"पहा"</string>
+    <string name="view_calendar" msgid="979609872939597838">"पाहा"</string>
     <string name="view_calendar_desc" msgid="5828320291870344584">"निवडलेली वेळ कॅलेंडरमध्ये पाहा"</string>
-    <string name="add_calendar_event" msgid="1953664627192056206">"शेड्यूल"</string>
-    <string name="add_calendar_event_desc" msgid="4326891793260687388">"निवडलेल्या वेळेसाठी इव्हेंट शेड्यूल करा"</string>
-    <string name="view_flight" msgid="7691640491425680214">"ट्रॅक"</string>
+    <string name="add_calendar_event" msgid="1953664627192056206">"शेड्युल करा"</string>
+    <string name="add_calendar_event_desc" msgid="4326891793260687388">"निवडलेल्या वेळेसाठी इव्हेंट शेड्युल करा"</string>
+    <string name="view_flight" msgid="7691640491425680214">"ट्रॅक करा"</string>
     <string name="view_flight_desc" msgid="3876322502674253506">"निवडलेले विमान ट्रॅक करा"</string>
-    <string name="translate" msgid="9218619809342576858">"भाषांतर"</string>
+    <string name="translate" msgid="9218619809342576858">"भाषांतर करा"</string>
     <string name="translate_desc" msgid="4502367770068777202">"निवडलेल्या मजकुराचे भाषांतर करा"</string>
     <string name="define" msgid="7394820043869954211">"व्याख्या सांगा"</string>
     <string name="define_desc" msgid="7910883642444919726">"निवडलेल्या मजकुराची व्याख्या सांगा"</string>
@@ -1143,18 +1143,18 @@
     <string name="use_a_different_app" msgid="8134926230585710243">"एक भिन्न अ‍ॅप वापरा"</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"डाउनलोड केलेल्या सिस्टम सेटिंग्ज &gt; Apps &gt; मधील डीफॉल्ट साफ करा."</string>
     <string name="chooseActivity" msgid="7486876147751803333">"क्रिया निवडा"</string>
-    <string name="chooseUsbActivity" msgid="6894748416073583509">"USB डिव्हाइससाठी अॅप निवडा"</string>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"USB डिव्हाइससाठी अ‍ॅप निवडा"</string>
     <string name="noApplications" msgid="2991814273936504689">"कोणतेही अॅप्स ही क्रिया करू शकत नाहीत."</string>
     <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g> थांबला आहे"</string>
     <string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> थांबली आहे"</string>
     <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> थांबतो"</string>
     <string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> थांबते"</string>
-    <string name="aerr_restart" msgid="7581308074153624475">"अॅप पुन्हा उघडा"</string>
+    <string name="aerr_restart" msgid="7581308074153624475">"अ‍ॅप पुन्हा उघडा"</string>
     <string name="aerr_report" msgid="5371800241488400617">"अभिप्राय पाठवा"</string>
     <string name="aerr_close" msgid="2991640326563991340">"बंद करा"</string>
     <string name="aerr_mute" msgid="1974781923723235953">"डिव्हाइस रीस्टार्ट होईपर्यंत म्यूट करा"</string>
     <string name="aerr_wait" msgid="3199956902437040261">"प्रतीक्षा करा"</string>
-    <string name="aerr_close_app" msgid="3269334853724920302">"अॅप बंद करा"</string>
+    <string name="aerr_close_app" msgid="3269334853724920302">"अ‍ॅप बंद करा"</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
     <string name="anr_activity_application" msgid="8493290105678066167">"<xliff:g id="APPLICATION">%2$s</xliff:g> प्रतिसाद देत नाही"</string>
     <string name="anr_activity_process" msgid="1622382268908620314">"<xliff:g id="ACTIVITY">%1$s</xliff:g> प्रतिसाद देत नाही"</string>
@@ -1164,7 +1164,7 @@
     <string name="report" msgid="4060218260984795706">"अहवाल द्या"</string>
     <string name="wait" msgid="7147118217226317732">"प्रतीक्षा करा"</string>
     <string name="webpage_unresponsive" msgid="3272758351138122503">"पृष्ठ प्रतिसाद न देणारे झाले आहे.\n\nतुम्ही हे बंद करू इच्छिता?"</string>
-    <string name="launch_warning_title" msgid="1547997780506713581">"अॅप पुनर्निर्देशित केला"</string>
+    <string name="launch_warning_title" msgid="1547997780506713581">"अ‍ॅप पुनर्निर्देशित केला"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> आता चालत आहे."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> मूळतः लाँच केले."</string>
     <string name="screen_compat_mode_scale" msgid="3202955667675944499">"स्केल"</string>
@@ -1175,7 +1175,7 @@
     <string name="unsupported_compile_sdk_message" msgid="4253168368781441759">"<xliff:g id="APP_NAME">%1$s</xliff:g> हे Android OS च्या विसंगत आवृत्तीसाठी तयार केले होते आणि ते अनपेक्षित पद्धतीने काम करू शकते. अॅपची अपडेट केलेली आवृत्ती उपलब्ध असू शकते."</string>
     <string name="unsupported_compile_sdk_show" msgid="2681877855260970231">"नेहमी दर्शवा"</string>
     <string name="unsupported_compile_sdk_check_update" msgid="3312723623323216101">"अपडेट आहे का ते तपासा"</string>
-    <string name="smv_application" msgid="3307209192155442829">"अॅप <xliff:g id="APPLICATION">%1$s</xliff:g> (प्रक्रिया <xliff:g id="PROCESS">%2$s</xliff:g>) ने तिच्या स्वयं-लागू केलेल्या StrictMode धोरणाचे उल्लंघन केले आहे."</string>
+    <string name="smv_application" msgid="3307209192155442829">"अ‍ॅप <xliff:g id="APPLICATION">%1$s</xliff:g> (प्रक्रिया <xliff:g id="PROCESS">%2$s</xliff:g>) ने तिच्या स्वयं-लागू केलेल्या StrictMode धोरणाचे उल्लंघन केले आहे."</string>
     <string name="smv_process" msgid="5120397012047462446">"<xliff:g id="PROCESS">%1$s</xliff:g> प्रक्रियेने तिच्या स्वतः-लागू केलेल्या StrictMode धोरणाचे उल्लंघन केले."</string>
     <string name="android_upgrading_title" product="default" msgid="7513829952443484438">"फोन अपडेट होत आहे…"</string>
     <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"टॅबलेट अपडेट होत आहे…"</string>
@@ -1186,7 +1186,7 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"संचयन ऑप्टिमाइझ करत आहे."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="1511552415039349062">"सिस्‍टम अपडेट संपत आहे…"</string>
     <string name="app_upgrading_toast" msgid="3008139776215597053">"<xliff:g id="APPLICATION">%1$s</xliff:g> श्रेणीसुधारित करत आहे…"</string>
-    <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> पैकी <xliff:g id="NUMBER_0">%1$d</xliff:g> अॅप ऑप्टिमाइझ करत आहे."</string>
+    <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> पैकी <xliff:g id="NUMBER_0">%1$d</xliff:g> अ‍ॅप ऑप्टिमाइझ करत आहे."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> तयार करत आहे."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"अॅप्स प्रारंभ करत आहे."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"बूट समाप्त होत आहे."</string>
@@ -1288,7 +1288,7 @@
     <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> वर फोन कनेक्ट केलेला असताना तो वाय-फाय वरून तात्पुरता डिस्कनेक्ट केला जाईल"</string>
     <string name="select_character" msgid="3365550120617701745">"वर्ण घाला"</string>
     <string name="sms_control_title" msgid="7296612781128917719">"SMS मेसेज पाठवत आहे"</string>
-    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; मोठ्या संख्येने SMS मेसेज पाठवत आहे. तुम्ही या अॅप ला मेसेज पाठविणे सुरु ठेवण्याची अनुमती देऊ इच्छिता?"</string>
+    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; मोठ्या संख्येने SMS मेसेज पाठवत आहे. तुम्ही या अ‍ॅप ला मेसेज पाठविणे सुरु ठेवण्याची अनुमती देऊ इच्छिता?"</string>
     <string name="sms_control_yes" msgid="3663725993855816807">"अनुमती द्या"</string>
     <string name="sms_control_no" msgid="625438561395534982">"नकार द्या"</string>
     <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; हा &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;वर एक मेसेज पाठवू इच्छितो."</string>
@@ -1445,7 +1445,7 @@
     <string name="no_file_chosen" msgid="6363648562170759465">"फाईल निवडली नाही"</string>
     <string name="reset" msgid="2448168080964209908">"रीसेट करा"</string>
     <string name="submit" msgid="1602335572089911941">"सबमिट करा"</string>
-    <string name="car_mode_disable_notification_title" msgid="5704265646471239078">"ड्रायव्हिंग अॅप चालू आहे"</string>
+    <string name="car_mode_disable_notification_title" msgid="5704265646471239078">"ड्रायव्हिंग अ‍ॅप चालू आहे"</string>
     <string name="car_mode_disable_notification_message" msgid="7647248420931129377">"ड्रायव्हिंग अॅपमधून बाहेर पाडण्यासाठी टॅप करा."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"टेदरिंग किंवा हॉटस्पॉट सक्रिय"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"सेट करण्यासाठी टॅप करा."</string>
@@ -1774,7 +1774,7 @@
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"आपल्या प्रशासकाने हटवले"</string>
     <string name="battery_saver_description_with_learn_more" msgid="6323937147992667707">"बॅटरी लाइफ वाढवण्‍यासाठी, बॅटरी सेव्‍हर काही डिव्‍हाइस वैशिष्‍ट्ये बंद करते आणि अॅप्‍सना प्रतिबंधित करते. "<annotation id="url">"अधिक जाणून घ्‍या"</annotation></string>
     <string name="battery_saver_description" msgid="769989536172631582">"बॅटरी लाइफ वाढवण्‍यासाठी, बॅटरी सेव्‍हर काही वैशिष्‍ट्ये बंद करते आणि अॅप्‍स प्रतिबंधित करते."</string>
-    <string name="data_saver_description" msgid="6015391409098303235">"डेटा वापर कमी करण्यात मदत करण्यासाठी, डेटा सर्व्हर काही अॅप्सना पार्श्वभूमीमध्ये डेटा पाठविण्यास किंवा प्राप्त करण्यास प्रतिबंधित करतो. तुम्ही सध्या वापरत असलेला अॅप डेटामध्ये प्रवेश करू शकतो परंतु तसे तो खूप कमी वेळा करू शकतो. याचा अर्थ, उदाहरणार्थ, तुम्ही इमेज टॅप करेपर्यंत त्या प्रदर्शित करणार नाहीत असा असू शकतो."</string>
+    <string name="data_saver_description" msgid="6015391409098303235">"डेटा वापर कमी करण्यात मदत करण्यासाठी, डेटा सर्व्हर काही अ‍ॅप्सना पार्श्वभूमीमध्ये डेटा पाठविण्यास किंवा प्राप्त करण्यास प्रतिबंधित करतो. तुम्ही सध्या वापरत असलेला अ‍ॅप डेटामध्ये प्रवेश करू शकतो परंतु तसे तो खूप कमी वेळा करू शकतो. याचा अर्थ, उदाहरणार्थ, तुम्ही इमेज टॅप करेपर्यंत त्या प्रदर्शित करणार नाहीत असा असू शकतो."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"डेटा बचतकर्ता चालू करायचा?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"चालू करा"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
@@ -1861,16 +1861,16 @@
     <string name="language_picker_section_all" msgid="3097279199511617537">"सर्व भाषा"</string>
     <string name="region_picker_section_all" msgid="8966316787153001779">"सर्व प्रदेश"</string>
     <string name="locale_search_menu" msgid="2560710726687249178">"शोध"</string>
-    <string name="app_suspended_title" msgid="2075071241147969611">"अॅप उपलब्ध नाही"</string>
+    <string name="app_suspended_title" msgid="2075071241147969611">"अ‍ॅप उपलब्ध नाही"</string>
     <string name="app_suspended_default_message" msgid="123166680425711887">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> आत्ता उपलब्ध नाही. हे <xliff:g id="APP_NAME_1">%2$s</xliff:g> कडून व्यवस्थापित केले जाते."</string>
     <string name="app_suspended_more_details" msgid="1131804827776778187">"अधिक जाणून घ्या"</string>
     <string name="work_mode_off_title" msgid="1118691887588435530">"कार्य प्रोफाइल चालू ठेवायची?"</string>
     <string name="work_mode_off_message" msgid="5130856710614337649">"तुमची कार्य अ‍ॅप्स, सूचना, डेटा आणि अन्य कार्य प्रोफाइल वैशिष्ट्ये चालू केली जातील"</string>
     <string name="work_mode_turn_on" msgid="2062544985670564875">"चालू करा"</string>
-    <string name="deprecated_target_sdk_message" msgid="1449696506742572767">"हे अॅप Android च्या जुन्या आवृत्ती साठी तयार करण्यात आले होते आणि योग्यरितीने कार्य करू शकणार नाही. अपडेट आहेत का ते तपासून पाहा, किंवा डेव्हलपरशी संपर्क साधण्याचा प्रयत्न करा."</string>
+    <string name="deprecated_target_sdk_message" msgid="1449696506742572767">"हे अ‍ॅप Android च्या जुन्या आवृत्ती साठी तयार करण्यात आले होते आणि योग्यरितीने कार्य करू शकणार नाही. अपडेट आहेत का ते तपासून पाहा, किंवा डेव्हलपरशी संपर्क साधण्याचा प्रयत्न करा."</string>
     <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"अपडेट आहे का ते तपासा"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"आपल्याकडे नवीन मेसेज आहेत"</string>
-    <string name="new_sms_notification_content" msgid="7002938807812083463">"पाहण्‍यासाठी SMS अॅप उघडा"</string>
+    <string name="new_sms_notification_content" msgid="7002938807812083463">"पाहण्‍यासाठी SMS अ‍ॅप उघडा"</string>
     <string name="user_encrypted_title" msgid="9054897468831672082">"काही कार्यक्षमता मर्यादित असू शकतात"</string>
     <string name="user_encrypted_message" msgid="4923292604515744267">"अनलॉक करण्यासाठी टॅप करा"</string>
     <string name="user_encrypted_detail" msgid="5708447464349420392">"वापरकर्ता डेटा लॉक केला"</string>
@@ -1880,7 +1880,7 @@
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"फायली पाहण्यासाठी टॅप करा"</string>
     <string name="pin_target" msgid="3052256031352291362">"पिन"</string>
     <string name="unpin_target" msgid="3556545602439143442">"अनपिन करा"</string>
-    <string name="app_info" msgid="6856026610594615344">"अॅप माहिती"</string>
+    <string name="app_info" msgid="6856026610594615344">"अ‍ॅप माहिती"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"डेमो प्रारंभ करत आहे..."</string>
     <string name="demo_restarting_message" msgid="952118052531642451">"डिव्हाइस रीसेट करत आहे..."</string>
@@ -1945,13 +1945,13 @@
     <string name="popup_window_default_title" msgid="4874318849712115433">"पॉपअप विंडो"</string>
     <string name="slice_more_content" msgid="8504342889413274608">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
     <string name="shortcut_restored_on_lower_version" msgid="4860853725206702336">"अ‍ॅपची आवृत्ती डाउनग्रेड केली, किंवा ती या शॉर्टकटशी कंपॅटिबल नाही"</string>
-    <string name="shortcut_restore_not_supported" msgid="5028808567940014190">"अॅप बॅकअप आणि रिस्‍टोअर करण्यास सपोर्ट देत नसल्यामुळे शॉर्टकट रिस्‍टोअर करू शकलो नाही"</string>
-    <string name="shortcut_restore_signature_mismatch" msgid="2406209324521327518">"अॅप स्वाक्षरी न जुळल्यामुळे शॉर्टकट रिस्‍टोअर करू शकलो नाही"</string>
+    <string name="shortcut_restore_not_supported" msgid="5028808567940014190">"अ‍ॅप बॅकअप आणि रिस्‍टोअर करण्यास सपोर्ट देत नसल्यामुळे शॉर्टकट रिस्‍टोअर करू शकलो नाही"</string>
+    <string name="shortcut_restore_signature_mismatch" msgid="2406209324521327518">"अ‍ॅप स्वाक्षरी न जुळल्यामुळे शॉर्टकट रिस्‍टोअर करू शकलो नाही"</string>
     <string name="shortcut_restore_unknown_issue" msgid="8703738064603262597">"शॉर्टकट रिस्‍टोअर करू शकलो नाही"</string>
     <string name="shortcut_disabled_reason_unknown" msgid="5276016910284687075">"शॉर्टकट बंद केलेला आहे"</string>
     <string name="harmful_app_warning_uninstall" msgid="4837672735619532931">"अनइंस्टॉल करा"</string>
     <string name="harmful_app_warning_open_anyway" msgid="596432803680914321">"तरीही उघडा"</string>
-    <string name="harmful_app_warning_title" msgid="8982527462829423432">"हानिकारक अॅप आढळला"</string>
+    <string name="harmful_app_warning_title" msgid="8982527462829423432">"हानिकारक अ‍ॅप आढळला"</string>
     <string name="slices_permission_request" msgid="8484943441501672932">"<xliff:g id="APP_0">%1$s</xliff:g> ला <xliff:g id="APP_2">%2$s</xliff:g> चे तुकडे दाखवायचे आहेत"</string>
     <string name="screenshot_edit" msgid="7867478911006447565">"संपादित करा"</string>
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="8902050240801159042">"कॉल आणि सूचनांवर व्हायब्रेट होईल"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 39afd74..a3da75e 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1083,24 +1083,24 @@
     <string name="deleteText" msgid="6979668428458199034">"ဖျက်ရန်"</string>
     <string name="inputMethod" msgid="1653630062304567879">"ထည့်သွင်းရန်နည်းလမ်း"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"စာတို လုပ်ဆောင်ချက်"</string>
-    <string name="email" msgid="4560673117055050403">"အီးမေးလ်"</string>
+    <string name="email" msgid="4560673117055050403">"အီးမေးလ်ပို့ရန်"</string>
     <string name="email_desc" msgid="3638665569546416795">"ရွေးထားသည့် လိပ်စာသို့ အီးမေးလ်ပို့ရန်"</string>
     <string name="dial" msgid="1253998302767701559">"ခေါ်ဆိုရန်"</string>
     <string name="dial_desc" msgid="6573723404985517250">"ရွေးထားသည့် ဖုန်းနံပါတ်ကို ခေါ်ရန်"</string>
-    <string name="map" msgid="5441053548030107189">"မြေပုံ"</string>
+    <string name="map" msgid="5441053548030107189">"မြေပုံဖွင့်ရန်"</string>
     <string name="map_desc" msgid="1836995341943772348">"ရွေးထားသည့် လိပ်စာကို ရှာဖွေရန်"</string>
     <string name="browse" msgid="1245903488306147205">"ဖွင့်ရန်"</string>
     <string name="browse_desc" msgid="8220976549618935044">"ရွေးထားသည့် URL ကို ဖွင့်ရန်"</string>
-    <string name="sms" msgid="4560537514610063430">"SMS"</string>
+    <string name="sms" msgid="4560537514610063430">"SMS ပို့ရန်"</string>
     <string name="sms_desc" msgid="7526588350969638809">"ရွေးထားသည့် ဖုန်းနံပါတ်ကို မက်ဆေ့ဂျ်ပို့ရန်"</string>
     <string name="add_contact" msgid="7867066569670597203">"ထည့်ရန်"</string>
     <string name="add_contact_desc" msgid="4830217847004590345">"အဆက်အသွယ်များသို့ ထည့်ရန်"</string>
     <string name="view_calendar" msgid="979609872939597838">"ကြည့်ရန်"</string>
     <string name="view_calendar_desc" msgid="5828320291870344584">"ရွေးထားသည့် အချိန်ကို ပြက္ခဒိန်တွင် ကြည့်ရန်"</string>
-    <string name="add_calendar_event" msgid="1953664627192056206">"အချိန်ဇယား"</string>
+    <string name="add_calendar_event" msgid="1953664627192056206">"အစီအစဉ်ထည့်ရန်"</string>
     <string name="add_calendar_event_desc" msgid="4326891793260687388">"ရွေးထားသည့်အချိန်အတွက် အစီအစဉ်ပြုလုပ်ရန်"</string>
     <string name="view_flight" msgid="7691640491425680214">"ရှာရန်"</string>
-    <string name="view_flight_desc" msgid="3876322502674253506">"ရွေးထားသည့် လေယာဉ်ခရီးစဉ်ကို ရှာဖွေရန်"</string>
+    <string name="view_flight_desc" msgid="3876322502674253506">"ရွေးထားသည့် လေယာဉ်ခရီးစဉ်ကို ရှာရန်"</string>
     <string name="translate" msgid="9218619809342576858">"ဘာသာပြန်ရန်"</string>
     <string name="translate_desc" msgid="4502367770068777202">"ရွေးထားသောစာသားကို ဘာသာပြန်ရန်"</string>
     <string name="define" msgid="7394820043869954211">"အဓိပ္ပာယ်ဖွင့်ဆိုရန်"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index f606d77..30cd600 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1265,7 +1265,7 @@
   </string-array>
     <string name="network_switch_type_name_unknown" msgid="4552612897806660656">"en ukjent nettverkstype"</string>
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Kan ikke koble til Wi-Fi"</string>
-    <string name="wifi_watchdog_network_disabled_detailed" msgid="4917472096696322767">" har en dårlig Internett-tilkobling."</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="4917472096696322767">" har en dårlig internettilkobling."</string>
     <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Vil du tillat tilkoblingen?"</string>
     <string name="wifi_connect_alert_message" msgid="6451273376815958922">"Appen %1$s vil koble til Wi-Fi-nettverket %2$s"</string>
     <string name="wifi_connect_default_application" msgid="7143109390475484319">"En app"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index a6bd007..2ff9fde 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -247,7 +247,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"Instellingen"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"Helpen"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Spraakassistent"</string>
-    <string name="global_action_lockdown" msgid="1099326950891078929">"Afgesloten"</string>
+    <string name="global_action_lockdown" msgid="1099326950891078929">"Lockdown"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999 +"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"Nieuwe melding"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtueel toetsenbord"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 1d1f3e7..e3fe527 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1083,7 +1083,7 @@
     <string name="deleteText" msgid="6979668428458199034">"ਮਿਟਾਓ"</string>
     <string name="inputMethod" msgid="1653630062304567879">"ਇਨਪੁੱਟ ਵਿਧੀ"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"ਟੈਕਸਟ ਕਿਰਿਆਵਾਂ"</string>
-    <string name="email" msgid="4560673117055050403">"ਈਮੇਲ ਕਰੋ"</string>
+    <string name="email" msgid="4560673117055050403">"ਈਮੇਲ ਖੋਲ੍ਹੋ"</string>
     <string name="email_desc" msgid="3638665569546416795">"ਚੁਣੇ ਹੋਏ ਪਤੇ \'ਤੇ ਈਮੇਲ ਭੇਜੋ"</string>
     <string name="dial" msgid="1253998302767701559">"ਕਾਲ ਕਰੋ"</string>
     <string name="dial_desc" msgid="6573723404985517250">"ਚੁਣੇ ਗਏ ਫ਼ੋਨ ਨੰਬਰ \'ਤੇ ਕਾਲ ਕਰੋ"</string>
@@ -1097,11 +1097,11 @@
     <string name="add_contact_desc" msgid="4830217847004590345">"ਸੰਪਰਕਾਂ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="view_calendar" msgid="979609872939597838">"ਦੇਖੋ"</string>
     <string name="view_calendar_desc" msgid="5828320291870344584">"ਕੈਲੰਡਰ ਵਿੱਚ ਚੁਣਿਆ ਗਿਆ ਸਮਾਂ ਦੇਖੋ"</string>
-    <string name="add_calendar_event" msgid="1953664627192056206">"ਸਮਾਂ-ਸੂਚੀ"</string>
+    <string name="add_calendar_event" msgid="1953664627192056206">"ਸਮਾਂ-ਸੂਚੀ ਬਣਾਓ"</string>
     <string name="add_calendar_event_desc" msgid="4326891793260687388">"ਚੁਣੇ ਗਏ ਸਮੇਂ ਲਈ ਇਵੈਂਟ ਦੀ ਸਮਾਂ-ਸੂਚੀ ਬਣਾਓ"</string>
     <string name="view_flight" msgid="7691640491425680214">"ਟਰੈਕ ਕਰੋ"</string>
     <string name="view_flight_desc" msgid="3876322502674253506">"ਚੁਣੀ ਗਈ ਉਡਾਣ ਨੂੰ ਟਰੈਕ ਕਰੋ"</string>
-    <string name="translate" msgid="9218619809342576858">"ਅਨੁਵਾਦ"</string>
+    <string name="translate" msgid="9218619809342576858">"ਅਨੁਵਾਦ ਕਰੋ"</string>
     <string name="translate_desc" msgid="4502367770068777202">"ਚੋਣਵੀਂ ਲਿਖਤ ਦਾ ਅਨੁਵਾਦ ਕਰੋ"</string>
     <string name="define" msgid="7394820043869954211">"ਪਰਿਭਾਸ਼ਾ ਦਿਓ"</string>
     <string name="define_desc" msgid="7910883642444919726">"ਚੋਣਵੀਂ ਲਿਖਤ ਦਾ ਅਨੁਵਾਦ ਕਰੋ"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 9a70f0b..0790e90 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1123,26 +1123,26 @@
     <string name="deleteText" msgid="6979668428458199034">"Izbriši"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Način vnosa"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Besedilna dejanja"</string>
-    <string name="email" msgid="4560673117055050403">"E-pošta"</string>
+    <string name="email" msgid="4560673117055050403">"Pošlji e-pošto"</string>
     <string name="email_desc" msgid="3638665569546416795">"Pošlji na izbrani naslov"</string>
     <string name="dial" msgid="1253998302767701559">"Pokliči"</string>
     <string name="dial_desc" msgid="6573723404985517250">"Pokliči izbrano telefonsko številko"</string>
-    <string name="map" msgid="5441053548030107189">"Zemljevid"</string>
+    <string name="map" msgid="5441053548030107189">"Odpri zemljevid"</string>
     <string name="map_desc" msgid="1836995341943772348">"Poišči izbrani naslov na zemljevidu"</string>
     <string name="browse" msgid="1245903488306147205">"Odpri"</string>
     <string name="browse_desc" msgid="8220976549618935044">"Odpri izbrani URL"</string>
-    <string name="sms" msgid="4560537514610063430">"Sporočilo"</string>
+    <string name="sms" msgid="4560537514610063430">"Pošlji SMS"</string>
     <string name="sms_desc" msgid="7526588350969638809">"Pošlji sporočilo na izbrano telefonsko številko"</string>
     <string name="add_contact" msgid="7867066569670597203">"Dodaj"</string>
     <string name="add_contact_desc" msgid="4830217847004590345">"Dodaj med stike"</string>
-    <string name="view_calendar" msgid="979609872939597838">"Ogled"</string>
-    <string name="view_calendar_desc" msgid="5828320291870344584">"Ogled izbranega časa v koledarju"</string>
+    <string name="view_calendar" msgid="979609872939597838">"Prikaži"</string>
+    <string name="view_calendar_desc" msgid="5828320291870344584">"Prikaži izbrani čas v koledarju"</string>
     <string name="add_calendar_event" msgid="1953664627192056206">"Dodaj na razpored"</string>
     <string name="add_calendar_event_desc" msgid="4326891793260687388">"Razporedi dogodek na izbrano uro"</string>
-    <string name="view_flight" msgid="7691640491425680214">"Sledenje"</string>
+    <string name="view_flight" msgid="7691640491425680214">"Sledi"</string>
     <string name="view_flight_desc" msgid="3876322502674253506">"Sledi izbranemu letu"</string>
     <string name="translate" msgid="9218619809342576858">"Prevedi"</string>
-    <string name="translate_desc" msgid="4502367770068777202">"Prevod izbranega besedila"</string>
+    <string name="translate_desc" msgid="4502367770068777202">"Prevedi izbrano besedilo"</string>
     <string name="define" msgid="7394820043869954211">"Opredeli"</string>
     <string name="define_desc" msgid="7910883642444919726">"Opredeli izbrano besedilo"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Prostor za shranjevanje bo pošel"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 25171b8..51ac513 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1096,10 +1096,10 @@
     <string name="add_contact" msgid="7867066569670597203">"Ongeza"</string>
     <string name="add_contact_desc" msgid="4830217847004590345">"Ongeza kwenye anwani"</string>
     <string name="view_calendar" msgid="979609872939597838">"Angalia"</string>
-    <string name="view_calendar_desc" msgid="5828320291870344584">"Angalia wakati uliyochagua katika kalenda"</string>
-    <string name="add_calendar_event" msgid="1953664627192056206">"Ratiba"</string>
+    <string name="view_calendar_desc" msgid="5828320291870344584">"Angalia wakati uliochagua katika kalenda"</string>
+    <string name="add_calendar_event" msgid="1953664627192056206">"Ratibu"</string>
     <string name="add_calendar_event_desc" msgid="4326891793260687388">"Ratibu tukio la wakati uliochagua"</string>
-    <string name="view_flight" msgid="7691640491425680214">"Toleo"</string>
+    <string name="view_flight" msgid="7691640491425680214">"Fuatilia"</string>
     <string name="view_flight_desc" msgid="3876322502674253506">"Fuatilia ndege uliyochagua"</string>
     <string name="translate" msgid="9218619809342576858">"Tafsiri"</string>
     <string name="translate_desc" msgid="4502367770068777202">"Tafsiri maandishi yaliyochaguliwa"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 492bad5..f59cfcb 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1091,7 +1091,7 @@
     <string name="map_desc" msgid="1836995341943772348">"搵出指定地址"</string>
     <string name="browse" msgid="1245903488306147205">"開啟"</string>
     <string name="browse_desc" msgid="8220976549618935044">"打開指定網址"</string>
-    <string name="sms" msgid="4560537514610063430">"短訊"</string>
+    <string name="sms" msgid="4560537514610063430">"發短訊"</string>
     <string name="sms_desc" msgid="7526588350969638809">"Send 短訊去指定電話號碼"</string>
     <string name="add_contact" msgid="7867066569670597203">"新增"</string>
     <string name="add_contact_desc" msgid="4830217847004590345">"加入通訊錄"</string>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index f8004ea..ab4bd05 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -271,6 +271,9 @@
         <!-- Additional flag from base permission type: this permission will be granted to the
              wellbeing app, as defined by the OEM. -->
         <flag name="wellbeing" value="0x20000" />
+        <!-- Additional flag from base permission type: this permission can be automatically
+            granted to the document manager -->
+        <flag name="documenter" value="0x40000" />
     </attr>
 
     <!-- Flags indicating more context for a permission group. -->
diff --git a/core/tests/coretests/src/android/os/BinderWorkSourceService.java b/core/tests/coretests/src/android/os/BinderWorkSourceService.java
index ac8d7ab..3bca5fb 100644
--- a/core/tests/coretests/src/android/os/BinderWorkSourceService.java
+++ b/core/tests/coretests/src/android/os/BinderWorkSourceService.java
@@ -25,9 +25,25 @@
 public class BinderWorkSourceService extends Service {
     private final IBinderWorkSourceService.Stub mBinder =
             new IBinderWorkSourceService.Stub() {
+        public int getBinderCallingUid() {
+            return Binder.getCallingUid();
+        }
+
         public int getIncomingWorkSourceUid() {
             return Binder.getCallingWorkSourceUid();
         }
+
+        public int getThreadLocalWorkSourceUid() {
+            return ThreadLocalWorkSource.getUid();
+        }
+
+        public void setWorkSourceProvider(int uid) {
+            Binder.setWorkSourceProvider(() -> uid);
+        }
+
+        public void clearWorkSourceProvider() {
+            Binder.setWorkSourceProvider(Binder::getCallingUid);
+        }
     };
 
     public IBinder onBind(Intent intent) {
diff --git a/core/tests/coretests/src/android/os/BinderWorkSourceTest.java b/core/tests/coretests/src/android/os/BinderWorkSourceTest.java
index ec17803..d1dbd3c 100644
--- a/core/tests/coretests/src/android/os/BinderWorkSourceTest.java
+++ b/core/tests/coretests/src/android/os/BinderWorkSourceTest.java
@@ -163,4 +163,24 @@
         // Initial work source restored.
         assertEquals(UID, Binder.getCallingWorkSourceUid());
     }
+
+    @Test
+    public void workSourceProvider_default() throws Exception {
+        Binder.clearCallingWorkSource();
+        mService.clearWorkSourceProvider();
+        assertEquals(Process.myUid(), mService.getThreadLocalWorkSourceUid());
+    }
+
+    @Test
+    public void workSourceProvider_customProvider() throws Exception {
+        Binder.clearCallingWorkSource();
+        mService.clearWorkSourceProvider();
+        // Calling uid should not be used.
+        mService.setWorkSourceProvider(SECOND_UID);
+        try {
+            assertEquals(SECOND_UID, mService.getThreadLocalWorkSourceUid());
+        } finally {
+            mService.clearWorkSourceProvider();
+        }
+    }
 }
diff --git a/core/tests/coretests/src/android/os/IBinderWorkSourceService.aidl b/core/tests/coretests/src/android/os/IBinderWorkSourceService.aidl
index 05d4e82..9322400 100644
--- a/core/tests/coretests/src/android/os/IBinderWorkSourceService.aidl
+++ b/core/tests/coretests/src/android/os/IBinderWorkSourceService.aidl
@@ -18,4 +18,8 @@
 
 interface IBinderWorkSourceService {
     int getIncomingWorkSourceUid();
+    int getBinderCallingUid();
+    int getThreadLocalWorkSourceUid();
+    void setWorkSourceProvider(int uid);
+    void clearWorkSourceProvider();
 }
diff --git a/core/tests/coretests/src/android/os/PowerManagerTest.java b/core/tests/coretests/src/android/os/PowerManagerTest.java
index da17b56..a828f44 100644
--- a/core/tests/coretests/src/android/os/PowerManagerTest.java
+++ b/core/tests/coretests/src/android/os/PowerManagerTest.java
@@ -16,13 +16,32 @@
 
 package android.os;
 
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+
 import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.uiautomator.UiDevice;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import org.junit.After;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
 public class PowerManagerTest extends AndroidTestCase {
 
     private PowerManager mPm;
+    private UiDevice mUiDevice;
+    private Executor mExec = Executors.newSingleThreadExecutor();
+    @Mock
+    private PowerManager.ThermalStatusCallback mCallback;
+    private static final long CALLBACK_TIMEOUT_MILLI_SEC = 5000;
 
     /**
      * Setup any common data for the upcoming tests.
@@ -30,7 +49,18 @@
     @Override
     public void setUp() throws Exception {
         super.setUp();
+        MockitoAnnotations.initMocks(this);
+        mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
         mPm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+        mUiDevice.executeShellCommand("cmd thermalservice override-status 0");
+    }
+
+    /**
+     * Reset data for the upcoming tests.
+     */
+    @After
+    public void tearDown() throws Exception {
+        mUiDevice.executeShellCommand("cmd thermalservice reset");
     }
 
     /**
@@ -137,4 +167,35 @@
 
         // TODO: Threaded test (needs handler) to make sure timed wakelocks work too
     }
+
+    @Test
+    public void testGetThermalStatus() throws Exception {
+        int status = 0;
+        assertEquals(status, mPm.getCurrentThermalStatus());
+        status = 3;
+        mUiDevice.executeShellCommand("cmd thermalservice override-status "
+                + Integer.toString(status));
+        assertEquals(status, mPm.getCurrentThermalStatus());
+    }
+
+    @Test
+    public void testThermalStatusCallback() throws Exception {
+        mPm.registerThermalStatusCallback(mCallback, mExec);
+        verify(mCallback, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+                .times(1)).onStatusChange(0);
+        reset(mCallback);
+        int status = 3;
+        mUiDevice.executeShellCommand("cmd thermalservice override-status "
+                + Integer.toString(status));
+        verify(mCallback, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+                .times(1)).onStatusChange(status);
+        reset(mCallback);
+        mPm.unregisterThermalStatusCallback(mCallback);
+        status = 2;
+        mUiDevice.executeShellCommand("cmd thermalservice override-status "
+                + Integer.toString(status));
+        verify(mCallback, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+                .times(0)).onStatusChange(status);
+
+    }
 }
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index ed80cd7..2ad6028 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -19,6 +19,7 @@
 import static android.view.InsetsState.TYPE_TOP_BAR;
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNull;
+import static org.mockito.Mockito.mock;
 
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.FlakyTest;
@@ -33,7 +34,7 @@
 @RunWith(AndroidJUnit4.class)
 public class InsetsControllerTest {
 
-    private InsetsController mController = new InsetsController();
+    private InsetsController mController = new InsetsController(mock(ViewRootImpl.class));
 
     private SurfaceSession mSession = new SurfaceSession();
     private SurfaceControl mLeash;
diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
index 5a20ba2..6d0f984 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
@@ -53,7 +53,7 @@
                 .setName("testSurface")
                 .build();
         mConsumer = new InsetsSourceConsumer(TYPE_TOP_BAR, new InsetsState(),
-                () -> mMockTransaction);
+                () -> mMockTransaction, mMockController);
         mConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mLeash));
     }
 
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
index e261819..97f02cb 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
@@ -57,9 +57,9 @@
         bcs.setSamplingInterval(5);
 
         Binder binder = new Binder();
-        CallSession callSession = bcs.callStarted(binder, 1);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.time += 10;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
         assertEquals(1, uidEntries.size());
@@ -73,17 +73,17 @@
         assertEquals(1, callStatsList.get(0).transactionCode);
 
         // CPU usage is sampled, should not be tracked here.
-        callSession = bcs.callStarted(binder, 1);
+        callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.time += 20;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
         assertEquals(2, uidEntry.callCount);
         assertEquals(1, uidEntry.recordedCallCount);
         assertEquals(10, uidEntry.cpuTimeMicros);
         assertEquals(1, callStatsList.size());
 
-        callSession = bcs.callStarted(binder, 2);
+        callSession = bcs.callStarted(binder, 2, WORKSOURCE_UID);
         bcs.time += 50;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
         uidEntry = bcs.getUidEntries().get(WORKSOURCE_UID);
         assertEquals(3, uidEntry.callCount);
         assertEquals(1, uidEntry.recordedCallCount);
@@ -98,9 +98,9 @@
         bcs.setDetailedTracking(true);
 
         Binder binder = new Binder();
-        CallSession callSession = bcs.callStarted(binder, 1);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.time += 10;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
         assertEquals(1, uidEntries.size());
@@ -116,9 +116,9 @@
         assertEquals(binder.getClass(), callStatsList.get(0).binderClass);
         assertEquals(1, callStatsList.get(0).transactionCode);
 
-        callSession = bcs.callStarted(binder, 1);
+        callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.time += 20;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         uidEntry = bcs.getUidEntries().get(WORKSOURCE_UID);
         assertEquals(2, uidEntry.callCount);
@@ -126,9 +126,9 @@
         callStatsList = new ArrayList(uidEntry.getCallStatsList());
         assertEquals(1, callStatsList.size());
 
-        callSession = bcs.callStarted(binder, 2);
+        callSession = bcs.callStarted(binder, 2, WORKSOURCE_UID);
         bcs.time += 50;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
         uidEntry = bcs.getUidEntries().get(WORKSOURCE_UID);
         assertEquals(3, uidEntry.callCount);
 
@@ -142,7 +142,7 @@
     public void testEnableInBetweenCall() {
         TestBinderCallsStats bcs = new TestBinderCallsStats();
         Binder binder = new Binder();
-        bcs.callEnded(null, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(null, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
         assertEquals(0, uidEntries.size());
@@ -153,7 +153,7 @@
         TestBinderCallsStats bcs = new TestBinderCallsStats();
         Binder binder = new Binder();
         bcs.callThrewException(null, new IllegalStateException());
-        bcs.callEnded(null, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(null, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
         assertEquals(0, uidEntries.size());
@@ -166,17 +166,17 @@
         bcs.setSamplingInterval(2);
 
         Binder binder = new Binder();
-        CallSession callSession = bcs.callStarted(binder, 1);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.time += 10;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
-        callSession = bcs.callStarted(binder, 1);
+        callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.time += 1000;  // shoud be ignored.
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
-        callSession = bcs.callStarted(binder, 1);
+        callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.time += 50;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
         assertEquals(1, uidEntries.size());
@@ -203,13 +203,13 @@
         bcs.setSamplingInterval(2);
 
         Binder binder = new Binder();
-        CallSession callSession = bcs.callStarted(binder, 1);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.time += 10;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
-        callSession = bcs.callStarted(binder, 2 /* another method */);
+        callSession = bcs.callStarted(binder, 2 /* another method */, WORKSOURCE_UID);
         bcs.time += 1000;  // shoud be ignored.
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
 
         SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
@@ -246,9 +246,9 @@
         TestBinderCallsStats bcs = new TestBinderCallsStats();
         bcs.setDetailedTracking(true);
         Binder binder = new BinderWithGetTransactionName();
-        CallSession callSession = bcs.callStarted(binder, 1);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.time += 10;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         List<BinderCallsStats.ExportedCallStat> callStatsList =
                 bcs.getExportedCallStats();
@@ -261,18 +261,18 @@
         bcs.setDetailedTracking(true);
 
         Binder binder = new AnotherBinderWithGetTransactionName();
-        CallSession callSession = bcs.callStarted(binder, 1);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.time += 10;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         Binder binder2 = new BinderWithGetTransactionName();
-        callSession = bcs.callStarted(binder2, 1);
+        callSession = bcs.callStarted(binder2, 1, WORKSOURCE_UID);
         bcs.time += 10;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
-        callSession = bcs.callStarted(binder, 2);
+        callSession = bcs.callStarted(binder, 2, WORKSOURCE_UID);
         bcs.time += 10;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         List<BinderCallsStats.ExportedCallStat> callStatsList =
                 bcs.getExportedCallStats();
@@ -292,9 +292,9 @@
         TestBinderCallsStats bcs = new TestBinderCallsStats();
         bcs.setDetailedTracking(true);
         Binder binder = new Binder();
-        CallSession callSession = bcs.callStarted(binder, 1);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.time += 10;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         List<BinderCallsStats.ExportedCallStat> callStatsList =
                 bcs.getExportedCallStats();
@@ -306,9 +306,9 @@
         TestBinderCallsStats bcs = new TestBinderCallsStats();
         bcs.setDetailedTracking(true);
         Binder binder = new Binder();
-        CallSession callSession = bcs.callStarted(binder, 1);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.time += 10;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         List<BinderCallsStats.CallStat> callStatsList =
                 new ArrayList(bcs.getUidEntries().get(WORKSOURCE_UID).getCallStatsList());
@@ -322,13 +322,13 @@
         TestBinderCallsStats bcs = new TestBinderCallsStats();
         bcs.setDetailedTracking(true);
         Binder binder = new Binder();
-        CallSession callSession = bcs.callStarted(binder, 1);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.time += 50;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
-        callSession = bcs.callStarted(binder, 1);
+        callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.time += 10;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         List<BinderCallsStats.CallStat> callStatsList =
                 new ArrayList(bcs.getUidEntries().get(WORKSOURCE_UID).getCallStatsList());
@@ -341,13 +341,13 @@
         TestBinderCallsStats bcs = new TestBinderCallsStats();
         bcs.setDetailedTracking(true);
         Binder binder = new Binder();
-        CallSession callSession = bcs.callStarted(binder, 1);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.elapsedTime += 5;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
-        callSession = bcs.callStarted(binder, 1);
+        callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.elapsedTime += 1;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         List<BinderCallsStats.CallStat> callStatsList =
                 new ArrayList(bcs.getUidEntries().get(WORKSOURCE_UID).getCallStatsList());
@@ -368,17 +368,17 @@
         TestBinderCallsStats bcs = new TestBinderCallsStats();
         bcs.setDetailedTracking(true);
         Binder binder = new Binder();
-        CallSession callSession = bcs.callStarted(binder, 1);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.callThrewException(callSession, new IllegalStateException());
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
-        callSession = bcs.callStarted(binder, 1);
+        callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.callThrewException(callSession, new IllegalStateException());
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
-        callSession = bcs.callStarted(binder, 1);
+        callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.callThrewException(callSession, new RuntimeException());
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         ArrayMap<String, Integer> expected = new ArrayMap<>();
         expected.put("java.lang.IllegalStateException", 2);
@@ -391,9 +391,9 @@
         TestBinderCallsStats bcs = new TestBinderCallsStats(null);
         bcs.setDetailedTracking(true);
         Binder binder = new Binder();
-        CallSession callSession = bcs.callStarted(binder, 1);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.time += 10;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         bcs.setDeviceState(mDeviceState.getReadonlyClient());
 
@@ -408,8 +408,8 @@
         mDeviceState.setCharging(true);
 
         Binder binder = new Binder();
-        CallSession callSession = bcs.callStarted(binder, 1);
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         assertEquals(0, bcs.getUidEntries().size());
     }
@@ -420,8 +420,8 @@
         bcs.setDetailedTracking(true);
         mDeviceState.setScreenInteractive(false);
         Binder binder = new Binder();
-        CallSession callSession = bcs.callStarted(binder, 1);
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
         assertEquals(1, uidEntries.size());
@@ -437,8 +437,8 @@
         bcs.setDetailedTracking(true);
         mDeviceState.setScreenInteractive(true);
         Binder binder = new Binder();
-        CallSession callSession = bcs.callStarted(binder, 1);
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
         assertEquals(1, uidEntries.size());
@@ -455,8 +455,8 @@
         mDeviceState.setCharging(true);
 
         Binder binder = new Binder();
-        CallSession callSession = bcs.callStarted(binder, 1);
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         assertEquals(0, bcs.getExportedCallStats().size());
     }
@@ -468,8 +468,8 @@
         mDeviceState.setCharging(false);
 
         Binder binder = new Binder();
-        CallSession callSession = bcs.callStarted(binder, 1);
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         assertEquals(1, bcs.getExportedCallStats().size());
     }
@@ -479,12 +479,12 @@
         TestBinderCallsStats bcs = new TestBinderCallsStats();
         bcs.setDetailedTracking(true);
         Binder binder = new Binder();
-        CallSession callSession = bcs.callStarted(binder, 1);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.callThrewException(callSession, new IllegalStateException());
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         PrintWriter pw = new PrintWriter(new StringWriter());
-        bcs.dump(pw, new HashMap<>(), true);
+        bcs.dump(pw, new AppIdToPackageMap(new HashMap<>()), true);
     }
 
     @Test
@@ -492,8 +492,8 @@
         TestBinderCallsStats bcs = new TestBinderCallsStats();
         bcs.setDetailedTracking(false);
         Binder binder = new Binder();
-        CallSession callSession = bcs.callStarted(binder, 1);
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         assertEquals(0, bcs.getExportedCallStats().size());
     }
@@ -504,10 +504,10 @@
         bcs.setDetailedTracking(true);
 
         Binder binder = new Binder();
-        CallSession callSession = bcs.callStarted(binder, 1);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.time += 10;
         bcs.elapsedTime += 20;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         assertEquals(1, bcs.getExportedCallStats().size());
         BinderCallsStats.ExportedCallStat stat = bcs.getExportedCallStats().get(0);
@@ -549,15 +549,15 @@
         bcs.setMaxBinderCallStats(2);
 
         Binder binder = new Binder();
-        CallSession callSession = bcs.callStarted(binder, 1);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
         bcs.time += 10;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
-        callSession = bcs.callStarted(binder, 1);
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
-        callSession = bcs.callStarted(binder, 1);
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         BinderCallsStats.UidEntry uidEntry = bcs.getUidEntries().get(WORKSOURCE_UID);
         List<BinderCallsStats.CallStat> callStatsList = new ArrayList(uidEntry.getCallStatsList());
@@ -574,12 +574,15 @@
         bcs.setMaxBinderCallStats(1);
 
         Binder binder = new Binder();
-        CallSession callSession = bcs.callStarted(binder, 1);
-        bcs.time += 10;
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
-        callSession = bcs.callStarted(binder, 2);
-        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+        callSession = bcs.callStarted(binder, 2, WORKSOURCE_UID);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
+
+        // Should use the same overflow entry.
+        callSession = bcs.callStarted(binder, 3, WORKSOURCE_UID);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
 
         List<BinderCallsStats.ExportedCallStat> callStatsList = bcs.getExportedCallStats();
         assertEquals(2, callStatsList.size());
@@ -590,11 +593,46 @@
         assertEquals(CALLING_UID, callStats.callingUid);
 
         callStats = callStatsList.get(1);
-        assertEquals(1, callStats.callCount);
+        assertEquals(2, callStats.callCount);
         assertEquals("-1", callStats.methodName);
         assertEquals("com.android.internal.os.BinderCallsStats$OverflowBinder",
                 callStats.className);
-        assertEquals(CALLING_UID, callStats.callingUid);
+        assertEquals(false , callStats.screenInteractive);
+        assertEquals(-1 , callStats.callingUid);
+    }
+
+    @Test
+    public void testOverflow_oneOverflowEntryPerUid() {
+        TestBinderCallsStats bcs = new TestBinderCallsStats();
+        bcs.setDetailedTracking(true);
+        bcs.setSamplingInterval(1);
+        bcs.setMaxBinderCallStats(1);
+
+        Binder binder = new Binder();
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
+
+        callSession = bcs.callStarted(binder, 2, WORKSOURCE_UID + 1);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID + 1);
+
+        // Different uids have different overflow entries.
+        callSession = bcs.callStarted(binder, 2, WORKSOURCE_UID + 2);
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID + 2);
+
+        List<BinderCallsStats.ExportedCallStat> callStatsList = bcs.getExportedCallStats();
+        assertEquals(3, callStatsList.size());
+
+        BinderCallsStats.ExportedCallStat callStats = callStatsList.get(1);
+        assertEquals(WORKSOURCE_UID + 1, callStats.workSourceUid);
+        assertEquals(1, callStats.callCount);
+        assertEquals("com.android.internal.os.BinderCallsStats$OverflowBinder",
+                callStats.className);
+
+        callStats = callStatsList.get(2);
+        assertEquals(WORKSOURCE_UID + 2, callStats.workSourceUid);
+        assertEquals(1, callStats.callCount);
+        assertEquals("com.android.internal.os.BinderCallsStats$OverflowBinder",
+                callStats.className);
     }
 
     @Test
@@ -620,7 +658,6 @@
 
     class TestBinderCallsStats extends BinderCallsStats {
         public int callingUid = CALLING_UID;
-        public int workSourceUid = WORKSOURCE_UID;
         public long time = 1234;
         public long elapsedTime = 0;
 
@@ -662,11 +699,6 @@
         protected int getCallingUid() {
             return callingUid;
         }
-
-        @Override
-        protected int getWorkSourceUid() {
-            return workSourceUid;
-        }
     }
 
 }
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index f237344..0a2f057 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -141,6 +141,7 @@
         <permission name="android.permission.MANAGE_USERS"/>
         <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
         <permission name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"/>
+        <permission name="android.permission.CLEAR_APP_USER_DATA"/>
     </privapp-permissions>
 
     <privapp-permissions package="com.android.permissioncontroller">
diff --git a/libs/androidfw/LocaleData.cpp b/libs/androidfw/LocaleData.cpp
index 889d166..020cef6 100644
--- a/libs/androidfw/LocaleData.cpp
+++ b/libs/androidfw/LocaleData.cpp
@@ -34,11 +34,11 @@
 }
 
 inline uint32_t dropRegion(uint32_t packed_locale) {
-    return packed_locale & 0xFFFF0000lu;
+    return packed_locale & 0xFFFF0000LU;
 }
 
 inline bool hasRegion(uint32_t packed_locale) {
-    return (packed_locale & 0x0000FFFFlu) != 0;
+    return (packed_locale & 0x0000FFFFLU) != 0;
 }
 
 const size_t SCRIPT_LENGTH = 4;
@@ -122,9 +122,9 @@
     return (REPRESENTATIVE_LOCALES.count(packed_locale) != 0);
 }
 
-const uint32_t US_SPANISH = 0x65735553lu; // es-US
-const uint32_t MEXICAN_SPANISH = 0x65734D58lu; // es-MX
-const uint32_t LATIN_AMERICAN_SPANISH = 0x6573A424lu; // es-419
+const uint32_t US_SPANISH = 0x65735553LU; // es-US
+const uint32_t MEXICAN_SPANISH = 0x65734D58LU; // es-MX
+const uint32_t LATIN_AMERICAN_SPANISH = 0x6573A424LU; // es-419
 
 // The two locales es-US and es-MX are treated as special fallbacks for es-419.
 // If there is no es-419, they are considered its equivalent.
@@ -225,8 +225,8 @@
 }
 
 const uint32_t ENGLISH_STOP_LIST[2] = {
-    0x656E0000lu, // en
-    0x656E8400lu, // en-001
+    0x656E0000LU, // en
+    0x656E8400LU, // en-001
 };
 const char ENGLISH_CHARS[2] = {'e', 'n'};
 const char LATIN_CHARS[4] = {'L', 'a', 't', 'n'};
diff --git a/libs/androidfw/LocaleDataTables.cpp b/libs/androidfw/LocaleDataTables.cpp
index 7c381ef..c276a23 100644
--- a/libs/androidfw/LocaleDataTables.cpp
+++ b/libs/androidfw/LocaleDataTables.cpp
@@ -1446,733 +1446,733 @@
 });
 
 std::unordered_set<uint64_t> REPRESENTATIVE_LOCALES({
-    0x616145544C61746Ellu, // aa_Latn_ET
-    0x616247454379726Cllu, // ab_Cyrl_GE
-    0xC42047484C61746Ellu, // abr_Latn_GH
-    0x904049444C61746Ellu, // ace_Latn_ID
-    0x9C4055474C61746Ellu, // ach_Latn_UG
-    0x806047484C61746Ellu, // ada_Latn_GH
-    0xE06052554379726Cllu, // ady_Cyrl_RU
-    0x6165495241767374llu, // ae_Avst_IR
-    0x8480544E41726162llu, // aeb_Arab_TN
-    0x61665A414C61746Ellu, // af_Latn_ZA
-    0xC0C0434D4C61746Ellu, // agq_Latn_CM
-    0xB8E0494E41686F6Dllu, // aho_Ahom_IN
-    0x616B47484C61746Ellu, // ak_Latn_GH
-    0xA940495158737578llu, // akk_Xsux_IQ
-    0xB560584B4C61746Ellu, // aln_Latn_XK
-    0xCD6052554379726Cllu, // alt_Cyrl_RU
-    0x616D455445746869llu, // am_Ethi_ET
-    0xB9804E474C61746Ellu, // amo_Latn_NG
-    0xE5C049444C61746Ellu, // aoz_Latn_ID
-    0x8DE0544741726162llu, // apd_Arab_TG
-    0x6172454741726162llu, // ar_Arab_EG
-    0x8A20495241726D69llu, // arc_Armi_IR
-    0x8A204A4F4E626174llu, // arc_Nbat_JO
-    0x8A20535950616C6Dllu, // arc_Palm_SY
-    0xB620434C4C61746Ellu, // arn_Latn_CL
-    0xBA20424F4C61746Ellu, // aro_Latn_BO
-    0xC220445A41726162llu, // arq_Arab_DZ
-    0xE2204D4141726162llu, // ary_Arab_MA
-    0xE620454741726162llu, // arz_Arab_EG
-    0x6173494E42656E67llu, // as_Beng_IN
-    0x8240545A4C61746Ellu, // asa_Latn_TZ
-    0x9240555353676E77llu, // ase_Sgnw_US
-    0xCE4045534C61746Ellu, // ast_Latn_ES
-    0xA66043414C61746Ellu, // atj_Latn_CA
-    0x617652554379726Cllu, // av_Cyrl_RU
-    0x82C0494E44657661llu, // awa_Deva_IN
-    0x6179424F4C61746Ellu, // ay_Latn_BO
-    0x617A495241726162llu, // az_Arab_IR
-    0x617A415A4C61746Ellu, // az_Latn_AZ
-    0x626152554379726Cllu, // ba_Cyrl_RU
-    0xAC01504B41726162llu, // bal_Arab_PK
-    0xB40149444C61746Ellu, // ban_Latn_ID
-    0xBC014E5044657661llu, // bap_Deva_NP
-    0xC40141544C61746Ellu, // bar_Latn_AT
-    0xC801434D4C61746Ellu, // bas_Latn_CM
-    0xDC01434D42616D75llu, // bax_Bamu_CM
-    0x882149444C61746Ellu, // bbc_Latn_ID
-    0xA421434D4C61746Ellu, // bbj_Latn_CM
-    0xA04143494C61746Ellu, // bci_Latn_CI
-    0x626542594379726Cllu, // be_Cyrl_BY
-    0xA481534441726162llu, // bej_Arab_SD
-    0xB0815A4D4C61746Ellu, // bem_Latn_ZM
-    0xD88149444C61746Ellu, // bew_Latn_ID
-    0xE481545A4C61746Ellu, // bez_Latn_TZ
-    0x8CA1434D4C61746Ellu, // bfd_Latn_CM
-    0xC0A1494E54616D6Cllu, // bfq_Taml_IN
-    0xCCA1504B41726162llu, // bft_Arab_PK
-    0xE0A1494E44657661llu, // bfy_Deva_IN
-    0x626742474379726Cllu, // bg_Cyrl_BG
-    0x88C1494E44657661llu, // bgc_Deva_IN
-    0xB4C1504B41726162llu, // bgn_Arab_PK
-    0xDCC154524772656Bllu, // bgx_Grek_TR
-    0x84E1494E44657661llu, // bhb_Deva_IN
-    0xA0E1494E44657661llu, // bhi_Deva_IN
-    0xA8E150484C61746Ellu, // bhk_Latn_PH
-    0xB8E1494E44657661llu, // bho_Deva_IN
-    0x626956554C61746Ellu, // bi_Latn_VU
-    0xA90150484C61746Ellu, // bik_Latn_PH
-    0xB5014E474C61746Ellu, // bin_Latn_NG
-    0xA521494E44657661llu, // bjj_Deva_IN
-    0xB52149444C61746Ellu, // bjn_Latn_ID
-    0xB141434D4C61746Ellu, // bkm_Latn_CM
-    0xD14150484C61746Ellu, // bku_Latn_PH
-    0xCD61564E54617674llu, // blt_Tavt_VN
-    0x626D4D4C4C61746Ellu, // bm_Latn_ML
-    0xC1814D4C4C61746Ellu, // bmq_Latn_ML
-    0x626E424442656E67llu, // bn_Beng_BD
-    0x626F434E54696274llu, // bo_Tibt_CN
-    0xE1E1494E42656E67llu, // bpy_Beng_IN
-    0xA201495241726162llu, // bqi_Arab_IR
-    0xD60143494C61746Ellu, // bqv_Latn_CI
-    0x627246524C61746Ellu, // br_Latn_FR
-    0x8221494E44657661llu, // bra_Deva_IN
-    0x9E21504B41726162llu, // brh_Arab_PK
-    0xDE21494E44657661llu, // brx_Deva_IN
-    0x627342414C61746Ellu, // bs_Latn_BA
-    0xC2414C5242617373llu, // bsq_Bass_LR
-    0xCA41434D4C61746Ellu, // bss_Latn_CM
-    0xBA6150484C61746Ellu, // bto_Latn_PH
-    0xD661504B44657661llu, // btv_Deva_PK
-    0x828152554379726Cllu, // bua_Cyrl_RU
-    0x8A8159544C61746Ellu, // buc_Latn_YT
-    0x9A8149444C61746Ellu, // bug_Latn_ID
-    0xB281434D4C61746Ellu, // bum_Latn_CM
-    0x86A147514C61746Ellu, // bvb_Latn_GQ
-    0xB701455245746869llu, // byn_Ethi_ER
-    0xD701434D4C61746Ellu, // byv_Latn_CM
-    0x93214D4C4C61746Ellu, // bze_Latn_ML
-    0x636145534C61746Ellu, // ca_Latn_ES
-    0x9C424E474C61746Ellu, // cch_Latn_NG
-    0xBC42494E42656E67llu, // ccp_Beng_IN
-    0xBC42424443616B6Dllu, // ccp_Cakm_BD
-    0x636552554379726Cllu, // ce_Cyrl_RU
-    0x848250484C61746Ellu, // ceb_Latn_PH
-    0x98C255474C61746Ellu, // cgg_Latn_UG
-    0x636847554C61746Ellu, // ch_Latn_GU
-    0xA8E2464D4C61746Ellu, // chk_Latn_FM
-    0xB0E252554379726Cllu, // chm_Cyrl_RU
-    0xB8E255534C61746Ellu, // cho_Latn_US
-    0xBCE243414C61746Ellu, // chp_Latn_CA
-    0xC4E2555343686572llu, // chr_Cher_US
-    0x81224B4841726162llu, // cja_Arab_KH
-    0xB122564E4368616Dllu, // cjm_Cham_VN
-    0x8542495141726162llu, // ckb_Arab_IQ
-    0x636F46524C61746Ellu, // co_Latn_FR
-    0xBDC24547436F7074llu, // cop_Copt_EG
-    0xC9E250484C61746Ellu, // cps_Latn_PH
-    0x6372434143616E73llu, // cr_Cans_CA
-    0xA622434143616E73llu, // crj_Cans_CA
-    0xAA22434143616E73llu, // crk_Cans_CA
-    0xAE22434143616E73llu, // crl_Cans_CA
-    0xB222434143616E73llu, // crm_Cans_CA
-    0xCA2253434C61746Ellu, // crs_Latn_SC
-    0x6373435A4C61746Ellu, // cs_Latn_CZ
-    0x8642504C4C61746Ellu, // csb_Latn_PL
-    0xDA42434143616E73llu, // csw_Cans_CA
-    0x8E624D4D50617563llu, // ctd_Pauc_MM
-    0x637552554379726Cllu, // cu_Cyrl_RU
-    0x63754247476C6167llu, // cu_Glag_BG
-    0x637652554379726Cllu, // cv_Cyrl_RU
-    0x637947424C61746Ellu, // cy_Latn_GB
-    0x6461444B4C61746Ellu, // da_Latn_DK
-    0xA80355534C61746Ellu, // dak_Latn_US
-    0xC40352554379726Cllu, // dar_Cyrl_RU
-    0xD4034B454C61746Ellu, // dav_Latn_KE
-    0x8843494E41726162llu, // dcc_Arab_IN
-    0x646544454C61746Ellu, // de_Latn_DE
-    0xB48343414C61746Ellu, // den_Latn_CA
-    0xC4C343414C61746Ellu, // dgr_Latn_CA
-    0x91234E454C61746Ellu, // dje_Latn_NE
-    0xA5A343494C61746Ellu, // dnj_Latn_CI
-    0xA1C3494E41726162llu, // doi_Arab_IN
-    0x864344454C61746Ellu, // dsb_Latn_DE
-    0xB2634D4C4C61746Ellu, // dtm_Latn_ML
-    0xBE634D594C61746Ellu, // dtp_Latn_MY
-    0xE2634E5044657661llu, // dty_Deva_NP
-    0x8283434D4C61746Ellu, // dua_Latn_CM
-    0x64764D5654686161llu, // dv_Thaa_MV
-    0xBB03534E4C61746Ellu, // dyo_Latn_SN
-    0xD30342464C61746Ellu, // dyu_Latn_BF
-    0x647A425454696274llu, // dz_Tibt_BT
-    0xD0244B454C61746Ellu, // ebu_Latn_KE
-    0x656547484C61746Ellu, // ee_Latn_GH
-    0xA0A44E474C61746Ellu, // efi_Latn_NG
-    0xACC449544C61746Ellu, // egl_Latn_IT
-    0xE0C4454745677970llu, // egy_Egyp_EG
-    0xE1444D4D4B616C69llu, // eky_Kali_MM
-    0x656C47524772656Bllu, // el_Grek_GR
-    0x656E47424C61746Ellu, // en_Latn_GB
-    0x656E55534C61746Ellu, // en_Latn_US
-    0x656E474253686177llu, // en_Shaw_GB
-    0x657345534C61746Ellu, // es_Latn_ES
-    0x65734D584C61746Ellu, // es_Latn_MX
-    0x657355534C61746Ellu, // es_Latn_US
-    0xD24455534C61746Ellu, // esu_Latn_US
-    0x657445454C61746Ellu, // et_Latn_EE
-    0xCE6449544974616Cllu, // ett_Ital_IT
-    0x657545534C61746Ellu, // eu_Latn_ES
-    0xBAC4434D4C61746Ellu, // ewo_Latn_CM
-    0xCEE445534C61746Ellu, // ext_Latn_ES
-    0x6661495241726162llu, // fa_Arab_IR
-    0xB40547514C61746Ellu, // fan_Latn_GQ
-    0x6666474E41646C6Dllu, // ff_Adlm_GN
-    0x6666534E4C61746Ellu, // ff_Latn_SN
-    0xB0A54D4C4C61746Ellu, // ffm_Latn_ML
-    0x666946494C61746Ellu, // fi_Latn_FI
-    0x8105534441726162llu, // fia_Arab_SD
-    0xAD0550484C61746Ellu, // fil_Latn_PH
-    0xCD0553454C61746Ellu, // fit_Latn_SE
-    0x666A464A4C61746Ellu, // fj_Latn_FJ
-    0x666F464F4C61746Ellu, // fo_Latn_FO
-    0xB5C5424A4C61746Ellu, // fon_Latn_BJ
-    0x667246524C61746Ellu, // fr_Latn_FR
-    0x8A2555534C61746Ellu, // frc_Latn_US
-    0xBE2546524C61746Ellu, // frp_Latn_FR
-    0xC62544454C61746Ellu, // frr_Latn_DE
-    0xCA2544454C61746Ellu, // frs_Latn_DE
-    0x8685434D41726162llu, // fub_Arab_CM
-    0x8E8557464C61746Ellu, // fud_Latn_WF
-    0x9685474E4C61746Ellu, // fuf_Latn_GN
-    0xC2854E454C61746Ellu, // fuq_Latn_NE
-    0xC68549544C61746Ellu, // fur_Latn_IT
-    0xD6854E474C61746Ellu, // fuv_Latn_NG
-    0xC6A553444C61746Ellu, // fvr_Latn_SD
-    0x66794E4C4C61746Ellu, // fy_Latn_NL
-    0x676149454C61746Ellu, // ga_Latn_IE
-    0x800647484C61746Ellu, // gaa_Latn_GH
-    0x98064D444C61746Ellu, // gag_Latn_MD
-    0xB406434E48616E73llu, // gan_Hans_CN
-    0xE00649444C61746Ellu, // gay_Latn_ID
-    0xB026494E44657661llu, // gbm_Deva_IN
-    0xE426495241726162llu, // gbz_Arab_IR
-    0xC44647464C61746Ellu, // gcr_Latn_GF
-    0x676447424C61746Ellu, // gd_Latn_GB
-    0xE486455445746869llu, // gez_Ethi_ET
-    0xB4C64E5044657661llu, // ggn_Deva_NP
-    0xAD064B494C61746Ellu, // gil_Latn_KI
-    0xA926504B41726162llu, // gjk_Arab_PK
-    0xD126504B41726162llu, // gju_Arab_PK
-    0x676C45534C61746Ellu, // gl_Latn_ES
-    0xA966495241726162llu, // glk_Arab_IR
-    0x676E50594C61746Ellu, // gn_Latn_PY
-    0xB1C6494E44657661llu, // gom_Deva_IN
-    0xB5C6494E54656C75llu, // gon_Telu_IN
-    0xC5C649444C61746Ellu, // gor_Latn_ID
-    0xC9C64E4C4C61746Ellu, // gos_Latn_NL
-    0xCDC65541476F7468llu, // got_Goth_UA
-    0x8A26435943707274llu, // grc_Cprt_CY
-    0x8A2647524C696E62llu, // grc_Linb_GR
-    0xCE26494E42656E67llu, // grt_Beng_IN
-    0xDA4643484C61746Ellu, // gsw_Latn_CH
-    0x6775494E47756A72llu, // gu_Gujr_IN
-    0x868642524C61746Ellu, // gub_Latn_BR
-    0x8A86434F4C61746Ellu, // guc_Latn_CO
-    0xC68647484C61746Ellu, // gur_Latn_GH
-    0xE6864B454C61746Ellu, // guz_Latn_KE
-    0x6776494D4C61746Ellu, // gv_Latn_IM
-    0xC6A64E5044657661llu, // gvr_Deva_NP
-    0xA2C643414C61746Ellu, // gwi_Latn_CA
-    0x68614E474C61746Ellu, // ha_Latn_NG
-    0xA807434E48616E73llu, // hak_Hans_CN
-    0xD80755534C61746Ellu, // haw_Latn_US
-    0xE407414641726162llu, // haz_Arab_AF
-    0x6865494C48656272llu, // he_Hebr_IL
-    0x6869494E44657661llu, // hi_Deva_IN
-    0x9507464A4C61746Ellu, // hif_Latn_FJ
-    0xAD0750484C61746Ellu, // hil_Latn_PH
-    0xD1675452486C7577llu, // hlu_Hluw_TR
-    0x8D87434E506C7264llu, // hmd_Plrd_CN
-    0x8DA7504B41726162llu, // hnd_Arab_PK
-    0x91A7494E44657661llu, // hne_Deva_IN
-    0xA5A74C41486D6E67llu, // hnj_Hmng_LA
-    0xB5A750484C61746Ellu, // hnn_Latn_PH
-    0xB9A7504B41726162llu, // hno_Arab_PK
-    0x686F50474C61746Ellu, // ho_Latn_PG
-    0x89C7494E44657661llu, // hoc_Deva_IN
-    0xA5C7494E44657661llu, // hoj_Deva_IN
-    0x687248524C61746Ellu, // hr_Latn_HR
-    0x864744454C61746Ellu, // hsb_Latn_DE
-    0xB647434E48616E73llu, // hsn_Hans_CN
-    0x687448544C61746Ellu, // ht_Latn_HT
-    0x687548554C61746Ellu, // hu_Latn_HU
-    0x6879414D41726D6Ellu, // hy_Armn_AM
-    0x687A4E414C61746Ellu, // hz_Latn_NA
-    0x696146524C61746Ellu, // ia_Latn_FR
-    0x80284D594C61746Ellu, // iba_Latn_MY
-    0x84284E474C61746Ellu, // ibb_Latn_NG
-    0x696449444C61746Ellu, // id_Latn_ID
-    0x69674E474C61746Ellu, // ig_Latn_NG
-    0x6969434E59696969llu, // ii_Yiii_CN
-    0x696B55534C61746Ellu, // ik_Latn_US
-    0xCD4843414C61746Ellu, // ikt_Latn_CA
-    0xB96850484C61746Ellu, // ilo_Latn_PH
-    0x696E49444C61746Ellu, // in_Latn_ID
-    0x9DA852554379726Cllu, // inh_Cyrl_RU
-    0x697349534C61746Ellu, // is_Latn_IS
-    0x697449544C61746Ellu, // it_Latn_IT
-    0x6975434143616E73llu, // iu_Cans_CA
-    0x6977494C48656272llu, // iw_Hebr_IL
-    0x9F2852554C61746Ellu, // izh_Latn_RU
-    0x6A614A504A70616Ellu, // ja_Jpan_JP
-    0xB0094A4D4C61746Ellu, // jam_Latn_JM
-    0xB8C9434D4C61746Ellu, // jgo_Latn_CM
-    0x8989545A4C61746Ellu, // jmc_Latn_TZ
-    0xAD894E5044657661llu, // jml_Deva_NP
-    0xCE89444B4C61746Ellu, // jut_Latn_DK
-    0x6A7649444C61746Ellu, // jv_Latn_ID
-    0x6A7749444C61746Ellu, // jw_Latn_ID
-    0x6B61474547656F72llu, // ka_Geor_GE
-    0x800A555A4379726Cllu, // kaa_Cyrl_UZ
-    0x840A445A4C61746Ellu, // kab_Latn_DZ
-    0x880A4D4D4C61746Ellu, // kac_Latn_MM
-    0xA40A4E474C61746Ellu, // kaj_Latn_NG
-    0xB00A4B454C61746Ellu, // kam_Latn_KE
-    0xB80A4D4C4C61746Ellu, // kao_Latn_ML
-    0x8C2A52554379726Cllu, // kbd_Cyrl_RU
-    0xE02A4E4541726162llu, // kby_Arab_NE
-    0x984A4E474C61746Ellu, // kcg_Latn_NG
-    0xA84A5A574C61746Ellu, // kck_Latn_ZW
-    0x906A545A4C61746Ellu, // kde_Latn_TZ
-    0x9C6A544741726162llu, // kdh_Arab_TG
-    0xCC6A544854686169llu, // kdt_Thai_TH
-    0x808A43564C61746Ellu, // kea_Latn_CV
-    0xB48A434D4C61746Ellu, // ken_Latn_CM
-    0xB8AA43494C61746Ellu, // kfo_Latn_CI
-    0xC4AA494E44657661llu, // kfr_Deva_IN
-    0xE0AA494E44657661llu, // kfy_Deva_IN
-    0x6B6743444C61746Ellu, // kg_Latn_CD
-    0x90CA49444C61746Ellu, // kge_Latn_ID
-    0xBCCA42524C61746Ellu, // kgp_Latn_BR
-    0x80EA494E4C61746Ellu, // kha_Latn_IN
-    0x84EA434E54616C75llu, // khb_Talu_CN
-    0xB4EA494E44657661llu, // khn_Deva_IN
-    0xC0EA4D4C4C61746Ellu, // khq_Latn_ML
-    0xCCEA494E4D796D72llu, // kht_Mymr_IN
-    0xD8EA504B41726162llu, // khw_Arab_PK
-    0x6B694B454C61746Ellu, // ki_Latn_KE
-    0xD10A54524C61746Ellu, // kiu_Latn_TR
-    0x6B6A4E414C61746Ellu, // kj_Latn_NA
-    0x992A4C414C616F6Fllu, // kjg_Laoo_LA
-    0x6B6B434E41726162llu, // kk_Arab_CN
-    0x6B6B4B5A4379726Cllu, // kk_Cyrl_KZ
-    0xA54A434D4C61746Ellu, // kkj_Latn_CM
-    0x6B6C474C4C61746Ellu, // kl_Latn_GL
-    0xB56A4B454C61746Ellu, // kln_Latn_KE
-    0x6B6D4B484B686D72llu, // km_Khmr_KH
-    0x858A414F4C61746Ellu, // kmb_Latn_AO
-    0x6B6E494E4B6E6461llu, // kn_Knda_IN
-    0x6B6F4B524B6F7265llu, // ko_Kore_KR
-    0xA1CA52554379726Cllu, // koi_Cyrl_RU
-    0xA9CA494E44657661llu, // kok_Deva_IN
-    0xC9CA464D4C61746Ellu, // kos_Latn_FM
-    0x91EA4C524C61746Ellu, // kpe_Latn_LR
-    0x8A2A52554379726Cllu, // krc_Cyrl_RU
-    0xA22A534C4C61746Ellu, // kri_Latn_SL
-    0xA62A50484C61746Ellu, // krj_Latn_PH
-    0xAE2A52554C61746Ellu, // krl_Latn_RU
-    0xD22A494E44657661llu, // kru_Deva_IN
-    0x6B73494E41726162llu, // ks_Arab_IN
-    0x864A545A4C61746Ellu, // ksb_Latn_TZ
-    0x964A434D4C61746Ellu, // ksf_Latn_CM
-    0x9E4A44454C61746Ellu, // ksh_Latn_DE
-    0x6B75495141726162llu, // ku_Arab_IQ
-    0x6B7554524C61746Ellu, // ku_Latn_TR
-    0xB28A52554379726Cllu, // kum_Cyrl_RU
-    0x6B7652554379726Cllu, // kv_Cyrl_RU
-    0xC6AA49444C61746Ellu, // kvr_Latn_ID
-    0xDEAA504B41726162llu, // kvx_Arab_PK
-    0x6B7747424C61746Ellu, // kw_Latn_GB
-    0xB2EA544854686169llu, // kxm_Thai_TH
-    0xBEEA504B41726162llu, // kxp_Arab_PK
-    0x6B79434E41726162llu, // ky_Arab_CN
-    0x6B794B474379726Cllu, // ky_Cyrl_KG
-    0x6B7954524C61746Ellu, // ky_Latn_TR
-    0x6C6156414C61746Ellu, // la_Latn_VA
-    0x840B47524C696E61llu, // lab_Lina_GR
-    0x8C0B494C48656272llu, // lad_Hebr_IL
-    0x980B545A4C61746Ellu, // lag_Latn_TZ
-    0x9C0B504B41726162llu, // lah_Arab_PK
-    0xA40B55474C61746Ellu, // laj_Latn_UG
-    0x6C624C554C61746Ellu, // lb_Latn_LU
-    0x902B52554379726Cllu, // lbe_Cyrl_RU
-    0xD82B49444C61746Ellu, // lbw_Latn_ID
-    0xBC4B434E54686169llu, // lcp_Thai_CN
-    0xBC8B494E4C657063llu, // lep_Lepc_IN
-    0xE48B52554379726Cllu, // lez_Cyrl_RU
-    0x6C6755474C61746Ellu, // lg_Latn_UG
-    0x6C694E4C4C61746Ellu, // li_Latn_NL
-    0x950B4E5044657661llu, // lif_Deva_NP
-    0x950B494E4C696D62llu, // lif_Limb_IN
-    0xA50B49544C61746Ellu, // lij_Latn_IT
-    0xC90B434E4C697375llu, // lis_Lisu_CN
-    0xBD2B49444C61746Ellu, // ljp_Latn_ID
-    0xA14B495241726162llu, // lki_Arab_IR
-    0xCD4B55534C61746Ellu, // lkt_Latn_US
-    0xB58B494E54656C75llu, // lmn_Telu_IN
-    0xB98B49544C61746Ellu, // lmo_Latn_IT
-    0x6C6E43444C61746Ellu, // ln_Latn_CD
-    0x6C6F4C414C616F6Fllu, // lo_Laoo_LA
-    0xADCB43444C61746Ellu, // lol_Latn_CD
-    0xE5CB5A4D4C61746Ellu, // loz_Latn_ZM
-    0x8A2B495241726162llu, // lrc_Arab_IR
-    0x6C744C544C61746Ellu, // lt_Latn_LT
-    0x9A6B4C564C61746Ellu, // ltg_Latn_LV
-    0x6C7543444C61746Ellu, // lu_Latn_CD
-    0x828B43444C61746Ellu, // lua_Latn_CD
-    0xBA8B4B454C61746Ellu, // luo_Latn_KE
-    0xE28B4B454C61746Ellu, // luy_Latn_KE
-    0xE68B495241726162llu, // luz_Arab_IR
-    0x6C764C564C61746Ellu, // lv_Latn_LV
-    0xAECB544854686169llu, // lwl_Thai_TH
-    0x9F2B434E48616E73llu, // lzh_Hans_CN
-    0xE72B54524C61746Ellu, // lzz_Latn_TR
-    0x8C0C49444C61746Ellu, // mad_Latn_ID
-    0x940C434D4C61746Ellu, // maf_Latn_CM
-    0x980C494E44657661llu, // mag_Deva_IN
-    0xA00C494E44657661llu, // mai_Deva_IN
-    0xA80C49444C61746Ellu, // mak_Latn_ID
-    0xB40C474D4C61746Ellu, // man_Latn_GM
-    0xB40C474E4E6B6F6Fllu, // man_Nkoo_GN
-    0xC80C4B454C61746Ellu, // mas_Latn_KE
-    0xE40C4D584C61746Ellu, // maz_Latn_MX
-    0x946C52554379726Cllu, // mdf_Cyrl_RU
-    0x9C6C50484C61746Ellu, // mdh_Latn_PH
-    0xC46C49444C61746Ellu, // mdr_Latn_ID
-    0xB48C534C4C61746Ellu, // men_Latn_SL
-    0xC48C4B454C61746Ellu, // mer_Latn_KE
-    0x80AC544841726162llu, // mfa_Arab_TH
-    0x90AC4D554C61746Ellu, // mfe_Latn_MU
-    0x6D674D474C61746Ellu, // mg_Latn_MG
-    0x9CCC4D5A4C61746Ellu, // mgh_Latn_MZ
-    0xB8CC434D4C61746Ellu, // mgo_Latn_CM
-    0xBCCC4E5044657661llu, // mgp_Deva_NP
-    0xE0CC545A4C61746Ellu, // mgy_Latn_TZ
-    0x6D684D484C61746Ellu, // mh_Latn_MH
-    0x6D694E5A4C61746Ellu, // mi_Latn_NZ
-    0xB50C49444C61746Ellu, // min_Latn_ID
-    0xC90C495148617472llu, // mis_Hatr_IQ
-    0x6D6B4D4B4379726Cllu, // mk_Cyrl_MK
-    0x6D6C494E4D6C796Dllu, // ml_Mlym_IN
-    0xC96C53444C61746Ellu, // mls_Latn_SD
-    0x6D6E4D4E4379726Cllu, // mn_Cyrl_MN
-    0x6D6E434E4D6F6E67llu, // mn_Mong_CN
-    0xA1AC494E42656E67llu, // mni_Beng_IN
-    0xD9AC4D4D4D796D72llu, // mnw_Mymr_MM
-    0x91CC43414C61746Ellu, // moe_Latn_CA
-    0x9DCC43414C61746Ellu, // moh_Latn_CA
-    0xC9CC42464C61746Ellu, // mos_Latn_BF
-    0x6D72494E44657661llu, // mr_Deva_IN
-    0x8E2C4E5044657661llu, // mrd_Deva_NP
-    0xA62C52554379726Cllu, // mrj_Cyrl_RU
-    0xBA2C42444D726F6Fllu, // mro_Mroo_BD
-    0x6D734D594C61746Ellu, // ms_Latn_MY
-    0x6D744D544C61746Ellu, // mt_Latn_MT
-    0xC66C494E44657661llu, // mtr_Deva_IN
-    0x828C434D4C61746Ellu, // mua_Latn_CM
-    0xCA8C55534C61746Ellu, // mus_Latn_US
-    0xE2AC504B41726162llu, // mvy_Arab_PK
-    0xAACC4D4C4C61746Ellu, // mwk_Latn_ML
-    0xC6CC494E44657661llu, // mwr_Deva_IN
-    0xD6CC49444C61746Ellu, // mwv_Latn_ID
-    0x8AEC5A574C61746Ellu, // mxc_Latn_ZW
-    0x6D794D4D4D796D72llu, // my_Mymr_MM
-    0xD70C52554379726Cllu, // myv_Cyrl_RU
-    0xDF0C55474C61746Ellu, // myx_Latn_UG
-    0xE70C49524D616E64llu, // myz_Mand_IR
-    0xB72C495241726162llu, // mzn_Arab_IR
-    0x6E614E524C61746Ellu, // na_Latn_NR
-    0xB40D434E48616E73llu, // nan_Hans_CN
-    0xBC0D49544C61746Ellu, // nap_Latn_IT
-    0xC00D4E414C61746Ellu, // naq_Latn_NA
-    0x6E624E4F4C61746Ellu, // nb_Latn_NO
-    0x9C4D4D584C61746Ellu, // nch_Latn_MX
-    0x6E645A574C61746Ellu, // nd_Latn_ZW
-    0x886D4D5A4C61746Ellu, // ndc_Latn_MZ
-    0xC86D44454C61746Ellu, // nds_Latn_DE
-    0x6E654E5044657661llu, // ne_Deva_NP
-    0xD88D4E5044657661llu, // new_Deva_NP
-    0x6E674E414C61746Ellu, // ng_Latn_NA
-    0xACCD4D5A4C61746Ellu, // ngl_Latn_MZ
-    0x90ED4D584C61746Ellu, // nhe_Latn_MX
-    0xD8ED4D584C61746Ellu, // nhw_Latn_MX
-    0xA50D49444C61746Ellu, // nij_Latn_ID
-    0xD10D4E554C61746Ellu, // niu_Latn_NU
-    0xB92D494E4C61746Ellu, // njo_Latn_IN
-    0x6E6C4E4C4C61746Ellu, // nl_Latn_NL
-    0x998D434D4C61746Ellu, // nmg_Latn_CM
-    0x6E6E4E4F4C61746Ellu, // nn_Latn_NO
-    0x9DAD434D4C61746Ellu, // nnh_Latn_CM
-    0x6E6F4E4F4C61746Ellu, // no_Latn_NO
-    0x8DCD54484C616E61llu, // nod_Lana_TH
-    0x91CD494E44657661llu, // noe_Deva_IN
-    0xB5CD534552756E72llu, // non_Runr_SE
-    0xBA0D474E4E6B6F6Fllu, // nqo_Nkoo_GN
-    0x6E725A414C61746Ellu, // nr_Latn_ZA
-    0xAA4D434143616E73llu, // nsk_Cans_CA
-    0xBA4D5A414C61746Ellu, // nso_Latn_ZA
-    0xCA8D53534C61746Ellu, // nus_Latn_SS
-    0x6E7655534C61746Ellu, // nv_Latn_US
-    0xC2ED434E4C61746Ellu, // nxq_Latn_CN
-    0x6E794D574C61746Ellu, // ny_Latn_MW
-    0xB30D545A4C61746Ellu, // nym_Latn_TZ
-    0xB70D55474C61746Ellu, // nyn_Latn_UG
-    0xA32D47484C61746Ellu, // nzi_Latn_GH
-    0x6F6346524C61746Ellu, // oc_Latn_FR
-    0x6F6D45544C61746Ellu, // om_Latn_ET
-    0x6F72494E4F727961llu, // or_Orya_IN
-    0x6F7347454379726Cllu, // os_Cyrl_GE
-    0x824E55534F736765llu, // osa_Osge_US
-    0xAA6E4D4E4F726B68llu, // otk_Orkh_MN
-    0x7061504B41726162llu, // pa_Arab_PK
-    0x7061494E47757275llu, // pa_Guru_IN
-    0x980F50484C61746Ellu, // pag_Latn_PH
-    0xAC0F495250686C69llu, // pal_Phli_IR
-    0xAC0F434E50686C70llu, // pal_Phlp_CN
-    0xB00F50484C61746Ellu, // pam_Latn_PH
-    0xBC0F41574C61746Ellu, // pap_Latn_AW
-    0xD00F50574C61746Ellu, // pau_Latn_PW
-    0x8C4F46524C61746Ellu, // pcd_Latn_FR
-    0xB04F4E474C61746Ellu, // pcm_Latn_NG
-    0x886F55534C61746Ellu, // pdc_Latn_US
-    0xCC6F43414C61746Ellu, // pdt_Latn_CA
-    0xB88F49525870656Fllu, // peo_Xpeo_IR
-    0xACAF44454C61746Ellu, // pfl_Latn_DE
-    0xB4EF4C4250686E78llu, // phn_Phnx_LB
-    0x814F494E42726168llu, // pka_Brah_IN
-    0xB94F4B454C61746Ellu, // pko_Latn_KE
-    0x706C504C4C61746Ellu, // pl_Latn_PL
-    0xC98F49544C61746Ellu, // pms_Latn_IT
-    0xCDAF47524772656Bllu, // pnt_Grek_GR
-    0xB5CF464D4C61746Ellu, // pon_Latn_FM
-    0x822F504B4B686172llu, // pra_Khar_PK
-    0x8E2F495241726162llu, // prd_Arab_IR
-    0x7073414641726162llu, // ps_Arab_AF
-    0x707442524C61746Ellu, // pt_Latn_BR
-    0xD28F47414C61746Ellu, // puu_Latn_GA
-    0x717550454C61746Ellu, // qu_Latn_PE
-    0x8A9047544C61746Ellu, // quc_Latn_GT
-    0x9A9045434C61746Ellu, // qug_Latn_EC
-    0xA411494E44657661llu, // raj_Deva_IN
-    0x945152454C61746Ellu, // rcf_Latn_RE
-    0xA49149444C61746Ellu, // rej_Latn_ID
-    0xB4D149544C61746Ellu, // rgn_Latn_IT
-    0x8111494E4C61746Ellu, // ria_Latn_IN
-    0x95114D4154666E67llu, // rif_Tfng_MA
-    0xC9314E5044657661llu, // rjs_Deva_NP
-    0xCD51424442656E67llu, // rkt_Beng_BD
-    0x726D43484C61746Ellu, // rm_Latn_CH
-    0x959146494C61746Ellu, // rmf_Latn_FI
-    0xB99143484C61746Ellu, // rmo_Latn_CH
-    0xCD91495241726162llu, // rmt_Arab_IR
-    0xD19153454C61746Ellu, // rmu_Latn_SE
-    0x726E42494C61746Ellu, // rn_Latn_BI
-    0x99B14D5A4C61746Ellu, // rng_Latn_MZ
-    0x726F524F4C61746Ellu, // ro_Latn_RO
-    0x85D149444C61746Ellu, // rob_Latn_ID
-    0x95D1545A4C61746Ellu, // rof_Latn_TZ
-    0xB271464A4C61746Ellu, // rtm_Latn_FJ
-    0x727552554379726Cllu, // ru_Cyrl_RU
-    0x929155414379726Cllu, // rue_Cyrl_UA
-    0x9A9153424C61746Ellu, // rug_Latn_SB
-    0x727752574C61746Ellu, // rw_Latn_RW
-    0xAAD1545A4C61746Ellu, // rwk_Latn_TZ
-    0xD3114A504B616E61llu, // ryu_Kana_JP
-    0x7361494E44657661llu, // sa_Deva_IN
-    0x941247484C61746Ellu, // saf_Latn_GH
-    0x9C1252554379726Cllu, // sah_Cyrl_RU
-    0xC0124B454C61746Ellu, // saq_Latn_KE
-    0xC81249444C61746Ellu, // sas_Latn_ID
-    0xCC12494E4C61746Ellu, // sat_Latn_IN
-    0xE412494E53617572llu, // saz_Saur_IN
-    0xBC32545A4C61746Ellu, // sbp_Latn_TZ
-    0x736349544C61746Ellu, // sc_Latn_IT
-    0xA852494E44657661llu, // sck_Deva_IN
-    0xB45249544C61746Ellu, // scn_Latn_IT
-    0xB85247424C61746Ellu, // sco_Latn_GB
-    0xC85243414C61746Ellu, // scs_Latn_CA
-    0x7364504B41726162llu, // sd_Arab_PK
-    0x7364494E44657661llu, // sd_Deva_IN
-    0x7364494E4B686F6Allu, // sd_Khoj_IN
-    0x7364494E53696E64llu, // sd_Sind_IN
-    0x887249544C61746Ellu, // sdc_Latn_IT
-    0x9C72495241726162llu, // sdh_Arab_IR
-    0x73654E4F4C61746Ellu, // se_Latn_NO
-    0x949243494C61746Ellu, // sef_Latn_CI
-    0x9C924D5A4C61746Ellu, // seh_Latn_MZ
-    0xA0924D584C61746Ellu, // sei_Latn_MX
-    0xC8924D4C4C61746Ellu, // ses_Latn_ML
-    0x736743464C61746Ellu, // sg_Latn_CF
-    0x80D249454F67616Dllu, // sga_Ogam_IE
-    0xC8D24C544C61746Ellu, // sgs_Latn_LT
-    0xA0F24D4154666E67llu, // shi_Tfng_MA
-    0xB4F24D4D4D796D72llu, // shn_Mymr_MM
-    0x73694C4B53696E68llu, // si_Sinh_LK
-    0x8D1245544C61746Ellu, // sid_Latn_ET
-    0x736B534B4C61746Ellu, // sk_Latn_SK
-    0xC552504B41726162llu, // skr_Arab_PK
-    0x736C53494C61746Ellu, // sl_Latn_SI
-    0xA172504C4C61746Ellu, // sli_Latn_PL
-    0xE17249444C61746Ellu, // sly_Latn_ID
-    0x736D57534C61746Ellu, // sm_Latn_WS
-    0x819253454C61746Ellu, // sma_Latn_SE
-    0xA59253454C61746Ellu, // smj_Latn_SE
-    0xB59246494C61746Ellu, // smn_Latn_FI
-    0xBD92494C53616D72llu, // smp_Samr_IL
-    0xC99246494C61746Ellu, // sms_Latn_FI
-    0x736E5A574C61746Ellu, // sn_Latn_ZW
-    0xA9B24D4C4C61746Ellu, // snk_Latn_ML
-    0x736F534F4C61746Ellu, // so_Latn_SO
-    0xD1D2544854686169llu, // sou_Thai_TH
-    0x7371414C4C61746Ellu, // sq_Latn_AL
-    0x737252534379726Cllu, // sr_Cyrl_RS
-    0x737252534C61746Ellu, // sr_Latn_RS
-    0x8632494E536F7261llu, // srb_Sora_IN
-    0xB63253524C61746Ellu, // srn_Latn_SR
-    0xC632534E4C61746Ellu, // srr_Latn_SN
-    0xDE32494E44657661llu, // srx_Deva_IN
-    0x73735A414C61746Ellu, // ss_Latn_ZA
-    0xE25245524C61746Ellu, // ssy_Latn_ER
-    0x73745A414C61746Ellu, // st_Latn_ZA
-    0xC27244454C61746Ellu, // stq_Latn_DE
-    0x737549444C61746Ellu, // su_Latn_ID
-    0xAA92545A4C61746Ellu, // suk_Latn_TZ
-    0xCA92474E4C61746Ellu, // sus_Latn_GN
-    0x737653454C61746Ellu, // sv_Latn_SE
-    0x7377545A4C61746Ellu, // sw_Latn_TZ
-    0x86D2595441726162llu, // swb_Arab_YT
-    0x8AD243444C61746Ellu, // swc_Latn_CD
-    0x9AD244454C61746Ellu, // swg_Latn_DE
-    0xD6D2494E44657661llu, // swv_Deva_IN
-    0xB6F249444C61746Ellu, // sxn_Latn_ID
-    0xAF12424442656E67llu, // syl_Beng_BD
-    0xC712495153797263llu, // syr_Syrc_IQ
-    0xAF32504C4C61746Ellu, // szl_Latn_PL
-    0x7461494E54616D6Cllu, // ta_Taml_IN
-    0xA4134E5044657661llu, // taj_Deva_NP
-    0xD83350484C61746Ellu, // tbw_Latn_PH
-    0xE053494E4B6E6461llu, // tcy_Knda_IN
-    0x8C73434E54616C65llu, // tdd_Tale_CN
-    0x98734E5044657661llu, // tdg_Deva_NP
-    0x9C734E5044657661llu, // tdh_Deva_NP
-    0x7465494E54656C75llu, // te_Telu_IN
-    0xB093534C4C61746Ellu, // tem_Latn_SL
-    0xB89355474C61746Ellu, // teo_Latn_UG
-    0xCC93544C4C61746Ellu, // tet_Latn_TL
-    0x7467504B41726162llu, // tg_Arab_PK
-    0x7467544A4379726Cllu, // tg_Cyrl_TJ
-    0x7468544854686169llu, // th_Thai_TH
-    0xACF34E5044657661llu, // thl_Deva_NP
-    0xC0F34E5044657661llu, // thq_Deva_NP
-    0xC4F34E5044657661llu, // thr_Deva_NP
-    0x7469455445746869llu, // ti_Ethi_ET
-    0x9913455245746869llu, // tig_Ethi_ER
-    0xD5134E474C61746Ellu, // tiv_Latn_NG
-    0x746B544D4C61746Ellu, // tk_Latn_TM
-    0xAD53544B4C61746Ellu, // tkl_Latn_TK
-    0xC553415A4C61746Ellu, // tkr_Latn_AZ
-    0xCD534E5044657661llu, // tkt_Deva_NP
-    0x746C50484C61746Ellu, // tl_Latn_PH
-    0xE173415A4C61746Ellu, // tly_Latn_AZ
-    0x9D934E454C61746Ellu, // tmh_Latn_NE
-    0x746E5A414C61746Ellu, // tn_Latn_ZA
-    0x746F544F4C61746Ellu, // to_Latn_TO
-    0x99D34D574C61746Ellu, // tog_Latn_MW
-    0xA1F350474C61746Ellu, // tpi_Latn_PG
-    0x747254524C61746Ellu, // tr_Latn_TR
-    0xD23354524C61746Ellu, // tru_Latn_TR
-    0xD63354574C61746Ellu, // trv_Latn_TW
-    0x74735A414C61746Ellu, // ts_Latn_ZA
-    0x8E5347524772656Bllu, // tsd_Grek_GR
-    0x96534E5044657661llu, // tsf_Deva_NP
-    0x9A5350484C61746Ellu, // tsg_Latn_PH
-    0xA653425454696274llu, // tsj_Tibt_BT
-    0x747452554379726Cllu, // tt_Cyrl_RU
-    0xA67355474C61746Ellu, // ttj_Latn_UG
-    0xCA73544854686169llu, // tts_Thai_TH
-    0xCE73415A4C61746Ellu, // ttt_Latn_AZ
-    0xB2934D574C61746Ellu, // tum_Latn_MW
-    0xAEB354564C61746Ellu, // tvl_Latn_TV
-    0xC2D34E454C61746Ellu, // twq_Latn_NE
-    0x9AF3434E54616E67llu, // txg_Tang_CN
-    0x747950464C61746Ellu, // ty_Latn_PF
-    0xD71352554379726Cllu, // tyv_Cyrl_RU
-    0xB3334D414C61746Ellu, // tzm_Latn_MA
-    0xB07452554379726Cllu, // udm_Cyrl_RU
-    0x7567434E41726162llu, // ug_Arab_CN
-    0x75674B5A4379726Cllu, // ug_Cyrl_KZ
-    0x80D4535955676172llu, // uga_Ugar_SY
-    0x756B55414379726Cllu, // uk_Cyrl_UA
-    0xA174464D4C61746Ellu, // uli_Latn_FM
-    0x8594414F4C61746Ellu, // umb_Latn_AO
-    0xC5B4494E42656E67llu, // unr_Beng_IN
-    0xC5B44E5044657661llu, // unr_Deva_NP
-    0xDDB4494E42656E67llu, // unx_Beng_IN
-    0x7572504B41726162llu, // ur_Arab_PK
-    0x757A414641726162llu, // uz_Arab_AF
-    0x757A555A4C61746Ellu, // uz_Latn_UZ
-    0xA0154C5256616969llu, // vai_Vaii_LR
-    0x76655A414C61746Ellu, // ve_Latn_ZA
-    0x889549544C61746Ellu, // vec_Latn_IT
-    0xBC9552554C61746Ellu, // vep_Latn_RU
-    0x7669564E4C61746Ellu, // vi_Latn_VN
-    0x891553584C61746Ellu, // vic_Latn_SX
-    0xC97542454C61746Ellu, // vls_Latn_BE
-    0x959544454C61746Ellu, // vmf_Latn_DE
-    0xD9954D5A4C61746Ellu, // vmw_Latn_MZ
-    0xCDD552554C61746Ellu, // vot_Latn_RU
-    0xBA3545454C61746Ellu, // vro_Latn_EE
-    0xB695545A4C61746Ellu, // vun_Latn_TZ
-    0x776142454C61746Ellu, // wa_Latn_BE
-    0x901643484C61746Ellu, // wae_Latn_CH
-    0xAC16455445746869llu, // wal_Ethi_ET
-    0xC41650484C61746Ellu, // war_Latn_PH
-    0xBC3641554C61746Ellu, // wbp_Latn_AU
-    0xC036494E54656C75llu, // wbq_Telu_IN
-    0xC436494E44657661llu, // wbr_Deva_IN
-    0xC97657464C61746Ellu, // wls_Latn_WF
-    0xA1B64B4D41726162llu, // wni_Arab_KM
-    0x776F534E4C61746Ellu, // wo_Latn_SN
-    0xB276494E44657661llu, // wtm_Deva_IN
-    0xD296434E48616E73llu, // wuu_Hans_CN
-    0xD41742524C61746Ellu, // xav_Latn_BR
-    0xC457545243617269llu, // xcr_Cari_TR
-    0x78685A414C61746Ellu, // xh_Latn_ZA
-    0x897754524C796369llu, // xlc_Lyci_TR
-    0x8D7754524C796469llu, // xld_Lydi_TR
-    0x9597474547656F72llu, // xmf_Geor_GE
-    0xB597434E4D616E69llu, // xmn_Mani_CN
-    0xC59753444D657263llu, // xmr_Merc_SD
-    0x81B753414E617262llu, // xna_Narb_SA
-    0xC5B7494E44657661llu, // xnr_Deva_IN
-    0x99D755474C61746Ellu, // xog_Latn_UG
-    0xC5F7495250727469llu, // xpr_Prti_IR
-    0x8257594553617262llu, // xsa_Sarb_YE
-    0xC6574E5044657661llu, // xsr_Deva_NP
-    0xB8184D5A4C61746Ellu, // yao_Latn_MZ
-    0xBC18464D4C61746Ellu, // yap_Latn_FM
-    0xD418434D4C61746Ellu, // yav_Latn_CM
-    0x8438434D4C61746Ellu, // ybb_Latn_CM
-    0x796F4E474C61746Ellu, // yo_Latn_NG
-    0xAE3842524C61746Ellu, // yrl_Latn_BR
-    0x82984D584C61746Ellu, // yua_Latn_MX
-    0x9298434E48616E73llu, // yue_Hans_CN
-    0x9298484B48616E74llu, // yue_Hant_HK
-    0x7A61434E4C61746Ellu, // za_Latn_CN
-    0x981953444C61746Ellu, // zag_Latn_SD
-    0xA4794B4D41726162llu, // zdj_Arab_KM
-    0x80994E4C4C61746Ellu, // zea_Latn_NL
-    0x9CD94D4154666E67llu, // zgh_Tfng_MA
-    0x7A685457426F706Fllu, // zh_Bopo_TW
-    0x7A68545748616E62llu, // zh_Hanb_TW
-    0x7A68434E48616E73llu, // zh_Hans_CN
-    0x7A68545748616E74llu, // zh_Hant_TW
-    0xB17954474C61746Ellu, // zlm_Latn_TG
-    0xA1994D594C61746Ellu, // zmi_Latn_MY
-    0x7A755A414C61746Ellu, // zu_Latn_ZA
-    0x833954524C61746Ellu, // zza_Latn_TR
+    0x616145544C61746ELLU, // aa_Latn_ET
+    0x616247454379726CLLU, // ab_Cyrl_GE
+    0xC42047484C61746ELLU, // abr_Latn_GH
+    0x904049444C61746ELLU, // ace_Latn_ID
+    0x9C4055474C61746ELLU, // ach_Latn_UG
+    0x806047484C61746ELLU, // ada_Latn_GH
+    0xE06052554379726CLLU, // ady_Cyrl_RU
+    0x6165495241767374LLU, // ae_Avst_IR
+    0x8480544E41726162LLU, // aeb_Arab_TN
+    0x61665A414C61746ELLU, // af_Latn_ZA
+    0xC0C0434D4C61746ELLU, // agq_Latn_CM
+    0xB8E0494E41686F6DLLU, // aho_Ahom_IN
+    0x616B47484C61746ELLU, // ak_Latn_GH
+    0xA940495158737578LLU, // akk_Xsux_IQ
+    0xB560584B4C61746ELLU, // aln_Latn_XK
+    0xCD6052554379726CLLU, // alt_Cyrl_RU
+    0x616D455445746869LLU, // am_Ethi_ET
+    0xB9804E474C61746ELLU, // amo_Latn_NG
+    0xE5C049444C61746ELLU, // aoz_Latn_ID
+    0x8DE0544741726162LLU, // apd_Arab_TG
+    0x6172454741726162LLU, // ar_Arab_EG
+    0x8A20495241726D69LLU, // arc_Armi_IR
+    0x8A204A4F4E626174LLU, // arc_Nbat_JO
+    0x8A20535950616C6DLLU, // arc_Palm_SY
+    0xB620434C4C61746ELLU, // arn_Latn_CL
+    0xBA20424F4C61746ELLU, // aro_Latn_BO
+    0xC220445A41726162LLU, // arq_Arab_DZ
+    0xE2204D4141726162LLU, // ary_Arab_MA
+    0xE620454741726162LLU, // arz_Arab_EG
+    0x6173494E42656E67LLU, // as_Beng_IN
+    0x8240545A4C61746ELLU, // asa_Latn_TZ
+    0x9240555353676E77LLU, // ase_Sgnw_US
+    0xCE4045534C61746ELLU, // ast_Latn_ES
+    0xA66043414C61746ELLU, // atj_Latn_CA
+    0x617652554379726CLLU, // av_Cyrl_RU
+    0x82C0494E44657661LLU, // awa_Deva_IN
+    0x6179424F4C61746ELLU, // ay_Latn_BO
+    0x617A495241726162LLU, // az_Arab_IR
+    0x617A415A4C61746ELLU, // az_Latn_AZ
+    0x626152554379726CLLU, // ba_Cyrl_RU
+    0xAC01504B41726162LLU, // bal_Arab_PK
+    0xB40149444C61746ELLU, // ban_Latn_ID
+    0xBC014E5044657661LLU, // bap_Deva_NP
+    0xC40141544C61746ELLU, // bar_Latn_AT
+    0xC801434D4C61746ELLU, // bas_Latn_CM
+    0xDC01434D42616D75LLU, // bax_Bamu_CM
+    0x882149444C61746ELLU, // bbc_Latn_ID
+    0xA421434D4C61746ELLU, // bbj_Latn_CM
+    0xA04143494C61746ELLU, // bci_Latn_CI
+    0x626542594379726CLLU, // be_Cyrl_BY
+    0xA481534441726162LLU, // bej_Arab_SD
+    0xB0815A4D4C61746ELLU, // bem_Latn_ZM
+    0xD88149444C61746ELLU, // bew_Latn_ID
+    0xE481545A4C61746ELLU, // bez_Latn_TZ
+    0x8CA1434D4C61746ELLU, // bfd_Latn_CM
+    0xC0A1494E54616D6CLLU, // bfq_Taml_IN
+    0xCCA1504B41726162LLU, // bft_Arab_PK
+    0xE0A1494E44657661LLU, // bfy_Deva_IN
+    0x626742474379726CLLU, // bg_Cyrl_BG
+    0x88C1494E44657661LLU, // bgc_Deva_IN
+    0xB4C1504B41726162LLU, // bgn_Arab_PK
+    0xDCC154524772656BLLU, // bgx_Grek_TR
+    0x84E1494E44657661LLU, // bhb_Deva_IN
+    0xA0E1494E44657661LLU, // bhi_Deva_IN
+    0xA8E150484C61746ELLU, // bhk_Latn_PH
+    0xB8E1494E44657661LLU, // bho_Deva_IN
+    0x626956554C61746ELLU, // bi_Latn_VU
+    0xA90150484C61746ELLU, // bik_Latn_PH
+    0xB5014E474C61746ELLU, // bin_Latn_NG
+    0xA521494E44657661LLU, // bjj_Deva_IN
+    0xB52149444C61746ELLU, // bjn_Latn_ID
+    0xB141434D4C61746ELLU, // bkm_Latn_CM
+    0xD14150484C61746ELLU, // bku_Latn_PH
+    0xCD61564E54617674LLU, // blt_Tavt_VN
+    0x626D4D4C4C61746ELLU, // bm_Latn_ML
+    0xC1814D4C4C61746ELLU, // bmq_Latn_ML
+    0x626E424442656E67LLU, // bn_Beng_BD
+    0x626F434E54696274LLU, // bo_Tibt_CN
+    0xE1E1494E42656E67LLU, // bpy_Beng_IN
+    0xA201495241726162LLU, // bqi_Arab_IR
+    0xD60143494C61746ELLU, // bqv_Latn_CI
+    0x627246524C61746ELLU, // br_Latn_FR
+    0x8221494E44657661LLU, // bra_Deva_IN
+    0x9E21504B41726162LLU, // brh_Arab_PK
+    0xDE21494E44657661LLU, // brx_Deva_IN
+    0x627342414C61746ELLU, // bs_Latn_BA
+    0xC2414C5242617373LLU, // bsq_Bass_LR
+    0xCA41434D4C61746ELLU, // bss_Latn_CM
+    0xBA6150484C61746ELLU, // bto_Latn_PH
+    0xD661504B44657661LLU, // btv_Deva_PK
+    0x828152554379726CLLU, // bua_Cyrl_RU
+    0x8A8159544C61746ELLU, // buc_Latn_YT
+    0x9A8149444C61746ELLU, // bug_Latn_ID
+    0xB281434D4C61746ELLU, // bum_Latn_CM
+    0x86A147514C61746ELLU, // bvb_Latn_GQ
+    0xB701455245746869LLU, // byn_Ethi_ER
+    0xD701434D4C61746ELLU, // byv_Latn_CM
+    0x93214D4C4C61746ELLU, // bze_Latn_ML
+    0x636145534C61746ELLU, // ca_Latn_ES
+    0x9C424E474C61746ELLU, // cch_Latn_NG
+    0xBC42494E42656E67LLU, // ccp_Beng_IN
+    0xBC42424443616B6DLLU, // ccp_Cakm_BD
+    0x636552554379726CLLU, // ce_Cyrl_RU
+    0x848250484C61746ELLU, // ceb_Latn_PH
+    0x98C255474C61746ELLU, // cgg_Latn_UG
+    0x636847554C61746ELLU, // ch_Latn_GU
+    0xA8E2464D4C61746ELLU, // chk_Latn_FM
+    0xB0E252554379726CLLU, // chm_Cyrl_RU
+    0xB8E255534C61746ELLU, // cho_Latn_US
+    0xBCE243414C61746ELLU, // chp_Latn_CA
+    0xC4E2555343686572LLU, // chr_Cher_US
+    0x81224B4841726162LLU, // cja_Arab_KH
+    0xB122564E4368616DLLU, // cjm_Cham_VN
+    0x8542495141726162LLU, // ckb_Arab_IQ
+    0x636F46524C61746ELLU, // co_Latn_FR
+    0xBDC24547436F7074LLU, // cop_Copt_EG
+    0xC9E250484C61746ELLU, // cps_Latn_PH
+    0x6372434143616E73LLU, // cr_Cans_CA
+    0xA622434143616E73LLU, // crj_Cans_CA
+    0xAA22434143616E73LLU, // crk_Cans_CA
+    0xAE22434143616E73LLU, // crl_Cans_CA
+    0xB222434143616E73LLU, // crm_Cans_CA
+    0xCA2253434C61746ELLU, // crs_Latn_SC
+    0x6373435A4C61746ELLU, // cs_Latn_CZ
+    0x8642504C4C61746ELLU, // csb_Latn_PL
+    0xDA42434143616E73LLU, // csw_Cans_CA
+    0x8E624D4D50617563LLU, // ctd_Pauc_MM
+    0x637552554379726CLLU, // cu_Cyrl_RU
+    0x63754247476C6167LLU, // cu_Glag_BG
+    0x637652554379726CLLU, // cv_Cyrl_RU
+    0x637947424C61746ELLU, // cy_Latn_GB
+    0x6461444B4C61746ELLU, // da_Latn_DK
+    0xA80355534C61746ELLU, // dak_Latn_US
+    0xC40352554379726CLLU, // dar_Cyrl_RU
+    0xD4034B454C61746ELLU, // dav_Latn_KE
+    0x8843494E41726162LLU, // dcc_Arab_IN
+    0x646544454C61746ELLU, // de_Latn_DE
+    0xB48343414C61746ELLU, // den_Latn_CA
+    0xC4C343414C61746ELLU, // dgr_Latn_CA
+    0x91234E454C61746ELLU, // dje_Latn_NE
+    0xA5A343494C61746ELLU, // dnj_Latn_CI
+    0xA1C3494E41726162LLU, // doi_Arab_IN
+    0x864344454C61746ELLU, // dsb_Latn_DE
+    0xB2634D4C4C61746ELLU, // dtm_Latn_ML
+    0xBE634D594C61746ELLU, // dtp_Latn_MY
+    0xE2634E5044657661LLU, // dty_Deva_NP
+    0x8283434D4C61746ELLU, // dua_Latn_CM
+    0x64764D5654686161LLU, // dv_Thaa_MV
+    0xBB03534E4C61746ELLU, // dyo_Latn_SN
+    0xD30342464C61746ELLU, // dyu_Latn_BF
+    0x647A425454696274LLU, // dz_Tibt_BT
+    0xD0244B454C61746ELLU, // ebu_Latn_KE
+    0x656547484C61746ELLU, // ee_Latn_GH
+    0xA0A44E474C61746ELLU, // efi_Latn_NG
+    0xACC449544C61746ELLU, // egl_Latn_IT
+    0xE0C4454745677970LLU, // egy_Egyp_EG
+    0xE1444D4D4B616C69LLU, // eky_Kali_MM
+    0x656C47524772656BLLU, // el_Grek_GR
+    0x656E47424C61746ELLU, // en_Latn_GB
+    0x656E55534C61746ELLU, // en_Latn_US
+    0x656E474253686177LLU, // en_Shaw_GB
+    0x657345534C61746ELLU, // es_Latn_ES
+    0x65734D584C61746ELLU, // es_Latn_MX
+    0x657355534C61746ELLU, // es_Latn_US
+    0xD24455534C61746ELLU, // esu_Latn_US
+    0x657445454C61746ELLU, // et_Latn_EE
+    0xCE6449544974616CLLU, // ett_Ital_IT
+    0x657545534C61746ELLU, // eu_Latn_ES
+    0xBAC4434D4C61746ELLU, // ewo_Latn_CM
+    0xCEE445534C61746ELLU, // ext_Latn_ES
+    0x6661495241726162LLU, // fa_Arab_IR
+    0xB40547514C61746ELLU, // fan_Latn_GQ
+    0x6666474E41646C6DLLU, // ff_Adlm_GN
+    0x6666534E4C61746ELLU, // ff_Latn_SN
+    0xB0A54D4C4C61746ELLU, // ffm_Latn_ML
+    0x666946494C61746ELLU, // fi_Latn_FI
+    0x8105534441726162LLU, // fia_Arab_SD
+    0xAD0550484C61746ELLU, // fil_Latn_PH
+    0xCD0553454C61746ELLU, // fit_Latn_SE
+    0x666A464A4C61746ELLU, // fj_Latn_FJ
+    0x666F464F4C61746ELLU, // fo_Latn_FO
+    0xB5C5424A4C61746ELLU, // fon_Latn_BJ
+    0x667246524C61746ELLU, // fr_Latn_FR
+    0x8A2555534C61746ELLU, // frc_Latn_US
+    0xBE2546524C61746ELLU, // frp_Latn_FR
+    0xC62544454C61746ELLU, // frr_Latn_DE
+    0xCA2544454C61746ELLU, // frs_Latn_DE
+    0x8685434D41726162LLU, // fub_Arab_CM
+    0x8E8557464C61746ELLU, // fud_Latn_WF
+    0x9685474E4C61746ELLU, // fuf_Latn_GN
+    0xC2854E454C61746ELLU, // fuq_Latn_NE
+    0xC68549544C61746ELLU, // fur_Latn_IT
+    0xD6854E474C61746ELLU, // fuv_Latn_NG
+    0xC6A553444C61746ELLU, // fvr_Latn_SD
+    0x66794E4C4C61746ELLU, // fy_Latn_NL
+    0x676149454C61746ELLU, // ga_Latn_IE
+    0x800647484C61746ELLU, // gaa_Latn_GH
+    0x98064D444C61746ELLU, // gag_Latn_MD
+    0xB406434E48616E73LLU, // gan_Hans_CN
+    0xE00649444C61746ELLU, // gay_Latn_ID
+    0xB026494E44657661LLU, // gbm_Deva_IN
+    0xE426495241726162LLU, // gbz_Arab_IR
+    0xC44647464C61746ELLU, // gcr_Latn_GF
+    0x676447424C61746ELLU, // gd_Latn_GB
+    0xE486455445746869LLU, // gez_Ethi_ET
+    0xB4C64E5044657661LLU, // ggn_Deva_NP
+    0xAD064B494C61746ELLU, // gil_Latn_KI
+    0xA926504B41726162LLU, // gjk_Arab_PK
+    0xD126504B41726162LLU, // gju_Arab_PK
+    0x676C45534C61746ELLU, // gl_Latn_ES
+    0xA966495241726162LLU, // glk_Arab_IR
+    0x676E50594C61746ELLU, // gn_Latn_PY
+    0xB1C6494E44657661LLU, // gom_Deva_IN
+    0xB5C6494E54656C75LLU, // gon_Telu_IN
+    0xC5C649444C61746ELLU, // gor_Latn_ID
+    0xC9C64E4C4C61746ELLU, // gos_Latn_NL
+    0xCDC65541476F7468LLU, // got_Goth_UA
+    0x8A26435943707274LLU, // grc_Cprt_CY
+    0x8A2647524C696E62LLU, // grc_Linb_GR
+    0xCE26494E42656E67LLU, // grt_Beng_IN
+    0xDA4643484C61746ELLU, // gsw_Latn_CH
+    0x6775494E47756A72LLU, // gu_Gujr_IN
+    0x868642524C61746ELLU, // gub_Latn_BR
+    0x8A86434F4C61746ELLU, // guc_Latn_CO
+    0xC68647484C61746ELLU, // gur_Latn_GH
+    0xE6864B454C61746ELLU, // guz_Latn_KE
+    0x6776494D4C61746ELLU, // gv_Latn_IM
+    0xC6A64E5044657661LLU, // gvr_Deva_NP
+    0xA2C643414C61746ELLU, // gwi_Latn_CA
+    0x68614E474C61746ELLU, // ha_Latn_NG
+    0xA807434E48616E73LLU, // hak_Hans_CN
+    0xD80755534C61746ELLU, // haw_Latn_US
+    0xE407414641726162LLU, // haz_Arab_AF
+    0x6865494C48656272LLU, // he_Hebr_IL
+    0x6869494E44657661LLU, // hi_Deva_IN
+    0x9507464A4C61746ELLU, // hif_Latn_FJ
+    0xAD0750484C61746ELLU, // hil_Latn_PH
+    0xD1675452486C7577LLU, // hlu_Hluw_TR
+    0x8D87434E506C7264LLU, // hmd_Plrd_CN
+    0x8DA7504B41726162LLU, // hnd_Arab_PK
+    0x91A7494E44657661LLU, // hne_Deva_IN
+    0xA5A74C41486D6E67LLU, // hnj_Hmng_LA
+    0xB5A750484C61746ELLU, // hnn_Latn_PH
+    0xB9A7504B41726162LLU, // hno_Arab_PK
+    0x686F50474C61746ELLU, // ho_Latn_PG
+    0x89C7494E44657661LLU, // hoc_Deva_IN
+    0xA5C7494E44657661LLU, // hoj_Deva_IN
+    0x687248524C61746ELLU, // hr_Latn_HR
+    0x864744454C61746ELLU, // hsb_Latn_DE
+    0xB647434E48616E73LLU, // hsn_Hans_CN
+    0x687448544C61746ELLU, // ht_Latn_HT
+    0x687548554C61746ELLU, // hu_Latn_HU
+    0x6879414D41726D6ELLU, // hy_Armn_AM
+    0x687A4E414C61746ELLU, // hz_Latn_NA
+    0x696146524C61746ELLU, // ia_Latn_FR
+    0x80284D594C61746ELLU, // iba_Latn_MY
+    0x84284E474C61746ELLU, // ibb_Latn_NG
+    0x696449444C61746ELLU, // id_Latn_ID
+    0x69674E474C61746ELLU, // ig_Latn_NG
+    0x6969434E59696969LLU, // ii_Yiii_CN
+    0x696B55534C61746ELLU, // ik_Latn_US
+    0xCD4843414C61746ELLU, // ikt_Latn_CA
+    0xB96850484C61746ELLU, // ilo_Latn_PH
+    0x696E49444C61746ELLU, // in_Latn_ID
+    0x9DA852554379726CLLU, // inh_Cyrl_RU
+    0x697349534C61746ELLU, // is_Latn_IS
+    0x697449544C61746ELLU, // it_Latn_IT
+    0x6975434143616E73LLU, // iu_Cans_CA
+    0x6977494C48656272LLU, // iw_Hebr_IL
+    0x9F2852554C61746ELLU, // izh_Latn_RU
+    0x6A614A504A70616ELLU, // ja_Jpan_JP
+    0xB0094A4D4C61746ELLU, // jam_Latn_JM
+    0xB8C9434D4C61746ELLU, // jgo_Latn_CM
+    0x8989545A4C61746ELLU, // jmc_Latn_TZ
+    0xAD894E5044657661LLU, // jml_Deva_NP
+    0xCE89444B4C61746ELLU, // jut_Latn_DK
+    0x6A7649444C61746ELLU, // jv_Latn_ID
+    0x6A7749444C61746ELLU, // jw_Latn_ID
+    0x6B61474547656F72LLU, // ka_Geor_GE
+    0x800A555A4379726CLLU, // kaa_Cyrl_UZ
+    0x840A445A4C61746ELLU, // kab_Latn_DZ
+    0x880A4D4D4C61746ELLU, // kac_Latn_MM
+    0xA40A4E474C61746ELLU, // kaj_Latn_NG
+    0xB00A4B454C61746ELLU, // kam_Latn_KE
+    0xB80A4D4C4C61746ELLU, // kao_Latn_ML
+    0x8C2A52554379726CLLU, // kbd_Cyrl_RU
+    0xE02A4E4541726162LLU, // kby_Arab_NE
+    0x984A4E474C61746ELLU, // kcg_Latn_NG
+    0xA84A5A574C61746ELLU, // kck_Latn_ZW
+    0x906A545A4C61746ELLU, // kde_Latn_TZ
+    0x9C6A544741726162LLU, // kdh_Arab_TG
+    0xCC6A544854686169LLU, // kdt_Thai_TH
+    0x808A43564C61746ELLU, // kea_Latn_CV
+    0xB48A434D4C61746ELLU, // ken_Latn_CM
+    0xB8AA43494C61746ELLU, // kfo_Latn_CI
+    0xC4AA494E44657661LLU, // kfr_Deva_IN
+    0xE0AA494E44657661LLU, // kfy_Deva_IN
+    0x6B6743444C61746ELLU, // kg_Latn_CD
+    0x90CA49444C61746ELLU, // kge_Latn_ID
+    0xBCCA42524C61746ELLU, // kgp_Latn_BR
+    0x80EA494E4C61746ELLU, // kha_Latn_IN
+    0x84EA434E54616C75LLU, // khb_Talu_CN
+    0xB4EA494E44657661LLU, // khn_Deva_IN
+    0xC0EA4D4C4C61746ELLU, // khq_Latn_ML
+    0xCCEA494E4D796D72LLU, // kht_Mymr_IN
+    0xD8EA504B41726162LLU, // khw_Arab_PK
+    0x6B694B454C61746ELLU, // ki_Latn_KE
+    0xD10A54524C61746ELLU, // kiu_Latn_TR
+    0x6B6A4E414C61746ELLU, // kj_Latn_NA
+    0x992A4C414C616F6FLLU, // kjg_Laoo_LA
+    0x6B6B434E41726162LLU, // kk_Arab_CN
+    0x6B6B4B5A4379726CLLU, // kk_Cyrl_KZ
+    0xA54A434D4C61746ELLU, // kkj_Latn_CM
+    0x6B6C474C4C61746ELLU, // kl_Latn_GL
+    0xB56A4B454C61746ELLU, // kln_Latn_KE
+    0x6B6D4B484B686D72LLU, // km_Khmr_KH
+    0x858A414F4C61746ELLU, // kmb_Latn_AO
+    0x6B6E494E4B6E6461LLU, // kn_Knda_IN
+    0x6B6F4B524B6F7265LLU, // ko_Kore_KR
+    0xA1CA52554379726CLLU, // koi_Cyrl_RU
+    0xA9CA494E44657661LLU, // kok_Deva_IN
+    0xC9CA464D4C61746ELLU, // kos_Latn_FM
+    0x91EA4C524C61746ELLU, // kpe_Latn_LR
+    0x8A2A52554379726CLLU, // krc_Cyrl_RU
+    0xA22A534C4C61746ELLU, // kri_Latn_SL
+    0xA62A50484C61746ELLU, // krj_Latn_PH
+    0xAE2A52554C61746ELLU, // krl_Latn_RU
+    0xD22A494E44657661LLU, // kru_Deva_IN
+    0x6B73494E41726162LLU, // ks_Arab_IN
+    0x864A545A4C61746ELLU, // ksb_Latn_TZ
+    0x964A434D4C61746ELLU, // ksf_Latn_CM
+    0x9E4A44454C61746ELLU, // ksh_Latn_DE
+    0x6B75495141726162LLU, // ku_Arab_IQ
+    0x6B7554524C61746ELLU, // ku_Latn_TR
+    0xB28A52554379726CLLU, // kum_Cyrl_RU
+    0x6B7652554379726CLLU, // kv_Cyrl_RU
+    0xC6AA49444C61746ELLU, // kvr_Latn_ID
+    0xDEAA504B41726162LLU, // kvx_Arab_PK
+    0x6B7747424C61746ELLU, // kw_Latn_GB
+    0xB2EA544854686169LLU, // kxm_Thai_TH
+    0xBEEA504B41726162LLU, // kxp_Arab_PK
+    0x6B79434E41726162LLU, // ky_Arab_CN
+    0x6B794B474379726CLLU, // ky_Cyrl_KG
+    0x6B7954524C61746ELLU, // ky_Latn_TR
+    0x6C6156414C61746ELLU, // la_Latn_VA
+    0x840B47524C696E61LLU, // lab_Lina_GR
+    0x8C0B494C48656272LLU, // lad_Hebr_IL
+    0x980B545A4C61746ELLU, // lag_Latn_TZ
+    0x9C0B504B41726162LLU, // lah_Arab_PK
+    0xA40B55474C61746ELLU, // laj_Latn_UG
+    0x6C624C554C61746ELLU, // lb_Latn_LU
+    0x902B52554379726CLLU, // lbe_Cyrl_RU
+    0xD82B49444C61746ELLU, // lbw_Latn_ID
+    0xBC4B434E54686169LLU, // lcp_Thai_CN
+    0xBC8B494E4C657063LLU, // lep_Lepc_IN
+    0xE48B52554379726CLLU, // lez_Cyrl_RU
+    0x6C6755474C61746ELLU, // lg_Latn_UG
+    0x6C694E4C4C61746ELLU, // li_Latn_NL
+    0x950B4E5044657661LLU, // lif_Deva_NP
+    0x950B494E4C696D62LLU, // lif_Limb_IN
+    0xA50B49544C61746ELLU, // lij_Latn_IT
+    0xC90B434E4C697375LLU, // lis_Lisu_CN
+    0xBD2B49444C61746ELLU, // ljp_Latn_ID
+    0xA14B495241726162LLU, // lki_Arab_IR
+    0xCD4B55534C61746ELLU, // lkt_Latn_US
+    0xB58B494E54656C75LLU, // lmn_Telu_IN
+    0xB98B49544C61746ELLU, // lmo_Latn_IT
+    0x6C6E43444C61746ELLU, // ln_Latn_CD
+    0x6C6F4C414C616F6FLLU, // lo_Laoo_LA
+    0xADCB43444C61746ELLU, // lol_Latn_CD
+    0xE5CB5A4D4C61746ELLU, // loz_Latn_ZM
+    0x8A2B495241726162LLU, // lrc_Arab_IR
+    0x6C744C544C61746ELLU, // lt_Latn_LT
+    0x9A6B4C564C61746ELLU, // ltg_Latn_LV
+    0x6C7543444C61746ELLU, // lu_Latn_CD
+    0x828B43444C61746ELLU, // lua_Latn_CD
+    0xBA8B4B454C61746ELLU, // luo_Latn_KE
+    0xE28B4B454C61746ELLU, // luy_Latn_KE
+    0xE68B495241726162LLU, // luz_Arab_IR
+    0x6C764C564C61746ELLU, // lv_Latn_LV
+    0xAECB544854686169LLU, // lwl_Thai_TH
+    0x9F2B434E48616E73LLU, // lzh_Hans_CN
+    0xE72B54524C61746ELLU, // lzz_Latn_TR
+    0x8C0C49444C61746ELLU, // mad_Latn_ID
+    0x940C434D4C61746ELLU, // maf_Latn_CM
+    0x980C494E44657661LLU, // mag_Deva_IN
+    0xA00C494E44657661LLU, // mai_Deva_IN
+    0xA80C49444C61746ELLU, // mak_Latn_ID
+    0xB40C474D4C61746ELLU, // man_Latn_GM
+    0xB40C474E4E6B6F6FLLU, // man_Nkoo_GN
+    0xC80C4B454C61746ELLU, // mas_Latn_KE
+    0xE40C4D584C61746ELLU, // maz_Latn_MX
+    0x946C52554379726CLLU, // mdf_Cyrl_RU
+    0x9C6C50484C61746ELLU, // mdh_Latn_PH
+    0xC46C49444C61746ELLU, // mdr_Latn_ID
+    0xB48C534C4C61746ELLU, // men_Latn_SL
+    0xC48C4B454C61746ELLU, // mer_Latn_KE
+    0x80AC544841726162LLU, // mfa_Arab_TH
+    0x90AC4D554C61746ELLU, // mfe_Latn_MU
+    0x6D674D474C61746ELLU, // mg_Latn_MG
+    0x9CCC4D5A4C61746ELLU, // mgh_Latn_MZ
+    0xB8CC434D4C61746ELLU, // mgo_Latn_CM
+    0xBCCC4E5044657661LLU, // mgp_Deva_NP
+    0xE0CC545A4C61746ELLU, // mgy_Latn_TZ
+    0x6D684D484C61746ELLU, // mh_Latn_MH
+    0x6D694E5A4C61746ELLU, // mi_Latn_NZ
+    0xB50C49444C61746ELLU, // min_Latn_ID
+    0xC90C495148617472LLU, // mis_Hatr_IQ
+    0x6D6B4D4B4379726CLLU, // mk_Cyrl_MK
+    0x6D6C494E4D6C796DLLU, // ml_Mlym_IN
+    0xC96C53444C61746ELLU, // mls_Latn_SD
+    0x6D6E4D4E4379726CLLU, // mn_Cyrl_MN
+    0x6D6E434E4D6F6E67LLU, // mn_Mong_CN
+    0xA1AC494E42656E67LLU, // mni_Beng_IN
+    0xD9AC4D4D4D796D72LLU, // mnw_Mymr_MM
+    0x91CC43414C61746ELLU, // moe_Latn_CA
+    0x9DCC43414C61746ELLU, // moh_Latn_CA
+    0xC9CC42464C61746ELLU, // mos_Latn_BF
+    0x6D72494E44657661LLU, // mr_Deva_IN
+    0x8E2C4E5044657661LLU, // mrd_Deva_NP
+    0xA62C52554379726CLLU, // mrj_Cyrl_RU
+    0xBA2C42444D726F6FLLU, // mro_Mroo_BD
+    0x6D734D594C61746ELLU, // ms_Latn_MY
+    0x6D744D544C61746ELLU, // mt_Latn_MT
+    0xC66C494E44657661LLU, // mtr_Deva_IN
+    0x828C434D4C61746ELLU, // mua_Latn_CM
+    0xCA8C55534C61746ELLU, // mus_Latn_US
+    0xE2AC504B41726162LLU, // mvy_Arab_PK
+    0xAACC4D4C4C61746ELLU, // mwk_Latn_ML
+    0xC6CC494E44657661LLU, // mwr_Deva_IN
+    0xD6CC49444C61746ELLU, // mwv_Latn_ID
+    0x8AEC5A574C61746ELLU, // mxc_Latn_ZW
+    0x6D794D4D4D796D72LLU, // my_Mymr_MM
+    0xD70C52554379726CLLU, // myv_Cyrl_RU
+    0xDF0C55474C61746ELLU, // myx_Latn_UG
+    0xE70C49524D616E64LLU, // myz_Mand_IR
+    0xB72C495241726162LLU, // mzn_Arab_IR
+    0x6E614E524C61746ELLU, // na_Latn_NR
+    0xB40D434E48616E73LLU, // nan_Hans_CN
+    0xBC0D49544C61746ELLU, // nap_Latn_IT
+    0xC00D4E414C61746ELLU, // naq_Latn_NA
+    0x6E624E4F4C61746ELLU, // nb_Latn_NO
+    0x9C4D4D584C61746ELLU, // nch_Latn_MX
+    0x6E645A574C61746ELLU, // nd_Latn_ZW
+    0x886D4D5A4C61746ELLU, // ndc_Latn_MZ
+    0xC86D44454C61746ELLU, // nds_Latn_DE
+    0x6E654E5044657661LLU, // ne_Deva_NP
+    0xD88D4E5044657661LLU, // new_Deva_NP
+    0x6E674E414C61746ELLU, // ng_Latn_NA
+    0xACCD4D5A4C61746ELLU, // ngl_Latn_MZ
+    0x90ED4D584C61746ELLU, // nhe_Latn_MX
+    0xD8ED4D584C61746ELLU, // nhw_Latn_MX
+    0xA50D49444C61746ELLU, // nij_Latn_ID
+    0xD10D4E554C61746ELLU, // niu_Latn_NU
+    0xB92D494E4C61746ELLU, // njo_Latn_IN
+    0x6E6C4E4C4C61746ELLU, // nl_Latn_NL
+    0x998D434D4C61746ELLU, // nmg_Latn_CM
+    0x6E6E4E4F4C61746ELLU, // nn_Latn_NO
+    0x9DAD434D4C61746ELLU, // nnh_Latn_CM
+    0x6E6F4E4F4C61746ELLU, // no_Latn_NO
+    0x8DCD54484C616E61LLU, // nod_Lana_TH
+    0x91CD494E44657661LLU, // noe_Deva_IN
+    0xB5CD534552756E72LLU, // non_Runr_SE
+    0xBA0D474E4E6B6F6FLLU, // nqo_Nkoo_GN
+    0x6E725A414C61746ELLU, // nr_Latn_ZA
+    0xAA4D434143616E73LLU, // nsk_Cans_CA
+    0xBA4D5A414C61746ELLU, // nso_Latn_ZA
+    0xCA8D53534C61746ELLU, // nus_Latn_SS
+    0x6E7655534C61746ELLU, // nv_Latn_US
+    0xC2ED434E4C61746ELLU, // nxq_Latn_CN
+    0x6E794D574C61746ELLU, // ny_Latn_MW
+    0xB30D545A4C61746ELLU, // nym_Latn_TZ
+    0xB70D55474C61746ELLU, // nyn_Latn_UG
+    0xA32D47484C61746ELLU, // nzi_Latn_GH
+    0x6F6346524C61746ELLU, // oc_Latn_FR
+    0x6F6D45544C61746ELLU, // om_Latn_ET
+    0x6F72494E4F727961LLU, // or_Orya_IN
+    0x6F7347454379726CLLU, // os_Cyrl_GE
+    0x824E55534F736765LLU, // osa_Osge_US
+    0xAA6E4D4E4F726B68LLU, // otk_Orkh_MN
+    0x7061504B41726162LLU, // pa_Arab_PK
+    0x7061494E47757275LLU, // pa_Guru_IN
+    0x980F50484C61746ELLU, // pag_Latn_PH
+    0xAC0F495250686C69LLU, // pal_Phli_IR
+    0xAC0F434E50686C70LLU, // pal_Phlp_CN
+    0xB00F50484C61746ELLU, // pam_Latn_PH
+    0xBC0F41574C61746ELLU, // pap_Latn_AW
+    0xD00F50574C61746ELLU, // pau_Latn_PW
+    0x8C4F46524C61746ELLU, // pcd_Latn_FR
+    0xB04F4E474C61746ELLU, // pcm_Latn_NG
+    0x886F55534C61746ELLU, // pdc_Latn_US
+    0xCC6F43414C61746ELLU, // pdt_Latn_CA
+    0xB88F49525870656FLLU, // peo_Xpeo_IR
+    0xACAF44454C61746ELLU, // pfl_Latn_DE
+    0xB4EF4C4250686E78LLU, // phn_Phnx_LB
+    0x814F494E42726168LLU, // pka_Brah_IN
+    0xB94F4B454C61746ELLU, // pko_Latn_KE
+    0x706C504C4C61746ELLU, // pl_Latn_PL
+    0xC98F49544C61746ELLU, // pms_Latn_IT
+    0xCDAF47524772656BLLU, // pnt_Grek_GR
+    0xB5CF464D4C61746ELLU, // pon_Latn_FM
+    0x822F504B4B686172LLU, // pra_Khar_PK
+    0x8E2F495241726162LLU, // prd_Arab_IR
+    0x7073414641726162LLU, // ps_Arab_AF
+    0x707442524C61746ELLU, // pt_Latn_BR
+    0xD28F47414C61746ELLU, // puu_Latn_GA
+    0x717550454C61746ELLU, // qu_Latn_PE
+    0x8A9047544C61746ELLU, // quc_Latn_GT
+    0x9A9045434C61746ELLU, // qug_Latn_EC
+    0xA411494E44657661LLU, // raj_Deva_IN
+    0x945152454C61746ELLU, // rcf_Latn_RE
+    0xA49149444C61746ELLU, // rej_Latn_ID
+    0xB4D149544C61746ELLU, // rgn_Latn_IT
+    0x8111494E4C61746ELLU, // ria_Latn_IN
+    0x95114D4154666E67LLU, // rif_Tfng_MA
+    0xC9314E5044657661LLU, // rjs_Deva_NP
+    0xCD51424442656E67LLU, // rkt_Beng_BD
+    0x726D43484C61746ELLU, // rm_Latn_CH
+    0x959146494C61746ELLU, // rmf_Latn_FI
+    0xB99143484C61746ELLU, // rmo_Latn_CH
+    0xCD91495241726162LLU, // rmt_Arab_IR
+    0xD19153454C61746ELLU, // rmu_Latn_SE
+    0x726E42494C61746ELLU, // rn_Latn_BI
+    0x99B14D5A4C61746ELLU, // rng_Latn_MZ
+    0x726F524F4C61746ELLU, // ro_Latn_RO
+    0x85D149444C61746ELLU, // rob_Latn_ID
+    0x95D1545A4C61746ELLU, // rof_Latn_TZ
+    0xB271464A4C61746ELLU, // rtm_Latn_FJ
+    0x727552554379726CLLU, // ru_Cyrl_RU
+    0x929155414379726CLLU, // rue_Cyrl_UA
+    0x9A9153424C61746ELLU, // rug_Latn_SB
+    0x727752574C61746ELLU, // rw_Latn_RW
+    0xAAD1545A4C61746ELLU, // rwk_Latn_TZ
+    0xD3114A504B616E61LLU, // ryu_Kana_JP
+    0x7361494E44657661LLU, // sa_Deva_IN
+    0x941247484C61746ELLU, // saf_Latn_GH
+    0x9C1252554379726CLLU, // sah_Cyrl_RU
+    0xC0124B454C61746ELLU, // saq_Latn_KE
+    0xC81249444C61746ELLU, // sas_Latn_ID
+    0xCC12494E4C61746ELLU, // sat_Latn_IN
+    0xE412494E53617572LLU, // saz_Saur_IN
+    0xBC32545A4C61746ELLU, // sbp_Latn_TZ
+    0x736349544C61746ELLU, // sc_Latn_IT
+    0xA852494E44657661LLU, // sck_Deva_IN
+    0xB45249544C61746ELLU, // scn_Latn_IT
+    0xB85247424C61746ELLU, // sco_Latn_GB
+    0xC85243414C61746ELLU, // scs_Latn_CA
+    0x7364504B41726162LLU, // sd_Arab_PK
+    0x7364494E44657661LLU, // sd_Deva_IN
+    0x7364494E4B686F6ALLU, // sd_Khoj_IN
+    0x7364494E53696E64LLU, // sd_Sind_IN
+    0x887249544C61746ELLU, // sdc_Latn_IT
+    0x9C72495241726162LLU, // sdh_Arab_IR
+    0x73654E4F4C61746ELLU, // se_Latn_NO
+    0x949243494C61746ELLU, // sef_Latn_CI
+    0x9C924D5A4C61746ELLU, // seh_Latn_MZ
+    0xA0924D584C61746ELLU, // sei_Latn_MX
+    0xC8924D4C4C61746ELLU, // ses_Latn_ML
+    0x736743464C61746ELLU, // sg_Latn_CF
+    0x80D249454F67616DLLU, // sga_Ogam_IE
+    0xC8D24C544C61746ELLU, // sgs_Latn_LT
+    0xA0F24D4154666E67LLU, // shi_Tfng_MA
+    0xB4F24D4D4D796D72LLU, // shn_Mymr_MM
+    0x73694C4B53696E68LLU, // si_Sinh_LK
+    0x8D1245544C61746ELLU, // sid_Latn_ET
+    0x736B534B4C61746ELLU, // sk_Latn_SK
+    0xC552504B41726162LLU, // skr_Arab_PK
+    0x736C53494C61746ELLU, // sl_Latn_SI
+    0xA172504C4C61746ELLU, // sli_Latn_PL
+    0xE17249444C61746ELLU, // sly_Latn_ID
+    0x736D57534C61746ELLU, // sm_Latn_WS
+    0x819253454C61746ELLU, // sma_Latn_SE
+    0xA59253454C61746ELLU, // smj_Latn_SE
+    0xB59246494C61746ELLU, // smn_Latn_FI
+    0xBD92494C53616D72LLU, // smp_Samr_IL
+    0xC99246494C61746ELLU, // sms_Latn_FI
+    0x736E5A574C61746ELLU, // sn_Latn_ZW
+    0xA9B24D4C4C61746ELLU, // snk_Latn_ML
+    0x736F534F4C61746ELLU, // so_Latn_SO
+    0xD1D2544854686169LLU, // sou_Thai_TH
+    0x7371414C4C61746ELLU, // sq_Latn_AL
+    0x737252534379726CLLU, // sr_Cyrl_RS
+    0x737252534C61746ELLU, // sr_Latn_RS
+    0x8632494E536F7261LLU, // srb_Sora_IN
+    0xB63253524C61746ELLU, // srn_Latn_SR
+    0xC632534E4C61746ELLU, // srr_Latn_SN
+    0xDE32494E44657661LLU, // srx_Deva_IN
+    0x73735A414C61746ELLU, // ss_Latn_ZA
+    0xE25245524C61746ELLU, // ssy_Latn_ER
+    0x73745A414C61746ELLU, // st_Latn_ZA
+    0xC27244454C61746ELLU, // stq_Latn_DE
+    0x737549444C61746ELLU, // su_Latn_ID
+    0xAA92545A4C61746ELLU, // suk_Latn_TZ
+    0xCA92474E4C61746ELLU, // sus_Latn_GN
+    0x737653454C61746ELLU, // sv_Latn_SE
+    0x7377545A4C61746ELLU, // sw_Latn_TZ
+    0x86D2595441726162LLU, // swb_Arab_YT
+    0x8AD243444C61746ELLU, // swc_Latn_CD
+    0x9AD244454C61746ELLU, // swg_Latn_DE
+    0xD6D2494E44657661LLU, // swv_Deva_IN
+    0xB6F249444C61746ELLU, // sxn_Latn_ID
+    0xAF12424442656E67LLU, // syl_Beng_BD
+    0xC712495153797263LLU, // syr_Syrc_IQ
+    0xAF32504C4C61746ELLU, // szl_Latn_PL
+    0x7461494E54616D6CLLU, // ta_Taml_IN
+    0xA4134E5044657661LLU, // taj_Deva_NP
+    0xD83350484C61746ELLU, // tbw_Latn_PH
+    0xE053494E4B6E6461LLU, // tcy_Knda_IN
+    0x8C73434E54616C65LLU, // tdd_Tale_CN
+    0x98734E5044657661LLU, // tdg_Deva_NP
+    0x9C734E5044657661LLU, // tdh_Deva_NP
+    0x7465494E54656C75LLU, // te_Telu_IN
+    0xB093534C4C61746ELLU, // tem_Latn_SL
+    0xB89355474C61746ELLU, // teo_Latn_UG
+    0xCC93544C4C61746ELLU, // tet_Latn_TL
+    0x7467504B41726162LLU, // tg_Arab_PK
+    0x7467544A4379726CLLU, // tg_Cyrl_TJ
+    0x7468544854686169LLU, // th_Thai_TH
+    0xACF34E5044657661LLU, // thl_Deva_NP
+    0xC0F34E5044657661LLU, // thq_Deva_NP
+    0xC4F34E5044657661LLU, // thr_Deva_NP
+    0x7469455445746869LLU, // ti_Ethi_ET
+    0x9913455245746869LLU, // tig_Ethi_ER
+    0xD5134E474C61746ELLU, // tiv_Latn_NG
+    0x746B544D4C61746ELLU, // tk_Latn_TM
+    0xAD53544B4C61746ELLU, // tkl_Latn_TK
+    0xC553415A4C61746ELLU, // tkr_Latn_AZ
+    0xCD534E5044657661LLU, // tkt_Deva_NP
+    0x746C50484C61746ELLU, // tl_Latn_PH
+    0xE173415A4C61746ELLU, // tly_Latn_AZ
+    0x9D934E454C61746ELLU, // tmh_Latn_NE
+    0x746E5A414C61746ELLU, // tn_Latn_ZA
+    0x746F544F4C61746ELLU, // to_Latn_TO
+    0x99D34D574C61746ELLU, // tog_Latn_MW
+    0xA1F350474C61746ELLU, // tpi_Latn_PG
+    0x747254524C61746ELLU, // tr_Latn_TR
+    0xD23354524C61746ELLU, // tru_Latn_TR
+    0xD63354574C61746ELLU, // trv_Latn_TW
+    0x74735A414C61746ELLU, // ts_Latn_ZA
+    0x8E5347524772656BLLU, // tsd_Grek_GR
+    0x96534E5044657661LLU, // tsf_Deva_NP
+    0x9A5350484C61746ELLU, // tsg_Latn_PH
+    0xA653425454696274LLU, // tsj_Tibt_BT
+    0x747452554379726CLLU, // tt_Cyrl_RU
+    0xA67355474C61746ELLU, // ttj_Latn_UG
+    0xCA73544854686169LLU, // tts_Thai_TH
+    0xCE73415A4C61746ELLU, // ttt_Latn_AZ
+    0xB2934D574C61746ELLU, // tum_Latn_MW
+    0xAEB354564C61746ELLU, // tvl_Latn_TV
+    0xC2D34E454C61746ELLU, // twq_Latn_NE
+    0x9AF3434E54616E67LLU, // txg_Tang_CN
+    0x747950464C61746ELLU, // ty_Latn_PF
+    0xD71352554379726CLLU, // tyv_Cyrl_RU
+    0xB3334D414C61746ELLU, // tzm_Latn_MA
+    0xB07452554379726CLLU, // udm_Cyrl_RU
+    0x7567434E41726162LLU, // ug_Arab_CN
+    0x75674B5A4379726CLLU, // ug_Cyrl_KZ
+    0x80D4535955676172LLU, // uga_Ugar_SY
+    0x756B55414379726CLLU, // uk_Cyrl_UA
+    0xA174464D4C61746ELLU, // uli_Latn_FM
+    0x8594414F4C61746ELLU, // umb_Latn_AO
+    0xC5B4494E42656E67LLU, // unr_Beng_IN
+    0xC5B44E5044657661LLU, // unr_Deva_NP
+    0xDDB4494E42656E67LLU, // unx_Beng_IN
+    0x7572504B41726162LLU, // ur_Arab_PK
+    0x757A414641726162LLU, // uz_Arab_AF
+    0x757A555A4C61746ELLU, // uz_Latn_UZ
+    0xA0154C5256616969LLU, // vai_Vaii_LR
+    0x76655A414C61746ELLU, // ve_Latn_ZA
+    0x889549544C61746ELLU, // vec_Latn_IT
+    0xBC9552554C61746ELLU, // vep_Latn_RU
+    0x7669564E4C61746ELLU, // vi_Latn_VN
+    0x891553584C61746ELLU, // vic_Latn_SX
+    0xC97542454C61746ELLU, // vls_Latn_BE
+    0x959544454C61746ELLU, // vmf_Latn_DE
+    0xD9954D5A4C61746ELLU, // vmw_Latn_MZ
+    0xCDD552554C61746ELLU, // vot_Latn_RU
+    0xBA3545454C61746ELLU, // vro_Latn_EE
+    0xB695545A4C61746ELLU, // vun_Latn_TZ
+    0x776142454C61746ELLU, // wa_Latn_BE
+    0x901643484C61746ELLU, // wae_Latn_CH
+    0xAC16455445746869LLU, // wal_Ethi_ET
+    0xC41650484C61746ELLU, // war_Latn_PH
+    0xBC3641554C61746ELLU, // wbp_Latn_AU
+    0xC036494E54656C75LLU, // wbq_Telu_IN
+    0xC436494E44657661LLU, // wbr_Deva_IN
+    0xC97657464C61746ELLU, // wls_Latn_WF
+    0xA1B64B4D41726162LLU, // wni_Arab_KM
+    0x776F534E4C61746ELLU, // wo_Latn_SN
+    0xB276494E44657661LLU, // wtm_Deva_IN
+    0xD296434E48616E73LLU, // wuu_Hans_CN
+    0xD41742524C61746ELLU, // xav_Latn_BR
+    0xC457545243617269LLU, // xcr_Cari_TR
+    0x78685A414C61746ELLU, // xh_Latn_ZA
+    0x897754524C796369LLU, // xlc_Lyci_TR
+    0x8D7754524C796469LLU, // xld_Lydi_TR
+    0x9597474547656F72LLU, // xmf_Geor_GE
+    0xB597434E4D616E69LLU, // xmn_Mani_CN
+    0xC59753444D657263LLU, // xmr_Merc_SD
+    0x81B753414E617262LLU, // xna_Narb_SA
+    0xC5B7494E44657661LLU, // xnr_Deva_IN
+    0x99D755474C61746ELLU, // xog_Latn_UG
+    0xC5F7495250727469LLU, // xpr_Prti_IR
+    0x8257594553617262LLU, // xsa_Sarb_YE
+    0xC6574E5044657661LLU, // xsr_Deva_NP
+    0xB8184D5A4C61746ELLU, // yao_Latn_MZ
+    0xBC18464D4C61746ELLU, // yap_Latn_FM
+    0xD418434D4C61746ELLU, // yav_Latn_CM
+    0x8438434D4C61746ELLU, // ybb_Latn_CM
+    0x796F4E474C61746ELLU, // yo_Latn_NG
+    0xAE3842524C61746ELLU, // yrl_Latn_BR
+    0x82984D584C61746ELLU, // yua_Latn_MX
+    0x9298434E48616E73LLU, // yue_Hans_CN
+    0x9298484B48616E74LLU, // yue_Hant_HK
+    0x7A61434E4C61746ELLU, // za_Latn_CN
+    0x981953444C61746ELLU, // zag_Latn_SD
+    0xA4794B4D41726162LLU, // zdj_Arab_KM
+    0x80994E4C4C61746ELLU, // zea_Latn_NL
+    0x9CD94D4154666E67LLU, // zgh_Tfng_MA
+    0x7A685457426F706FLLU, // zh_Bopo_TW
+    0x7A68545748616E62LLU, // zh_Hanb_TW
+    0x7A68434E48616E73LLU, // zh_Hans_CN
+    0x7A68545748616E74LLU, // zh_Hant_TW
+    0xB17954474C61746ELLU, // zlm_Latn_TG
+    0xA1994D594C61746ELLU, // zmi_Latn_MY
+    0x7A755A414C61746ELLU, // zu_Latn_ZA
+    0x833954524C61746ELLU, // zza_Latn_TR
 });
 
 const std::unordered_map<uint32_t, uint32_t> ARAB_PARENTS({
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index a2e8672..89d3cc4 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -14,7 +14,6 @@
 
 cc_library_shared {
     name: "libinputservice",
-    cpp_std: "c++17",
     srcs: [
         "PointerController.cpp",
         "SpriteController.cpp",
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index d10900e..da52a26 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -5152,6 +5152,15 @@
         return reportedSurroundFormats;
     }
 
+    /**
+     * Return if audio haptic coupled playback is supported or not.
+     *
+     * @return whether audio haptic playback supported.
+     */
+    public static boolean isHapticPlaybackSupported() {
+        return AudioSystem.isHapticPlaybackSupported();
+    }
+
 
     //---------------------------------------------------------
     // Inner classes
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 082a375..36f635a 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -933,6 +933,11 @@
      */
     public static native int setA11yServicesUids(int[] uids);
 
+    /**
+     * @see AudioManager#isHapticPlaybackSupported()
+     */
+    public static native boolean isHapticPlaybackSupported();
+
     // Items shared with audio service
 
     /**
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index 29238d3..f3442f4 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -500,17 +500,17 @@
 
     if (extractor == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return -1ll;
+        return -1LL;
     }
 
     int64_t sampleTimeUs;
     status_t err = extractor->getSampleTime(&sampleTimeUs);
 
     if (err == ERROR_END_OF_STREAM) {
-        return -1ll;
+        return -1LL;
     } else if (err != OK) {
         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-        return -1ll;
+        return -1LL;
     }
 
     return (jlong) sampleTimeUs;
@@ -522,17 +522,17 @@
 
     if (extractor == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return -1ll;
+        return -1LL;
     }
 
     size_t sampleSize;
     status_t err = extractor->getSampleSize(&sampleSize);
 
     if (err == ERROR_END_OF_STREAM) {
-        return -1ll;
+        return -1LL;
     } else if (err != OK) {
         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-        return -1ll;
+        return -1LL;
     }
 
     return (jlong) sampleSize;
@@ -858,13 +858,13 @@
 
     if (extractor == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return -1ll;
+        return -1LL;
     }
 
     int64_t cachedDurationUs;
     bool eos;
     if (!extractor->getCachedDuration(&cachedDurationUs, &eos)) {
-        return -1ll;
+        return -1LL;
     }
 
     return (jlong) cachedDurationUs;
diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp
index ed2afdd..5f51320 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/jni/soundpool/SoundPool.cpp
@@ -513,7 +513,8 @@
 
 static status_t decode(int fd, int64_t offset, int64_t length,
         uint32_t *rate, int *numChannels, audio_format_t *audioFormat,
-        sp<MemoryHeapBase> heap, size_t *memsize) {
+        audio_channel_mask_t *channelMask, sp<MemoryHeapBase> heap,
+        size_t *memsize) {
 
     ALOGV("fd %d, offset %" PRId64 ", size %" PRId64, fd, offset, length);
     AMediaExtractor *ex = AMediaExtractor_new();
@@ -650,6 +651,10 @@
                 (void)AMediaFormat_delete(format);
                 return UNKNOWN_ERROR;
             }
+            if (!AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_MASK,
+                    (int32_t*) channelMask)) {
+                *channelMask = AUDIO_CHANNEL_NONE;
+            }
             (void)AMediaFormat_delete(format);
             *memsize = written;
             return OK;
@@ -665,12 +670,13 @@
     uint32_t sampleRate;
     int numChannels;
     audio_format_t format;
+    audio_channel_mask_t channelMask;
     status_t status;
     mHeap = new MemoryHeapBase(kDefaultHeapSize);
 
     ALOGV("Start decode");
     status = decode(mFd, mOffset, mLength, &sampleRate, &numChannels, &format,
-                                 mHeap, &mSize);
+                    &channelMask, mHeap, &mSize);
     ALOGV("close(%d)", mFd);
     ::close(mFd);
     mFd = -1;
@@ -697,6 +703,7 @@
     mSampleRate = sampleRate;
     mNumChannels = numChannels;
     mFormat = format;
+    mChannelMask = channelMask;
     mState = READY;
     return NO_ERROR;
 
@@ -781,7 +788,11 @@
             // wrong audio audio buffer size  (mAudioBufferSize)
             unsigned long toggle = mToggle ^ 1;
             void *userData = (void *)((unsigned long)this | toggle);
-            audio_channel_mask_t channelMask = audio_channel_out_mask_from_count(numChannels);
+            audio_channel_mask_t sampleChannelMask = sample->channelMask();
+            // When sample contains a not none channel mask, use it as is.
+            // Otherwise, use channel count to calculate channel mask.
+            audio_channel_mask_t channelMask = sampleChannelMask != AUDIO_CHANNEL_NONE
+                    ? sampleChannelMask : audio_channel_out_mask_from_count(numChannels);
 
             // do not create a new audio track if current track is compatible with sample parameters
     #ifdef USE_SHARED_MEM_BUFFER
diff --git a/media/jni/soundpool/SoundPool.h b/media/jni/soundpool/SoundPool.h
index 5c48a90..9d74103 100644
--- a/media/jni/soundpool/SoundPool.h
+++ b/media/jni/soundpool/SoundPool.h
@@ -58,6 +58,7 @@
     int numChannels() { return mNumChannels; }
     int sampleRate() { return mSampleRate; }
     audio_format_t format() { return mFormat; }
+    audio_channel_mask_t channelMask() { return mChannelMask; }
     size_t size() { return mSize; }
     int state() { return mState; }
     uint8_t* data() { return static_cast<uint8_t*>(mData->pointer()); }
@@ -68,18 +69,19 @@
 private:
     void init();
 
-    size_t              mSize;
-    volatile int32_t    mRefCount;
-    uint16_t            mSampleID;
-    uint16_t            mSampleRate;
-    uint8_t             mState;
-    uint8_t             mNumChannels;
-    audio_format_t      mFormat;
-    int                 mFd;
-    int64_t             mOffset;
-    int64_t             mLength;
-    sp<IMemory>         mData;
-    sp<MemoryHeapBase>  mHeap;
+    size_t               mSize;
+    volatile int32_t     mRefCount;
+    uint16_t             mSampleID;
+    uint16_t             mSampleRate;
+    uint8_t              mState;
+    uint8_t              mNumChannels;
+    audio_format_t       mFormat;
+    audio_channel_mask_t mChannelMask;
+    int                  mFd;
+    int64_t              mOffset;
+    int64_t              mLength;
+    sp<IMemory>          mData;
+    sp<MemoryHeapBase>   mHeap;
 };
 
 // stores pending events for stolen channels
diff --git a/packages/ExtServices/res/values/strings.xml b/packages/ExtServices/res/values/strings.xml
index 617e49a..a9a5450 100644
--- a/packages/ExtServices/res/values/strings.xml
+++ b/packages/ExtServices/res/values/strings.xml
@@ -22,5 +22,6 @@
     <string name="autofill_field_classification_default_algorithm">EDIT_DISTANCE</string>
     <string-array name="autofill_field_classification_available_algorithms">
         <item>EDIT_DISTANCE</item>
+        <item>EXACT_MATCH</item>
     </string-array>
 </resources>
diff --git a/packages/ExtServices/src/android/ext/services/autofill/AutofillFieldClassificationServiceImpl.java b/packages/ExtServices/src/android/ext/services/autofill/AutofillFieldClassificationServiceImpl.java
index 9ba7e09..e379db8 100644
--- a/packages/ExtServices/src/android/ext/services/autofill/AutofillFieldClassificationServiceImpl.java
+++ b/packages/ExtServices/src/android/ext/services/autofill/AutofillFieldClassificationServiceImpl.java
@@ -15,8 +15,6 @@
  */
 package android.ext.services.autofill;
 
-import static android.ext.services.autofill.EditDistanceScorer.DEFAULT_ALGORITHM;
-
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.Bundle;
@@ -26,27 +24,72 @@
 
 import com.android.internal.util.ArrayUtils;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 public class AutofillFieldClassificationServiceImpl extends AutofillFieldClassificationService {
 
     private static final String TAG = "AutofillFieldClassificationServiceImpl";
 
+    private static final String DEFAULT_ALGORITHM = REQUIRED_ALGORITHM_EDIT_DISTANCE;
+
     @Nullable
     @Override
-    public float[][] onGetScores(@Nullable String algorithmName,
-            @Nullable Bundle algorithmArgs, @NonNull List<AutofillValue> actualValues,
-            @NonNull List<String> userDataValues) {
+    /** @hide */
+    public float[][] onCalculateScores(@NonNull List<AutofillValue> actualValues,
+            @NonNull List<String> userDataValues, @NonNull List<String> categoryIds,
+            @Nullable String defaultAlgorithm, @Nullable Bundle defaultArgs,
+            @Nullable Map algorithms, @Nullable Map args) {
         if (ArrayUtils.isEmpty(actualValues) || ArrayUtils.isEmpty(userDataValues)) {
-            Log.w(TAG, "getScores(): empty currentvalues (" + actualValues + ") or userValues ("
-                    + userDataValues + ")");
+            Log.w(TAG, "calculateScores(): empty currentvalues (" + actualValues
+                    + ") or userValues (" + userDataValues + ")");
             return null;
         }
-        if (algorithmName != null && !algorithmName.equals(DEFAULT_ALGORITHM)) {
-            Log.w(TAG, "Ignoring invalid algorithm (" + algorithmName + ") and using "
-                    + DEFAULT_ALGORITHM + " instead");
-        }
 
-        return EditDistanceScorer.getScores(actualValues, userDataValues);
+        return calculateScores(actualValues, userDataValues, categoryIds, defaultAlgorithm,
+                defaultArgs, (HashMap<String, String>) algorithms,
+                (HashMap<String, Bundle>) args);
+    }
+
+    /** @hide */
+    public float[][] calculateScores(@NonNull List<AutofillValue> actualValues,
+            @NonNull List<String> userDataValues, @NonNull List<String> categoryIds,
+            @Nullable String defaultAlgorithm, @Nullable Bundle defaultArgs,
+            @Nullable HashMap<String, String> algorithms,
+            @Nullable HashMap<String, Bundle> args) {
+        final int actualValuesSize = actualValues.size();
+        final int userDataValuesSize = userDataValues.size();
+        final float[][] scores = new float[actualValuesSize][userDataValuesSize];
+
+        for (int j = 0; j < userDataValuesSize; j++) {
+            final String categoryId = categoryIds.get(j);
+            String algorithmName = defaultAlgorithm;
+            Bundle arg = defaultArgs;
+            if (algorithms != null && algorithms.containsKey(categoryId)) {
+                algorithmName = algorithms.get(categoryId);
+            }
+            if (args != null && args.containsKey(categoryId)) {
+                arg = args.get(categoryId);
+            }
+
+            if (algorithmName == null || (!algorithmName.equals(DEFAULT_ALGORITHM)
+                    && !algorithmName.equals(REQUIRED_ALGORITHM_EXACT_MATCH))) {
+                Log.w(TAG, "algorithmName is " + algorithmName + ", defaulting to "
+                        + DEFAULT_ALGORITHM);
+                algorithmName = DEFAULT_ALGORITHM;
+            }
+
+            for (int i = 0; i < actualValuesSize; i++) {
+                if (algorithmName.equals(DEFAULT_ALGORITHM)) {
+                    scores[i][j] = EditDistanceScorer.calculateScore(actualValues.get(i),
+                            userDataValues.get(j));
+                } else {
+                    scores[i][j] = ExactMatch.calculateScore(actualValues.get(i),
+                            userDataValues.get(j), arg);
+                }
+            }
+        }
+        return scores;
     }
 }
diff --git a/packages/ExtServices/src/android/ext/services/autofill/EditDistanceScorer.java b/packages/ExtServices/src/android/ext/services/autofill/EditDistanceScorer.java
index 302b160..6a47901 100644
--- a/packages/ExtServices/src/android/ext/services/autofill/EditDistanceScorer.java
+++ b/packages/ExtServices/src/android/ext/services/autofill/EditDistanceScorer.java
@@ -17,13 +17,10 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.util.Log;
 import android.view.autofill.AutofillValue;
 
 import com.android.internal.annotations.VisibleForTesting;
 
-import java.util.List;
-
 final class EditDistanceScorer {
 
     private static final String TAG = "EditDistanceScorer";
@@ -31,15 +28,14 @@
     // TODO(b/70291841): STOPSHIP - set to false before launching
     private static final boolean DEBUG = true;
 
-    static final String DEFAULT_ALGORITHM = "EDIT_DISTANCE";
-
     /**
      * Gets the field classification score of 2 values based on the edit distance between them.
      *
      * <p>The score is defined as: @(max_length - edit_distance) / max_length
      */
     @VisibleForTesting
-    static float getScore(@Nullable AutofillValue actualValue, @Nullable String userDataValue) {
+    static float calculateScore(@Nullable AutofillValue actualValue,
+            @Nullable String userDataValue) {
         if (actualValue == null || !actualValue.isText() || userDataValue == null) return 0;
 
         final String actualValueText = actualValue.getTextValue().toString();
@@ -123,26 +119,5 @@
 
         return d[m][n];
     }
-    /**
-     * Gets the scores in a batch.
-     */
-    static float[][] getScores(@NonNull List<AutofillValue> actualValues,
-            @NonNull List<String> userDataValues) {
-        final int actualValuesSize = actualValues.size();
-        final int userDataValuesSize = userDataValues.size();
-        if (DEBUG) {
-            Log.d(TAG, "getScores() will return a " + actualValuesSize + "x"
-                    + userDataValuesSize + " matrix for " + DEFAULT_ALGORITHM);
-        }
-        final float[][] scores = new float[actualValuesSize][userDataValuesSize];
-
-        for (int i = 0; i < actualValuesSize; i++) {
-            for (int j = 0; j < userDataValuesSize; j++) {
-                final float score = getScore(actualValues.get(i), userDataValues.get(j));
-                scores[i][j] = score;
-            }
-        }
-        return scores;
-    }
 
 }
diff --git a/packages/ExtServices/src/android/ext/services/autofill/ExactMatch.java b/packages/ExtServices/src/android/ext/services/autofill/ExactMatch.java
new file mode 100644
index 0000000..3e55c5c
--- /dev/null
+++ b/packages/ExtServices/src/android/ext/services/autofill/ExactMatch.java
@@ -0,0 +1,67 @@
+/*
+ * 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.ext.services.autofill;
+
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.view.autofill.AutofillValue;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+final class ExactMatch {
+
+    /**
+     * Gets the field classification score of 2 values based on whether they are an exact match
+     *
+     * @return {@code 1.0} if the two values are an exact match, {@code 0.0} otherwise.
+     */
+    @VisibleForTesting
+    static float calculateScore(@Nullable AutofillValue actualValue,
+            @Nullable String userDataValue, @Nullable Bundle args) {
+        if (actualValue == null || !actualValue.isText() || userDataValue == null) return 0;
+
+        final String actualValueText = actualValue.getTextValue().toString();
+
+        final int suffixLength;
+        if (args != null) {
+            suffixLength = args.getInt("suffix", -1);
+
+            if (suffixLength < 0) {
+                throw new IllegalArgumentException("suffix argument is invalid");
+            }
+
+            final String actualValueSuffix;
+            if (suffixLength < actualValueText.length()) {
+                actualValueSuffix = actualValueText.substring(actualValueText.length()
+                        - suffixLength);
+            } else {
+                actualValueSuffix = actualValueText;
+            }
+
+            final String userDataValueSuffix;
+            if (suffixLength < userDataValue.length()) {
+                userDataValueSuffix = userDataValue.substring(userDataValue.length()
+                        - suffixLength);
+            } else {
+                userDataValueSuffix = userDataValue;
+            }
+
+            return (actualValueSuffix.equalsIgnoreCase(userDataValueSuffix)) ? 1 : 0;
+        } else {
+            return actualValueText.equalsIgnoreCase(userDataValue) ? 1 : 0;
+        }
+    }
+}
diff --git a/packages/ExtServices/tests/Android.mk b/packages/ExtServices/tests/Android.mk
index 0a95b85..a57fa94 100644
--- a/packages/ExtServices/tests/Android.mk
+++ b/packages/ExtServices/tests/Android.mk
@@ -12,7 +12,8 @@
     mockito-target-minus-junit4 \
     espresso-core \
     truth-prebuilt \
-    testables
+    testables \
+    testng
 
 # Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/packages/ExtServices/tests/src/android/ext/services/autofill/AutofillFieldClassificationServiceImplTest.java b/packages/ExtServices/tests/src/android/ext/services/autofill/AutofillFieldClassificationServiceImplTest.java
index 48c076e..6fda4c7 100644
--- a/packages/ExtServices/tests/src/android/ext/services/autofill/AutofillFieldClassificationServiceImplTest.java
+++ b/packages/ExtServices/tests/src/android/ext/services/autofill/AutofillFieldClassificationServiceImplTest.java
@@ -16,14 +16,21 @@
 
 package android.ext.services.autofill;
 
+import static android.service.autofill.AutofillFieldClassificationService.REQUIRED_ALGORITHM_EXACT_MATCH;
+import static android.view.autofill.AutofillValue.forText;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.os.Bundle;
+import android.view.autofill.AutofillValue;
+
 import org.junit.Test;
 
 import java.util.Arrays;
 import java.util.Collections;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.view.autofill.AutofillValue;
+import java.util.HashMap;
+import java.util.List;
 
 /**
  * Contains the base tests that does not rely on the specific algorithm implementation.
@@ -34,26 +41,78 @@
             new AutofillFieldClassificationServiceImpl();
 
     @Test
-    public void testOnGetScores_nullActualValues() {
-        assertThat(mService.onGetScores(null, null, null, Arrays.asList("whatever"))).isNull();
+    public void testOnCalculateScores_nullActualValues() {
+        assertThat(mService.onCalculateScores(null, null, null, null, null, null, null)).isNull();
     }
 
     @Test
-    public void testOnGetScores_emptyActualValues() {
-        assertThat(mService.onGetScores(null, null, Collections.emptyList(),
-                Arrays.asList("whatever"))).isNull();
+    public void testOnCalculateScores_emptyActualValues() {
+        assertThat(mService.onCalculateScores(Collections.emptyList(), Arrays.asList("whatever"),
+                null, null, null, null, null)).isNull();
     }
 
     @Test
-    public void testOnGetScores_nullUserDataValues() {
-        assertThat(mService.onGetScores(null, null,
-                Arrays.asList(AutofillValue.forText("whatever")), null)).isNull();
+    public void testOnCalculateScores_nullUserDataValues() {
+        assertThat(mService.onCalculateScores(Arrays.asList(AutofillValue.forText("whatever")),
+                null, null, null, null, null, null)).isNull();
     }
 
     @Test
-    public void testOnGetScores_emptyUserDataValues() {
-        assertThat(mService.onGetScores(null, null,
-                Arrays.asList(AutofillValue.forText("whatever")), Collections.emptyList()))
-                        .isNull();
+    public void testOnCalculateScores_emptyUserDataValues() {
+        assertThat(mService.onCalculateScores(Arrays.asList(AutofillValue.forText("whatever")),
+                Collections.emptyList(), null, null, null, null, null))
+                .isNull();
+    }
+
+    @Test
+    public void testCalculateScores() {
+        final List<AutofillValue> actualValues = Arrays.asList(forText("A"), forText("b"),
+                forText("dude"));
+        final List<String> userDataValues = Arrays.asList("a", "b", "B", "ab", "c", "dude",
+                "sweet_dude", "dude_sweet");
+        final List<String> categoryIds = Arrays.asList("cat", "cat", "cat", "cat", "cat", "last4",
+                "last4", "last4");
+        final HashMap<String, String> algorithms = new HashMap<>(1);
+        algorithms.put("last4", REQUIRED_ALGORITHM_EXACT_MATCH);
+
+        final Bundle last4Bundle = new Bundle();
+        last4Bundle.putInt("suffix", 4);
+
+        final HashMap<String, Bundle> args = new HashMap<>(1);
+        args.put("last4", last4Bundle);
+
+        final float[][] expectedScores = new float[][] {
+                new float[] { 1F, 0F, 0F, 0.5F, 0F, 0F, 0F, 0F },
+                new float[] { 0F, 1F, 1F, 0.5F, 0F, 0F, 0F, 0F },
+                new float[] { 0F, 0F, 0F, 0F  , 0F, 1F, 1F, 0F }
+        };
+        final float[][] actualScores = mService.onCalculateScores(actualValues, userDataValues,
+                categoryIds, null, null, algorithms, args);
+
+        // Unfortunately, Truth does not have an easy way to compare float matrices and show useful
+        // messages in case of error, so we need to check.
+        assertWithMessage("actual=%s, expected=%s", toString(actualScores),
+                toString(expectedScores)).that(actualScores.length).isEqualTo(3);
+        for (int i = 0; i < 3; i++) {
+            assertWithMessage("actual=%s, expected=%s", toString(actualScores),
+                    toString(expectedScores)).that(actualScores[i].length).isEqualTo(8);
+        }
+
+        for (int i = 0; i < actualScores.length; i++) {
+            final float[] line = actualScores[i];
+            for (int j = 0; j < line.length; j++) {
+                float cell = line[j];
+                assertWithMessage("wrong score at [%s, %s]", i, j).that(cell).isWithin(0.01F)
+                        .of(expectedScores[i][j]);
+            }
+        }
+    }
+
+    public static String toString(float[][] matrix) {
+        final StringBuilder string = new StringBuilder("[ ");
+        for (int i = 0; i < matrix.length; i++) {
+            string.append(Arrays.toString(matrix[i])).append(" ");
+        }
+        return string.append(" ]").toString();
     }
 }
diff --git a/packages/ExtServices/tests/src/android/ext/services/autofill/EditDistanceScorerTest.java b/packages/ExtServices/tests/src/android/ext/services/autofill/EditDistanceScorerTest.java
index afe2236..9b9d4be 100644
--- a/packages/ExtServices/tests/src/android/ext/services/autofill/EditDistanceScorerTest.java
+++ b/packages/ExtServices/tests/src/android/ext/services/autofill/EditDistanceScorerTest.java
@@ -15,107 +15,67 @@
  */
 package android.ext.services.autofill;
 
-import static android.ext.services.autofill.EditDistanceScorer.getScore;
-import static android.ext.services.autofill.EditDistanceScorer.getScores;
-import static android.view.autofill.AutofillValue.forText;
+import static android.ext.services.autofill.EditDistanceScorer.calculateScore;
 
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
 
 import android.view.autofill.AutofillValue;
 
 import org.junit.Test;
 
-import java.util.Arrays;
-import java.util.List;
-
 public class EditDistanceScorerTest {
 
     @Test
-    public void testGetScore_nullValue() {
-        assertFloat(getScore(null, "D'OH!"), 0);
+    public void testCalculateScore_nullValue() {
+        assertFloat(calculateScore(null, "D'OH!"), 0);
     }
 
     @Test
-    public void testGetScore_nonTextValue() {
-        assertFloat(getScore(AutofillValue.forToggle(true), "D'OH!"), 0);
+    public void testCalculateScore_nonTextValue() {
+        assertFloat(calculateScore(AutofillValue.forToggle(true), "D'OH!"), 0);
     }
 
     @Test
-    public void testGetScore_nullUserData() {
-        assertFloat(getScore(AutofillValue.forText("D'OH!"), null), 0);
+    public void testCalculateScore_nullUserData() {
+        assertFloat(calculateScore(AutofillValue.forText("D'OH!"), null), 0);
     }
 
     @Test
-    public void testGetScore_fullMatch() {
-        assertFloat(getScore(AutofillValue.forText("D'OH!"), "D'OH!"), 1);
-        assertFloat(getScore(AutofillValue.forText(""), ""), 1);
+    public void testCalculateScore_fullMatch() {
+        assertFloat(calculateScore(AutofillValue.forText("D'OH!"), "D'OH!"), 1);
+        assertFloat(calculateScore(AutofillValue.forText(""), ""), 1);
     }
 
     @Test
-    public void testGetScore_fullMatchMixedCase() {
-        assertFloat(getScore(AutofillValue.forText("D'OH!"), "D'oH!"), 1);
+    public void testCalculateScore_fullMatchMixedCase() {
+        assertFloat(calculateScore(AutofillValue.forText("D'OH!"), "D'oH!"), 1);
     }
 
     @Test
-    public void testGetScore_mismatchDifferentSizes() {
-        assertFloat(getScore(AutofillValue.forText("X"), "Xy"), 0.50F);
-        assertFloat(getScore(AutofillValue.forText("Xy"), "X"), 0.50F);
-        assertFloat(getScore(AutofillValue.forText("One"), "MoreThanOne"), 0.27F);
-        assertFloat(getScore(AutofillValue.forText("MoreThanOne"), "One"), 0.27F);
-        assertFloat(getScore(AutofillValue.forText("1600 Amphitheatre Parkway"),
+    public void testCalculateScore_mismatchDifferentSizes() {
+        assertFloat(calculateScore(AutofillValue.forText("X"), "Xy"), 0.50F);
+        assertFloat(calculateScore(AutofillValue.forText("Xy"), "X"), 0.50F);
+        assertFloat(calculateScore(AutofillValue.forText("One"), "MoreThanOne"), 0.27F);
+        assertFloat(calculateScore(AutofillValue.forText("MoreThanOne"), "One"), 0.27F);
+        assertFloat(calculateScore(AutofillValue.forText("1600 Amphitheatre Parkway"),
                 "1600 Amphitheatre Pkwy"), 0.88F);
-        assertFloat(getScore(AutofillValue.forText("1600 Amphitheatre Pkwy"),
+        assertFloat(calculateScore(AutofillValue.forText("1600 Amphitheatre Pkwy"),
                 "1600 Amphitheatre Parkway"), 0.88F);
     }
 
     @Test
-    public void testGetScore_partialMatch() {
-        assertFloat(getScore(AutofillValue.forText("Dude"), "Dxxx"), 0.25F);
-        assertFloat(getScore(AutofillValue.forText("Dude"), "DUxx"), 0.50F);
-        assertFloat(getScore(AutofillValue.forText("Dude"), "DUDx"), 0.75F);
-        assertFloat(getScore(AutofillValue.forText("Dxxx"), "Dude"), 0.25F);
-        assertFloat(getScore(AutofillValue.forText("DUxx"), "Dude"), 0.50F);
-        assertFloat(getScore(AutofillValue.forText("DUDx"), "Dude"), 0.75F);
-    }
-
-    @Test
-    public void testGetScores() {
-        final List<AutofillValue> actualValues = Arrays.asList(forText("A"), forText("b"));
-        final List<String> userDataValues = Arrays.asList("a", "B", "ab", "c");
-        final float[][] expectedScores = new float[][] {
-            new float[] { 1F, 0F, 0.5F, 0F },
-            new float[] { 0F, 1F, 0.5F, 0F }
-        };
-        final float[][] actualScores = getScores(actualValues, userDataValues);
-
-        // Unfortunately, Truth does not have an easy way to compare float matrices and show useful
-        // messages in case of error, so we need to check.
-        assertWithMessage("actual=%s, expected=%s", toString(actualScores),
-                toString(expectedScores)).that(actualScores.length).isEqualTo(2);
-        assertWithMessage("actual=%s, expected=%s", toString(actualScores),
-                toString(expectedScores)).that(actualScores[0].length).isEqualTo(4);
-        assertWithMessage("actual=%s, expected=%s", toString(actualScores),
-                toString(expectedScores)).that(actualScores[1].length).isEqualTo(4);
-        for (int i = 0; i < actualScores.length; i++) {
-            final float[] line = actualScores[i];
-            for (int j = 0; j < line.length; j++) {
-                float cell = line[j];
-                assertWithMessage("wrong score at [%s, %s]", i, j).that(cell).isWithin(0.01F)
-                        .of(expectedScores[i][j]);
-            }
-        }
+    public void testCalculateScore_partialMatch() {
+        assertFloat(calculateScore(AutofillValue.forText("Dude"), "Dxxx"), 0.25F);
+        assertFloat(calculateScore(AutofillValue.forText("Dude"), "DUxx"), 0.50F);
+        assertFloat(calculateScore(AutofillValue.forText("Dude"), "DUDx"), 0.75F);
+        assertFloat(calculateScore(AutofillValue.forText("Dxxx"), "Dude"), 0.25F);
+        assertFloat(calculateScore(AutofillValue.forText("DUxx"), "Dude"), 0.50F);
+        assertFloat(calculateScore(AutofillValue.forText("DUDx"), "Dude"), 0.75F);
     }
 
     public static void assertFloat(float actualValue, float expectedValue) {
         assertThat(actualValue).isWithin(0.01F).of(expectedValue);
     }
 
-    public static String toString(float[][] matrix) {
-        final StringBuilder string = new StringBuilder("[ ");
-        for (int i = 0; i < matrix.length; i++) {
-            string.append(Arrays.toString(matrix[i])).append(" ");
-        }
-        return string.append(" ]").toString();
-    }
+
 }
diff --git a/packages/ExtServices/tests/src/android/ext/services/autofill/ExactMatchTest.java b/packages/ExtServices/tests/src/android/ext/services/autofill/ExactMatchTest.java
new file mode 100644
index 0000000..bf5e160
--- /dev/null
+++ b/packages/ExtServices/tests/src/android/ext/services/autofill/ExactMatchTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.ext.services.autofill;
+
+import static android.ext.services.autofill.ExactMatch.calculateScore;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.assertThrows;
+
+import android.os.Bundle;
+import android.view.autofill.AutofillValue;
+
+import org.junit.Test;
+
+public class ExactMatchTest {
+
+    private Bundle last4Bundle() {
+        final Bundle bundle = new Bundle();
+        bundle.putInt("suffix", 4);
+        return bundle;
+    }
+
+    @Test
+    public void testCalculateScore_nullValue() {
+        assertFloat(calculateScore(null, "TEST", null), 0);
+    }
+
+    @Test
+    public void testCalculateScore_nonTextValue() {
+        assertFloat(calculateScore(AutofillValue.forToggle(true), "TEST", null), 0);
+    }
+
+    @Test
+    public void testCalculateScore_nullUserData() {
+        assertFloat(calculateScore(AutofillValue.forText("TEST"), null, null), 0);
+    }
+
+    @Test
+    public void testCalculateScore_succeedMatchMixedCases_last4() {
+        final Bundle last4 = last4Bundle();
+        assertFloat(calculateScore(AutofillValue.forText("TEST"), "1234 test", last4), 1);
+        assertFloat(calculateScore(AutofillValue.forText("test"), "1234 TEST", last4), 1);
+    }
+
+    @Test
+    public void testCalculateScore_mismatchDifferentSizes_last4() {
+        final Bundle last4 = last4Bundle();
+        assertFloat(calculateScore(AutofillValue.forText("TEST"), "TEST1", last4), 0);
+        assertFloat(calculateScore(AutofillValue.forText(""), "TEST", last4), 0);
+        assertFloat(calculateScore(AutofillValue.forText("TEST"), "", last4), 0);
+    }
+
+    @Test
+    public void testCalculateScore_match() {
+        final Bundle last4 = last4Bundle();
+        assertFloat(calculateScore(AutofillValue.forText("1234 1234 1234 1234"),
+                "xxxx xxxx xxxx 1234", last4), 1);
+        assertFloat(calculateScore(AutofillValue.forText("TEST"), "TEST", null), 1);
+        assertFloat(calculateScore(AutofillValue.forText("TEST 1234"), "1234", last4), 1);
+        assertFloat(calculateScore(AutofillValue.forText("TEST"), "test", null), 1);
+    }
+
+    @Test
+    public void testCalculateScore_badBundle() {
+        final Bundle bundle = new Bundle();
+        bundle.putInt("suffix", -2);
+        assertThrows(IllegalArgumentException.class, () -> calculateScore(
+                AutofillValue.forText("TEST"), "TEST", bundle));
+
+        final Bundle largeBundle = new Bundle();
+        largeBundle.putInt("suffix", 10);
+        assertFloat(calculateScore(AutofillValue.forText("TEST"), "TEST", largeBundle), 1);
+
+        final Bundle stringBundle = new Bundle();
+        stringBundle.putString("suffix", "value");
+        assertThrows(IllegalArgumentException.class, () -> calculateScore(
+                AutofillValue.forText("TEST"), "TEST", stringBundle));
+
+    }
+
+    public static void assertFloat(float actualValue, float expectedValue) {
+        assertThat(actualValue).isWithin(0.01F).of(expectedValue);
+    }
+}
diff --git a/packages/PackageInstaller/AndroidManifest.xml b/packages/PackageInstaller/AndroidManifest.xml
index eb9ec82..18b8662 100644
--- a/packages/PackageInstaller/AndroidManifest.xml
+++ b/packages/PackageInstaller/AndroidManifest.xml
@@ -15,6 +15,7 @@
     <uses-permission android:name="android.permission.MANAGE_APP_OPS_MODES" />
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
     <uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" />
+    <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />
 
     <uses-permission android:name="com.google.android.permission.INSTALL_WEARABLE_PACKAGES" />
 
diff --git a/packages/PackageInstaller/res/layout/uninstall_content_view.xml b/packages/PackageInstaller/res/layout/uninstall_content_view.xml
new file mode 100644
index 0000000..5ecb614
--- /dev/null
+++ b/packages/PackageInstaller/res/layout/uninstall_content_view.xml
@@ -0,0 +1,47 @@
+<?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.
+  -->
+
+<!-- Check box that is displayed in the activity resolver UI for the user
+     to make their selection the preferred activity. -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:theme="?android:attr/alertDialogTheme"
+    android:orientation="vertical"
+    android:paddingTop="8dp"
+    android:paddingStart="?android:attr/dialogPreferredPadding"
+    android:paddingEnd="?android:attr/dialogPreferredPadding"
+    android:clipToPadding="false">
+
+    <TextView
+        android:id="@+id/message"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        style="@android:style/TextAppearance.Material.Subhead" />
+
+    <CheckBox
+        android:id="@+id/checkbox"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:layout_marginStart="-8dp"
+        android:paddingLeft="8sp"
+        style="@android:style/TextAppearance.Material.Subhead" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/PackageInstaller/res/values-mr/strings.xml b/packages/PackageInstaller/res/values-mr/strings.xml
index d751c42..01f3e5b 100644
--- a/packages/PackageInstaller/res/values-mr/strings.xml
+++ b/packages/PackageInstaller/res/values-mr/strings.xml
@@ -22,17 +22,17 @@
     <string name="cancel" msgid="1018267193425558088">"रद्द करा"</string>
     <string name="installing" msgid="4921993079741206516">"इंस्‍टॉल होत आहे…"</string>
     <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> इंस्टॉल होत आहे…"</string>
-    <string name="install_done" msgid="5987363587661783896">"अॅप इंस्टॉल झाले."</string>
+    <string name="install_done" msgid="5987363587661783896">"अ‍ॅप इंस्टॉल झाले."</string>
     <string name="install_confirm_question" msgid="8176284075816604590">"तुम्हाला हे अॅप्लिकेशन इंस्टॉल करायचे आहे का?"</string>
     <string name="install_confirm_question_update" msgid="7942235418781274635">"तुम्हाच्या विद्यमान अॅप्लिकेशनवर अपडेट इंस्टॉल करायचे आहे का? तुमचा विद्यमान डेटा गमावणार नाही."</string>
     <string name="install_confirm_question_update_system" msgid="4713001702777910263">"तुम्हाला या बिल्ट-इन अॅप्लिकेशनवर अपडेट इंस्टॉल करायचे आहे का? तुमचा विद्यमान डेटा गमावणार नाही."</string>
-    <string name="install_failed" msgid="5777824004474125469">"अॅप इंस्टॉल झाले नाही."</string>
+    <string name="install_failed" msgid="5777824004474125469">"अ‍ॅप इंस्टॉल झाले नाही."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"पॅकेज इंस्टॉल होण्यापासून ब्लॉक केले होते."</string>
-    <string name="install_failed_conflict" msgid="3493184212162521426">"पॅकेजचा विद्यमान पॅकेजशी विरोध असल्याने अॅप इंस्टॉल झाले नाही."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"तुमच्या टॅबलेटशी कंपॅटिबल नसल्याने अॅप इंस्टॉल झाले नाही."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"हे अॅप तुमच्या टीव्हीशी कंपॅटिबल नाही."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"तुमच्या फोनशी कंपॅटिबल नसल्याने अॅप इंस्टॉल झाले नाही."</string>
-    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"पॅकेज अयोग्य असल्याचे दिसत असल्याने अॅप इंस्टॉल झाले नाही."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"पॅकेजचा विद्यमान पॅकेजशी विरोध असल्याने अ‍ॅप इंस्टॉल झाले नाही."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"तुमच्या टॅबलेटशी कंपॅटिबल नसल्याने अ‍ॅप इंस्टॉल झाले नाही."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"हे अ‍ॅप तुमच्या टीव्हीशी कंपॅटिबल नाही."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"तुमच्या फोनशी कंपॅटिबल नसल्याने अ‍ॅप इंस्टॉल झाले नाही."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"पॅकेज अयोग्य असल्याचे दिसत असल्याने अ‍ॅप इंस्टॉल झाले नाही."</string>
     <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> तुमच्या टॅबलेटवर इंस्टॉल केले जाऊ शकत नाही."</string>
     <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> तुमच्या टीव्हीवर इंस्टॉल केले जाऊ शकत नाही."</string>
     <string name="install_failed_msg" product="default" msgid="6484461562647915707">"<xliff:g id="APP_NAME">%1$s</xliff:g> तुमच्या फोनवर इंस्टॉल केले जाऊ शकत नाही."</string>
@@ -44,20 +44,20 @@
     <string name="manage_applications" msgid="5400164782453975580">"अ‍ॅप्स व्यवस्थापन"</string>
     <string name="out_of_space_dlg_title" msgid="4156690013884649502">"जागा संपली"</string>
     <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> इंस्टॉल केले जाऊ शकत नाही. काही जागा मोकळी करा आणि पुन्हा प्रयत्न करा."</string>
-    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"अॅप आढळले नाही"</string>
-    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"इंस्टॉल केलेल्या अॅप्सच्या सूचीमध्ये अॅप आढळले नाही."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"अ‍ॅप आढळले नाही"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"इंस्टॉल केलेल्या अ‍ॅप्सच्या सूचीमध्ये अ‍ॅप आढळले नाही."</string>
     <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"अनुमती नाही"</string>
     <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"हे अनइंस्टॉल करण्याची विद्यमान वापरकर्त्यास अनुमती नाही."</string>
     <string name="generic_error_dlg_title" msgid="5863195085927067752">"एरर"</string>
-    <string name="generic_error_dlg_text" msgid="5287861443265795232">"अॅप अनइंस्टॉल करणे शक्य झाले नाही."</string>
-    <string name="uninstall_application_title" msgid="4045420072401428123">"अॅप अनइंस्टॉल करा"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"अ‍ॅप अनइंस्टॉल करणे शक्य झाले नाही."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"अ‍ॅप अनइंस्टॉल करा"</string>
     <string name="uninstall_update_title" msgid="824411791011583031">"अपडेट अनइंस्टॉल करा"</string>
     <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> खालील अॅपचा भाग आहे:"</string>
-    <string name="uninstall_application_text" msgid="3816830743706143980">"तुम्हाला हे अॅप अनइंस्टॉल करायचे आहे का?"</string>
-    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"तुम्हाला हे अॅप "<b>"सर्व"</b>" वापरकर्त्यांसाठी अनइंस्टॉल करायचे आहे का? अॅप्लिकेशन आणि त्याचा डेटा डिव्हाइसवरील "<b>"सर्व"</b>" वापरकर्त्यांकडून काढला जाईल."</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"तुम्हाला हे अ‍ॅप अनइंस्टॉल करायचे आहे का?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"तुम्हाला हे अ‍ॅप "<b>"सर्व"</b>" वापरकर्त्यांसाठी अनइंस्टॉल करायचे आहे का? अ‍ॅप्लिकेशन आणि त्याचा डेटा डिव्हाइसवरील "<b>"सर्व"</b>" वापरकर्त्यांकडून काढला जाईल."</string>
     <string name="uninstall_application_text_user" msgid="498072714173920526">"तुम्हाला <xliff:g id="USERNAME">%1$s</xliff:g> वापरकर्त्यासाठी हे अ‍ॅप अनइंस्टॉल करायचे आहे का?"</string>
-    <string name="uninstall_update_text" msgid="863648314632448705">"फॅक्टरी आवृत्तीसह हे अॅप बदलायचे का? सर्व डेटा काढला जाईल."</string>
-    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"फॅक्टरी आवृत्तीसह हे अॅप बदलायचे? सर्व डेटा काढला जाईल. हे कार्य प्रोफाइल असलेल्यांसह या डिव्हाइसच्या सर्व वापरकर्त्यांना प्रभावित करते."</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"फॅक्टरी आवृत्तीसह हे अ‍ॅप बदलायचे का? सर्व डेटा काढला जाईल."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"फॅक्टरी आवृत्तीसह हे अ‍ॅप बदलायचे? सर्व डेटा काढला जाईल. हे कार्य प्रोफाइल असलेल्यांसह या डिव्हाइसच्या सर्व वापरकर्त्यांना प्रभावित करते."</string>
     <string name="uninstalling_notification_channel" msgid="840153394325714653">"अनइंस्टॉल रन होत आहेत"</string>
     <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"अनइंस्टॉल करता आले नाही"</string>
     <string name="uninstalling" msgid="8709566347688966845">"अनइंस्टॉल करत आहे…"</string>
@@ -68,7 +68,7 @@
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल करता आले नाही."</string>
     <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"अॅक्टिव्ह डिव्हाइस प्रशासक अ‍ॅप अनइंस्टॉल करू शकत नाही"</string>
     <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"<xliff:g id="USERNAME">%1$s</xliff:g> साठी अॅक्टिव्ह डिव्हाइस प्रशासक अ‍ॅप अनइंस्टॉल करू शकत नाही"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"हे अॅप काही वापरकर्ते किंवा प्रोफाइलसाठी आवश्यक आहे आणि इतरांसाठी अनइंस्टॉल करण्यात आले"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"हे अ‍ॅप काही वापरकर्ते किंवा प्रोफाइलसाठी आवश्यक आहे आणि इतरांसाठी अनइंस्टॉल करण्यात आले"</string>
     <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"तुमच्या प्रोफाइलसाठी हे अ‍ॅप आवश्यक आहे आणि अनइंस्टॉल केले जाऊ शकत नाही."</string>
     <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"तुमच्या डिव्हाइस प्रशासकास हे अ‍ॅप आवश्यक आहे आणि ते अनइंस्टॉल केले जाऊ शकत नाही."</string>
     <string name="manage_device_administrators" msgid="3092696419363842816">"डिव्हाइस प्रशासक अ‍ॅप्स व्यवस्थापित करा"</string>
@@ -77,18 +77,18 @@
     <string name="Parse_error_dlg_text" msgid="1661404001063076789">"पॅकेज पार्स करण्यात समस्या आली."</string>
     <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
     <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"इंस्टॉल करा/अनइंस्टॉल करा क्रिया Wear वर सपोर्ट करत नाहीत."</string>
-    <string name="message_staging" msgid="8032722385658438567">"अॅप सुरुवातीच्या स्थितीत आहे…"</string>
+    <string name="message_staging" msgid="8032722385658438567">"अ‍ॅप सुरुवातीच्या स्थितीत आहे…"</string>
     <string name="app_name_unknown" msgid="6881210203354323926">"अज्ञात"</string>
     <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"तुमच्या सुरक्षिततेसाठी, तुमच्या टॅबलेटला या स्रोताकडील अज्ञात अ‍ॅप्स इंस्टॉल करण्याची अनुमती नाही."</string>
     <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"तुमच्या सुरक्षिततेसाठी, तुमच्या टीव्हीला या स्रोताकडील अज्ञात अ‍ॅप्स इंस्टॉल करण्याची अनुमती नाही."</string>
     <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"तुमच्या सुरक्षिततेसाठी, तुमच्या फोनला या स्रोताकडील अज्ञात अ‍ॅप्स इंस्टॉल करण्याची अनुमती नाही."</string>
-    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"तुमचा फोन आणि वैयक्तिक डेटा अज्ञात अॅप्‍सकडून होणार्‍या अटॅकमुळे अधिक असुरक्षित आहे. हे अॅप इंस्टॉल करून, तुम्‍ही सहमती देता की ते वापरल्‍याने होणार्‍या तुमच्‍या फोनचे कोणत्‍याही प्रकारे होणारे नुकसान किंवा डेटा हानीसाठी तुम्‍ही जबाबदार आहात."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"तुमचा टॅबलेट आणि वैयक्तिक डेटा अज्ञात अॅप्‍सकडून होणार्‍या अटॅकमुळे अधिक असुरक्षित आहे. हे अॅप इंस्टॉल करून, तुम्‍ही सहमती देता की ते वापरल्‍याने तुमच्‍या टॅबलेटचे कोणत्‍याही प्रकारे होणारे नुकसान किंवा डेटा हानीसाठी तुम्‍ही जबाबदार आहात."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"तुमचा टीव्‍ही आणि वैयक्तिक डेटा अज्ञात अॅप्‍सकडून होणार्‍या अटॅकमुळे अधिक असुरक्षित आहे. हे अॅप इंस्टॉल करून, तुम्ही सहमती देता की ते वापरल्‍याने तुमच्‍या टीव्‍हीचे कोणत्‍याही प्रकारे होणारे नुकसान किंवा डेटा हानीसाठी तुम्‍ही जबाबदार आहात."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"तुमचा फोन आणि वैयक्तिक डेटा अज्ञात अ‍ॅप्‍सकडून होणार्‍या अटॅकमुळे अधिक असुरक्षित आहे. हे अ‍ॅप इंस्टॉल करून, तुम्‍ही सहमती देता की ते वापरल्‍याने होणार्‍या तुमच्‍या फोनचे कोणत्‍याही प्रकारे होणारे नुकसान किंवा डेटा हानीसाठी तुम्‍ही जबाबदार आहात."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"तुमचा टॅबलेट आणि वैयक्तिक डेटा अज्ञात अ‍ॅप्‍सकडून होणार्‍या अटॅकमुळे अधिक असुरक्षित आहे. हे अ‍ॅप इंस्टॉल करून, तुम्‍ही सहमती देता की ते वापरल्‍याने तुमच्‍या टॅबलेटचे कोणत्‍याही प्रकारे होणारे नुकसान किंवा डेटा हानीसाठी तुम्‍ही जबाबदार आहात."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"तुमचा टीव्‍ही आणि वैयक्तिक डेटा अज्ञात अ‍ॅप्‍सकडून होणार्‍या अटॅकमुळे अधिक असुरक्षित आहे. हे अ‍ॅप इंस्टॉल करून, तुम्ही सहमती देता की ते वापरल्‍याने तुमच्‍या टीव्‍हीचे कोणत्‍याही प्रकारे होणारे नुकसान किंवा डेटा हानीसाठी तुम्‍ही जबाबदार आहात."</string>
     <string name="anonymous_source_continue" msgid="4375745439457209366">"सुरू ठेवा"</string>
     <string name="external_sources_settings" msgid="4046964413071713807">"सेटिंग्ज"</string>
     <string name="wear_app_channel" msgid="1960809674709107850">"wear अ‍ॅप्स इंस्टॉल/अनइंस्टॉल करत आहे"</string>
-    <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"अॅप इंस्टॉल सूचना"</string>
+    <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"अ‍ॅप इंस्टॉल सूचना"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"यशस्वीरित्या इंस्टॉल केले"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" यशस्वीरित्या इंस्टॉल झाले"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values/strings.xml b/packages/PackageInstaller/res/values/strings.xml
index 0f065ab..1d8747a1 100644
--- a/packages/PackageInstaller/res/values/strings.xml
+++ b/packages/PackageInstaller/res/values/strings.xml
@@ -119,6 +119,8 @@
     <string name="uninstall_update_text">Replace this app with the factory version? All data will be removed.</string>
     <!--  [CHAR LIMIT=none] -->
     <string name="uninstall_update_text_multiuser">Replace this app with the factory version? All data will be removed. This affects all users of this device, including those with work profiles.</string>
+    <!-- Label of a checkbox that allows to remove the files contributed by app during uninstall [CHAR LIMIT=none] -->
+    <string name="uninstall_remove_contributed_files">Also remove <xliff:g id="size" example="1.5MB">%1$s</xliff:g> of associated media files.</string>
 
     <!-- Label for the notification channel containing notifications for current uninstall operations [CHAR LIMIT=40] -->
     <string name="uninstalling_notification_channel">Running uninstalls</string>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallUninstalling.java b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallUninstalling.java
index 1c0aec1..d13bb65 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallUninstalling.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallUninstalling.java
@@ -50,6 +50,8 @@
             "com.android.packageinstaller.ACTION_UNINSTALL_COMMIT";
 
     static final String EXTRA_APP_LABEL = "com.android.packageinstaller.extra.APP_LABEL";
+    static final String EXTRA_CLEAR_CONTRIBUTED_FILES =
+            "com.android.packageinstaller.extra.CLEAR_CONTRIBUTED_FILES";
 
     private int mUninstallId;
     private ApplicationInfo mAppInfo;
@@ -72,6 +74,8 @@
             if (savedInstanceState == null) {
                 boolean allUsers = getIntent().getBooleanExtra(Intent.EXTRA_UNINSTALL_ALL_USERS,
                         false);
+                boolean clearContributedFiles = getIntent().getBooleanExtra(
+                        EXTRA_CLEAR_CONTRIBUTED_FILES, false);
                 UserHandle user = getIntent().getParcelableExtra(Intent.EXTRA_USER);
 
                 // Show dialog, which is the whole UI
@@ -95,12 +99,15 @@
                 PendingIntent pendingIntent = PendingIntent.getBroadcast(this, mUninstallId,
                         broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
 
+                int flags = allUsers ? PackageManager.DELETE_ALL_USERS : 0;
+                flags |= clearContributedFiles ? PackageManager.DELETE_CONTRIBUTED_MEDIA : 0;
+
                 try {
                     ActivityThread.getPackageManager().getPackageInstaller().uninstall(
                             new VersionedPackage(mAppInfo.packageName,
                                     PackageManager.VERSION_CODE_HIGHEST),
-                            getPackageName(), allUsers ? PackageManager.DELETE_ALL_USERS : 0,
-                            pendingIntent.getIntentSender(), user.getIdentifier());
+                            getPackageName(), flags, pendingIntent.getIntentSender(),
+                            user.getIdentifier());
                 } catch (RemoteException e) {
                     e.rethrowFromSystemServer();
                 }
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java
index 1a01dc0..0fa8c9a 100755
--- a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java
@@ -285,7 +285,7 @@
         fragment.show(ft, "dialog");
     }
 
-    public void startUninstallProgress() {
+    public void startUninstallProgress(boolean clearContributedFiles) {
         boolean returnResult = getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false);
         CharSequence label = mDialogInfo.appInfo.loadSafeLabel(getPackageManager());
 
@@ -310,6 +310,8 @@
             newIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, mDialogInfo.allUsers);
             newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, mDialogInfo.appInfo);
             newIntent.putExtra(UninstallUninstalling.EXTRA_APP_LABEL, label);
+            newIntent.putExtra(UninstallUninstalling.EXTRA_CLEAR_CONTRIBUTED_FILES,
+                    clearContributedFiles);
             newIntent.putExtra(PackageInstaller.EXTRA_CALLBACK, mDialogInfo.callback);
 
             if (returnResult) {
@@ -358,12 +360,14 @@
             try {
                 Log.i(TAG, "Uninstalling extras=" + broadcastIntent.getExtras());
 
+                int flags = mDialogInfo.allUsers ? PackageManager.DELETE_ALL_USERS : 0;
+                flags |= clearContributedFiles ? PackageManager.DELETE_CONTRIBUTED_MEDIA : 0;
+
                 ActivityThread.getPackageManager().getPackageInstaller().uninstall(
                         new VersionedPackage(mDialogInfo.appInfo.packageName,
                                 PackageManager.VERSION_CODE_HIGHEST),
-                        getPackageName(), mDialogInfo.allUsers
-                                ? PackageManager.DELETE_ALL_USERS : 0,
-                        pendingIntent.getIntentSender(), mDialogInfo.user.getIdentifier());
+                        getPackageName(), flags, pendingIntent.getIntentSender(),
+                        mDialogInfo.user.getIdentifier());
             } catch (Exception e) {
                 notificationManager.cancel(uninstallId);
 
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java
index e0ca74e..e4e1275 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java
@@ -16,6 +16,9 @@
 
 package com.android.packageinstaller.handheld;
 
+import static android.text.format.Formatter.formatFileSize;
+
+import android.annotation.NonNull;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.DialogFragment;
@@ -24,14 +27,41 @@
 import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
 import android.os.Bundle;
+import android.os.UserHandle;
 import android.os.UserManager;
+import android.provider.MediaStore;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+import android.widget.CheckBox;
+import android.widget.TextView;
 
 import com.android.packageinstaller.R;
 import com.android.packageinstaller.UninstallerActivity;
 
+import java.io.IOException;
+import java.util.List;
+
 public class UninstallAlertDialogFragment extends DialogFragment implements
         DialogInterface.OnClickListener {
 
+    private CheckBox mClearContributedFiles;
+
+    /**
+     * Get number of bytes of the combined files contributed by the package.
+     *
+     * @param pkg The package that might have contibuted files.
+     * @param user The user the package belongs to.
+     *
+     * @return The number of bytes.
+     */
+    private long getContributedMediaSize(@NonNull String pkg, @NonNull UserHandle user) {
+        try {
+            return MediaStore.getContributedMediaSize(getContext(), pkg, user);
+        } catch (IOException e) {
+            return 0;
+        }
+    }
+
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         final PackageManager pm = getActivity().getPackageManager();
@@ -76,14 +106,44 @@
         dialogBuilder.setTitle(appLabel);
         dialogBuilder.setPositiveButton(android.R.string.ok, this);
         dialogBuilder.setNegativeButton(android.R.string.cancel, this);
-        dialogBuilder.setMessage(messageBuilder.toString());
+
+        String pkg = dialogInfo.appInfo.packageName;
+        long contributedFileSize = 0;
+        if (dialogInfo.allUsers) {
+            List<UserInfo> users = userManager.getUsers();
+
+            int numUsers = users.size();
+            for (int i = 0; i < numUsers; i++) {
+                UserHandle user = UserHandle.of(users.get(i).id);
+
+                contributedFileSize += getContributedMediaSize(pkg, user);
+            }
+        } else {
+            contributedFileSize = getContributedMediaSize(pkg, dialogInfo.user);
+        }
+
+        if (contributedFileSize == 0) {
+            dialogBuilder.setMessage(messageBuilder.toString());
+        } else {
+            LayoutInflater inflater = getContext().getSystemService(LayoutInflater.class);
+            ViewGroup content = (ViewGroup) inflater.inflate(R.layout.uninstall_content_view, null);
+
+            ((TextView) content.requireViewById(R.id.message)).setText(messageBuilder.toString());
+            mClearContributedFiles = content.requireViewById(R.id.checkbox);
+            mClearContributedFiles.setText(getString(R.string.uninstall_remove_contributed_files,
+                            formatFileSize(getContext(), contributedFileSize)));
+
+            dialogBuilder.setView(content);
+        }
+
         return dialogBuilder.create();
     }
 
     @Override
     public void onClick(DialogInterface dialog, int which) {
         if (which == Dialog.BUTTON_POSITIVE) {
-            ((UninstallerActivity) getActivity()).startUninstallProgress();
+            ((UninstallerActivity) getActivity()).startUninstallProgress(
+                    mClearContributedFiles != null && mClearContributedFiles.isChecked());
         } else {
             ((UninstallerActivity) getActivity()).dispatchAborted();
         }
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAlertFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAlertFragment.java
index 828e5db..21d25f5 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAlertFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAlertFragment.java
@@ -99,7 +99,7 @@
     public void onGuidedActionClicked(GuidedAction action) {
         if (isAdded()) {
             if (action.getId() == GuidedAction.ACTION_ID_OK) {
-                ((UninstallerActivity) getActivity()).startUninstallProgress();
+                ((UninstallerActivity) getActivity()).startUninstallProgress(false);
                 getActivity().finish();
             } else {
                 ((UninstallerActivity) getActivity()).dispatchAborted();
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 424368d..b071355 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -418,7 +418,7 @@
             case Settings.CALL_METHOD_PUT_CONFIG: {
                 String value = getSettingValue(args);
                 final boolean makeDefault = getSettingMakeDefault(args);
-                insertConfigSetting(name, value, null, makeDefault, requestingUserId, false);
+                insertConfigSetting(name, value, makeDefault);
                 break;
             }
 
@@ -447,7 +447,7 @@
             case Settings.CALL_METHOD_RESET_CONFIG: {
                 final int mode = getResetModeEnforcingPermission(args);
                 String prefix = getSettingPrefix(args);
-                resetConfigSetting(requestingUserId, mode, prefix);
+                resetConfigSetting(mode, prefix);
                 break;
             }
 
@@ -466,7 +466,7 @@
             }
 
             case Settings.CALL_METHOD_DELETE_CONFIG: {
-                int rows  = deleteConfigSetting(name, requestingUserId, false) ? 1 : 0;
+                int rows  = deleteConfigSetting(name) ? 1 : 0;
                 Bundle result = new Bundle();
                 result.putInt(RESULT_ROWS_DELETED, rows);
                 return result;
@@ -1067,38 +1067,33 @@
         }
     }
 
-    private boolean insertConfigSetting(String name, String value, String tag,
-            boolean makeDefault, int requestingUserId, boolean forceNotify) {
+    private boolean insertConfigSetting(String name, String value, boolean makeDefault) {
         if (DEBUG) {
             Slog.v(LOG_TAG, "insertConfigSetting(" + name + ", " + value  + ", "
-                    + ", " + tag + ", " + makeDefault + ", " + requestingUserId
-                    + ", " + forceNotify + ")");
+                    + makeDefault + ")");
         }
-        return mutateConfigSetting(name, value, tag, makeDefault, requestingUserId,
-                MUTATION_OPERATION_INSERT, forceNotify, 0);
+        return mutateConfigSetting(name, value, null, makeDefault,
+                MUTATION_OPERATION_INSERT, 0);
     }
 
-    private boolean deleteConfigSetting(String name, int requestingUserId, boolean forceNotify) {
+    private boolean deleteConfigSetting(String name) {
         if (DEBUG) {
-            Slog.v(LOG_TAG, "deleteConfigSetting(" + name + ", " + requestingUserId
-                    + ", " + forceNotify + ")");
+            Slog.v(LOG_TAG, "deleteConfigSetting(" + name + ")");
         }
-        return mutateConfigSetting(name, null, null, false, requestingUserId,
-                MUTATION_OPERATION_DELETE, forceNotify, 0);
+        return mutateConfigSetting(name, null, null, false,
+                MUTATION_OPERATION_DELETE, 0);
     }
 
-    private void resetConfigSetting(int requestingUserId, int mode, String prefix) {
+    private void resetConfigSetting(int mode, String prefix) {
         if (DEBUG) {
-            Slog.v(LOG_TAG, "resetConfigSetting(" + requestingUserId + ", "
-                    + mode + ", " + prefix + ")");
+            Slog.v(LOG_TAG, "resetConfigSetting(" + mode + ", " + prefix + ")");
         }
-        mutateConfigSetting(null, null, prefix, false, requestingUserId,
-                MUTATION_OPERATION_RESET, false, mode);
+        mutateConfigSetting(null, null, prefix, false,
+                MUTATION_OPERATION_RESET, mode);
     }
 
     private boolean mutateConfigSetting(String name, String value, String prefix,
-            boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
-            int mode) {
+            boolean makeDefault, int operation, int mode) {
         // TODO(b/117663715): check the new permission when it's added.
         // enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS);
 
@@ -1107,13 +1102,13 @@
             switch (operation) {
                 case MUTATION_OPERATION_INSERT: {
                     return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_CONFIG,
-                            UserHandle.USER_SYSTEM, name, value, null, makeDefault,
-                            getCallingPackage(), forceNotify, null);
+                            UserHandle.USER_SYSTEM, name, value, null, makeDefault, true,
+                            getCallingPackage(), false, null);
                 }
 
                 case MUTATION_OPERATION_DELETE: {
                     return mSettingsRegistry.deleteSettingLocked(SETTINGS_TYPE_CONFIG,
-                            UserHandle.USER_SYSTEM, name, forceNotify, null);
+                            UserHandle.USER_SYSTEM, name, false, null);
                 }
 
                 case MUTATION_OPERATION_RESET: {
@@ -2631,13 +2626,20 @@
         public boolean insertSettingLocked(int type, int userId, String name, String value,
                 String tag, boolean makeDefault, String packageName, boolean forceNotify,
                 Set<String> criticalSettings) {
+            return insertSettingLocked(type, userId, name, value, tag, makeDefault, false,
+                    packageName, forceNotify, criticalSettings);
+        }
+
+        public boolean insertSettingLocked(int type, int userId, String name, String value,
+                String tag, boolean makeDefault, boolean forceNonSystemPackage, String packageName,
+                boolean forceNotify, Set<String> criticalSettings) {
             final int key = makeKey(type, userId);
 
             boolean success = false;
             SettingsState settingsState = peekSettingsStateLocked(key);
             if (settingsState != null) {
                 success = settingsState.insertSettingLocked(name, value,
-                        tag, makeDefault, packageName);
+                        tag, makeDefault, forceNonSystemPackage, packageName);
             }
 
             if (success && criticalSettings != null && criticalSettings.contains(name)) {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index ae2ca3f..521163f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -377,6 +377,13 @@
     @GuardedBy("mLock")
     public boolean insertSettingLocked(String name, String value, String tag,
             boolean makeDefault, String packageName) {
+        return insertSettingLocked(name, value, tag, makeDefault, false, packageName);
+    }
+
+    // The settings provider must hold its lock when calling here.
+    @GuardedBy("mLock")
+    public boolean insertSettingLocked(String name, String value, String tag,
+            boolean makeDefault, boolean forceNonSystemPackage, String packageName) {
         if (TextUtils.isEmpty(name)) {
             return false;
         }
@@ -387,7 +394,7 @@
         Setting newState;
 
         if (oldState != null) {
-            if (!oldState.update(value, makeDefault, packageName, tag, false)) {
+            if (!oldState.update(value, makeDefault, packageName, tag, forceNonSystemPackage)) {
                 return false;
             }
             newState = oldState;
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/DeviceConfigServiceTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/DeviceConfigServiceTest.java
index 59de6a7e..9d0462e 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/DeviceConfigServiceTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/DeviceConfigServiceTest.java
@@ -17,10 +17,9 @@
 package com.android.providers.settings;
 
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertNull;
 
-import static org.junit.Assert.assertNotNull;
-
 import android.content.ContentResolver;
 import android.net.Uri;
 import android.os.Bundle;
@@ -147,10 +146,10 @@
     }
 
     @Test
-    public void testReset_setUntrustedDefault() throws Exception {
+    public void testReset() throws Exception {
         String newValue = "value2";
 
-        // make sValue the untrusted default (set by root)
+        // make sValue the default value
         executeShellCommand(
                 "device_config put " + sNamespace + " " + sKey + " " + sValue + " default");
         // make newValue the current value
@@ -159,40 +158,19 @@
         String result = getFromContentProvider(mContentResolver, sNamespace, sKey);
         assertEquals(newValue, result);
 
+        // reset values that were set by untrusted packages
         executeShellCommand("device_config reset untrusted_defaults " + sNamespace);
         result = getFromContentProvider(mContentResolver, sNamespace, sKey);
-        // back to the default
+        // the default value has been restored
         assertEquals(sValue, result);
 
+        // clear values that were set by untrusted packages
         executeShellCommand("device_config reset trusted_defaults " + sNamespace);
         result = getFromContentProvider(mContentResolver, sNamespace, sKey);
-        // not trusted default was set
+        // even the default value is gone now
         assertNull(result);
     }
 
-    @Test
-    public void testReset_setTrustedDefault() throws Exception {
-        String newValue = "value2";
-
-        // make sValue the trusted default (set by system)
-        putWithContentProvider(mContentResolver, sNamespace, sKey, sValue, true);
-        // make newValue the current value
-        executeShellCommand(
-                "device_config put " + sNamespace + " " + sKey + " " + newValue);
-        String result = getFromContentProvider(mContentResolver, sNamespace, sKey);
-        assertEquals(newValue, result);
-
-        executeShellCommand("device_config reset untrusted_defaults " + sNamespace);
-        result = getFromContentProvider(mContentResolver, sNamespace, sKey);
-        // back to the default
-        assertEquals(sValue, result);
-
-        executeShellCommand("device_config reset trusted_defaults " + sNamespace);
-        result = getFromContentProvider(mContentResolver, sNamespace, sKey);
-        // our trusted default is still set
-        assertEquals(sValue, result);
-    }
-
     private static void executeShellCommand(String command) throws IOException {
         InputStream is = new FileInputStream(InstrumentationRegistry.getInstrumentation()
                 .getUiAutomation().executeShellCommand(command).getFileDescriptor());
@@ -212,8 +190,7 @@
         if (makeDefault) {
             args.putBoolean(Settings.CALL_METHOD_MAKE_DEFAULT_KEY, true);
         }
-        resolver.call(
-                CONFIG_CONTENT_URI, Settings.CALL_METHOD_PUT_CONFIG, compositeName, args);
+        resolver.call(CONFIG_CONTENT_URI, Settings.CALL_METHOD_PUT_CONFIG, compositeName, args);
     }
 
     private static String getFromContentProvider(ContentResolver resolver, String namespace,
diff --git a/packages/Shell/res/values-mr/strings.xml b/packages/Shell/res/values-mr/strings.xml
index dc6a6126..9595e28 100644
--- a/packages/Shell/res/values-mr/strings.xml
+++ b/packages/Shell/res/values-mr/strings.xml
@@ -28,7 +28,7 @@
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"तुमचा बग रीपोर्ट स्क्रीनशॉटशिवाय शेअर करण्यासाठी टॅप करा किंवा स्क्रीनशॉट पूर्ण होण्याची प्रतीक्षा करा"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"स्क्रीनशॉट शिवाय तुमचा बग रीपोर्ट शेअर करण्यासाठी टॅप करा किंवा समाप्त करण्यासाठी स्क्रीनशॉटची प्रतीक्षा करा"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"स्क्रीनशॉट शिवाय तुमचा बग रीपोर्ट शेअर करण्यासाठी टॅप करा किंवा समाप्त करण्यासाठी स्क्रीनशॉटची प्रतीक्षा करा"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"बग रीपोर्टांमध्ये तुम्ही संवेदनशील (अॅप-वापर आणि स्थान डेटा यासारखा) डेटा म्हणून विचार करता त्या डेटाच्या समावेशासह सिस्टीमच्या विविध लॉग फायलींमधील डेटा असतो. ज्या लोकांवर आणि अॅपवर तुमचा विश्वास आहे केवळ त्यांच्यासह हा बग रीपोर्ट शेअर करा."</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"बग रीपोर्टांमध्ये तुम्ही संवेदनशील (अ‍ॅप-वापर आणि स्थान डेटा यासारखा) डेटा म्हणून विचार करता त्या डेटाच्या समावेशासह सिस्टीमच्या विविध लॉग फायलींमधील डेटा असतो. ज्या लोकांवर आणि अ‍ॅपवर तुमचा विश्वास आहे केवळ त्यांच्यासह हा बग रीपोर्ट शेअर करा."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"पुन्हा दर्शवू नका"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"बग रीपोर्ट"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"बग रीपोर्ट फाईल वाचणे शक्य झाले नाही"</string>
diff --git a/packages/SystemUI/res/layout/bubble_expanded_view.xml b/packages/SystemUI/res/layout/bubble_expanded_view.xml
new file mode 100644
index 0000000..b2307e7
--- /dev/null
+++ b/packages/SystemUI/res/layout/bubble_expanded_view.xml
@@ -0,0 +1,30 @@
+<?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
+  -->
+<com.android.systemui.bubbles.BubbleExpandedViewContainer
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_height="wrap_content"
+    android:layout_width="match_parent"
+    android:id="@+id/bubble_expanded_view">
+
+    <!-- TODO: header -->
+
+    <View
+        android:id="@+id/pointer_view"
+        android:layout_width="@dimen/bubble_pointer_width"
+        android:layout_height="@dimen/bubble_pointer_height"
+    />
+</com.android.systemui.bubbles.BubbleExpandedViewContainer>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 7ea4027..6fb44cc 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -89,7 +89,7 @@
     <string name="usb_preference_title" msgid="6551050377388882787">"USB फाईल स्थानांतरण पर्याय"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"मीडिया प्लेअर म्हणून माउंट करा (MTP)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"कॅमेरा म्हणून माउंट करा (PTP)"</string>
-    <string name="installer_cd_button_title" msgid="2312667578562201583">"Mac साठी Android फाईल स्थानांतर अॅप इंस्टॉल करा"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"Mac साठी Android फाईल स्थानांतर अ‍ॅप इंस्टॉल करा"</string>
     <string name="accessibility_back" msgid="567011538994429120">"मागे"</string>
     <string name="accessibility_home" msgid="8217216074895377641">"होम"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"मेनू"</string>
@@ -598,7 +598,7 @@
     <string name="tuner_full_importance_settings" msgid="3207312268609236827">"पॉवर सूचना नियंत्रणे"</string>
     <string name="tuner_full_importance_settings_on" msgid="7545060756610299966">"चालू"</string>
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"बंद"</string>
-    <string name="power_notification_controls_description" msgid="4372459941671353358">"पॉवर सूचना नियंत्रणांच्या साहाय्याने तुम्ही अॅप सूचनांसाठी 0 ते 5 असे महत्त्व स्तर सेट करू शकता. \n\n"<b>"स्तर 5"</b>" \n- सूचना सूचीच्या शीर्षस्थानी दाखवा \n- फुल स्क्रीन व्यत्ययास अनुमती द्या \n- नेहमी डोकावून पहा \n\n"<b>"स्तर 4"</b>\n" - फुल स्क्रीन व्यत्ययास प्रतिबंधित करा \n- नेहमी डोकावून पहा \n\n"<b>"स्तर 3"</b>" \n- फुल स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n\n"<b>"स्तर 2"</b>" \n- फुल स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n- कधीही ध्वनी किंवा व्हायब्रेट करू नका \n\n"<b>"स्तर 1"</b>\n"- फुल स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n- कधीही ध्वनी किंवा व्हायब्रेट करू नका \n- लॉक स्क्रीन आणि स्टेटस बार मधून लपवा \n- सूचना सूचीच्या तळाशी दर्शवा \n\n"<b>"स्तर 0"</b>" \n- अॅपमधील सर्व सूचना ब्लॉक करा"</string>
+    <string name="power_notification_controls_description" msgid="4372459941671353358">"पॉवर सूचना नियंत्रणांच्या साहाय्याने तुम्ही अ‍ॅप सूचनांसाठी 0 ते 5 असे महत्त्व स्तर सेट करू शकता. \n\n"<b>"स्तर 5"</b>" \n- सूचना सूचीच्या शीर्षस्थानी दाखवा \n- फुल स्क्रीन व्यत्ययास अनुमती द्या \n- नेहमी डोकावून पहा \n\n"<b>"स्तर 4"</b>\n" - फुल स्क्रीन व्यत्ययास प्रतिबंधित करा \n- नेहमी डोकावून पहा \n\n"<b>"स्तर 3"</b>" \n- फुल स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n\n"<b>"स्तर 2"</b>" \n- फुल स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n- कधीही ध्वनी किंवा व्हायब्रेट करू नका \n\n"<b>"स्तर 1"</b>\n"- फुल स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n- कधीही ध्वनी किंवा व्हायब्रेट करू नका \n- लॉक स्क्रीन आणि स्टेटस बार मधून लपवा \n- सूचना सूचीच्या तळाशी दर्शवा \n\n"<b>"स्तर 0"</b>" \n- अ‍ॅपमधील सर्व सूचना ब्लॉक करा"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"सूचना"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"आता तुम्हाला या सूचना दिसणार नाहीत"</string>
     <string name="notification_channel_minimized" msgid="1664411570378910931">"या सूचना लहान केल्या जातील"</string>
@@ -621,13 +621,13 @@
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"या अ‍ॅपकडील सूचना दाखवणे सुरू ठेवायचे?"</string>
     <string name="notification_unblockable_desc" msgid="1037434112919403708">"या सूचना बंद करता येत नाहीत"</string>
     <string name="notification_delegate_header" msgid="9167022191405284627">"<xliff:g id="APP_NAME">%1$s</xliff:g> मार्गे"</string>
-    <string name="appops_camera" msgid="8100147441602585776">"हे अॅप कॅमेरा वापरत आहे."</string>
-    <string name="appops_microphone" msgid="741508267659494555">"हे अॅप मायक्रोफोन वापरत आहे."</string>
-    <string name="appops_overlay" msgid="6165912637560323464">"हे अॅप स्क्रीनवरील इतर अॅप्स वर प्रदर्शित होत आहे."</string>
-    <string name="appops_camera_mic" msgid="1576901651150187433">"हे अॅप मायक्रोफोन आणि कॅमेरा वापरत आहे."</string>
-    <string name="appops_camera_overlay" msgid="8869400080809298814">"हे अॅप तुमच्या स्क्रीनवरील इतर अॅप्स वर प्रदर्शित होत आहे आणि कॅमेरा वापरत आहे."</string>
-    <string name="appops_mic_overlay" msgid="4835157962857919804">"हे अॅप तुमच्या स्क्रीनवरील इतर अॅप्स वर प्रदर्शित होत आहे आणि मायक्रोफोन वापरत आहे."</string>
-    <string name="appops_camera_mic_overlay" msgid="6718768197048030993">"हे अॅप तुमच्या स्क्रीनवरील इतर अॅप्स वर प्रदर्शित होत आहे आणि मायक्रोफोन आणि कॅमेरा वापरत आहे."</string>
+    <string name="appops_camera" msgid="8100147441602585776">"हे अ‍ॅप कॅमेरा वापरत आहे."</string>
+    <string name="appops_microphone" msgid="741508267659494555">"हे अ‍ॅप मायक्रोफोन वापरत आहे."</string>
+    <string name="appops_overlay" msgid="6165912637560323464">"हे अ‍ॅप स्क्रीनवरील इतर अ‍ॅप्स वर प्रदर्शित होत आहे."</string>
+    <string name="appops_camera_mic" msgid="1576901651150187433">"हे अ‍ॅप मायक्रोफोन आणि कॅमेरा वापरत आहे."</string>
+    <string name="appops_camera_overlay" msgid="8869400080809298814">"हे अ‍ॅप तुमच्या स्क्रीनवरील इतर अ‍ॅप्स वर प्रदर्शित होत आहे आणि कॅमेरा वापरत आहे."</string>
+    <string name="appops_mic_overlay" msgid="4835157962857919804">"हे अ‍ॅप तुमच्या स्क्रीनवरील इतर अ‍ॅप्स वर प्रदर्शित होत आहे आणि मायक्रोफोन वापरत आहे."</string>
+    <string name="appops_camera_mic_overlay" msgid="6718768197048030993">"हे अ‍ॅप तुमच्या स्क्रीनवरील इतर अ‍ॅप्स वर प्रदर्शित होत आहे आणि मायक्रोफोन आणि कॅमेरा वापरत आहे."</string>
     <string name="notification_appops_settings" msgid="1028328314935908050">"सेटिंग्ज"</string>
     <string name="notification_appops_ok" msgid="1156966426011011434">"ओके"</string>
     <string name="notification_channel_controls_opened_accessibility" msgid="6553950422055908113">"<xliff:g id="APP_NAME">%1$s</xliff:g> साठी सूचना नियंत्रणे खुली आहेत"</string>
@@ -776,8 +776,8 @@
     <string name="accessibility_qs_edit_tile_move" msgid="3108103090006972938">"<xliff:g id="TILE_NAME">%1$s</xliff:g> <xliff:g id="POSITION">%2$d</xliff:g> स्थानावर हलवा"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"द्रुत सेटिंग्ज संपादक."</string>
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> सूचना: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
-    <string name="dock_forced_resizable" msgid="5914261505436217520">"अॅप कदाचित विभाजित-स्क्रीनसह कार्य करू शकत नाही."</string>
-    <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"अॅप स्क्रीन-विभाजनास समर्थन देत नाही."</string>
+    <string name="dock_forced_resizable" msgid="5914261505436217520">"अ‍ॅप कदाचित विभाजित-स्क्रीनसह कार्य करू शकत नाही."</string>
+    <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"अ‍ॅप स्क्रीन-विभाजनास समर्थन देत नाही."</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"दुसऱ्या डिस्प्लेवर अ‍ॅप कदाचित चालणार नाही."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"दुसऱ्या डिस्प्लेवर अ‍ॅप लाँच होणार नाही."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"सेटिंग्ज उघडा."</string>
@@ -806,7 +806,7 @@
     <string name="pip_skip_to_prev" msgid="1955311326688637914">"डावलून मागे जा"</string>
     <string name="thermal_shutdown_title" msgid="4458304833443861111">"तापल्‍यामुळे फोन बंद झाला"</string>
     <string name="thermal_shutdown_message" msgid="9006456746902370523">"तुमचा फोन आता व्‍यवस्थित चालू आहे"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"तुमचा फोन खूप तापलाय, म्हणून तो थंड होण्यासाठी बंद झाला आहे. तुमचा फोन आता व्‍यवस्थित चालू आहे.\n\nतुम्ही असे केल्यास तुमचा फोन खूप तापेल:\n	•संसाधन केंद्रित अॅप वापरणे (गेमिंग, व्हिडिओ किंवा नेव्हिगेशन अॅप यासारखे)\n	•मोठ्या फायली डाउनलोड किंवा अपलोड करणे\n	•उच्च तापमानामध्ये तुमचा फोन वापरणे"</string>
+    <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"तुमचा फोन खूप तापलाय, म्हणून तो थंड होण्यासाठी बंद झाला आहे. तुमचा फोन आता व्‍यवस्थित चालू आहे.\n\nतुम्ही असे केल्यास तुमचा फोन खूप तापेल:\n	•संसाधन केंद्रित अ‍ॅप वापरणे (गेमिंग, व्हिडिओ किंवा नेव्हिगेशन अ‍ॅप यासारखे)\n	•मोठ्या फायली डाउनलोड किंवा अपलोड करणे\n	•उच्च तापमानामध्ये तुमचा फोन वापरणे"</string>
     <string name="high_temp_title" msgid="4589508026407318374">"फोन ऊष्ण होत आहे"</string>
     <string name="high_temp_notif_message" msgid="5642466103153429279">"फोन थंड होत असताना काही वैशिष्‍ट्ये मर्यादित असतात"</string>
     <string name="high_temp_dialog_message" msgid="6840700639374113553">"तुमचा फोन स्वयंचलितपणे थंड होईल. तुम्ही अद्यापही तुमचा फोन वापरू शकता परंतु तो कदाचित धीमेपणे कार्य करेल.\n\nतुमचा फोन एकदा थंड झाला की, तो सामान्यपणे कार्य करेल."</string>
@@ -832,9 +832,9 @@
     <string name="notification_channel_hints" msgid="7323870212489152689">"सूचना"</string>
     <string name="instant_apps" msgid="6647570248119804907">"इन्सटंट अ‍ॅप्स"</string>
     <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> रन होत आहे"</string>
-    <string name="instant_apps_message" msgid="1183313016396018086">"इंस्टॉल केल्याशिवाय अॅप उघडले."</string>
-    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"इंस्टॉल केल्याशिवाय अॅप उघडले. अधिक जाणून घेण्यासाठी टॅप करा."</string>
-    <string name="app_info" msgid="6856026610594615344">"अॅप माहिती"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"इंस्टॉल केल्याशिवाय अ‍ॅप उघडले."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"इंस्टॉल केल्याशिवाय अ‍ॅप उघडले. अधिक जाणून घेण्यासाठी टॅप करा."</string>
+    <string name="app_info" msgid="6856026610594615344">"अ‍ॅप माहिती"</string>
     <string name="go_to_web" msgid="2650669128861626071">"ब्राउझरवर जा"</string>
     <string name="mobile_data" msgid="7094582042819250762">"मोबाइल डेटा"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
@@ -873,7 +873,7 @@
     <!-- no translation found for ongoing_privacy_chip_content_multiple_apps_single_op (4871926099254314088) -->
     <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"रद्द करा"</string>
     <string name="ongoing_privacy_dialog_open_settings" msgid="2074844974365194279">"तपशील पाहा"</string>
-    <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"अॅप तुमचे <xliff:g id="TYPES_LIST">%s</xliff:g> वापरत आहे"</string>
+    <string name="ongoing_privacy_dialog_single_app_title" msgid="6019646962021696632">"अ‍ॅप तुमचे <xliff:g id="TYPES_LIST">%s</xliff:g> वापरत आहे"</string>
     <string name="ongoing_privacy_dialog_multiple_apps_title" msgid="8013356222977903365">"अॅप्स तुमचे <xliff:g id="TYPES_LIST">%s</xliff:g> वापरत आहेत"</string>
     <string name="ongoing_privacy_dialog_separator" msgid="6854860652480837439">", "</string>
     <string name="ongoing_privacy_dialog_last_separator" msgid="2400503446627122483">" आणि "</string>
@@ -882,6 +882,6 @@
     <string name="privacy_type_microphone" msgid="4153045784928554506">"मायक्रोफोन"</string>
     <plurals name="ongoing_privacy_dialog_overflow_text" formatted="false" msgid="3441296594927649172">
       <item quantity="one">इतर <xliff:g id="NUM_APPS_1">%d</xliff:g> अॅ​प</item>
-      <item quantity="other">इतर <xliff:g id="NUM_APPS_1">%d</xliff:g> अॅप्स</item>
+      <item quantity="other">इतर <xliff:g id="NUM_APPS_1">%d</xliff:g> अ‍ॅप्स</item>
     </plurals>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 4f5b23e..558fd9b 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -785,7 +785,7 @@
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Lukk hurtiginnstillingene."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="1863000242431528676">"Alarm er angitt."</string>
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Logget på som <xliff:g id="ID_1">%s</xliff:g>"</string>
-    <string name="data_connection_no_internet" msgid="4503302451650972989">"Ingen Internett-tilkobling"</string>
+    <string name="data_connection_no_internet" msgid="4503302451650972989">"Ingen internettilkobling"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Åpne informasjonen."</string>
     <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Utilgjengelig fordi <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Åpne <xliff:g id="ID_1">%s</xliff:g>-innstillingene."</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 5e7a119..06467b8 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -651,7 +651,7 @@
       <item quantity="other">%d minuten</item>
       <item quantity="one">%d minuut</item>
     </plurals>
-    <string name="battery_panel_title" msgid="7944156115535366613">"Accugebruik"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"Batterijgebruik"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterijbesparing niet beschikbaar tijdens opladen"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterijbesparing"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Vermindert de prestaties en achtergrondgegevens"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index b6c9b8c..3851190 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -361,6 +361,7 @@
     <!-- The height of the qs customize header. Should be (28dp - qs_tile_margin_top_bottom). -->
     <dimen name="qs_customize_header_min_height">40dp</dimen>
     <dimen name="qs_tile_margin_top">18dp</dimen>
+    <dimen name="qs_tile_background_size">40dp</dimen>
     <dimen name="qs_quick_tile_size">48dp</dimen>
     <!-- Maximum width of quick quick settings panel. Defaults to MATCH_PARENT-->
     <dimen name="qs_quick_layout_width">-1px</dimen>
@@ -993,4 +994,10 @@
     <dimen name="bubble_icon_size">24dp</dimen>
     <!-- Default height of the expanded view shown when the bubble is expanded -->
     <dimen name="bubble_expanded_default_height">400dp</dimen>
+    <!-- Height of the triangle that points to the expanded bubble -->
+    <dimen name="bubble_pointer_height">4dp</dimen>
+    <!-- Width of the triangle that points to the expanded bubble -->
+    <dimen name="bubble_pointer_width">6dp</dimen>
+    <!-- Extra padding around the dismiss target for bubbles -->
+    <dimen name="bubble_dismiss_slop">16dp</dimen>
 </resources>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplier.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplier.java
index a9cf857..807edf6 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplier.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplier.java
@@ -25,6 +25,8 @@
 import android.view.View;
 import android.view.ViewRootImpl;
 
+import java.util.function.Consumer;
+
 /**
  * Helper class to apply surface transactions in sync with RenderThread.
  */
@@ -78,6 +80,35 @@
         applyParams(t.mTransaction, params, t.mTmpValues);
     }
 
+    /**
+     * Creates an instance of SyncRtSurfaceTransactionApplier, deferring until the target view is
+     * attached if necessary.
+     */
+    public static void create(final View targetView,
+            final Consumer<SyncRtSurfaceTransactionApplier> callback) {
+        if (targetView == null) {
+            // No target view, no applier
+            callback.accept(null);
+        } else if (targetView.getViewRootImpl() != null) {
+            // Already attached, we're good to go
+            callback.accept(new SyncRtSurfaceTransactionApplier(targetView));
+        } else {
+            // Haven't been attached before we can get the view root
+            targetView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
+                @Override
+                public void onViewAttachedToWindow(View v) {
+                    targetView.removeOnAttachStateChangeListener(this);
+                    callback.accept(new SyncRtSurfaceTransactionApplier(targetView));
+                }
+
+                @Override
+                public void onViewDetachedFromWindow(View v) {
+                    // Do nothing
+                }
+            });
+        }
+    }
+
     private static void applyParams(Transaction t, SurfaceParams params, float[] tmpFloat9) {
         t.setMatrix(params.surface, params.matrix, tmpFloat9);
         t.setWindowCrop(params.surface, params.windowCrop);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedViewContainer.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedViewContainer.java
new file mode 100644
index 0000000..e28d96b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedViewContainer.java
@@ -0,0 +1,102 @@
+/*
+ * 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.systemui.bubbles;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Color;
+import android.graphics.drawable.ShapeDrawable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import com.android.systemui.R;
+import com.android.systemui.recents.TriangleShape;
+
+/**
+ * Container for the expanded bubble view, handles rendering the caret and header of the view.
+ */
+public class BubbleExpandedViewContainer extends LinearLayout {
+
+    // The triangle pointing to the expanded view
+    private View mPointerView;
+    // The view that is being displayed for the expanded state
+    private View mExpandedView;
+
+    public BubbleExpandedViewContainer(Context context) {
+        this(context, null);
+    }
+
+    public BubbleExpandedViewContainer(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public BubbleExpandedViewContainer(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public BubbleExpandedViewContainer(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        setOrientation(VERTICAL);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+
+        Resources res = getResources();
+        mPointerView = findViewById(R.id.pointer_view);
+        int width = res.getDimensionPixelSize(R.dimen.bubble_pointer_width);
+        int height = res.getDimensionPixelSize(R.dimen.bubble_pointer_height);
+        ShapeDrawable triangleDrawable = new ShapeDrawable(
+                TriangleShape.create(width, height, true /* pointUp */));
+        triangleDrawable.setTint(Color.WHITE); // TODO: dark mode
+        mPointerView.setBackground(triangleDrawable);
+    }
+
+    /**
+     * Set the x position that the tip of the triangle should point to.
+     */
+    public void setPointerPosition(int x) {
+        // Adjust for the pointer size
+        x -= (mPointerView.getWidth() / 2);
+        mPointerView.setTranslationX(x);
+    }
+
+    /**
+     * Set the view to display for the expanded state. Passing null will clear the view.
+     */
+    public void setExpandedView(View view) {
+        if (mExpandedView != null) {
+            removeView(mExpandedView);
+        }
+        mExpandedView = view;
+        if (mExpandedView != null) {
+            addView(mExpandedView);
+        }
+    }
+
+    /**
+     * @return the view containing the expanded content, can be null.
+     */
+    @Nullable
+    public View getExpandedView() {
+        return mExpandedView;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index e395c4c..dfd18b2 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -25,6 +25,7 @@
 import android.content.res.Resources;
 import android.graphics.Point;
 import android.graphics.RectF;
+import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
@@ -52,7 +53,7 @@
     private Point mDisplaySize;
 
     private FrameLayout mBubbleContainer;
-    private FrameLayout mExpandedViewContainer;
+    private BubbleExpandedViewContainer mExpandedViewContainer;
 
     private int mBubbleSize;
     private int mBubblePadding;
@@ -111,7 +112,9 @@
 
         int padding = res.getDimensionPixelSize(R.dimen.bubble_expanded_view_padding);
         int elevation = res.getDimensionPixelSize(R.dimen.bubble_elevation);
-        mExpandedViewContainer = new FrameLayout(context);
+        mExpandedViewContainer = (BubbleExpandedViewContainer)
+                LayoutInflater.from(context).inflate(R.layout.bubble_expanded_view,
+                        this /* parent */, false /* attachToRoot */);
         mExpandedViewContainer.setElevation(elevation);
         mExpandedViewContainer.setPadding(padding, padding, padding, padding);
         mExpandedViewContainer.setClipChildren(false);
@@ -390,16 +393,19 @@
             ExpandableNotificationRow row = mExpandedBubble.getRowView();
             if (!row.equals(mExpandedViewContainer.getChildAt(0))) {
                 // Different expanded view than what we have
-                mExpandedViewContainer.removeAllViews();
+                mExpandedViewContainer.setExpandedView(null);
             }
-            mExpandedViewContainer.addView(row);
+            int pointerPosition = mExpandedBubble.getPosition().x
+                    + (mExpandedBubble.getWidth() / 2);
+            mExpandedViewContainer.setPointerPosition(pointerPosition);
+            mExpandedViewContainer.setExpandedView(row);
         }
     }
 
     private void applyCurrentState() {
         mExpandedViewContainer.setVisibility(mIsExpanded ? VISIBLE : GONE);
         if (!mIsExpanded) {
-            mExpandedViewContainer.removeAllViews();
+            mExpandedViewContainer.setExpandedView(null);
         } else {
             mExpandedViewContainer.setTranslationY(mBubbleContainer.getHeight());
             ExpandableNotificationRow row = mExpandedBubble.getRowView();
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java
index 8262b54..8224365 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java
@@ -51,6 +51,8 @@
 
     // Used for dismissing a bubble -- bubble should be in the target to be considered a dismiss
     private View mTargetView;
+    private int mTargetSlop;
+    private Point mWindowSize;
     private int[] mLoc = new int[2];
     private boolean mIntersecting;
     private Vibrator mVibe;
@@ -69,12 +71,14 @@
             // Determine sizes for the view
             final Rect stableInsets = new Rect();
             WindowManagerWrapper.getInstance().getStableInsets(stableInsets);
-            final Point windowSize = new Point();
-            mWindowManager.getDefaultDisplay().getRealSize(windowSize);
+            mWindowSize = new Point();
+            mWindowManager.getDefaultDisplay().getRealSize(mWindowSize);
             final int gradientHeight = mContext.getResources().getDimensionPixelSize(
                     R.dimen.pip_dismiss_gradient_height);
             final int bottomMargin = mContext.getResources().getDimensionPixelSize(
                     R.dimen.pip_dismiss_text_bottom_margin);
+            mTargetSlop = mContext.getResources().getDimensionPixelSize(
+                    R.dimen.bubble_dismiss_slop);
 
             // Create a new view for the dismiss target
             LayoutInflater inflater = LayoutInflater.from(mContext);
@@ -96,7 +100,7 @@
             // Add the target to the window
             LayoutParams lp =  new LayoutParams(
                     LayoutParams.MATCH_PARENT, gradientHeight,
-                    0, windowSize.y - gradientHeight,
+                    0, mWindowSize.y - gradientHeight,
                     LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
                     LayoutParams.FLAG_LAYOUT_IN_SCREEN
                             | LayoutParams.FLAG_NOT_TOUCHABLE
@@ -112,7 +116,7 @@
 
 
     /**
-     * Updates the dismiss target based on location of the view.
+     * Updates the dismiss target based on location of the view, only used for bubbles not for PIP.
      *
      * @return whether the view is within the dismiss target.
      */
@@ -127,11 +131,13 @@
             mTargetView.getLocationOnScreen(mLoc);
             Rect targetRect = new Rect(mLoc[0], mLoc[1], mLoc[0] + mTargetView.getWidth(),
                     mLoc[1] + mTargetView.getHeight());
+            expandRect(targetRect, mTargetSlop);
             boolean intersecting = targetRect.intersect(viewRect);
-            if (intersecting && !mIntersecting) {
+            if (intersecting != mIntersecting) {
                 // TODO: is this the right effect?
-                mVibe.vibrate(VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
-                mIntersecting = true;
+                mVibe.vibrate(VibrationEffect.get(intersecting
+                        ? VibrationEffect.EFFECT_CLICK
+                        : VibrationEffect.EFFECT_TICK));
             }
             mIntersecting = intersecting;
             return intersecting;
@@ -139,7 +145,6 @@
         return false;
     }
 
-
     /**
      * Shows the dismiss target.
      */
@@ -172,4 +177,11 @@
                     .start();
         }
     }
+
+    private void expandRect(Rect outRect, int expandAmount) {
+        outRect.left = Math.max(0, outRect.left - expandAmount);
+        outRect.top = Math.max(0, outRect.top - expandAmount);
+        outRect.right = Math.min(mWindowSize.x, outRect.right + expandAmount);
+        outRect.bottom = Math.min(mWindowSize.y, outRect.bottom + expandAmount);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
index 3a96595d..32fd2dc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
@@ -19,14 +19,19 @@
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.TypedArray;
+import android.graphics.Path;
+import android.graphics.drawable.AdaptiveIconDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.RippleDrawable;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.PathShape;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.service.quicksettings.Tile;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.PathParser;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
@@ -46,6 +51,7 @@
 public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView {
 
     private static final String TAG = "QSTileBaseView";
+    private static final int ICON_MASK_ID = com.android.internal.R.string.config_icon_mask;
     private final H mHandler = new H();
     private final int[] mLocInScreen = new int[2];
     private final FrameLayout mIconFrame;
@@ -62,6 +68,7 @@
     private final int mColorInactive;
     private final int mColorDisabled;
     private int mCircleColor;
+    private int mBgSize;
 
     public QSTileBaseView(Context context, QSIconView icon) {
         this(context, icon, false);
@@ -71,15 +78,23 @@
         super(context);
         // Default to Quick Tile padding, and QSTileView will specify its own padding.
         int padding = context.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_padding);
-
         mIconFrame = new FrameLayout(context);
         mIconFrame.setForegroundGravity(Gravity.CENTER);
         int size = context.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_size);
         addView(mIconFrame, new LayoutParams(size, size));
         mBg = new ImageView(getContext());
+        Path path = new Path(PathParser.createPathFromPathData(
+                context.getResources().getString(ICON_MASK_ID)));
+        float pathSize = AdaptiveIconDrawable.MASK_SIZE;
+        PathShape p = new PathShape(path, pathSize, pathSize);
+        ShapeDrawable d = new ShapeDrawable(p);
+        int bgSize = context.getResources().getDimensionPixelSize(R.dimen.qs_tile_background_size);
+        d.setIntrinsicHeight(bgSize);
+        d.setIntrinsicWidth(bgSize);
         mBg.setScaleType(ScaleType.FIT_CENTER);
-        mBg.setImageResource(R.drawable.ic_qs_circle);
-        mIconFrame.addView(mBg);
+        mBg.setImageDrawable(d);
+        mIconFrame.addView(mBg, ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT);
         mIcon = icon;
         FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
                 ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
@@ -107,7 +122,7 @@
         setFocusable(true);
     }
 
-    public View getBgCicle() {
+    public View getBgCircle() {
         return mBg;
     }
 
@@ -303,6 +318,7 @@
 
     private class H extends Handler {
         private static final int STATE_CHANGED = 1;
+
         public H() {
             super(Looper.getMainLooper());
         }
@@ -314,4 +330,4 @@
             }
         }
     }
-}
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java
index d9fe982..f543b46 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java
@@ -588,7 +588,7 @@
         }
 
         public boolean areGutsExposed() {
-            return row != null && row.getGuts().isExposed();
+            return row != null && row.getGuts() != null && row.getGuts().isExposed();
         }
 
         public boolean isChildInGroup() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index 20c4816..b1fa6a5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -21,7 +21,6 @@
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
@@ -60,10 +59,11 @@
     private ViewGroup mTransientContainer;
     private boolean mInShelf;
     private boolean mTransformingInShelf;
-    @Nullable private ExpandableViewState mViewState;
+    private final ExpandableViewState mViewState;
 
     public ExpandableView(Context context, AttributeSet attrs) {
         super(context, attrs);
+        mViewState = createExpandableViewState();
     }
 
     @Override
@@ -536,11 +536,6 @@
 
     /** Sets {@link ExpandableViewState} to default state. */
     public ExpandableViewState resetViewState() {
-        // TODO(http://b/119762423): Move the null check to getViewState().
-        if (mViewState == null) {
-            mViewState = createExpandableViewState();
-        }
-
         // initialize with the default values of the view
         mViewState.height = getIntrinsicHeight();
         mViewState.gone = getVisibility() == View.GONE;
@@ -573,9 +568,7 @@
 
     /** Applies internal {@link ExpandableViewState} to this view. */
     public void applyViewState() {
-        if (mViewState == null) {
-            Log.wtf(TAG, "No child state was found when applying this state to the hostView");
-        } else if (!mViewState.gone) {
+        if (!mViewState.gone) {
             mViewState.applyToView(this);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
index 9eb5737a..0cec637 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
@@ -296,13 +296,15 @@
                     } else if (exceededSwipeHorizontalTouchSlop) {
                         if (mDragHPositive ? (posH < touchDownH) : (posH > touchDownH)) {
                             // Swiping left (rtl) gesture
-                            int index = isEdgeSwipeAlongNavBar(touchDownH, !mDragHPositive)
+                            int index = mGestureActions[ACTION_SWIPE_LEFT_FROM_EDGE_INDEX] != null
+                                        && isEdgeSwipeAlongNavBar(touchDownH, !mDragHPositive)
                                     ? ACTION_SWIPE_LEFT_FROM_EDGE_INDEX : ACTION_SWIPE_LEFT_INDEX;
                             tryToStartGesture(mGestureActions[index], true /* alignedWithNavBar */,
                                     event);
                         } else {
                             // Swiping right (ltr) gesture
-                            int index = isEdgeSwipeAlongNavBar(touchDownH, mDragHPositive)
+                            int index = mGestureActions[ACTION_SWIPE_RIGHT_FROM_EDGE_INDEX] != null
+                                        && isEdgeSwipeAlongNavBar(touchDownH, mDragHPositive)
                                     ? ACTION_SWIPE_RIGHT_FROM_EDGE_INDEX : ACTION_SWIPE_RIGHT_INDEX;
                             tryToStartGesture(mGestureActions[index], true /* alignedWithNavBar */,
                                     event);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index b351f1d..1d6a1e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -121,8 +121,6 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.StatusBarIcon;
-import com.android.internal.widget.MessagingGroup;
-import com.android.internal.widget.MessagingMessage;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.ViewMediatorCallback;
@@ -1116,8 +1114,6 @@
 
     @Override
     public void onDensityOrFontScaleChanged() {
-        MessagingMessage.dropCache();
-        MessagingGroup.dropCache();
         // TODO: Remove this.
         if (mBrightnessMirrorController != null) {
             mBrightnessMirrorController.onDensityOrFontScaleChanged();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index d99af1f..acdd5e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -37,6 +37,8 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.widget.MessagingGroup;
+import com.android.internal.widget.MessagingMessage;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.Dependency;
 import com.android.systemui.InitController;
@@ -62,9 +64,11 @@
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
 import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 
-public class StatusBarNotificationPresenter implements NotificationPresenter {
+public class StatusBarNotificationPresenter implements NotificationPresenter,
+        ConfigurationController.ConfigurationListener {
 
     private final LockscreenGestureLogger mLockscreenGestureLogger =
             Dependency.get(LockscreenGestureLogger.class);
@@ -168,9 +172,13 @@
 
             onUserSwitched(mLockscreenUserManager.getCurrentUserId());
         });
+        Dependency.get(ConfigurationController.class).addCallback(this);
     }
 
+    @Override
     public void onDensityOrFontScaleChanged() {
+        MessagingMessage.dropCache();
+        MessagingGroup.dropCache();
         if (!KeyguardUpdateMonitor.getInstance(mContext).isSwitchingUser()) {
             mEntryManager.updateNotificationsOnDensityOrFontScaleChanged();
         } else {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
index abb8c79..2805908 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
@@ -601,6 +601,25 @@
         assertGestureDragsHitTargetAllDirections(buttonView, true /* isRTL */, NAV_BAR_LEFT);
     }
 
+    @Test
+    public void testNoEdgeActionsTriggerNormalActions() {
+        doReturn(NAVBAR_WIDTH).when(mNavigationBarView).getWidth();
+        doReturn(NAVBAR_HEIGHT).when(mNavigationBarView).getHeight();
+
+        NavigationGestureAction swipeUp = mockAction(true);
+        NavigationGestureAction swipeDown = mockAction(true);
+        NavigationGestureAction swipeLeft = mockAction(true);
+        NavigationGestureAction swipeRight = mockAction(true);
+        mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight,
+                null /* swipeLeftFromEdgeAction */,
+                null /* swipeLeftFromEdgeAction */);
+
+        // Swipe Left from Edge
+        assertGestureTriggersAction(swipeLeft, NAVBAR_WIDTH, 1, 5, 1);
+        // Swipe Right from Edge
+        assertGestureTriggersAction(swipeRight, 0, 1, NAVBAR_WIDTH, 5);
+    }
+
     private void assertGestureDragsHitTargetAllDirections(View buttonView, boolean isRTL,
             int navPos) {
         mController.setBarState(isRTL, navPos);
@@ -665,7 +684,6 @@
         reset(buttonView);
     }
 
-
     private MotionEvent event(int action, float x, float y) {
         final MotionEvent event = mock(MotionEvent.class);
         doReturn(x).when(event).getX();
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index f2ae161..2d30640 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -6627,6 +6627,16 @@
     // OS: Q
     ACTION_DISPLAY_FOLD = 1594;
 
+    // OPEN: WifiDppConfiguratorActivity (android.settings.WIFI_DPP_CONFIGURATOR_XXX action intents)
+    // CATEGORY: SETTINGS
+    // OS: Q
+    SETTINGS_WIFI_DPP_CONFIGURATOR = 1595;
+
+    // OPEN: WifiDppEnrolleeActivity (android.settings.WIFI_DPP_ENROLLEE_XXX action intents)
+    // CATEGORY: SETTINGS
+    // OS: Q
+    SETTINGS_WIFI_DPP_ENROLLEE = 1596;
+
     // ---- End Q Constants, all Q constants go above this line ----
 
     // Add new aosp constants above this line.
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index e8887e7..612c929 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -484,15 +484,15 @@
     }
 
     // Called by Shell command.
-    void getScore(@Nullable String algorithmName, @NonNull String value1,
+    void calculateScore(@Nullable String algorithmName, @NonNull String value1,
             @NonNull String value2, @NonNull RemoteCallback callback) {
         enforceCallingPermissionForManagement();
 
         final FieldClassificationStrategy strategy =
                 new FieldClassificationStrategy(getContext(), UserHandle.USER_CURRENT);
 
-        strategy.getScores(callback, algorithmName, null,
-                Arrays.asList(AutofillValue.forText(value1)), new String[] { value2 });
+        strategy.calculateScores(callback, Arrays.asList(AutofillValue.forText(value1)),
+                new String[] { value2 }, null, algorithmName, null, null, null);
     }
 
     // Called by Shell command.
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 5a0d12c..fa62ef8 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -76,7 +76,6 @@
 import com.android.server.autofill.RemoteAugmentedAutofillService.RemoteAugmentedAutofillServiceCallbacks;
 import com.android.server.autofill.ui.AutoFillUI;
 import com.android.server.infra.AbstractPerUserSystemService;
-import com.android.server.infra.AbstractRemoteService;
 import com.android.server.infra.FrameworkResourcesServiceNameResolver;
 import com.android.server.infra.SecureSettingsServiceNameResolver;
 
@@ -1031,8 +1030,7 @@
                 return null;
             }
             final ComponentName componentName = RemoteAugmentedAutofillService.getComponentName(
-                    getContext(), serviceName, mUserId,
-                    mAugmentedAutofillResolver.isTemporaryLocked());
+                    serviceName, mUserId, mAugmentedAutofillResolver.isTemporaryLocked());
             if (componentName == null) return null;
             if (sVerbose) {
                 Slog.v(TAG, "getRemoteAugmentedAutofillServiceLocked(): " + componentName);
@@ -1041,8 +1039,7 @@
             mRemoteAugmentedAutofillService = new RemoteAugmentedAutofillService(getContext(),
                     componentName, mUserId, new RemoteAugmentedAutofillServiceCallbacks() {
                         @Override
-                        public void onServiceDied(
-                                AbstractRemoteService<? extends AbstractRemoteService<?>> service) {
+                        public void onServiceDied(@NonNull RemoteAugmentedAutofillService service) {
                             // TODO(b/111330312): properly implement
                             Slog.w(TAG, "remote augmented autofill service died");
                         }
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
index 35c5102..c562fb1 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
@@ -233,7 +233,7 @@
         final String value2 = getNextArgRequired();
 
         final CountDownLatch latch = new CountDownLatch(1);
-        mService.getScore(algorithm, value1, value2, new RemoteCallback((result) -> {
+        mService.calculateScore(algorithm, value1, value2, new RemoteCallback((result) -> {
             final Scores scores = result.getParcelable(EXTRA_SCORES);
             if (scores == null) {
                 pw.println("no score");
diff --git a/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java b/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java
index 293f908e..9db6254 100644
--- a/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java
+++ b/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java
@@ -15,11 +15,12 @@
  */
 package com.android.server.autofill;
 
-import static com.android.server.autofill.Helper.sDebug;
-import static com.android.server.autofill.Helper.sVerbose;
 import static android.service.autofill.AutofillFieldClassificationService.SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS;
 import static android.service.autofill.AutofillFieldClassificationService.SERVICE_META_DATA_KEY_DEFAULT_ALGORITHM;
 
+import static com.android.server.autofill.Helper.sDebug;
+import static com.android.server.autofill.Helper.sVerbose;
+
 import android.Manifest;
 import android.annotation.MainThread;
 import android.annotation.NonNull;
@@ -40,6 +41,7 @@
 import android.os.UserHandle;
 import android.service.autofill.AutofillFieldClassificationService;
 import android.service.autofill.IAutofillFieldClassificationService;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Slog;
 import android.view.autofill.AutofillValue;
@@ -257,13 +259,13 @@
         return parser.get(res, resourceId);
     }
 
-    //TODO(b/70291841): rename this method (and all others in the chain) to something like
-    // calculateScores() ?
-    void getScores(RemoteCallback callback, @Nullable String algorithmName,
-            @Nullable Bundle algorithmArgs, @NonNull List<AutofillValue> actualValues,
-            @NonNull String[] userDataValues) {
-        connectAndRun((service) -> service.getScores(callback, algorithmName,
-                algorithmArgs, actualValues, userDataValues));
+    void calculateScores(RemoteCallback callback, @NonNull List<AutofillValue> actualValues,
+            @NonNull String[] userDataValues, @NonNull String[] categoryIds,
+            @Nullable String defaultAlgorithm, @Nullable Bundle defaultArgs,
+            @Nullable ArrayMap<String, String> algorithms,
+            @Nullable ArrayMap<String, Bundle> args) {
+        connectAndRun((service) -> service.calculateScores(callback, actualValues,
+                userDataValues, categoryIds, defaultAlgorithm, defaultArgs, algorithms, args));
     }
 
     void dump(String prefix, PrintWriter pw) {
diff --git a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
index 222888c..fc7265d 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
@@ -26,7 +26,6 @@
 import android.content.pm.ServiceInfo;
 import android.os.Bundle;
 import android.os.IBinder;
-import android.os.IInterface;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.service.autofill.augmented.AugmentedAutofillService;
@@ -43,7 +42,8 @@
 import com.android.server.infra.AbstractSinglePendingRequestRemoteService;
 
 final class RemoteAugmentedAutofillService
-        extends AbstractSinglePendingRequestRemoteService<RemoteAugmentedAutofillService> {
+        extends AbstractSinglePendingRequestRemoteService<RemoteAugmentedAutofillService,
+            IAugmentedAutofillService> {
 
     private static final String TAG = RemoteAugmentedAutofillService.class.getSimpleName();
 
@@ -51,20 +51,16 @@
     private static final long TIMEOUT_IDLE_BIND_MILLIS = 2 * DateUtils.MINUTE_IN_MILLIS;
     private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 2 * DateUtils.SECOND_IN_MILLIS;
 
-    private final RemoteAugmentedAutofillServiceCallbacks mCallbacks;
-    private IAugmentedAutofillService mService;
-
     RemoteAugmentedAutofillService(Context context, ComponentName serviceName,
             int userId, RemoteAugmentedAutofillServiceCallbacks callbacks,
             boolean bindInstantServiceAllowed, boolean verbose) {
         super(context, AugmentedAutofillService.SERVICE_INTERFACE, serviceName, userId, callbacks,
                 bindInstantServiceAllowed, verbose);
-        mCallbacks = callbacks;
     }
 
     @Nullable
-    public static ComponentName getComponentName(@NonNull Context context,
-            @NonNull String componentName, @UserIdInt int userId, boolean isTemporary) {
+    public static ComponentName getComponentName(@NonNull String componentName,
+            @UserIdInt int userId, boolean isTemporary) {
         int flags = PackageManager.GET_META_DATA;
         if (!isTemporary) {
             flags |= PackageManager.MATCH_SYSTEM_ONLY;
@@ -88,9 +84,8 @@
     }
 
     @Override // from AbstractRemoteService
-    protected IInterface getServiceInterface(IBinder service) {
-        mService = IAugmentedAutofillService.Stub.asInterface(service);
-        return mService;
+    protected IAugmentedAutofillService getServiceInterface(IBinder service) {
+        return IAugmentedAutofillService.Stub.asInterface(service);
     }
 
     @Override // from AbstractRemoteService
@@ -109,7 +104,6 @@
     public void onRequestAutofillLocked(int sessionId, @NonNull IAutoFillManagerClient client,
             int taskId, @NonNull ComponentName activityComponent, @NonNull AutofillId focusedId,
             @Nullable AutofillValue focusedValue) {
-        cancelScheduledUnbind();
         scheduleRequest(new PendingAutofillRequest(this, sessionId, client, taskId,
                 activityComponent, focusedId, focusedValue));
     }
@@ -118,12 +112,12 @@
      * Called by {@link Session} when it's time to destroy all augmented autofill requests.
      */
     public void onDestroyAutofillWindowsRequest(int sessionId) {
-        cancelScheduledUnbind();
-        scheduleRequest(new PendingDestroyAutofillWindowsRequest(this, sessionId));
+        scheduleAsyncRequest((s) -> s.onDestroyFillWindowRequest(sessionId));
     }
 
+    // TODO(b/111330312): inline into PendingAutofillRequest if it doesn't have any other subclass
     private abstract static class MyPendingRequest
-            extends PendingRequest<RemoteAugmentedAutofillService> {
+            extends PendingRequest<RemoteAugmentedAutofillService, IAugmentedAutofillService> {
         protected final int mSessionId;
 
         private MyPendingRequest(@NonNull RemoteAugmentedAutofillService service, int sessionId) {
@@ -196,38 +190,8 @@
 
     }
 
-    private static final class PendingDestroyAutofillWindowsRequest extends MyPendingRequest {
-
-        protected PendingDestroyAutofillWindowsRequest(
-                @NonNull RemoteAugmentedAutofillService service, @NonNull int sessionId) {
-            super(service, sessionId);
-        }
-
-        @Override
-        public void run() {
-            final RemoteAugmentedAutofillService remoteService = getService();
-            if (remoteService == null) return;
-
-            try {
-                remoteService.mService.onDestroyFillWindowRequest(mSessionId);
-            } catch (RemoteException e) {
-                Slog.w(TAG, "exception handling onDestroyAutofillWindowsRequest() for "
-                        + mSessionId + ": " + e);
-            } finally {
-                // Service is not calling back, so we finish right away.
-                finish();
-            }
-        }
-
-        @Override
-        protected void onTimeout(RemoteAugmentedAutofillService remoteService) {
-            // Should not happen because we called finish() on run(), although currently it might
-            // be called if the service is destroyed while showing it.
-            Slog.e(TAG, "timed out: " + this);
-        }
-    }
-
-    public interface RemoteAugmentedAutofillServiceCallbacks extends VultureCallback {
+    public interface RemoteAugmentedAutofillServiceCallbacks
+            extends VultureCallback<RemoteAugmentedAutofillService> {
         // NOTE: so far we don't need to notify the callback implementation (an inner class on
         // AutofillManagerServiceImpl) of the request results (success, timeouts, etc..), so this
         // callback interface is empty.
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 4b7d290..417ea9c 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -28,7 +28,6 @@
 import android.content.IntentSender;
 import android.os.IBinder;
 import android.os.ICancellationSignal;
-import android.os.IInterface;
 import android.os.RemoteException;
 import android.service.autofill.AutofillService;
 import android.service.autofill.FillRequest;
@@ -42,15 +41,15 @@
 
 import com.android.server.infra.AbstractSinglePendingRequestRemoteService;
 
-final class RemoteFillService extends AbstractSinglePendingRequestRemoteService<RemoteFillService> {
+final class RemoteFillService
+        extends AbstractSinglePendingRequestRemoteService<RemoteFillService, IAutoFillService> {
 
     private static final long TIMEOUT_IDLE_BIND_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;
     private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;
 
     private final FillServiceCallbacks mCallbacks;
-    private IAutoFillService mAutoFillService;
 
-    public interface FillServiceCallbacks extends VultureCallback {
+    public interface FillServiceCallbacks extends VultureCallback<RemoteFillService> {
         void onFillRequestSuccess(int requestId, @Nullable FillResponse response,
                 @NonNull String servicePackageName, int requestFlags);
         void onFillRequestFailure(int requestId, @Nullable CharSequence message);
@@ -71,21 +70,20 @@
 
     @Override // from AbstractRemoteService
     protected void handleOnConnectedStateChanged(boolean state) {
-        if (mAutoFillService == null) {
+        if (mService == null) {
             Slog.w(mTag, "onConnectedStateChanged(): null service");
             return;
         }
         try {
-            mAutoFillService.onConnectedStateChanged(state);
+            mService.onConnectedStateChanged(state);
         } catch (Exception e) {
             Slog.w(mTag, "Exception calling onConnectedStateChanged(): " + e);
         }
     }
 
     @Override // from AbstractRemoteService
-    protected IInterface getServiceInterface(IBinder service) {
-        mAutoFillService = IAutoFillService.Stub.asInterface(service);
-        return mAutoFillService;
+    protected IAutoFillService getServiceInterface(IBinder service) {
+        return IAutoFillService.Stub.asInterface(service);
     }
 
     @Override // from AbstractRemoteService
@@ -127,17 +125,15 @@
     }
 
     public void onFillRequest(@NonNull FillRequest request) {
-        cancelScheduledUnbind();
         scheduleRequest(new PendingFillRequest(request, this));
     }
 
     public void onSaveRequest(@NonNull SaveRequest request) {
-        cancelScheduledUnbind();
         scheduleRequest(new PendingSaveRequest(request, this));
     }
 
     private boolean handleResponseCallbackCommon(
-            @NonNull PendingRequest<RemoteFillService> pendingRequest) {
+            @NonNull PendingRequest<RemoteFillService, IAutoFillService> pendingRequest) {
         if (isDestroyed()) return false;
 
         if (mPendingRequest == pendingRequest) {
@@ -204,7 +200,8 @@
         });
     }
 
-    private static final class PendingFillRequest extends PendingRequest<RemoteFillService> {
+    private static final class PendingFillRequest
+            extends PendingRequest<RemoteFillService, IAutoFillService> {
         private final FillRequest mRequest;
         private final IFillCallback mCallback;
         private ICancellationSignal mCancellation;
@@ -282,7 +279,7 @@
             if (remoteService != null) {
                 if (sVerbose) Slog.v(mTag, "calling onFillRequest() for id=" + mRequest.getId());
                 try {
-                    remoteService.mAutoFillService.onFillRequest(mRequest, mCallback);
+                    remoteService.mService.onFillRequest(mRequest, mCallback);
                 } catch (RemoteException e) {
                     Slog.e(mTag, "Error calling on fill request", e);
 
@@ -310,7 +307,8 @@
         }
     }
 
-    private static final class PendingSaveRequest extends PendingRequest<RemoteFillService> {
+    private static final class PendingSaveRequest
+            extends PendingRequest<RemoteFillService, IAutoFillService> {
         private final SaveRequest mRequest;
         private final ISaveCallback mCallback;
 
@@ -355,7 +353,7 @@
             if (remoteService != null) {
                 if (sVerbose) Slog.v(mTag, "calling onSaveRequest()");
                 try {
-                    remoteService.mAutoFillService.onSaveRequest(mRequest, mCallback);
+                    remoteService.mService.onSaveRequest(mRequest, mCallback);
                 } catch (RemoteException e) {
                     Slog.e(mTag, "Error calling on save request", e);
 
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index aef16b1..0e9b407 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -98,7 +98,6 @@
 import com.android.server.autofill.AutofillManagerService.SmartSuggestionMode;
 import com.android.server.autofill.ui.AutoFillUI;
 import com.android.server.autofill.ui.PendingUi;
-import com.android.server.infra.AbstractRemoteService;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -909,7 +908,7 @@
 
     // VultureCallback
     @Override
-    public void onServiceDied(AbstractRemoteService<? extends AbstractRemoteService<?>> service) {
+    public void onServiceDied(@NonNull RemoteFillService service) {
         Slog.w(TAG, "removing session because service died");
         forceRemoveSelfLocked();
     }
@@ -1402,6 +1401,12 @@
         final String[] userValues = userData.getValues();
         final String[] categoryIds = userData.getCategoryIds();
 
+        final String defaultAlgorithm = userData.getFieldClassificationAlgorithm();
+        final Bundle defaultArgs = userData.getDefaultFieldClassificationArgs();
+
+        final ArrayMap<String, String> algorithms = userData.getFieldClassificationAlgorithms();
+        final ArrayMap<String, Bundle> args = userData.getFieldClassificationArgs();
+
         // Sanity check
         if (userValues == null || categoryIds == null || userValues.length != categoryIds.length) {
             final int valuesLength = userValues == null ? -1 : userValues.length;
@@ -1417,8 +1422,6 @@
         final ArrayList<FieldClassification> detectedFieldClassifications = new ArrayList<>(
                 maxFieldsSize);
 
-        final String algorithm = userData.getFieldClassificationAlgorithm();
-        final Bundle algorithmArgs = userData.getAlgorithmArgs();
         final int viewsSize = viewStates.size();
 
         // First, we get all scores.
@@ -1505,7 +1508,8 @@
                     mComponentName, mCompatMode);
         });
 
-        fcStrategy.getScores(callback, algorithm, algorithmArgs, currentValues, userValues);
+        fcStrategy.calculateScores(callback, currentValues, userValues, categoryIds,
+                defaultAlgorithm, defaultArgs, algorithms, args);
     }
 
     /**
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 3acdc8e3..a917ced 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -16,7 +16,9 @@
 
 package com.android.server.backup;
 
+import android.Manifest;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.backup.IBackupManagerMonitor;
 import android.app.backup.IBackupObserver;
@@ -30,6 +32,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.os.Binder;
 import android.os.Environment;
 import android.os.HandlerThread;
 import android.os.IBinder;
@@ -79,6 +82,7 @@
         return sInstance;
     }
 
+    private final Context mContext;
     private UserBackupManagerService mUserBackupManagerService;
 
     /** Instantiate a new instance of {@link BackupManagerService}. */
@@ -91,11 +95,26 @@
             transportWhitelist = Collections.emptySet();
         }
 
+        mContext = context;
         mUserBackupManagerService =
                 UserBackupManagerService.createAndInitializeService(
                         context, trampoline, backupThread, transportWhitelist);
     }
 
+    /**
+     * If {@code userId} is different from the calling user id, then the caller must hold the
+     * android.permission.INTERACT_ACROSS_USERS_FULL permission.
+     *
+     * @param userId User id on which the backup operation is being requested.
+     * @param message A message to include in the exception if it is thrown.
+     */
+    private void enforceCallingPermissionOnUserId(int userId, String message) {
+        if (Binder.getCallingUserHandle().getIdentifier() != userId) {
+            mContext.enforceCallingOrSelfPermission(
+                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
+        }
+    }
+
     // TODO(b/118520567): Remove when tests are modified to use per-user instance.
     @VisibleForTesting
     void setUserBackupManagerService(UserBackupManagerService userBackupManagerService) {
@@ -314,7 +333,8 @@
     // ---------------------------------------------
 
     /** Enable/disable the backup service. This is user-configurable via backup settings. */
-    public void setBackupEnabled(boolean enable) {
+    public void setBackupEnabled(@UserIdInt int userId, boolean enable) {
+        enforceCallingPermissionOnUserId(userId, "setBackupEnabled");
         mUserBackupManagerService.setBackupEnabled(enable);
     }
 
@@ -331,7 +351,8 @@
     /**
      * Return {@code true} if the backup mechanism is currently enabled, else returns {@code false}.
      */
-    public boolean isBackupEnabled() {
+    public boolean isBackupEnabled(@UserIdInt int userId) {
+        enforceCallingPermissionOnUserId(userId, "isBackupEnabled");
         return mUserBackupManagerService.isBackupEnabled();
     }
 
@@ -355,7 +376,8 @@
      * Run a backup pass immediately for any key-value backup applications that have declared that
      * they have pending updates.
      */
-    public void backupNow() {
+    public void backupNow(@UserIdInt int userId) {
+        enforceCallingPermissionOnUserId(userId, "backupNow");
         mUserBackupManagerService.backupNow();
     }
 
@@ -364,12 +386,18 @@
      * IBackupManagerMonitor} for receiving events during the operation.
      */
     public int requestBackup(
-            String[] packages, IBackupObserver observer, IBackupManagerMonitor monitor, int flags) {
+            @UserIdInt int userId,
+            String[] packages,
+            IBackupObserver observer,
+            IBackupManagerMonitor monitor,
+            int flags) {
+        enforceCallingPermissionOnUserId(userId, "requestBackup");
         return mUserBackupManagerService.requestBackup(packages, observer, monitor, flags);
     }
 
     /** Cancel all running backup operations. */
-    public void cancelBackups() {
+    public void cancelBackups(@UserIdInt int userId) {
+        enforceCallingPermissionOnUserId(userId, "cancelBackups");
         mUserBackupManagerService.cancelBackups();
     }
 
@@ -533,8 +561,10 @@
             stage.renameTo(enableFile);
             // will be synced immediately by the try-with-resources call to close()
         } catch (IOException | RuntimeException e) {
-            Slog.e(TAG, "Unable to record backup enable state; reverting to disabled: "
-                    + e.getMessage());
+            Slog.e(
+                    TAG,
+                    "Unable to record backup enable state; reverting to disabled: "
+                            + e.getMessage());
             enableFile.delete();
             stage.delete();
         }
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index 108f50d..ed6ff9b 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -19,6 +19,7 @@
 import static com.android.server.backup.BackupManagerService.TAG;
 
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.app.admin.DevicePolicyManager;
 import android.app.backup.BackupManager;
 import android.app.backup.IBackupManager;
@@ -123,6 +124,10 @@
                 == MULTI_USER_ENABLED;
     }
 
+    protected int binderGetCallingUserId() {
+        return Binder.getCallingUserHandle().getIdentifier();
+    }
+
     protected int binderGetCallingUid() {
         return Binder.getCallingUid();
     }
@@ -319,14 +324,20 @@
     }
 
     @Override
-    public void setBackupEnabled(boolean isEnabled) throws RemoteException {
+    public void setBackupEnabledForUser(@UserIdInt int userId, boolean isEnabled)
+            throws RemoteException {
         BackupManagerService svc = mService;
         if (svc != null) {
-            svc.setBackupEnabled(isEnabled);
+            svc.setBackupEnabled(userId, isEnabled);
         }
     }
 
     @Override
+    public void setBackupEnabled(boolean isEnabled) throws RemoteException {
+        setBackupEnabledForUser(binderGetCallingUserId(), isEnabled);
+    }
+
+    @Override
     public void setAutoRestore(boolean doAutoRestore) throws RemoteException {
         BackupManagerService svc = mService;
         if (svc != null) {
@@ -343,9 +354,14 @@
     }
 
     @Override
-    public boolean isBackupEnabled() throws RemoteException {
+    public boolean isBackupEnabledForUser(@UserIdInt int userId) throws RemoteException {
         BackupManagerService svc = mService;
-        return (svc != null) ? svc.isBackupEnabled() : false;
+        return (svc != null) ? svc.isBackupEnabled(userId) : false;
+    }
+
+    @Override
+    public boolean isBackupEnabled() throws RemoteException {
+        return isBackupEnabledForUser(binderGetCallingUserId());
     }
 
     @Override
@@ -361,14 +377,19 @@
     }
 
     @Override
-    public void backupNow() throws RemoteException {
+    public void backupNowForUser(@UserIdInt int userId) throws RemoteException {
         BackupManagerService svc = mService;
         if (svc != null) {
-            svc.backupNow();
+            svc.backupNow(userId);
         }
     }
 
     @Override
+    public void backupNow() throws RemoteException {
+        backupNowForUser(binderGetCallingUserId());
+    }
+
+    @Override
     public void adbBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs,
             boolean includeShared, boolean doWidgets, boolean allApps,
             boolean allIncludesSystem, boolean doCompress, boolean doKeyValue, String[] packageNames)
@@ -543,21 +564,33 @@
     }
 
     @Override
-    public int requestBackup(String[] packages, IBackupObserver observer,
-            IBackupManagerMonitor monitor, int flags) throws RemoteException {
+    public int requestBackupForUser(@UserIdInt int userId, String[] packages, IBackupObserver
+            observer, IBackupManagerMonitor monitor, int flags) throws RemoteException {
         BackupManagerService svc = mService;
         if (svc == null) {
             return BackupManager.ERROR_BACKUP_NOT_ALLOWED;
         }
-        return svc.requestBackup(packages, observer, monitor, flags);
+        return svc.requestBackup(userId, packages, observer, monitor, flags);
+    }
+
+    @Override
+    public int requestBackup(String[] packages, IBackupObserver observer,
+            IBackupManagerMonitor monitor, int flags) throws RemoteException {
+        return requestBackupForUser(binderGetCallingUserId(), packages,
+                observer, monitor, flags);
+    }
+
+    @Override
+    public void cancelBackupsForUser(@UserIdInt int userId) throws RemoteException {
+        BackupManagerService svc = mService;
+        if (svc != null) {
+            svc.cancelBackups(userId);
+        }
     }
 
     @Override
     public void cancelBackups() throws RemoteException {
-        BackupManagerService svc = mService;
-        if (svc != null) {
-            svc.cancelBackups();
-        }
+        cancelBackupsForUser(binderGetCallingUserId());
     }
 
     @Override
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureSession.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureSession.java
index 2302b7d..a4012d5 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureSession.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureSession.java
@@ -29,7 +29,6 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.Preconditions;
 import com.android.server.contentcapture.RemoteContentCaptureService.ContentCaptureServiceCallbacks;
-import com.android.server.infra.AbstractRemoteService;
 
 import java.io.PrintWriter;
 import java.util.List;
@@ -124,8 +123,8 @@
         }
     }
 
-    @Override // from RemoteScreenObservationServiceCallbacks
-    public void onServiceDied(AbstractRemoteService<?> service) {
+    @Override // from RemoteContentCaptureServiceCallbacks
+    public void onServiceDied(@NonNull RemoteContentCaptureService service) {
         // TODO(b/111276913): implement (remove session from PerUserSession?)
         if (mService.isDebug()) {
             Slog.d(TAG, "onServiceDied() for " + mId);
@@ -135,17 +134,6 @@
         }
     }
 
-    @Override // from RemoteScreenObservationServiceCallbacks
-    public void onFailureOrTimeout(boolean timedOut) {
-        // TODO(b/111276913): log metrics on whether timed out or not
-        if (mService.isDebug()) {
-            Slog.d(TAG, "onFailureOrTimeout(" + mId + "): timed out=" + timedOut);
-        }
-        synchronized (mLock) {
-            removeSelfLocked(/* notifyRemoteService= */ false);
-        }
-    }
-
     @GuardedBy("mLock")
     public void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) {
         pw.print(prefix); pw.print("id: ");  pw.print(mId); pw.println();
diff --git a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
index 6a111f2..33b6c8d 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
@@ -20,14 +20,11 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.os.IBinder;
-import android.os.IInterface;
-import android.os.RemoteException;
 import android.service.contentcapture.ContentCaptureEventsRequest;
 import android.service.contentcapture.IContentCaptureService;
 import android.service.contentcapture.InteractionContext;
 import android.service.contentcapture.SnapshotData;
 import android.text.format.DateUtils;
-import android.util.Slog;
 import android.view.contentcapture.ContentCaptureEvent;
 
 import com.android.server.infra.AbstractMultiplePendingRequestsRemoteService;
@@ -35,30 +32,24 @@
 import java.util.List;
 
 final class RemoteContentCaptureService
-        extends AbstractMultiplePendingRequestsRemoteService<RemoteContentCaptureService> {
-
-    private static final String TAG = RemoteContentCaptureService.class.getSimpleName();
+        extends AbstractMultiplePendingRequestsRemoteService<RemoteContentCaptureService,
+        IContentCaptureService> {
 
     // TODO(b/117779333): changed it so it's permanentely bound
     private static final long TIMEOUT_IDLE_BIND_MILLIS = 2 * DateUtils.MINUTE_IN_MILLIS;
     private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 2 * DateUtils.SECOND_IN_MILLIS;
 
-    private final ContentCaptureServiceCallbacks mCallbacks;
-    private IContentCaptureService mService;
-
     RemoteContentCaptureService(Context context, String serviceInterface,
             ComponentName componentName, int userId,
             ContentCaptureServiceCallbacks callbacks, boolean bindInstantServiceAllowed,
             boolean verbose) {
         super(context, serviceInterface, componentName, userId, callbacks,
                 bindInstantServiceAllowed, verbose, /* initialCapacity= */ 2);
-        mCallbacks = callbacks;
     }
 
     @Override // from RemoteService
-    protected IInterface getServiceInterface(@NonNull IBinder service) {
-        mService = IContentCaptureService.Stub.asInterface(service);
-        return mService;
+    protected IContentCaptureService getServiceInterface(@NonNull IBinder service) {
+        return IContentCaptureService.Stub.asInterface(service);
     }
 
     // TODO(b/111276913): modify super class to allow permanent binding when value is 0 or negative
@@ -81,8 +72,7 @@
      */
     public void onSessionLifecycleRequest(@Nullable InteractionContext context,
             @NonNull String sessionId) {
-        cancelScheduledUnbind();
-        scheduleRequest(new PendingSessionLifecycleRequest(this, context, sessionId));
+        scheduleAsyncRequest((s) -> s.onSessionLifecycle(context, sessionId));
     }
 
     /**
@@ -90,8 +80,8 @@
      */
     public void onContentCaptureEventsRequest(@NonNull String sessionId,
             @NonNull List<ContentCaptureEvent> events) {
-        cancelScheduledUnbind();
-        scheduleRequest(new PendingOnContentCaptureEventsRequest(this, sessionId, events));
+        scheduleAsyncRequest((s) -> s.onContentCaptureEventsRequest(sessionId,
+                new ContentCaptureEventsRequest(events)));
     }
 
     /**
@@ -99,103 +89,13 @@
      */
     public void onActivitySnapshotRequest(@NonNull String sessionId,
             @NonNull SnapshotData snapshotData) {
-        cancelScheduledUnbind();
-        scheduleRequest(new PendingOnActivitySnapshotRequest(this, sessionId, snapshotData));
+        scheduleAsyncRequest((s) -> s.onActivitySnapshot(sessionId, snapshotData));
     }
 
-    private abstract static class MyPendingRequest
-            extends PendingRequest<RemoteContentCaptureService> {
-        protected final String mSessionId;
-
-        private MyPendingRequest(@NonNull RemoteContentCaptureService service,
-                @NonNull String sessionId) {
-            super(service);
-            mSessionId = sessionId;
-        }
-
-        @Override // from PendingRequest
-        protected final void onTimeout(RemoteContentCaptureService remoteService) {
-            Slog.w(TAG, "timed out handling " + getClass().getSimpleName() + " for "
-                    + mSessionId);
-            remoteService.mCallbacks.onFailureOrTimeout(/* timedOut= */ true);
-        }
-
-        @Override // from PendingRequest
-        public final void run() {
-            final RemoteContentCaptureService remoteService = getService();
-            if (remoteService != null) {
-                try {
-                    // We don't expect the service to call us back, so we finish right away.
-                    myRun(remoteService);
-                    // TODO(b/111330312): not true anymore!!
-                    finish();
-                } catch (RemoteException e) {
-                    Slog.w(TAG, "exception handling " + getClass().getSimpleName() + " for "
-                            + mSessionId + ": " + e);
-                    remoteService.mCallbacks.onFailureOrTimeout(/* timedOut= */ false);
-                }
-            }
-        }
-
-        protected abstract void myRun(@NonNull RemoteContentCaptureService service)
-                throws RemoteException;
-
-    }
-
-    private static final class PendingSessionLifecycleRequest extends MyPendingRequest {
-
-        private final InteractionContext mContext;
-
-        protected PendingSessionLifecycleRequest(@NonNull RemoteContentCaptureService service,
-                @Nullable InteractionContext context, @NonNull String sessionId) {
-            super(service, sessionId);
-            mContext = context;
-        }
-
-        @Override // from MyPendingRequest
-        public void myRun(@NonNull RemoteContentCaptureService remoteService)
-                throws RemoteException {
-            remoteService.mService.onSessionLifecycle(mContext, mSessionId);
-        }
-    }
-
-    private static final class PendingOnContentCaptureEventsRequest extends MyPendingRequest {
-
-        private final List<ContentCaptureEvent> mEvents;
-
-        protected PendingOnContentCaptureEventsRequest(@NonNull RemoteContentCaptureService service,
-                @NonNull String sessionId, @NonNull List<ContentCaptureEvent> events) {
-            super(service, sessionId);
-            mEvents = events;
-        }
-
-        @Override // from MyPendingRequest
-        public void myRun(@NonNull RemoteContentCaptureService remoteService)
-                throws RemoteException {
-            remoteService.mService.onContentCaptureEventsRequest(mSessionId,
-                    new ContentCaptureEventsRequest(mEvents));
-        }
-    }
-
-    private static final class PendingOnActivitySnapshotRequest extends MyPendingRequest {
-
-        private final SnapshotData mSnapshotData;
-
-        protected PendingOnActivitySnapshotRequest(@NonNull RemoteContentCaptureService service,
-                @NonNull String sessionId, @NonNull SnapshotData snapshotData) {
-            super(service, sessionId);
-            mSnapshotData = snapshotData;
-        }
-
-        @Override // from MyPendingRequest
-        protected void myRun(@NonNull RemoteContentCaptureService remoteService)
-                throws RemoteException {
-            remoteService.mService.onActivitySnapshot(mSessionId, mSnapshotData);
-        }
-    }
-
-    public interface ContentCaptureServiceCallbacks extends VultureCallback {
-        // To keep it simple, we use the same callback for all failures / timeouts.
-        void onFailureOrTimeout(boolean timedOut);
+    public interface ContentCaptureServiceCallbacks
+            extends VultureCallback<RemoteContentCaptureService> {
+        // NOTE: so far we don't need to notify the callback implementation (an inner class on
+        // AutofillManagerServiceImpl) of the request results (success, timeouts, etc..), so this
+        // callback interface is empty.
     }
 }
diff --git a/services/core/Android.bp b/services/core/Android.bp
index cccacf4..4408db8 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -7,7 +7,6 @@
             "frameworks/native/aidl/binder",
             "frameworks/native/cmds/dumpstate/binder",
             "system/core/storaged/binder",
-            "system/netd/server/binder",
             "system/vold/binder",
         ],
     },
@@ -21,7 +20,6 @@
         ":mediaupdateservice_aidl",
         "java/com/android/server/EventLogTags.logtags",
         "java/com/android/server/am/EventLogTags.logtags",
-        ":netd_metrics_aidl",
     ],
 
     libs: [
@@ -52,6 +50,7 @@
         "android.hardware.contexthub-V1.0-java",
         "android.hidl.manager-V1.0-java",
         "netd_aidl_interface-java",
+        "netd_event_listener_interface-java",
     ],
 }
 
diff --git a/services/core/java/com/android/server/BinderCallsStatsService.java b/services/core/java/com/android/server/BinderCallsStatsService.java
index 11a2fc9..8b7f321 100644
--- a/services/core/java/com/android/server/BinderCallsStatsService.java
+++ b/services/core/java/com/android/server/BinderCallsStatsService.java
@@ -19,7 +19,6 @@
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
 
-import android.app.AppGlobals;
 import android.content.Context;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -28,9 +27,7 @@
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Process;
-import android.os.RemoteException;
 import android.os.SystemProperties;
-import android.os.ThreadLocalWorkSource;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.ArrayMap;
@@ -38,19 +35,16 @@
 import android.util.KeyValueListParser;
 import android.util.Slog;
 
-import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.AppIdToPackageMap;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.os.BinderCallsStats;
 import com.android.internal.os.BinderInternal;
-import com.android.internal.os.BinderInternal.CallSession;
 import com.android.internal.os.CachedDeviceState;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 public class BinderCallsStatsService extends Binder {
 
@@ -60,10 +54,10 @@
             = "persist.sys.binder_calls_detailed_tracking";
 
     /** Resolves the work source of an incoming binder transaction. */
-    static class WorkSourceProvider {
+    static class AuthorizedWorkSourceProvider implements BinderInternal.WorkSourceProvider {
         private ArraySet<Integer> mAppIdWhitelist;
 
-        WorkSourceProvider() {
+        AuthorizedWorkSourceProvider() {
             mAppIdWhitelist = new ArraySet<>();
         }
 
@@ -82,11 +76,11 @@
             mAppIdWhitelist = createAppidWhitelist(context);
         }
 
-        public void dump(PrintWriter pw, Map<Integer, String> appIdToPackageName) {
+        public void dump(PrintWriter pw, AppIdToPackageMap packageMap) {
             pw.println("AppIds of apps that can set the work source:");
             final ArraySet<Integer> whitelist = mAppIdWhitelist;
             for (Integer appId : whitelist) {
-                pw.println("\t- " + appIdToPackageName.getOrDefault(appId, String.valueOf(appId)));
+                pw.println("\t- " + packageMap.mapAppId(appId));
             }
         }
 
@@ -103,7 +97,7 @@
             final ArraySet<Integer> whitelist = new ArraySet<>();
 
             // We trust our own process.
-            whitelist.add(Process.myUid());
+            whitelist.add(UserHandle.getAppId(Process.myUid()));
             // We only need to initialize it once. UPDATE_DEVICE_STATS is a system permission.
             final PackageManager pm = context.getPackageManager();
             final String[] permissions = { android.Manifest.permission.UPDATE_DEVICE_STATS };
@@ -125,41 +119,6 @@
         }
     }
 
-    /** Observer for all system server incoming binder transactions. */
-    @VisibleForTesting
-    static class BinderCallsObserver implements BinderInternal.Observer {
-        private final BinderInternal.Observer mBinderCallsStats;
-        private final WorkSourceProvider mWorkSourceProvider;
-
-        BinderCallsObserver(BinderInternal.Observer callsStats,
-                WorkSourceProvider workSourceProvider) {
-            mBinderCallsStats = callsStats;
-            mWorkSourceProvider = workSourceProvider;
-        }
-
-        @Override
-        public CallSession callStarted(Binder binder, int code) {
-            // We depend on the code in Binder#execTransact to reset the state of
-            // ThreadLocalWorkSource
-            setThreadLocalWorkSourceUid(mWorkSourceProvider.resolveWorkSourceUid());
-            return mBinderCallsStats.callStarted(binder, code);
-        }
-
-        @Override
-        public void callEnded(CallSession s, int parcelRequestSize, int parcelReplySize) {
-            mBinderCallsStats.callEnded(s, parcelRequestSize, parcelReplySize);
-        }
-
-        @Override
-        public void callThrewException(CallSession s, Exception exception) {
-            mBinderCallsStats.callThrewException(s, exception);
-        }
-
-        protected void setThreadLocalWorkSourceUid(int uid) {
-            ThreadLocalWorkSource.setUid(uid);
-        }
-    }
-
     /** Listens for flag changes. */
     private static class SettingsObserver extends ContentObserver {
         private static final String SETTINGS_ENABLED_KEY = "enabled";
@@ -173,16 +132,16 @@
         private final Context mContext;
         private final KeyValueListParser mParser = new KeyValueListParser(',');
         private final BinderCallsStats mBinderCallsStats;
-        private final BinderCallsObserver mBinderCallsObserver;
+        private final AuthorizedWorkSourceProvider mWorkSourceProvider;
 
         SettingsObserver(Context context, BinderCallsStats binderCallsStats,
-                BinderCallsObserver observer) {
+                AuthorizedWorkSourceProvider workSourceProvider) {
             super(BackgroundThread.getHandler());
             mContext = context;
             context.getContentResolver().registerContentObserver(mUri, false, this,
                     UserHandle.USER_SYSTEM);
             mBinderCallsStats = binderCallsStats;
-            mBinderCallsObserver = observer;
+            mWorkSourceProvider = workSourceProvider;
             // Always kick once to ensure that we match current state
             onChange();
         }
@@ -220,12 +179,14 @@
                     mParser.getBoolean(SETTINGS_ENABLED_KEY, BinderCallsStats.ENABLED_DEFAULT);
             if (mEnabled != enabled) {
                 if (enabled) {
-                    Binder.setObserver(mBinderCallsObserver);
+                    Binder.setObserver(mBinderCallsStats);
                     Binder.setProxyTransactListener(
                             new Binder.PropagateWorkSourceTransactListener());
+                    Binder.setWorkSourceProvider(mWorkSourceProvider);
                 } else {
                     Binder.setObserver(null);
                     Binder.setProxyTransactListener(null);
+                    Binder.setWorkSourceProvider(Binder::getCallingUid);
                 }
                 mEnabled = enabled;
                 mBinderCallsStats.reset();
@@ -268,7 +229,7 @@
     public static class LifeCycle extends SystemService {
         private BinderCallsStatsService mService;
         private BinderCallsStats mBinderCallsStats;
-        private WorkSourceProvider mWorkSourceProvider;
+        private AuthorizedWorkSourceProvider mWorkSourceProvider;
 
         public LifeCycle(Context context) {
             super(context);
@@ -277,11 +238,9 @@
         @Override
         public void onStart() {
             mBinderCallsStats = new BinderCallsStats(new BinderCallsStats.Injector());
-            mWorkSourceProvider = new WorkSourceProvider();
-            BinderCallsObserver binderCallsObserver =
-                    new BinderCallsObserver(mBinderCallsStats, mWorkSourceProvider);
+            mWorkSourceProvider = new AuthorizedWorkSourceProvider();
             mService = new BinderCallsStatsService(
-                    mBinderCallsStats, binderCallsObserver, mWorkSourceProvider);
+                    mBinderCallsStats, mWorkSourceProvider);
             publishLocalService(Internal.class, new Internal(mBinderCallsStats));
             publishBinderService("binder_calls_stats", mService);
             boolean detailedTrackingEnabled = SystemProperties.getBoolean(
@@ -311,18 +270,16 @@
 
     private SettingsObserver mSettingsObserver;
     private final BinderCallsStats mBinderCallsStats;
-    private final BinderCallsObserver mBinderCallsObserver;
-    private final WorkSourceProvider mWorkSourceProvider;
+    private final AuthorizedWorkSourceProvider mWorkSourceProvider;
 
-    BinderCallsStatsService(BinderCallsStats binderCallsStats, BinderCallsObserver observer,
-            WorkSourceProvider workSourceProvider) {
+    BinderCallsStatsService(BinderCallsStats binderCallsStats,
+            AuthorizedWorkSourceProvider workSourceProvider) {
         mBinderCallsStats = binderCallsStats;
-        mBinderCallsObserver = observer;
         mWorkSourceProvider = workSourceProvider;
     }
 
     public void systemReady(Context context) {
-        mSettingsObserver = new SettingsObserver(context, mBinderCallsStats, mBinderCallsObserver);
+        mSettingsObserver = new SettingsObserver(context, mBinderCallsStats, mWorkSourceProvider);
     }
 
     public void reset() {
@@ -342,7 +299,7 @@
                     pw.println("binder_calls_stats reset.");
                     return;
                 } else if ("--enable".equals(arg)) {
-                    Binder.setObserver(mBinderCallsObserver);
+                    Binder.setObserver(mBinderCallsStats);
                     return;
                 } else if ("--disable".equals(arg)) {
                     Binder.setObserver(null);
@@ -361,7 +318,7 @@
                     pw.println("Detailed tracking disabled");
                     return;
                 } else if ("--dump-worksource-provider".equals(arg)) {
-                    mWorkSourceProvider.dump(pw, getAppIdToPackagesMap());
+                    mWorkSourceProvider.dump(pw, AppIdToPackageMap.getSnapshot());
                     return;
                 } else if ("-h".equals(arg)) {
                     pw.println("binder_calls_stats commands:");
@@ -377,28 +334,6 @@
                 }
             }
         }
-        mBinderCallsStats.dump(pw, getAppIdToPackagesMap(), verbose);
-    }
-
-    private Map<Integer, String> getAppIdToPackagesMap() {
-        List<PackageInfo> packages;
-        try {
-            packages = AppGlobals.getPackageManager()
-                    .getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES,
-                            UserHandle.USER_SYSTEM).getList();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-        Map<Integer,String> map = new HashMap<>();
-        for (PackageInfo pkg : packages) {
-            String name = pkg.packageName;
-            int uid = pkg.applicationInfo.uid;
-            // Use sharedUserId string as package name if there are collisions
-            if (pkg.sharedUserId != null && map.containsKey(uid)) {
-                name = "shared:" + pkg.sharedUserId;
-            }
-            map.put(uid, name);
-        }
-        return map;
+        mBinderCallsStats.dump(pw, AppIdToPackageMap.getSnapshot(), verbose);
     }
 }
diff --git a/services/core/java/com/android/server/LooperStatsService.java b/services/core/java/com/android/server/LooperStatsService.java
index fa3baba..cee98c1 100644
--- a/services/core/java/com/android/server/LooperStatsService.java
+++ b/services/core/java/com/android/server/LooperStatsService.java
@@ -31,6 +31,7 @@
 import android.util.KeyValueListParser;
 import android.util.Slog;
 
+import com.android.internal.os.AppIdToPackageMap;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.os.CachedDeviceState;
 import com.android.internal.os.LooperStats;
@@ -92,6 +93,7 @@
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+        AppIdToPackageMap packageMap = AppIdToPackageMap.getSnapshot();
         pw.print("Start time: ");
         pw.println(DateFormat.format("yyyy-MM-dd HH:mm:ss", mStats.getStartTimeMillis()));
         pw.print("On battery time (ms): ");
@@ -121,7 +123,7 @@
         pw.println(header);
         for (LooperStats.ExportedEntry entry : entries) {
             pw.printf("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n",
-                    entry.workSourceUid,
+                    packageMap.mapUid(entry.workSourceUid),
                     entry.threadName,
                     entry.handlerClassName,
                     entry.messageName,
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 87a42fa..4678fec 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -956,18 +956,6 @@
     // INetworkManagementService members
     //
     @Override
-    public INetd getNetdService() throws RemoteException {
-        final CountDownLatch connectedSignal = mConnectedSignal;
-        if (connectedSignal != null) {
-            try {
-                connectedSignal.await();
-            } catch (InterruptedException ignored) {}
-        }
-
-        return mNetdService;
-    }
-
-    @Override
     public String[] listInterfaces() {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 40da881..c9cab98 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -17532,8 +17532,9 @@
         // how many slots we have for background processes; we may want
         // to put multiple processes in a slot of there are enough of
         // them.
-        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
-                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
+        final int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
+                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2
+                / ProcessList.CACHED_APP_IMPORTANCE_LEVELS;
         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
         if (numEmptyProcs > cachedProcessLimit) {
             // If there are more empty processes than our limit on cached
@@ -17544,17 +17545,19 @@
             // instead of a gazillion empty processes.
             numEmptyProcs = cachedProcessLimit;
         }
-        int emptyFactor = numEmptyProcs/numSlots;
+        int emptyFactor = (numEmptyProcs + numSlots - 1) / numSlots;
         if (emptyFactor < 1) emptyFactor = 1;
-        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
+        int cachedFactor = (mNumCachedHiddenProcs > 0 ? (mNumCachedHiddenProcs + numSlots - 1) : 1)
+                / numSlots;
         if (cachedFactor < 1) cachedFactor = 1;
-        int stepCached = 0;
-        int stepEmpty = 0;
+        int stepCached = -1;
+        int stepEmpty = -1;
         int numCached = 0;
         int numCachedExtraGroup = 0;
         int numEmpty = 0;
         int numTrimming = 0;
         int lastCachedGroup = 0;
+        int lastCachedGroupImportance = 0;
         int lastCachedGroupUid = 0;
 
         mNumNonCachedProcs = 0;
@@ -17563,9 +17566,10 @@
         // First update the OOM adjustment for each of the
         // application processes based on their current state.
         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
-        int nextCachedAdj = curCachedAdj+1;
-        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
-        int nextEmptyAdj = curEmptyAdj+2;
+        int nextCachedAdj = curCachedAdj + (ProcessList.CACHED_APP_IMPORTANCE_LEVELS * 2);
+        int curCachedImpAdj = 0;
+        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ + ProcessList.CACHED_APP_IMPORTANCE_LEVELS;
+        int nextEmptyAdj = curEmptyAdj + (ProcessList.CACHED_APP_IMPORTANCE_LEVELS * 2);
 
         boolean retryCycles = false;
 
@@ -17590,27 +17594,61 @@
                         case PROCESS_STATE_CACHED_ACTIVITY:
                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
                         case ActivityManager.PROCESS_STATE_CACHED_RECENT:
-                            // This process is a cached process holding activities...
-                            // assign it the next cached value for that type, and then
-                            // step that cached level.
-                            app.setCurRawAdj(curCachedAdj);
-                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
-                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
-                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
-                                    + ")");
-                            if (curCachedAdj != nextCachedAdj) {
+                            // Figure out the next cached level, taking into account groups.
+                            boolean inGroup = false;
+                            if (app.connectionGroup != 0) {
+                                if (lastCachedGroupUid == app.uid
+                                        && lastCachedGroup == app.connectionGroup) {
+                                    // This is in the same group as the last process, just tweak
+                                    // adjustment by importance.
+                                    if (app.connectionImportance > lastCachedGroupImportance) {
+                                        lastCachedGroupImportance = app.connectionImportance;
+                                        if (curCachedAdj < nextCachedAdj
+                                                && curCachedAdj < ProcessList.CACHED_APP_MAX_ADJ) {
+                                            curCachedImpAdj++;
+                                        }
+                                    }
+                                    inGroup = true;
+                                } else {
+                                    lastCachedGroupUid = app.uid;
+                                    lastCachedGroup = app.connectionGroup;
+                                    lastCachedGroupImportance = app.connectionImportance;
+                                }
+                            }
+                            if (!inGroup && curCachedAdj != nextCachedAdj) {
                                 stepCached++;
+                                curCachedImpAdj = 0;
                                 if (stepCached >= cachedFactor) {
                                     stepCached = 0;
                                     curCachedAdj = nextCachedAdj;
-                                    nextCachedAdj += 2;
+                                    nextCachedAdj += ProcessList.CACHED_APP_IMPORTANCE_LEVELS * 2;
                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
                                     }
                                 }
                             }
+                            // This process is a cached process holding activities...
+                            // assign it the next cached value for that type, and then
+                            // step that cached level.
+                            app.setCurRawAdj(curCachedAdj + curCachedImpAdj);
+                            app.curAdj = app.modifyRawOomAdj(curCachedAdj + curCachedImpAdj);
+                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
+                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
+                                    + " curCachedImpAdj=" + curCachedImpAdj + ")");
                             break;
                         default:
+                            // Figure out the next cached level.
+                            if (curEmptyAdj != nextEmptyAdj) {
+                                stepEmpty++;
+                                if (stepEmpty >= emptyFactor) {
+                                    stepEmpty = 0;
+                                    curEmptyAdj = nextEmptyAdj;
+                                    nextEmptyAdj += ProcessList.CACHED_APP_IMPORTANCE_LEVELS * 2;
+                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
+                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
+                                    }
+                                }
+                            }
                             // For everything else, assign next empty cached process
                             // level and bump that up.  Note that this means that
                             // long-running services that have dropped down to the
@@ -17621,22 +17659,9 @@
                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
                                     + ")");
-                            if (curEmptyAdj != nextEmptyAdj) {
-                                stepEmpty++;
-                                if (stepEmpty >= emptyFactor) {
-                                    stepEmpty = 0;
-                                    curEmptyAdj = nextEmptyAdj;
-                                    nextEmptyAdj += 2;
-                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
-                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
-                                    }
-                                }
-                            }
                             break;
                     }
                 }
-
-
             }
         }
 
@@ -17668,6 +17693,8 @@
             }
         }
 
+        lastCachedGroup = lastCachedGroupUid = 0;
+
         for (int i=N-1; i>=0; i--) {
             ProcessRecord app = mProcessList.mLruProcesses.get(i);
             if (!app.killedByAm && app.thread != null) {
@@ -18935,7 +18962,7 @@
                     ProcessMemoryState processMemoryState =
                             new ProcessMemoryState(uid,
                                     r.processName,
-                                    r.maxAdj,
+                                    r.curAdj,
                                     memoryStat.pgfault,
                                     memoryStat.pgmajfault,
                                     memoryStat.rssInBytes,
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 8c39d75..3a0899d 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -1337,7 +1337,7 @@
         // Broadcast is being executed, its package can't be stopped.
         try {
             AppGlobals.getPackageManager().setPackageStoppedState(
-                    r.curComponent.getPackageName(), false, UserHandle.getUserId(r.callingUid));
+                    r.curComponent.getPackageName(), false, r.userId);
         } catch (RemoteException e) {
         } catch (IllegalArgumentException e) {
             Slog.w(TAG, "Failed trying to unstop package "
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 8cf9f1e..117984e 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -137,9 +137,13 @@
 
     // This is a process only hosting activities that are not visible,
     // so it can be killed without any disruption.
-    static final int CACHED_APP_MAX_ADJ = 906;
+    static final int CACHED_APP_MAX_ADJ = 999;
     static final int CACHED_APP_MIN_ADJ = 900;
 
+    // Number of levels we have available for different service connection group importance
+    // levels.
+    static final int CACHED_APP_IMPORTANCE_LEVELS = 5;
+
     // The B list of SERVICE_ADJ -- these are the old and decrepit
     // services that aren't as shiny and interesting as the ones in the A list.
     static final int SERVICE_B_ADJ = 800;
diff --git a/services/core/java/com/android/server/infra/AbstractMultiplePendingRequestsRemoteService.java b/services/core/java/com/android/server/infra/AbstractMultiplePendingRequestsRemoteService.java
index 513a6a3..aaea45e 100644
--- a/services/core/java/com/android/server/infra/AbstractMultiplePendingRequestsRemoteService.java
+++ b/services/core/java/com/android/server/infra/AbstractMultiplePendingRequestsRemoteService.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.content.ComponentName;
 import android.content.Context;
+import android.os.IInterface;
 import android.util.Slog;
 
 import java.io.PrintWriter;
@@ -29,21 +30,21 @@
  * bound.
  *
  * @param <S> the concrete remote service class
- *
+ * @param <I> the interface of the binder service
  * @hide
  */
-public abstract class AbstractMultiplePendingRequestsRemoteService<
-        S extends AbstractMultiplePendingRequestsRemoteService<S>>
-        extends AbstractRemoteService<S> {
+public abstract class AbstractMultiplePendingRequestsRemoteService<S
+        extends AbstractMultiplePendingRequestsRemoteService<S, I>, I extends IInterface>
+        extends AbstractRemoteService<S, I> {
 
     private final int mInitialCapacity;
 
-    protected ArrayList<PendingRequest<S>> mPendingRequests;
+    protected ArrayList<PendingRequest<S, I>> mPendingRequests;
 
     public AbstractMultiplePendingRequestsRemoteService(@NonNull Context context,
             @NonNull String serviceInterface, @NonNull ComponentName componentName, int userId,
-            @NonNull VultureCallback callback, boolean bindInstantServiceAllowed, boolean verbose,
-            int initialCapacity) {
+            @NonNull VultureCallback<S> callback, boolean bindInstantServiceAllowed,
+            boolean verbose, int initialCapacity) {
         super(context, serviceInterface, componentName, userId, callback, bindInstantServiceAllowed,
                 verbose);
         mInitialCapacity = initialCapacity;
@@ -84,7 +85,7 @@
     }
 
     @Override // from AbstractRemoteService
-    void handlePendingRequestWhileUnBound(@NonNull PendingRequest<S> pendingRequest) {
+    void handlePendingRequestWhileUnBound(@NonNull PendingRequest<S, I> pendingRequest) {
         if (mPendingRequests == null) {
             mPendingRequests = new ArrayList<>(mInitialCapacity);
         }
diff --git a/services/core/java/com/android/server/infra/AbstractRemoteService.java b/services/core/java/com/android/server/infra/AbstractRemoteService.java
index 67b3ecf..41dcf89 100644
--- a/services/core/java/com/android/server/infra/AbstractRemoteService.java
+++ b/services/core/java/com/android/server/infra/AbstractRemoteService.java
@@ -54,13 +54,13 @@
  * (no pun intended) example of how to use it.
  *
  * @param <S> the concrete remote service class
+ * @param <I> the interface of the binder service
  *
  * @hide
  */
 //TODO(b/117779333): improve javadoc above instead of using Autofill as an example
-public abstract class AbstractRemoteService<S extends AbstractRemoteService<S>>
-        implements DeathRecipient {
-
+public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I>,
+        I extends IInterface> implements DeathRecipient {
     private static final int MSG_UNBIND = 1;
 
     protected static final int LAST_PRIVATE_MSG = MSG_UNBIND;
@@ -74,11 +74,11 @@
 
     private final Context mContext;
     private final Intent mIntent;
-    private final VultureCallback mVultureCallback;
+    private final VultureCallback<S> mVultureCallback;
     private final int mUserId;
     private final ServiceConnection mServiceConnection = new RemoteServiceConnection();
     private final boolean mBindInstantServiceAllowed;
-    private IInterface mServiceInterface;
+    protected I mService;
 
     private boolean mBinding;
     private boolean mDestroyed;
@@ -87,19 +87,21 @@
 
     /**
      * Callback called when the service dies.
+     *
+     * @param <T> service class
      */
-    public interface VultureCallback {
+    public interface VultureCallback<T> {
         /**
          * Called when the service dies.
          *
          * @param service service that died!
          */
-        void onServiceDied(AbstractRemoteService<? extends AbstractRemoteService<?>> service);
+        void onServiceDied(T service);
     }
 
     // NOTE: must be package-protected so this class is not extend outside
     AbstractRemoteService(@NonNull Context context, @NonNull String serviceInterface,
-            @NonNull ComponentName componentName, int userId, @NonNull VultureCallback callback,
+            @NonNull ComponentName componentName, int userId, @NonNull VultureCallback<S> callback,
             boolean bindInstantServiceAllowed, boolean verbose) {
         mContext = context;
         mVultureCallback = callback;
@@ -150,7 +152,7 @@
      * Gets the base Binder interface from the service.
      */
     @NonNull
-    protected abstract IInterface getServiceInterface(@NonNull IBinder service);
+    protected abstract I getServiceInterface(@NonNull IBinder service);
 
     /**
      * Defines How long after the last interaction with the service we would unbind.
@@ -183,12 +185,14 @@
 
     private void handleBinderDied() {
         if (checkIfDestroyed()) return;
-        if (mServiceInterface != null) {
-            mServiceInterface.asBinder().unlinkToDeath(this, 0);
+        if (mService != null) {
+            mService.asBinder().unlinkToDeath(this, 0);
         }
-        mServiceInterface = null;
+        mService = null;
         mServiceDied = true;
-        mVultureCallback.onServiceDied(this);
+        @SuppressWarnings("unchecked") // TODO(b/117779333): fix this warning
+        final S castService = (S) this;
+        mVultureCallback.onServiceDied(castService);
     }
 
     // Note: we are dumping without a lock held so this is a bit racy but
@@ -216,12 +220,35 @@
         pw.println();
     }
 
-    protected void scheduleRequest(@NonNull PendingRequest<S> pendingRequest) {
+    /**
+     * Schedules a "sync" request.
+     *
+     * <p>This request must be responded by the service somehow (typically using a callback),
+     * othewise it will trigger a {@link PendingRequest#onTimeout(AbstractRemoteService)} if the
+     * service doesn't respond.
+     */
+    protected void scheduleRequest(@NonNull PendingRequest<S, I> pendingRequest) {
+        cancelScheduledUnbind();
         mHandler.sendMessage(obtainMessage(
                 AbstractRemoteService::handlePendingRequest, this, pendingRequest));
     }
 
-    protected void cancelScheduledUnbind() {
+    /**
+     * Schedules an async request.
+     *
+     * <p>This request is not expecting a callback from the service, hence it's represented by
+     * a simple {@link Runnable}.
+     */
+    protected void scheduleAsyncRequest(@NonNull AsyncRequest<I> request) {
+        cancelScheduledUnbind();
+        // TODO(b/117779333): fix generics below
+        @SuppressWarnings({"unchecked", "rawtypes"})
+        final MyAsyncPendingRequest<S, I> asyncRequest = new MyAsyncPendingRequest(this, request);
+        mHandler.sendMessage(
+                obtainMessage(AbstractRemoteService::handlePendingRequest, this, asyncRequest));
+    }
+
+    private void cancelScheduledUnbind() {
         mHandler.removeMessages(MSG_UNBIND);
     }
 
@@ -244,7 +271,7 @@
      * Handles a request, either processing it right now when bound, or saving it to be handled when
      * bound.
      */
-    protected final void handlePendingRequest(@NonNull PendingRequest<S> pendingRequest) {
+    protected final void handlePendingRequest(@NonNull PendingRequest<S, I> pendingRequest) {
         if (checkIfDestroyed() || mCompleted) return;
 
         if (!handleIsBound()) {
@@ -263,10 +290,10 @@
     /**
      * Defines what to do with a request that arrives while not bound to the service.
      */
-    abstract void handlePendingRequestWhileUnBound(@NonNull PendingRequest<S> pendingRequest);
+    abstract void handlePendingRequestWhileUnBound(@NonNull PendingRequest<S, I> pendingRequest);
 
     private boolean handleIsBound() {
-        return mServiceInterface != null;
+        return mService != null;
     }
 
     private void handleEnsureBound() {
@@ -300,9 +327,9 @@
         mBinding = false;
         if (handleIsBound()) {
             handleOnConnectedStateChangedInternal(false);
-            if (mServiceInterface != null) {
-                mServiceInterface.asBinder().unlinkToDeath(this, 0);
-                mServiceInterface = null;
+            if (mService != null) {
+                mService.asBinder().unlinkToDeath(this, 0);
+                mService = null;
             }
         }
         mContext.unbindService(mServiceConnection);
@@ -318,7 +345,7 @@
                 return;
             }
             mBinding = false;
-            mServiceInterface = getServiceInterface(service);
+            mService = getServiceInterface(service);
             try {
                 service.linkToDeath(AbstractRemoteService.this, 0);
             } catch (RemoteException re) {
@@ -332,7 +359,7 @@
         @Override
         public void onServiceDisconnected(ComponentName name) {
             mBinding = true;
-            mServiceInterface = null;
+            mService = null;
         }
     }
 
@@ -349,10 +376,15 @@
     /**
      * Base class for the requests serviced by the remote service.
      *
+     * <p><b>NOTE: </b> this class is typically used when the service needs to use a callback to
+     * communicate back with the system server. For cases where that's not needed, you should use
+     * {@link AbstractRemoteService#scheduleAsyncRequest(AsyncRequest)} instead.
+     *
      * @param <S> the remote service class
+     * @param <I> the interface of the binder service
      */
-    public abstract static class PendingRequest<S extends AbstractRemoteService<S>>
-            implements Runnable {
+    public abstract static class PendingRequest<S extends AbstractRemoteService<S, I>,
+            I extends IInterface> implements Runnable {
         protected final String mTag = getClass().getSimpleName();
         protected final Object mLock = new Object();
 
@@ -366,7 +398,7 @@
         @GuardedBy("mLock")
         private boolean mCompleted;
 
-        protected PendingRequest(S service) {
+        protected PendingRequest(@NonNull S service) {
             mWeakService = new WeakReference<>(service);
             mServiceHandler = service.mHandler;
             mTimeoutTrigger = () -> {
@@ -452,4 +484,50 @@
             return false;
         }
     }
+
+    /**
+     * Represents a request that does not expect a callback from the remote service.
+     *
+     * @param <I> the interface of the binder service
+     */
+    public interface AsyncRequest<I extends IInterface> {
+
+        /**
+         * Run Forrest, run!
+         */
+        void run(@NonNull I binder) throws RemoteException;
+    }
+
+    private static final class MyAsyncPendingRequest<S extends AbstractRemoteService<S, I>,
+            I extends IInterface> extends PendingRequest<S, I> {
+        private static final String TAG = MyAsyncPendingRequest.class.getSimpleName();
+
+        private final AsyncRequest<I> mRequest;
+
+        protected MyAsyncPendingRequest(@NonNull S service, @NonNull AsyncRequest<I> request) {
+            super(service);
+
+            mRequest = request;
+        }
+
+        @Override
+        public void run() {
+            final S remoteService = getService();
+            if (remoteService == null) return;
+            try {
+                mRequest.run(remoteService.mService);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "exception handling async request (" + this + "): " + e);
+            } finally {
+                finish();
+            }
+        }
+
+        @Override
+        protected void onTimeout(S remoteService) {
+            // TODO(b/117779333): should not happen because we called finish() on run(), although
+            // currently it might be called if the service is destroyed while showing it.
+            Slog.w(TAG, "AsyncPending requested timed out");
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/infra/AbstractSinglePendingRequestRemoteService.java b/services/core/java/com/android/server/infra/AbstractSinglePendingRequestRemoteService.java
index 37a1f54..d32f13b 100644
--- a/services/core/java/com/android/server/infra/AbstractSinglePendingRequestRemoteService.java
+++ b/services/core/java/com/android/server/infra/AbstractSinglePendingRequestRemoteService.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.content.ComponentName;
 import android.content.Context;
+import android.os.IInterface;
 import android.util.Slog;
 
 import java.io.PrintWriter;
@@ -29,17 +30,19 @@
  * <p>If another request is received while not bound, the previous one will be canceled.
  *
  * @param <S> the concrete remote service class
+ * @param <I> the interface of the binder service
  *
  * @hide
  */
-public abstract class AbstractSinglePendingRequestRemoteService<
-        S extends AbstractSinglePendingRequestRemoteService<S>> extends AbstractRemoteService<S> {
+public abstract class AbstractSinglePendingRequestRemoteService<S
+        extends AbstractSinglePendingRequestRemoteService<S, I>, I extends IInterface>
+        extends AbstractRemoteService<S, I> {
 
-    protected PendingRequest<S> mPendingRequest;
+    protected PendingRequest<S, I> mPendingRequest;
 
     public AbstractSinglePendingRequestRemoteService(@NonNull Context context,
             @NonNull String serviceInterface, @NonNull ComponentName componentName, int userId,
-            @NonNull VultureCallback callback, boolean bindInstantServiceAllowed,
+            @NonNull VultureCallback<S> callback, boolean bindInstantServiceAllowed,
             boolean verbose) {
         super(context, serviceInterface, componentName, userId, callback, bindInstantServiceAllowed,
                 verbose);
@@ -48,7 +51,7 @@
     @Override // from AbstractRemoteService
     void handlePendingRequests() {
         if (mPendingRequest != null) {
-            final PendingRequest<S> pendingRequest = mPendingRequest;
+            final PendingRequest<S, I> pendingRequest = mPendingRequest;
             mPendingRequest = null;
             handlePendingRequest(pendingRequest);
         }
@@ -70,7 +73,7 @@
     }
 
     @Override // from AbstractRemoteService
-    void handlePendingRequestWhileUnBound(@NonNull PendingRequest<S> pendingRequest) {
+    void handlePendingRequestWhileUnBound(@NonNull PendingRequest<S, I> pendingRequest) {
         if (mPendingRequest != null) {
             if (mVerbose) {
                 Slog.v(mTag, "handlePendingRequestWhileUnBound(): cancelling " + mPendingRequest
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index f19ecf3..fc364c0 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -207,6 +207,7 @@
 import com.android.internal.util.XmlUtils;
 import com.android.server.DeviceIdleController;
 import com.android.server.EventLogTags;
+import com.android.server.IoThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.lights.Light;
@@ -265,7 +266,7 @@
 
     // message codes
     static final int MESSAGE_DURATION_REACHED = 2;
-    static final int MESSAGE_SAVE_POLICY_FILE = 3;
+    // 3: removed to a different handler
     static final int MESSAGE_SEND_RANKING_UPDATE = 4;
     static final int MESSAGE_LISTENER_HINTS_CHANGED = 5;
     static final int MESSAGE_LISTENER_NOTIFICATION_FILTER_CHANGED = 6;
@@ -573,7 +574,7 @@
             mListeners.migrateToXml();
             mAssistants.migrateToXml();
             mConditionProviders.migrateToXml();
-            savePolicyFile();
+            handleSavePolicyFile();
         }
 
         mAssistants.ensureAssistant();
@@ -603,34 +604,29 @@
         }
     }
 
-    /**
-     * Saves notification policy
-     */
-    public void savePolicyFile() {
-        mHandler.removeMessages(MESSAGE_SAVE_POLICY_FILE);
-        mHandler.sendEmptyMessage(MESSAGE_SAVE_POLICY_FILE);
-    }
+    @VisibleForTesting
+    protected void handleSavePolicyFile() {
+        IoThread.getHandler().post(() -> {
+            if (DBG) Slog.d(TAG, "handleSavePolicyFile");
+            synchronized (mPolicyFile) {
+                final FileOutputStream stream;
+                try {
+                    stream = mPolicyFile.startWrite();
+                } catch (IOException e) {
+                    Slog.w(TAG, "Failed to save policy file", e);
+                    return;
+                }
 
-    private void handleSavePolicyFile() {
-        if (DBG) Slog.d(TAG, "handleSavePolicyFile");
-        synchronized (mPolicyFile) {
-            final FileOutputStream stream;
-            try {
-                stream = mPolicyFile.startWrite();
-            } catch (IOException e) {
-                Slog.w(TAG, "Failed to save policy file", e);
-                return;
+                try {
+                    writePolicyXml(stream, false /*forBackup*/);
+                    mPolicyFile.finishWrite(stream);
+                } catch (IOException e) {
+                    Slog.w(TAG, "Failed to save policy file, restoring backup", e);
+                    mPolicyFile.failWrite(stream);
+                }
             }
-
-            try {
-                writePolicyXml(stream, false /*forBackup*/);
-                mPolicyFile.finishWrite(stream);
-            } catch (IOException e) {
-                Slog.w(TAG, "Failed to save policy file, restoring backup", e);
-                mPolicyFile.failWrite(stream);
-            }
-        }
-        BackupManager.dataChanged(getContext().getPackageName());
+            BackupManager.dataChanged(getContext().getPackageName());
+        });
     }
 
     private void writePolicyXml(OutputStream stream, boolean forBackup) throws IOException {
@@ -1138,8 +1134,9 @@
 
                     }
                 }
+
                 mHandler.scheduleOnPackageChanged(removingPackage, changeUserId, pkgList, uidList);
-                savePolicyFile();
+                handleSavePolicyFile();
             }
         }
     };
@@ -1206,7 +1203,7 @@
                 mListeners.onUserRemoved(userId);
                 mConditionProviders.onUserRemoved(userId);
                 mAssistants.onUserRemoved(userId);
-                savePolicyFile();
+                handleSavePolicyFile();
             } else if (action.equals(Intent.ACTION_USER_UNLOCKED)) {
                 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
                 mUserProfiles.updateCache(context);
@@ -1462,7 +1459,7 @@
         mZenModeHelper.addCallback(new ZenModeHelper.Callback() {
             @Override
             public void onConfigChanged() {
-                savePolicyFile();
+                handleSavePolicyFile();
             }
 
             @Override
@@ -1764,7 +1761,7 @@
                     modifiedChannel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);
         }
 
-        savePolicyFile();
+        handleSavePolicyFile();
     }
 
     private void maybeNotifyChannelOwner(String pkg, int uid, NotificationChannel preUpdate,
@@ -2232,7 +2229,7 @@
                 Slog.w(TAG, "Can't notify app about app block change", e);
             }
 
-            savePolicyFile();
+            handleSavePolicyFile();
         }
 
         /**
@@ -2289,7 +2286,7 @@
         public void setShowBadge(String pkg, int uid, boolean showBadge) {
             checkCallerIsSystem();
             mPreferencesHelper.setShowBadge(pkg, uid, showBadge);
-            savePolicyFile();
+            handleSavePolicyFile();
         }
 
         @Override
@@ -2305,7 +2302,7 @@
                 if (info != null) {
                     mPreferencesHelper.setNotificationDelegate(
                             callingPkg, callingUid, delegate, info.uid);
-                    savePolicyFile();
+                    handleSavePolicyFile();
                 }
             } catch (RemoteException e) {
                 // :(
@@ -2316,7 +2313,7 @@
         public void revokeNotificationDelegate(String callingPkg) {
             checkCallerIsSameApp(callingPkg);
             mPreferencesHelper.revokeNotificationDelegate(callingPkg, Binder.getCallingUid());
-            savePolicyFile();
+            handleSavePolicyFile();
         }
 
         @Override
@@ -2351,7 +2348,7 @@
                 NotificationChannelGroup group) throws RemoteException {
             enforceSystemOrSystemUI("Caller not system or systemui");
             createNotificationChannelGroup(pkg, uid, group, false, false);
-            savePolicyFile();
+            handleSavePolicyFile();
         }
 
         @Override
@@ -2364,7 +2361,7 @@
                 final NotificationChannelGroup group = groups.get(i);
                 createNotificationChannelGroup(pkg, Binder.getCallingUid(), group, true, false);
             }
-            savePolicyFile();
+            handleSavePolicyFile();
         }
 
         private void createNotificationChannelsImpl(String pkg, int uid,
@@ -2382,7 +2379,7 @@
                         mPreferencesHelper.getNotificationChannel(pkg, uid, channel.getId(), false),
                         NOTIFICATION_CHANNEL_OR_GROUP_ADDED);
             }
-            savePolicyFile();
+            handleSavePolicyFile();
         }
 
         @Override
@@ -2427,7 +2424,7 @@
                     UserHandle.getUserHandleForUid(callingUid),
                     mPreferencesHelper.getNotificationChannel(pkg, callingUid, channelId, true),
                     NOTIFICATION_CHANNEL_OR_GROUP_DELETED);
-            savePolicyFile();
+            handleSavePolicyFile();
         }
 
         @Override
@@ -2469,7 +2466,7 @@
                 mListeners.notifyNotificationChannelGroupChanged(
                         pkg, UserHandle.getUserHandleForUid(callingUid), groupToDelete,
                         NOTIFICATION_CHANNEL_OR_GROUP_DELETED);
-                savePolicyFile();
+                handleSavePolicyFile();
             }
         }
 
@@ -2602,7 +2599,7 @@
                         true, UserHandle.getCallingUserId(), packages, uids);
             }
 
-            savePolicyFile();
+            handleSavePolicyFile();
         }
 
 
@@ -3390,7 +3387,7 @@
                 final ByteArrayInputStream bais = new ByteArrayInputStream(payload);
                 try {
                     readPolicyXml(bais, true /*forRestore*/);
-                    savePolicyFile();
+                    handleSavePolicyFile();
                 } catch (NumberFormatException | XmlPullParserException | IOException e) {
                     Slog.w(TAG, "applyRestore: error reading payload", e);
                 }
@@ -3431,7 +3428,7 @@
                                     .setPackage(pkg)
                                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
                             UserHandle.of(userId), null);
-                    savePolicyFile();
+                    handleSavePolicyFile();
                 }
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -3575,7 +3572,7 @@
                                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
                             UserHandle.of(userId), null);
 
-                    savePolicyFile();
+                    handleSavePolicyFile();
                 }
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -3601,7 +3598,7 @@
                                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
                             UserHandle.of(userId), null);
 
-                    savePolicyFile();
+                    handleSavePolicyFile();
                 }
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -3624,12 +3621,19 @@
                                 && mAssistants.isSameUser(token, r.getUserId())) {
                             applyAdjustment(r, adjustment);
                             r.applyAdjustments();
+                            // importance is checked at the beginning of the
+                            // PostNotificationRunnable, before the signal extractors are run, so
+                            // calculate the final importance here
+                            r.calculateImportance();
                             foundEnqueued = true;
                             break;
                         }
                     }
                     if (!foundEnqueued) {
                         // adjustment arrived too late to apply to enqueued; apply to posted
+                        // However, since the notification is now posted and may have alerted,
+                        // ignore any importance related adjustments
+                        adjustment.getSignals().remove(Adjustment.KEY_IMPORTANCE);
                         applyAdjustmentFromAssistant(token, adjustment);
                     }
                 }
@@ -3659,8 +3663,12 @@
                         NotificationRecord r = mNotificationsByKey.get(adjustment.getKey());
                         if (r != null && mAssistants.isSameUser(token, r.getUserId())) {
                             applyAdjustment(r, adjustment);
-                            r.applyImportanceFromAdjustments();
-                            if (r.getImportance() == IMPORTANCE_NONE) {
+                            // If the assistant has blocked the notification, cancel it
+                            // This will trigger a sort, so we don't have to explicitly ask for
+                            // one here.
+                            if (adjustment.getSignals().containsKey(Adjustment.KEY_IMPORTANCE)
+                                    && adjustment.getSignals().getInt(Adjustment.KEY_IMPORTANCE)
+                                    == IMPORTANCE_NONE) {
                                 cancelNotificationsFromListener(token, new String[]{r.getKey()});
                             } else {
                                 needsSort = true;
@@ -3684,7 +3692,7 @@
             verifyPrivilegedListener(token, user, false);
             createNotificationChannelGroup(
                     pkg, getUidForPackageAndUser(pkg, user), group, false, true);
-            savePolicyFile();
+            handleSavePolicyFile();
         }
 
         @Override
@@ -3733,7 +3741,7 @@
             }
             if (allow != mLockScreenAllowSecureNotifications) {
                 mLockScreenAllowSecureNotifications = allow;
-                savePolicyFile();
+                handleSavePolicyFile();
             }
         }
 
@@ -4492,7 +4500,7 @@
                 Slog.d(TAG, "Ignored enqueue for snoozed notification " + r.getKey());
             }
             mSnoozeHelper.update(userId, r);
-            savePolicyFile();
+            handleSavePolicyFile();
             return false;
         }
 
@@ -4623,7 +4631,7 @@
                 mSnoozeHelper.snooze(r, mDuration);
             }
             r.recordSnoozed();
-            savePolicyFile();
+            handleSavePolicyFile();
         }
     }
 
@@ -4701,7 +4709,7 @@
                     if (mReason != REASON_SNOOZED) {
                         final boolean wasSnoozed = mSnoozeHelper.cancel(mUserId, mPkg, mTag, mId);
                         if (wasSnoozed) {
-                            savePolicyFile();
+                            handleSavePolicyFile();
                         }
                     }
                 }
@@ -4761,7 +4769,6 @@
                             enqueueStatus);
                 }
 
-                mRankingHelper.extractSignals(r);
                 // tell the assistant service about the notification
                 if (mAssistants.isEnabled()) {
                     mAssistants.onNotificationEnqueuedLocked(r);
@@ -4845,7 +4852,7 @@
                                 | Notification.FLAG_NO_CLEAR;
                     }
 
-                    applyZenModeLocked(r);
+                    mRankingHelper.extractSignals(r);
                     mRankingHelper.sort(mNotificationList);
 
                     if (!r.isHidden()) {
@@ -5630,6 +5637,7 @@
             ArrayList<Integer> suppressVisuallyBefore = new ArrayList<>(N);
             ArrayList<ArrayList<Notification.Action>> systemSmartActionsBefore = new ArrayList<>(N);
             ArrayList<ArrayList<CharSequence>> smartRepliesBefore = new ArrayList<>(N);
+            int[] importancesBefore = new int[N];
             for (int i = 0; i < N; i++) {
                 final NotificationRecord r = mNotificationList.get(i);
                 orderBefore.add(r.getKey());
@@ -5643,6 +5651,7 @@
                 suppressVisuallyBefore.add(r.getSuppressedVisualEffects());
                 systemSmartActionsBefore.add(r.getSystemGeneratedSmartActions());
                 smartRepliesBefore.add(r.getSmartReplies());
+                importancesBefore[i] = r.getImportance();
                 mRankingHelper.extractSignals(r);
             }
             mRankingHelper.sort(mNotificationList);
@@ -5660,7 +5669,8 @@
                         r.getSuppressedVisualEffects())
                         || !Objects.equals(systemSmartActionsBefore.get(i),
                                 r.getSystemGeneratedSmartActions())
-                        || !Objects.equals(smartRepliesBefore.get(i), r.getSmartReplies())) {
+                        || !Objects.equals(smartRepliesBefore.get(i), r.getSmartReplies())
+                        || importancesBefore[i] != r.getImportance()) {
                     mHandler.scheduleSendRankingUpdate();
                     return;
                 }
@@ -5750,9 +5760,6 @@
                 case MESSAGE_FINISH_TOKEN_TIMEOUT:
                     handleKillTokenTimeout((ToastRecord) msg.obj);
                     break;
-                case MESSAGE_SAVE_POLICY_FILE:
-                    handleSavePolicyFile();
-                    break;
                 case MESSAGE_SEND_RANKING_UPDATE:
                     handleSendRankingUpdate();
                     break;
@@ -6270,7 +6277,7 @@
             Slog.d(TAG, String.format("unsnooze event(%s, %s)", key, listenerName));
         }
         mSnoozeHelper.repost(key);
-        savePolicyFile();
+        handleSavePolicyFile();
     }
 
     @GuardedBy("mNotificationLock")
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 1a9257c..50810cc 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -21,10 +21,8 @@
 import static android.app.NotificationManager.IMPORTANCE_LOW;
 import static android.app.NotificationManager.IMPORTANCE_MIN;
 import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
-import static android.service.notification.NotificationListenerService.Ranking
-        .USER_SENTIMENT_NEUTRAL;
-import static android.service.notification.NotificationListenerService.Ranking
-        .USER_SENTIMENT_POSITIVE;
+import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
+import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE;
 
 import android.annotation.Nullable;
 import android.app.ActivityManager;
@@ -609,6 +607,17 @@
                 mIsAppImportanceLocked, this.sbn.getNotification());
     }
 
+    public boolean hasAdjustment(String key) {
+        synchronized (mAdjustments) {
+            for (Adjustment adjustment : mAdjustments) {
+                if (adjustment.getSignals().containsKey(key)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     public void addAdjustment(Adjustment adjustment) {
         synchronized (mAdjustments) {
             mAdjustments.add(adjustment);
@@ -669,18 +678,6 @@
                             .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_SMART_REPLIES,
                                     getSmartReplies().size()));
                 }
-            }
-            applyImportanceFromAdjustments();
-        }
-    }
-
-    /**
-     * Update importance from the adjustment.
-     */
-    public void applyImportanceFromAdjustments() {
-        synchronized (mAdjustments) {
-            for (Adjustment adjustment : mAdjustments) {
-                Bundle signals = adjustment.getSignals();
                 if (signals.containsKey(Adjustment.KEY_IMPORTANCE)) {
                     int importance = signals.getInt(Adjustment.KEY_IMPORTANCE);
                     importance = Math.max(IMPORTANCE_UNSPECIFIED, importance);
@@ -752,6 +749,8 @@
      */
     public void setSystemImportance(int importance) {
         mSystemImportance = importance;
+        // System importance is only changed in enqueue, so it's ok for us to calculate the
+        // importance directly instead of waiting for signal extractor.
         calculateImportance();
     }
 
@@ -762,7 +761,16 @@
      */
     public void setAssistantImportance(int importance) {
         mAssistantImportance = importance;
-        calculateImportance();
+        // Unlike the system importance, the assistant importance can change on posted
+        // notifications, so don't calculateImportance() here, but wait for the signal extractors.
+    }
+
+    /**
+     * Returns the importance set by the assistant, or IMPORTANCE_UNSPECIFIED if the assistant
+     * hasn't set it.
+     */
+    public int getAssistantImportance() {
+        return mAssistantImportance;
     }
 
     /**
@@ -774,7 +782,8 @@
         if (getChannel().hasUserSetImportance()) {
             mImportanceExplanation = "user";
         }
-        if (!getChannel().hasUserSetImportance() && mAssistantImportance != IMPORTANCE_UNSPECIFIED) {
+        if (!getChannel().hasUserSetImportance()
+                && mAssistantImportance != IMPORTANCE_UNSPECIFIED) {
             mImportance = mAssistantImportance;
             mImportanceExplanation = "asst";
         }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index b36ac98..edab94c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -237,6 +237,7 @@
 import android.os.storage.StorageManagerInternal;
 import android.os.storage.VolumeInfo;
 import android.os.storage.VolumeRecord;
+import android.provider.MediaStore;
 import android.provider.Settings.Global;
 import android.provider.Settings.Secure;
 import android.security.KeyStore;
@@ -1297,6 +1298,7 @@
     final @Nullable String mStorageManagerPackage;
     final @Nullable String mSystemTextClassifierPackage;
     final @Nullable String mWellbeingPackage;
+    final @Nullable String mDocumenterPackage;
     final @NonNull String mServicesSystemSharedLibraryPackageName;
     final @NonNull String mSharedSystemSharedLibraryPackageName;
 
@@ -2780,6 +2782,7 @@
             mSystemTextClassifierPackage = getSystemTextClassifierPackageName();
 
             mWellbeingPackage = getWellbeingPackageName();
+            mDocumenterPackage = getDocumenterPackageName();
 
             // Now that we know all of the shared libraries, update all clients to have
             // the correct library paths.
@@ -17924,7 +17927,7 @@
                 final int removedUserId = (user != null) ? user.getIdentifier()
                         : UserHandle.USER_ALL;
 
-                clearPackageStateForUserLIF(ps, removedUserId, outInfo);
+                clearPackageStateForUserLIF(ps, removedUserId, outInfo, flags);
                 markPackageUninstalledForUserLPw(ps, user);
                 scheduleWritePackageRestrictionsLocked(user);
                 return;
@@ -17954,7 +17957,7 @@
                     // we need to do is clear this user's data and save that
                     // it is uninstalled.
                     if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
-                    clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo);
+                    clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo, flags);
                     scheduleWritePackageRestrictionsLocked(user);
                     return;
                 } else {
@@ -17970,7 +17973,7 @@
                 // we need to do is clear this user's data and save that
                 // it is uninstalled.
                 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
-                clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo);
+                clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo, flags);
                 scheduleWritePackageRestrictionsLocked(user);
                 return;
             }
@@ -18087,7 +18090,7 @@
     }
 
     private void clearPackageStateForUserLIF(PackageSetting ps, int userId,
-            PackageRemovedInfo outInfo) {
+            PackageRemovedInfo outInfo, int flags) {
         final PackageParser.Package pkg;
         synchronized (mPackages) {
             pkg = mPackages.get(ps.name);
@@ -18112,6 +18115,14 @@
                 }
                 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
             }
+            // Also delete contributed media, when requested
+            if ((flags & PackageManager.DELETE_CONTRIBUTED_MEDIA) != 0) {
+                try {
+                    MediaStore.deleteContributedMedia(mContext, ps.name, UserHandle.of(nextUserId));
+                } catch (IOException e) {
+                    Slog.w(TAG, "Failed to delete contributed media for " + ps.name, e);
+                }
+            }
         }
 
         if (outInfo != null) {
@@ -19558,6 +19569,22 @@
         return mContext.getString(R.string.config_defaultTextClassifierPackage);
     }
 
+    private @Nullable String getDocumenterPackageName() {
+        final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+
+        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
+                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
+                        | MATCH_DISABLED_COMPONENTS,
+                UserHandle.myUserId());
+        if (matches.size() == 1) {
+            return matches.get(0).getComponentInfo().packageName;
+        } else {
+            Slog.e(TAG, "There should probably be exactly one documenter; found "
+                    + matches.size() + ": matches=" + matches);
+            return null;
+        }
+    }
+
     @Override
     public String getWellbeingPackageName() {
         return mContext.getString(R.string.config_defaultWellbeingPackage);
@@ -22721,6 +22748,8 @@
                     return mRequiredPermissionControllerPackage;
                 case PackageManagerInternal.PACKAGE_WELLBEING:
                     return mWellbeingPackage;
+                case PackageManagerInternal.PACKAGE_DOCUMENTER:
+                    return mDocumenterPackage;
             }
             return null;
         }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index c18ca25..d1d5818 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -31,6 +31,7 @@
 import android.app.IStopUserCallback;
 import android.app.KeyguardManager;
 import android.app.PendingIntent;
+import android.app.admin.DevicePolicyEventLogger;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -73,6 +74,7 @@
 import android.os.storage.StorageManager;
 import android.security.GateKeeper;
 import android.service.gatekeeper.IGateKeeperService;
+import android.stats.devicepolicy.DevicePolicyEnums;
 import android.util.AtomicFile;
 import android.util.IntArray;
 import android.util.Log;
@@ -100,6 +102,8 @@
 import com.android.server.storage.DeviceStorageMonitorInternal;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
+import libcore.io.IoUtils;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
@@ -121,8 +125,6 @@
 import java.util.List;
 import java.util.Objects;
 
-import libcore.io.IoUtils;
-
 /**
  * Service for {@link UserManager}.
  *
@@ -173,6 +175,8 @@
     private static final String TAG_ENTRY = "entry";
     private static final String TAG_VALUE = "value";
     private static final String TAG_SEED_ACCOUNT_OPTIONS = "seedAccountOptions";
+    private static final String TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL =
+            "lastRequestQuietModeEnabledCall";
     private static final String ATTR_KEY = "key";
     private static final String ATTR_VALUE_TYPE = "type";
     private static final String ATTR_MULTIPLE = "m";
@@ -268,6 +272,16 @@
         /** Elapsed realtime since boot when the user was unlocked. */
         long unlockRealtime;
 
+        private long mLastRequestQuietModeEnabledMillis;
+
+        void setLastRequestQuietModeEnabledMillis(long millis) {
+            mLastRequestQuietModeEnabledMillis = millis;
+        }
+
+        long getLastRequestQuietModeEnabledMillis() {
+            return mLastRequestQuietModeEnabledMillis;
+        }
+
         void clearSeedAccountData() {
             seedAccountName = null;
             seedAccountType = null;
@@ -389,8 +403,8 @@
             final IntentSender target = intent.getParcelableExtra(Intent.EXTRA_INTENT);
             final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_ID, UserHandle.USER_NULL);
             // Call setQuietModeEnabled on bg thread to avoid ANR
-            BackgroundThread.getHandler()
-                    .post(() -> setQuietModeEnabled(userHandle, false, target));
+            BackgroundThread.getHandler().post(() ->
+                    setQuietModeEnabled(userHandle, false, target, /* callingPackage */ null));
         }
     };
 
@@ -834,21 +848,24 @@
         ensureCanModifyQuietMode(callingPackage, Binder.getCallingUid(), target != null);
         final long identity = Binder.clearCallingIdentity();
         try {
+            boolean result = false;
             if (enableQuietMode) {
-                setQuietModeEnabled(userHandle, true /* enableQuietMode */, target);
-                return true;
+                setQuietModeEnabled(
+                        userHandle, true /* enableQuietMode */, target, callingPackage);
+                result = true;
             } else {
                 boolean needToShowConfirmCredential =
                         mLockPatternUtils.isSecure(userHandle)
                                 && !StorageManager.isUserKeyUnlocked(userHandle);
                 if (needToShowConfirmCredential) {
                     showConfirmCredentialToDisableQuietMode(userHandle, target);
-                    return false;
                 } else {
-                    setQuietModeEnabled(userHandle, false /* enableQuietMode */, target);
-                    return true;
+                    setQuietModeEnabled(
+                            userHandle, false /* enableQuietMode */, target, callingPackage);
+                    result = true;
                 }
             }
+            return result;
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -894,8 +911,8 @@
                 + "default launcher nor has MANAGE_USERS/MODIFY_QUIET_MODE permission");
     }
 
-    private void setQuietModeEnabled(
-            int userHandle, boolean enableQuietMode, IntentSender target) {
+    private void setQuietModeEnabled(int userHandle, boolean enableQuietMode,
+            IntentSender target, @Nullable String callingPackage) {
         final UserInfo profile, parent;
         final UserData profileUserData;
         synchronized (mUsersLock) {
@@ -927,6 +944,7 @@
                 ActivityManager.getService().startUserInBackgroundWithListener(
                         userHandle, callback);
             }
+            logQuietModeEnabled(userHandle, enableQuietMode, callingPackage);
         } catch (RemoteException e) {
             // Should not happen, same process.
             e.rethrowAsRuntimeException();
@@ -935,6 +953,28 @@
                 enableQuietMode);
     }
 
+    private void logQuietModeEnabled(int userHandle, boolean enableQuietMode,
+            @Nullable String callingPackage) {
+        UserData userData;
+        synchronized (mUsersLock) {
+            userData = getUserDataLU(userHandle);
+        }
+        if (userData == null) {
+            return;
+        }
+        final long now = System.currentTimeMillis();
+        final long period = (userData.getLastRequestQuietModeEnabledMillis() != 0L
+                ? now - userData.getLastRequestQuietModeEnabledMillis()
+                : now - userData.info.creationTime);
+        DevicePolicyEventLogger
+                .createEvent(DevicePolicyEnums.REQUEST_QUIET_MODE_ENABLED)
+                .setStrings(callingPackage)
+                .setBoolean(enableQuietMode)
+                .setTimePeriod(period)
+                .write();
+        userData.setLastRequestQuietModeEnabledMillis(now);
+    }
+
     @Override
     public boolean isQuietModeEnabled(int userHandle) {
         synchronized (mPackagesLock) {
@@ -2314,6 +2354,12 @@
             serializer.endTag(null, TAG_SEED_ACCOUNT_OPTIONS);
         }
 
+        if (userData.getLastRequestQuietModeEnabledMillis() != 0L) {
+            serializer.startTag(/* namespace */ null, TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL);
+            serializer.text(String.valueOf(userData.getLastRequestQuietModeEnabledMillis()));
+            serializer.endTag(/* namespace */ null, TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL);
+        }
+
         serializer.endTag(null, TAG_USER);
 
         serializer.endDocument();
@@ -2408,6 +2454,7 @@
         String iconPath = null;
         long creationTime = 0L;
         long lastLoggedInTime = 0L;
+        long lastRequestQuietModeEnabledTimestamp = 0L;
         String lastLoggedInFingerprint = null;
         int profileGroupId = UserInfo.NO_PROFILE_GROUP_ID;
         int profileBadge = 0;
@@ -2494,6 +2541,11 @@
                 } else if (TAG_SEED_ACCOUNT_OPTIONS.equals(tag)) {
                     seedAccountOptions = PersistableBundle.restoreFromXml(parser);
                     persistSeedData = true;
+                } else if (TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL.equals(tag)) {
+                    type = parser.next();
+                    if (type == XmlPullParser.TEXT) {
+                        lastRequestQuietModeEnabledTimestamp = Long.parseLong(parser.getText());
+                    }
                 }
             }
         }
@@ -2518,6 +2570,7 @@
         userData.seedAccountType = seedAccountType;
         userData.persistSeedData = persistSeedData;
         userData.seedAccountOptions = seedAccountOptions;
+        userData.setLastRequestQuietModeEnabledMillis(lastRequestQuietModeEnabledTimestamp);
 
         synchronized (mRestrictionsLock) {
             if (baseRestrictions != null) {
diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java
index 996f42b..3a49412 100644
--- a/services/core/java/com/android/server/pm/permission/BasePermission.java
+++ b/services/core/java/com/android/server/pm/permission/BasePermission.java
@@ -191,7 +191,8 @@
     }
 
     public boolean isRemoved() {
-        return perm.info != null && (perm.info.flags & PermissionInfo.FLAG_REMOVED) != 0;
+        return perm != null && perm.info != null
+                && (perm.info.flags & PermissionInfo.FLAG_REMOVED) != 0;
     }
 
     public boolean isSignature() {
@@ -243,6 +244,9 @@
     public boolean isWellbeing() {
         return (protectionLevel & PermissionInfo.PROTECTION_FLAG_WELLBEING) != 0;
     }
+    public boolean isDocumenter() {
+        return (protectionLevel & PermissionInfo.PROTECTION_FLAG_DOCUMENTER) != 0;
+    }
 
     public void transfer(@NonNull String origPackageName, @NonNull String newPackageName) {
         if (!origPackageName.equals(sourcePackageName)) {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index bc3c18d..31f5ce4 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1647,6 +1647,13 @@
                 // Special permission granted only to the OEM specified wellbeing app
                 allowed = true;
             }
+            if (!allowed && bp.isDocumenter()
+                    && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
+                            PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM))) {
+                // If this permission is to be granted to the documenter and
+                // this app is the documenter, then it gets the permission.
+                allowed = true;
+            }
         }
         return allowed;
     }
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 29d6237..565bb706 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -3221,6 +3221,20 @@
         mNativeWrapper.nativeSendPowerHint(hintId, data);
     }
 
+    @VisibleForTesting
+    boolean wasDeviceIdleForInternal(long ms) {
+        synchronized (mLock) {
+            return mLastUserActivityTime + ms < SystemClock.uptimeMillis();
+        }
+    }
+
+    @VisibleForTesting
+    void onUserActivity() {
+        synchronized (mLock) {
+            mLastUserActivityTime = SystemClock.uptimeMillis();
+        }
+    }
+
     /**
      * Low-level function turn the device off immediately, without trying
      * to be clean.  Most people should use {@link ShutdownThread} for a clean shutdown.
@@ -4874,5 +4888,10 @@
         public void powerHint(int hintId, int data) {
             powerHintInternal(hintId, data);
         }
+
+        @Override
+        public boolean wasDeviceIdleFor(long ms) {
+            return wasDeviceIdleForInternal(ms);
+        }
     }
 }
diff --git a/services/core/java/com/android/server/power/ThermalManagerService.java b/services/core/java/com/android/server/power/ThermalManagerService.java
index 2eea3a4..02689a9 100644
--- a/services/core/java/com/android/server/power/ThermalManagerService.java
+++ b/services/core/java/com/android/server/power/ThermalManagerService.java
@@ -453,14 +453,15 @@
             final long token = Binder.clearCallingIdentity();
             try {
                 synchronized (mLock) {
+                    pw.println("IsStatusOverride: " + mIsStatusOverride);
                     pw.println("ThermalEventListeners:");
                     mThermalEventListeners.dump(pw, "\t");
                     pw.println("ThermalStatusListeners:");
                     mThermalStatusListeners.dump(pw, "\t");
-                    pw.println("Thermal Status: " + Integer.toString(mStatus));
+                    pw.println("Thermal Status: " + mStatus);
                     pw.println("Cached temperatures:");
                     dumpTemperaturesLocked(pw, "\t", mTemperatureMap.values());
-                    pw.println("HAL Ready: " + Boolean.toString(mHalReady));
+                    pw.println("HAL Ready: " + mHalReady);
                     if (mHalReady) {
                         pw.println("HAL connection:");
                         mHalWrapper.dump(pw, "\t");
@@ -532,7 +533,7 @@
                     return -1;
                 }
                 if (!Temperature.isValidStatus(status)) {
-                    pw.println("Invalid status: " + Integer.toString(status));
+                    pw.println("Invalid status: " + status);
                     return -1;
                 }
                 synchronized (mLock) {
diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java
index 8711ddf..35013de 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleManagerService.java
@@ -22,8 +22,10 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
+import android.annotation.WorkerThread;
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
+import android.app.role.IOnRoleHoldersChangedListener;
 import android.app.role.IRoleManager;
 import android.app.role.IRoleManagerCallback;
 import android.app.role.RoleManager;
@@ -33,6 +35,9 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.Signature;
+import android.os.Handler;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.ShellCallback;
 import android.os.UserHandle;
@@ -53,6 +58,8 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.dump.DualDumpOutputStream;
+import com.android.internal.util.function.pooled.PooledLambda;
+import com.android.server.FgThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 
@@ -73,7 +80,7 @@
  *
  * @see RoleManager
  */
-public class RoleManagerService extends SystemService {
+public class RoleManagerService extends SystemService implements RoleUserState.Callback {
 
     private static final String LOG_TAG = RoleManagerService.class.getSimpleName();
 
@@ -100,6 +107,17 @@
     private final SparseArray<RemoteRoleControllerService> mControllerServices =
             new SparseArray<>();
 
+    /**
+     * Maps user id to its list of listeners.
+     */
+    @GuardedBy("mLock")
+    @NonNull
+    private final SparseArray<RemoteCallbackList<IOnRoleHoldersChangedListener>> mListeners =
+            new SparseArray<>();
+
+    @NonNull
+    private final Handler mListenerHandler = FgThread.getHandler();
+
     public RoleManagerService(@NonNull Context context) {
         super(context);
 
@@ -188,7 +206,7 @@
     }
 
     @Nullable
-    private String computeComponentStateHash(@UserIdInt int userId) {
+    private static String computeComponentStateHash(@UserIdInt int userId) {
         PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
         ByteArrayOutputStream out = new ByteArrayOutputStream();
 
@@ -223,7 +241,7 @@
         synchronized (mLock) {
             RoleUserState userState = mUserStates.get(userId);
             if (userState == null) {
-                userState = new RoleUserState(userId);
+                userState = new RoleUserState(userId, this);
                 mUserStates.put(userId, userState);
             }
             return userState;
@@ -242,17 +260,70 @@
         }
     }
 
+    @Nullable
+    private RemoteCallbackList<IOnRoleHoldersChangedListener> getListeners(@UserIdInt int userId) {
+        synchronized (mLock) {
+            return mListeners.get(userId);
+        }
+    }
+
+    @NonNull
+    private RemoteCallbackList<IOnRoleHoldersChangedListener> getOrCreateListeners(
+            @UserIdInt int userId) {
+        synchronized (mLock) {
+            RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = mListeners.get(userId);
+            if (listeners == null) {
+                listeners = new RemoteCallbackList<>();
+                mListeners.put(userId, listeners);
+            }
+            return listeners;
+        }
+    }
+
     private void onRemoveUser(@UserIdInt int userId) {
+        RemoteCallbackList<IOnRoleHoldersChangedListener> listeners;
         RoleUserState userState;
         synchronized (mLock) {
+            listeners = mListeners.removeReturnOld(userId);
             mControllerServices.remove(userId);
             userState = mUserStates.removeReturnOld(userId);
         }
+        if (listeners != null) {
+            listeners.kill();
+        }
         if (userState != null) {
             userState.destroy();
         }
     }
 
+    @Override
+    public void onRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId) {
+        mListenerHandler.sendMessage(PooledLambda.obtainMessage(
+                RoleManagerService::notifyRoleHoldersChanged, this, roleName, userId));
+    }
+
+    @WorkerThread
+    private void notifyRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId) {
+        RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = getListeners(userId);
+        if (listeners == null) {
+            return;
+        }
+
+        int broadcastCount = listeners.beginBroadcast();
+        try {
+            for (int i = 0; i < broadcastCount; i++) {
+                IOnRoleHoldersChangedListener listener = listeners.getBroadcastItem(i);
+                try {
+                    listener.onRoleHoldersChanged(roleName, userId);
+                } catch (RemoteException e) {
+                    Slog.e(LOG_TAG, "Error calling OnRoleHoldersChangedListener", e);
+                }
+            }
+        } finally {
+            listeners.finishBroadcast();
+        }
+    }
+
     private class Stub extends IRoleManager.Stub {
 
         @Override
@@ -357,6 +428,42 @@
         }
 
         @Override
+        public void addOnRoleHoldersChangedListenerAsUser(
+                @NonNull IOnRoleHoldersChangedListener listener, @UserIdInt int userId) {
+            Preconditions.checkNotNull(listener, "listener cannot be null");
+            if (!mUserManagerInternal.exists(userId)) {
+                Slog.e(LOG_TAG, "user " + userId + " does not exist");
+                return;
+            }
+            userId = handleIncomingUser(userId, "addOnRoleHoldersChangedListenerAsUser");
+            getContext().enforceCallingOrSelfPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS,
+                    "addOnRoleHoldersChangedListenerAsUser");
+
+            RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = getOrCreateListeners(
+                    userId);
+            listeners.register(listener);
+        }
+
+        @Override
+        public void removeOnRoleHoldersChangedListenerAsUser(
+                @NonNull IOnRoleHoldersChangedListener listener, @UserIdInt int userId) {
+            Preconditions.checkNotNull(listener, "listener cannot be null");
+            if (!mUserManagerInternal.exists(userId)) {
+                Slog.e(LOG_TAG, "user " + userId + " does not exist");
+                return;
+            }
+            userId = handleIncomingUser(userId, "removeOnRoleHoldersChangedListenerAsUser");
+            getContext().enforceCallingOrSelfPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS,
+                    "removeOnRoleHoldersChangedListenerAsUser");
+
+            RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = getListeners(userId);
+            if (listener == null) {
+                return;
+            }
+            listeners.unregister(listener);
+        }
+
+        @Override
         public void setRoleNamesFromController(@NonNull List<String> roleNames) {
             Preconditions.checkNotNull(roleNames, "roleNames cannot be null");
             getContext().enforceCallingOrSelfPermission(
diff --git a/services/core/java/com/android/server/role/RoleUserState.java b/services/core/java/com/android/server/role/RoleUserState.java
index ec614a4..d55e261 100644
--- a/services/core/java/com/android/server/role/RoleUserState.java
+++ b/services/core/java/com/android/server/role/RoleUserState.java
@@ -74,6 +74,9 @@
     private final int mUserId;
 
     @NonNull
+    private final Callback mCallback;
+
+    @NonNull
     private final Object mLock = new Object();
 
     @GuardedBy("mLock")
@@ -100,12 +103,14 @@
     private final Handler mWriteHandler = new Handler(BackgroundThread.getHandler().getLooper());
 
     /**
-     * Create a new instance of user state, and read its state from disk if previously persisted.
+     * Create a new user state, and read its state from disk if previously persisted.
      *
-     * @param userId the user id for the new user state
+     * @param userId the user id for this user state
+     * @param callback the callback for this user state
      */
-    public RoleUserState(@UserIdInt int userId) {
+    public RoleUserState(@UserIdInt int userId, @NonNull Callback callback) {
         mUserId = userId;
+        mCallback = callback;
 
         readFile();
     }
@@ -116,6 +121,7 @@
     public int getVersion() {
         synchronized (mLock) {
             throwIfDestroyedLocked();
+
             return mVersion;
         }
     }
@@ -128,6 +134,7 @@
     public void setVersion(int version) {
         synchronized (mLock) {
             throwIfDestroyedLocked();
+
             if (mVersion == version) {
                 return;
             }
@@ -156,6 +163,7 @@
     public void setPackagesHash(@Nullable String packagesHash) {
         synchronized (mLock) {
             throwIfDestroyedLocked();
+
             if (Objects.equals(mPackagesHash, packagesHash)) {
                 return;
             }
@@ -174,6 +182,7 @@
     public boolean isRoleAvailable(@NonNull String roleName) {
         synchronized (mLock) {
             throwIfDestroyedLocked();
+
             return mRoles.containsKey(roleName);
         }
     }
@@ -189,6 +198,7 @@
     public ArraySet<String> getRoleHolders(@NonNull String roleName) {
         synchronized (mLock) {
             throwIfDestroyedLocked();
+
             return new ArraySet<>(mRoles.get(roleName));
         }
     }
@@ -201,29 +211,34 @@
     public void setRoleNames(@NonNull List<String> roleNames) {
         synchronized (mLock) {
             throwIfDestroyedLocked();
+
             boolean changed = false;
+
             for (int i = mRoles.size() - 1; i >= 0; i--) {
                 String roleName = mRoles.keyAt(i);
+
                 if (!roleNames.contains(roleName)) {
                     ArraySet<String> packageNames = mRoles.valueAt(i);
                     if (!packageNames.isEmpty()) {
-                        Slog.e(LOG_TAG,
-                                "Holders of a removed role should have been cleaned up, role: "
-                                        + roleName + ", holders: " + packageNames);
+                        Slog.e(LOG_TAG, "Holders of a removed role should have been cleaned up,"
+                                + " role: " + roleName + ", holders: " + packageNames);
                     }
                     mRoles.removeAt(i);
                     changed = true;
                 }
             }
+
             int roleNamesSize = roleNames.size();
             for (int i = 0; i < roleNamesSize; i++) {
                 String roleName = roleNames.get(i);
+
                 if (!mRoles.containsKey(roleName)) {
                     mRoles.put(roleName, new ArraySet<>());
                     Slog.i(LOG_TAG, "Added new role: " + roleName);
                     changed = true;
                 }
             }
+
             if (changed) {
                 scheduleWriteFileLocked();
             }
@@ -241,20 +256,27 @@
      */
     @CheckResult
     public boolean addRoleHolder(@NonNull String roleName, @NonNull String packageName) {
+        boolean changed;
+
         synchronized (mLock) {
             throwIfDestroyedLocked();
+
             ArraySet<String> roleHolders = mRoles.get(roleName);
             if (roleHolders == null) {
                 Slog.e(LOG_TAG, "Cannot add role holder for unknown role, role: " + roleName
                         + ", package: " + packageName);
                 return false;
             }
-            boolean changed = roleHolders.add(packageName);
+            changed = roleHolders.add(packageName);
             if (changed) {
                 scheduleWriteFileLocked();
             }
-            return true;
         }
+
+        if (changed) {
+            mCallback.onRoleHoldersChanged(roleName, mUserId);
+        }
+        return true;
     }
 
     /**
@@ -268,20 +290,28 @@
      */
     @CheckResult
     public boolean removeRoleHolder(@NonNull String roleName, @NonNull String packageName) {
+        boolean changed;
+
         synchronized (mLock) {
             throwIfDestroyedLocked();
+
             ArraySet<String> roleHolders = mRoles.get(roleName);
             if (roleHolders == null) {
                 Slog.e(LOG_TAG, "Cannot remove role holder for unknown role, role: " + roleName
                         + ", package: " + packageName);
                 return false;
             }
-            boolean changed = roleHolders.remove(packageName);
+
+            changed = roleHolders.remove(packageName);
             if (changed) {
                 scheduleWriteFileLocked();
             }
-            return true;
         }
+
+        if (changed) {
+            mCallback.onRoleHoldersChanged(roleName, mUserId);
+        }
+        return true;
     }
 
     /**
@@ -520,8 +550,8 @@
     }
 
     /**
-     * Destroy this state and delete the corresponding file. Any pending writes to the file will be
-     * cancelled and any future interaction with this state will throw an exception.
+     * Destroy this user state and delete the corresponding file. Any pending writes to the file
+     * will be cancelled, and any future interaction with this state will throw an exception.
      */
     public void destroy() {
         synchronized (mLock) {
@@ -542,4 +572,18 @@
     private static @NonNull File getFile(@UserIdInt int userId) {
         return new File(Environment.getUserSystemDirectory(userId), ROLES_FILE_NAME);
     }
+
+    /**
+     * Callback for a user state.
+     */
+    public interface Callback {
+
+        /**
+         * Called when the holders of roles are changed.
+         *
+         * @param roleName the name of the role whose holders are changed
+         * @param userId the user id for this role holder change
+         */
+        void onRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId);
+    }
 }
diff --git a/services/core/java/com/android/server/signedconfig/SignedConfig.java b/services/core/java/com/android/server/signedconfig/SignedConfig.java
index a3f452c..e6bb800 100644
--- a/services/core/java/com/android/server/signedconfig/SignedConfig.java
+++ b/services/core/java/com/android/server/signedconfig/SignedConfig.java
@@ -48,7 +48,7 @@
     private static final String CONFIG_KEY_VALUE = "value";
 
     /**
-     * Represents config values targetting to an SDK range.
+     * Represents config values targeting an SDK range.
      */
     public static class PerSdkConfig {
         public final int minSdk;
@@ -90,11 +90,24 @@
     /**
      * Parse configuration from an APK.
      *
-     * @param config config as read from the APK metadata.
+     * @param config Config string as read from the APK metadata.
+     * @param allowedKeys Set of allowed keys in the config. Any key/value mapping for a key not in
+     *                    this set will result in an {@link InvalidConfigException} being thrown.
+     * @param keyValueMappers Mappings for values per key. The keys in the top level map should be
+     *                        a subset of {@code allowedKeys}. The keys in the inner map indicate
+     *                        the set of allowed values for that keys value. This map will be
+     *                        applied to the value in the configuration. This is intended to allow
+     *                        enum-like values to be encoded as strings in the configuration, and
+     *                        mapped back to integers when the configuration is parsed.
+     *
+     *                        <p>Any config key with a value that does not appear in the
+     *                        corresponding map will result in an {@link InvalidConfigException}
+     *                        being thrown.
      * @return Parsed configuration.
      * @throws InvalidConfigException If there's a problem parsing the config.
      */
-    public static SignedConfig parse(String config, Set<String> allowedKeys)
+    public static SignedConfig parse(String config, Set<String> allowedKeys,
+            Map<String, Map<String, String>> keyValueMappers)
             throws InvalidConfigException {
         try {
             JSONObject json = new JSONObject(config);
@@ -103,7 +116,8 @@
             JSONArray perSdkConfig = json.getJSONArray(KEY_CONFIG);
             List<PerSdkConfig> parsedConfigs = new ArrayList<>();
             for (int i = 0; i < perSdkConfig.length(); ++i) {
-                parsedConfigs.add(parsePerSdkConfig(perSdkConfig.getJSONObject(i), allowedKeys));
+                parsedConfigs.add(parsePerSdkConfig(perSdkConfig.getJSONObject(i), allowedKeys,
+                        keyValueMappers));
             }
 
             return new SignedConfig(version, parsedConfigs);
@@ -113,8 +127,17 @@
 
     }
 
+    private static CharSequence quoted(Object s) {
+        if (s == null) {
+            return "null";
+        } else {
+            return "\"" + s + "\"";
+        }
+    }
+
     @VisibleForTesting
-    static PerSdkConfig parsePerSdkConfig(JSONObject json, Set<String> allowedKeys)
+    static PerSdkConfig parsePerSdkConfig(JSONObject json, Set<String> allowedKeys,
+            Map<String, Map<String, String>> keyValueMappers)
             throws JSONException, InvalidConfigException {
         int minSdk = json.getInt(CONFIG_KEY_MIN_SDK);
         int maxSdk = json.getInt(CONFIG_KEY_MAX_SDK);
@@ -123,12 +146,23 @@
         for (int i = 0; i < valueArray.length(); ++i) {
             JSONObject keyValuePair = valueArray.getJSONObject(i);
             String key = keyValuePair.getString(CONFIG_KEY_KEY);
-            String value = keyValuePair.has(CONFIG_KEY_VALUE)
-                    ? keyValuePair.getString(CONFIG_KEY_VALUE)
+            Object valueObject = keyValuePair.has(CONFIG_KEY_VALUE)
+                    ? keyValuePair.get(CONFIG_KEY_VALUE)
                     : null;
+            String value = valueObject == JSONObject.NULL || valueObject == null
+                            ? null
+                            : valueObject.toString();
             if (!allowedKeys.contains(key)) {
                 throw new InvalidConfigException("Config key " + key + " is not allowed");
             }
+            if (keyValueMappers.containsKey(key)) {
+                Map<String, String> mapper = keyValueMappers.get(key);
+                if (!mapper.containsKey(value)) {
+                    throw new InvalidConfigException(
+                            "Config key " + key + " contains unsupported value " + quoted(value));
+                }
+                value = mapper.get(value);
+            }
             values.put(key, value);
         }
         return new PerSdkConfig(minSdk, maxSdk, values);
diff --git a/services/core/java/com/android/server/signedconfig/SignedConfigApplicator.java b/services/core/java/com/android/server/signedconfig/SignedConfigApplicator.java
index 2312f5f..e4d799a 100644
--- a/services/core/java/com/android/server/signedconfig/SignedConfigApplicator.java
+++ b/services/core/java/com/android/server/signedconfig/SignedConfigApplicator.java
@@ -17,8 +17,10 @@
 package com.android.server.signedconfig;
 
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
 import android.os.Build;
 import android.provider.Settings;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Slog;
 
@@ -37,6 +39,30 @@
                     Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS
             )));
 
+    private static final Map<String, String> HIDDEN_API_POLICY_KEY_MAP = makeMap(
+            "DEFAULT", String.valueOf(ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT),
+            "DISABLED", String.valueOf(ApplicationInfo.HIDDEN_API_ENFORCEMENT_DISABLED),
+            "JUST_WARN", String.valueOf(ApplicationInfo.HIDDEN_API_ENFORCEMENT_JUST_WARN),
+            "ENABLED", String.valueOf(ApplicationInfo.HIDDEN_API_ENFORCEMENT_ENABLED)
+    );
+
+    private static final Map<String, Map<String, String>> KEY_VALUE_MAPPERS = makeMap(
+            Settings.Global.HIDDEN_API_POLICY, HIDDEN_API_POLICY_KEY_MAP
+    );
+
+    private static <K, V> Map<K, V> makeMap(Object... keyValuePairs) {
+        if (keyValuePairs.length % 2 != 0) {
+            throw new IllegalArgumentException();
+        }
+        final int len = keyValuePairs.length / 2;
+        ArrayMap<K, V> m = new ArrayMap<>(len);
+        for (int i = 0; i < len;  ++i) {
+            m.put((K) keyValuePairs[i * 2], (V) keyValuePairs[(i * 2) + 1]);
+        }
+        return Collections.unmodifiableMap(m);
+
+    }
+
     private final Context mContext;
     private final String mSourcePackage;
 
@@ -75,7 +101,7 @@
         }
         SignedConfig config;
         try {
-            config = SignedConfig.parse(configStr, ALLOWED_KEYS);
+            config = SignedConfig.parse(configStr, ALLOWED_KEYS, KEY_VALUE_MAPPERS);
         } catch (InvalidConfigException e) {
             Slog.e(TAG, "Failed to parse config from package " + mSourcePackage, e);
             return;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
index c44f306..240b820 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
@@ -126,4 +126,14 @@
     public List<String> getCrossProfileCalendarPackagesForUser(int userHandle) {
         return Collections.emptyList();
     }
+
+    @Override
+    public boolean isManagedKiosk() {
+        return false;
+    }
+
+    @Override
+    public boolean isUnattendedManagedKiosk() {
+        return false;
+    }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index bfbaac9..bc550dc 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -448,6 +448,12 @@
     private static final long MINIMUM_STRONG_AUTH_TIMEOUT_MS = TimeUnit.HOURS.toMillis(1);
 
     /**
+     * The amount of ms that a managed kiosk must go without user interaction to be considered
+     * unattended.
+     */
+    private static final int UNATTENDED_MANAGED_KIOSK_MS = 30000;
+
+    /**
      * Strings logged with {@link
      * com.android.internal.logging.nano.MetricsProto.MetricsEvent#PROVISIONING_ENTRY_POINT_ADB}.
      */
@@ -5140,7 +5146,7 @@
             mInjector.binderRestoreCallingIdentity(ident);
         }
 
-        mInjector.getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin(
+        getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin(
                 UserHandle.USER_SYSTEM, timeMs);
     }
 
@@ -5159,7 +5165,7 @@
         }
         policy.mLastMaximumTimeToLock = timeMs;
 
-        mInjector.getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin(
+        getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin(
                 userId, policy.mLastMaximumTimeToLock);
     }
 
@@ -13577,4 +13583,79 @@
         }
         return Collections.emptyList();
     }
+
+    @Override
+    public boolean isManagedKiosk() {
+        if (!mHasFeature) {
+            return false;
+        }
+        enforceManageUsers();
+        long id = mInjector.binderClearCallingIdentity();
+        try {
+            return isManagedKioskInternal();
+        } catch (RemoteException e) {
+            throw new IllegalStateException(e);
+        } finally {
+            mInjector.binderRestoreCallingIdentity(id);
+        }
+    }
+
+    @Override
+    public boolean isUnattendedManagedKiosk() {
+        if (!mHasFeature) {
+            return false;
+        }
+        enforceManageUsers();
+        long id = mInjector.binderClearCallingIdentity();
+        try {
+            return isManagedKioskInternal()
+                    && getPowerManagerInternal().wasDeviceIdleFor(UNATTENDED_MANAGED_KIOSK_MS);
+        } catch (RemoteException e) {
+            throw new IllegalStateException(e);
+        } finally {
+            mInjector.binderRestoreCallingIdentity(id);
+        }
+    }
+
+    /**
+     * Returns whether the device is currently being used as a publicly-accessible dedicated device.
+     * Assumes that feature checks and permission checks have already been performed, and that the
+     * calling identity has been cleared.
+     */
+    private boolean isManagedKioskInternal() throws RemoteException {
+        return mOwners.hasDeviceOwner()
+                && mInjector.getIActivityManager().getLockTaskModeState()
+                        == ActivityManager.LOCK_TASK_MODE_LOCKED
+                && !isLockTaskFeatureEnabled(DevicePolicyManager.LOCK_TASK_FEATURE_SYSTEM_INFO)
+                && !deviceHasKeyguard()
+                && !inEphemeralUserSession();
+    }
+
+    private boolean isLockTaskFeatureEnabled(int lockTaskFeature) throws RemoteException {
+        int lockTaskFeatures =
+                getUserData(mInjector.getIActivityManager().getCurrentUser().id).mLockTaskFeatures;
+        return (lockTaskFeatures & lockTaskFeature) == lockTaskFeature;
+    }
+
+    private boolean deviceHasKeyguard() {
+        for (UserInfo userInfo : mUserManager.getUsers()) {
+            if (mLockPatternUtils.isSecure(userInfo.id)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean inEphemeralUserSession() {
+        for (UserInfo userInfo : mUserManager.getUsers()) {
+            if (mInjector.getUserManager().isUserEphemeral(userInfo.id)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private PowerManagerInternal getPowerManagerInternal() {
+        return mInjector.getPowerManagerInternal();
+    }
 }
diff --git a/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java b/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java
index b01adc9..96ef0ce 100644
--- a/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java
+++ b/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java
@@ -22,7 +22,10 @@
 
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
+import static org.robolectric.Shadows.shadowOf;
+import static org.testng.Assert.expectThrows;
 
+import android.annotation.UserIdInt;
 import android.app.Application;
 import android.app.backup.IBackupManagerMonitor;
 import android.app.backup.IBackupObserver;
@@ -32,11 +35,14 @@
 import android.content.Intent;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
+import android.os.UserHandle;
 import android.platform.test.annotations.Presubmit;
 
 import com.android.server.backup.testing.BackupManagerServiceTestUtils;
 import com.android.server.backup.testing.TransportData;
+import com.android.server.testing.shadows.ShadowBinder;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -44,6 +50,8 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowContextWrapper;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -51,14 +59,19 @@
 
 /** Tests for the user-aware backup/restore system service {@link BackupManagerService}. */
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowBinder.class})
 @Presubmit
 public class BackupManagerServiceTest {
     private static final String TEST_PACKAGE = "package";
     private static final String TEST_TRANSPORT = "transport";
 
+    private static final int NON_USER_SYSTEM = UserHandle.USER_SYSTEM + 1;
+
+    private ShadowContextWrapper mShadowContext;
     @Mock private UserBackupManagerService mUserBackupManagerService;
     private BackupManagerService mBackupManagerService;
     private Context mContext;
+    @UserIdInt private int mUserId;
 
     /** Initialize {@link BackupManagerService}. */
     @Before
@@ -67,6 +80,8 @@
 
         Application application = RuntimeEnvironment.application;
         mContext = application;
+        mShadowContext = shadowOf(application);
+        mUserId = NON_USER_SYSTEM;
         mBackupManagerService =
                 new BackupManagerService(
                         application,
@@ -76,6 +91,15 @@
     }
 
     /**
+     * Clean up and reset state that was created for testing {@link BackupManagerService}
+     * operations.
+     */
+    @After
+    public void tearDown() throws Exception {
+        ShadowBinder.reset();
+    }
+
+    /**
      * Test verifying that {@link BackupManagerService#MORE_DEBUG} is set to {@code false}.
      * This is specifically to prevent overloading the logs in production.
      */
@@ -274,11 +298,41 @@
     // ---------------------------------------------
     // Settings tests
     // ---------------------------------------------
+    /**
+     * Test verifying that {@link BackupManagerService#setBackupEnabled(int, boolean)} throws a
+     * {@link SecurityException} if the caller does not have INTERACT_ACROSS_USERS_FULL permission.
+     */
+    @Test
+    public void setBackupEnabled_withoutPermission_throwsSecurityException() {
+        mShadowContext.denyPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+
+        expectThrows(
+                SecurityException.class,
+                () -> mBackupManagerService.setBackupEnabled(mUserId, true));
+    }
+
+    /**
+     * Test verifying that {@link BackupManagerService#setBackupEnabled(int, boolean)} does not
+     * require the caller to have INTERACT_ACROSS_USERS_FULL permission when the calling user id is
+     * the same as the target user id.
+     */
+    @Test
+    public void setBackupEnabled_whenCallingUserIsTargetUser_doesntNeedPermission() {
+        ShadowBinder.setCallingUserHandle(UserHandle.of(mUserId));
+        mShadowContext.denyPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+
+        mBackupManagerService.setBackupEnabled(mUserId, true);
+
+        verify(mUserBackupManagerService).setBackupEnabled(true);
+    }
+
 
     /** Test that the backup service routes methods correctly to the user that requests it. */
     @Test
     public void setBackupEnabled_callsSetBackupEnabledForUser() throws Exception {
-        mBackupManagerService.setBackupEnabled(true);
+        mShadowContext.grantPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+
+        mBackupManagerService.setBackupEnabled(mUserId, true);
 
         verify(mUserBackupManagerService).setBackupEnabled(true);
     }
@@ -299,10 +353,25 @@
         verify(mUserBackupManagerService).setBackupProvisioned(true);
     }
 
+    /**
+     * Test verifying that {@link BackupManagerService#isBackupEnabled(int)} throws a
+     * {@link SecurityException} if the caller does not have INTERACT_ACROSS_USERS_FULL permission.
+     */
+    @Test
+    public void testIsBackupEnabled_withoutPermission_throwsSecurityException() {
+        mShadowContext.denyPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+
+        expectThrows(
+                SecurityException.class,
+                () -> mBackupManagerService.isBackupEnabled(mUserId));
+    }
+
     /** Test that the backup service routes methods correctly to the user that requests it. */
     @Test
     public void testIsBackupEnabled_callsIsBackupEnabledForUser() throws Exception {
-        mBackupManagerService.isBackupEnabled();
+        mShadowContext.grantPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+
+        mBackupManagerService.isBackupEnabled(mUserId);
 
         verify(mUserBackupManagerService).isBackupEnabled();
     }
@@ -330,30 +399,81 @@
         verify(mUserBackupManagerService).filterAppsEligibleForBackup(packages);
     }
 
+    /**
+     * Test verifying that {@link BackupManagerService#backupNow(int)} throws a
+     * {@link SecurityException} if the caller does not have INTERACT_ACROSS_USERS_FULL permission.
+     */
+    @Test
+    public void testBackupNow_withoutPermission_throwsSecurityException() {
+        mShadowContext.denyPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+
+        expectThrows(
+                SecurityException.class,
+                () -> mBackupManagerService.backupNow(mUserId));
+    }
+
     /** Test that the backup service routes methods correctly to the user that requests it. */
     @Test
     public void testBackupNow_callsBackupNowForUser() throws Exception {
-        mBackupManagerService.backupNow();
+        mShadowContext.grantPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+
+        mBackupManagerService.backupNow(mUserId);
 
         verify(mUserBackupManagerService).backupNow();
     }
 
-    /** Test that the backup service routes methods correctly to the user that requests it. */
+    /**
+     * Test verifying that {@link BackupManagerService#requestBackup(int, String[], IBackupObserver,
+     * IBackupManagerMonitor, int)} throws a {@link SecurityException} if the caller does not have
+     * INTERACT_ACROSS_USERS_FULL permission.
+     */
     @Test
-    public void testRequestBackup_callsRequestBackupForUser() throws Exception {
+    public void testRequestBackup_withoutPermission_throwsSecurityException() {
+        mShadowContext.denyPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
         String[] packages = {TEST_PACKAGE};
         IBackupObserver observer = mock(IBackupObserver.class);
         IBackupManagerMonitor monitor = mock(IBackupManagerMonitor.class);
 
-        mBackupManagerService.requestBackup(packages, observer, monitor, /* flags */ 0);
+        expectThrows(
+                SecurityException.class,
+                () -> mBackupManagerService.requestBackup(mUserId, packages, observer, monitor, 0));
+    }
+
+
+    /** Test that the backup service routes methods correctly to the user that requests it. */
+    @Test
+    public void testRequestBackup_callsRequestBackupForUser() throws Exception {
+        mShadowContext.grantPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+        String[] packages = {TEST_PACKAGE};
+        IBackupObserver observer = mock(IBackupObserver.class);
+        IBackupManagerMonitor monitor = mock(IBackupManagerMonitor.class);
+
+        mBackupManagerService.requestBackup(mUserId, packages, observer, monitor,
+                /* flags */ 0);
 
         verify(mUserBackupManagerService).requestBackup(packages, observer, monitor, /* flags */ 0);
     }
 
+    /**
+     * Test verifying that {@link BackupManagerService#cancelBackups(int)} throws a
+     * {@link SecurityException} if the caller does not have INTERACT_ACROSS_USERS_FULL permission.
+     */
+    @Test
+    public void testCancelBackups_withoutPermission_throwsSecurityException() {
+        mShadowContext.denyPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+
+        expectThrows(
+                SecurityException.class,
+                () -> mBackupManagerService.cancelBackups(mUserId));
+    }
+
+
     /** Test that the backup service routes methods correctly to the user that requests it. */
     @Test
     public void testCancelBackups_callsCancelBackupsForUser() throws Exception {
-        mBackupManagerService.cancelBackups();
+        mShadowContext.grantPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+
+        mBackupManagerService.cancelBackups(mUserId);
 
         verify(mUserBackupManagerService).cancelBackups();
     }
diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowBinder.java b/services/robotests/src/com/android/server/testing/shadows/ShadowBinder.java
index 1ece49e..9de9f50 100644
--- a/services/robotests/src/com/android/server/testing/shadows/ShadowBinder.java
+++ b/services/robotests/src/com/android/server/testing/shadows/ShadowBinder.java
@@ -17,9 +17,11 @@
 package com.android.server.testing.shadows;
 
 import android.os.Binder;
+import android.os.UserHandle;
 
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
 
 /**
  * Extends {@link org.robolectric.shadows.ShadowBinder} with {@link Binder#clearCallingIdentity()}
@@ -30,6 +32,7 @@
 public class ShadowBinder extends org.robolectric.shadows.ShadowBinder {
     public static final Integer LOCAL_UID = 1000;
     private static Integer originalCallingUid;
+    private static UserHandle sCallingUserHandle;
 
     @Implementation
     protected static long clearCallingIdentity() {
@@ -42,4 +45,30 @@
     protected static void restoreCallingIdentity(long token) {
         setCallingUid(originalCallingUid);
     }
+
+    public static void setCallingUserHandle(UserHandle userHandle) {
+        sCallingUserHandle = userHandle;
+    }
+
+    /**
+     * Shadows {@link Binder#getCallingUserHandle()}. If {@link ShadowBinder#sCallingUserHandle}
+     * is set, return that; otherwise mimic the default implementation.
+     */
+    @Implementation
+    public static UserHandle getCallingUserHandle() {
+        if (sCallingUserHandle != null) {
+            return sCallingUserHandle;
+        } else {
+            return UserHandle.of(UserHandle.getUserId(getCallingUid()));
+        }
+    }
+
+    /**
+     * Clean up and reset state that was created for testing.
+     */
+    @Resetter
+    public static void reset() {
+        sCallingUserHandle = null;
+        org.robolectric.shadows.ShadowBinder.reset();
+    }
 }
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index d49e78a..d7b1cb4 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -88,7 +88,7 @@
         "utils/**/*.java",
     ],
     static_libs: [
-        "android-support-test",
+        "junit",
         "mockito-target-minus-junit4",
     ],
     libs: [
diff --git a/services/tests/servicestests/src/com/android/server/BinderCallsStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/BinderCallsStatsServiceTest.java
index f70efdf..f75617e 100644
--- a/services/tests/servicestests/src/com/android/server/BinderCallsStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/BinderCallsStatsServiceTest.java
@@ -18,7 +18,6 @@
 
 import static org.junit.Assert.assertEquals;
 
-import android.os.Binder;
 import android.os.Process;
 import android.platform.test.annotations.Presubmit;
 
@@ -26,9 +25,7 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.internal.os.BinderInternal;
-import com.android.internal.os.BinderInternal.CallSession;
-import com.android.server.BinderCallsStatsService.WorkSourceProvider;
+import com.android.server.BinderCallsStatsService.AuthorizedWorkSourceProvider;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -39,7 +36,7 @@
 public class BinderCallsStatsServiceTest {
     @Test
     public void weTrustOurselves() {
-        WorkSourceProvider workSourceProvider = new WorkSourceProvider() {
+        AuthorizedWorkSourceProvider workSourceProvider = new AuthorizedWorkSourceProvider() {
             protected int getCallingUid() {
                 return Process.myUid();
             }
@@ -55,7 +52,7 @@
 
     @Test
     public void workSourceSetIfCallerHasPermission() {
-        WorkSourceProvider workSourceProvider = new WorkSourceProvider() {
+        AuthorizedWorkSourceProvider workSourceProvider = new AuthorizedWorkSourceProvider() {
             protected int getCallingUid() {
                 // System process uid which as UPDATE_DEVICE_STATS.
                 return 1001;
@@ -72,7 +69,7 @@
 
     @Test
     public void workSourceResolvedToCallingUid() {
-        WorkSourceProvider workSourceProvider = new WorkSourceProvider() {
+        AuthorizedWorkSourceProvider workSourceProvider = new AuthorizedWorkSourceProvider() {
             protected int getCallingUid() {
                 // UID without permissions.
                 return Integer.MAX_VALUE;
@@ -86,40 +83,4 @@
 
         assertEquals(Integer.MAX_VALUE, workSourceProvider.resolveWorkSourceUid());
     }
-
-    @Test
-    public void workSourceSet() {
-        TestObserver observer = new TestObserver();
-        observer.callStarted(new Binder(), 0);
-        assertEquals(true, observer.workSourceSet);
-    }
-
-    static class TestObserver extends BinderCallsStatsService.BinderCallsObserver {
-        public boolean workSourceSet = false;
-
-        TestObserver() {
-            super(new NoopObserver(), new WorkSourceProvider());
-        }
-
-        @Override
-        protected void setThreadLocalWorkSourceUid(int uid) {
-            workSourceSet = true;
-        }
-    }
-
-
-    static class NoopObserver implements BinderInternal.Observer {
-        @Override
-        public CallSession callStarted(Binder binder, int code) {
-            return null;
-        }
-
-        @Override
-        public void callEnded(CallSession s, int parcelRequestSize, int parcelReplySize) {
-        }
-
-        @Override
-        public void callThrewException(CallSession s, Exception exception) {
-        }
-    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java b/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java
index fd010f1..751ed9b 100644
--- a/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java
@@ -29,6 +29,7 @@
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
+import android.annotation.UserIdInt;
 import android.app.backup.BackupManager;
 import android.app.backup.IBackupManagerMonitor;
 import android.app.backup.IBackupObserver;
@@ -86,8 +87,9 @@
             new ComponentName("package1", "class1"),
             new ComponentName("package2", "class2")
     };
-    private final int NON_USER_SYSTEM = UserHandle.USER_SYSTEM + 1;
+    private static final int NON_USER_SYSTEM = UserHandle.USER_SYSTEM + 1;
 
+    @UserIdInt private int mUserId;
     @Mock private BackupManagerService mBackupManagerServiceMock;
     @Mock private Context mContextMock;
     @Mock private File mSuppressFileMock;
@@ -110,11 +112,13 @@
 
         TrampolineTestable.sBackupManagerServiceMock = mBackupManagerServiceMock;
         TrampolineTestable.sSuppressFile = mSuppressFileMock;
+        TrampolineTestable.sCallingUserId = UserHandle.USER_SYSTEM;
         TrampolineTestable.sCallingUid = Process.SYSTEM_UID;
         TrampolineTestable.sBackupDisabled = false;
 
         when(mSuppressFileMock.getParentFile()).thenReturn(mSuppressFileParentMock);
 
+        mUserId = NON_USER_SYSTEM;
         mTrampoline = new TrampolineTestable(mContextMock);
 
         mContentResolver = new MockContentResolver();
@@ -361,10 +365,22 @@
     }
 
     @Test
-    public void setBackupEnabled_forwarded() throws RemoteException {
+    public void setBackupEnabledForUser_forwarded() throws RemoteException {
         mTrampoline.initializeService(UserHandle.USER_SYSTEM);
+
+        mTrampoline.setBackupEnabledForUser(mUserId, true);
+
+        verify(mBackupManagerServiceMock).setBackupEnabled(mUserId, true);
+    }
+
+    @Test
+    public void setBackupEnabled_forwardedToCallingUserId() throws RemoteException {
+        TrampolineTestable.sCallingUserId = mUserId;
+        mTrampoline.initializeService(UserHandle.USER_SYSTEM);
+
         mTrampoline.setBackupEnabled(true);
-        verify(mBackupManagerServiceMock).setBackupEnabled(true);
+
+        verify(mBackupManagerServiceMock).setBackupEnabled(mUserId, true);
     }
 
     @Test
@@ -400,10 +416,22 @@
     }
 
     @Test
-    public void isBackupEnabled_forwarded() throws RemoteException {
+    public void isBackupEnabledForUser_forwarded() throws RemoteException {
         mTrampoline.initializeService(UserHandle.USER_SYSTEM);
+
+        mTrampoline.isBackupEnabledForUser(mUserId);
+
+        verify(mBackupManagerServiceMock).isBackupEnabled(mUserId);
+    }
+
+    @Test
+    public void isBackupEnabled_forwardedToCallingUserId() throws RemoteException {
+        TrampolineTestable.sCallingUserId = mUserId;
+        mTrampoline.initializeService(UserHandle.USER_SYSTEM);
+
         mTrampoline.isBackupEnabled();
-        verify(mBackupManagerServiceMock).isBackupEnabled();
+
+        verify(mBackupManagerServiceMock).isBackupEnabled(mUserId);
     }
 
     @Test
@@ -439,10 +467,22 @@
     }
 
     @Test
-    public void backupNow_forwarded() throws RemoteException {
+    public void backupNowForUser_forwarded() throws RemoteException {
         mTrampoline.initializeService(UserHandle.USER_SYSTEM);
+
+        mTrampoline.backupNowForUser(mUserId);
+
+        verify(mBackupManagerServiceMock).backupNow(mUserId);
+    }
+
+    @Test
+    public void backupNow_forwardedToCallingUserId() throws RemoteException {
+        TrampolineTestable.sCallingUserId = mUserId;
+        mTrampoline.initializeService(UserHandle.USER_SYSTEM);
+
         mTrampoline.backupNow();
-        verify(mBackupManagerServiceMock).backupNow();
+
+        verify(mBackupManagerServiceMock).backupNow(mUserId);
     }
 
     @Test
@@ -798,15 +838,28 @@
     }
 
     @Test
-    public void requestBackup_forwarded() throws RemoteException {
-        when(mBackupManagerServiceMock.requestBackup(PACKAGE_NAMES, mBackupObserverMock,
-                mBackupManagerMonitorMock, 123)).thenReturn(456);
-
+    public void requestBackupForUser_forwarded() throws RemoteException {
+        when(mBackupManagerServiceMock.requestBackup(mUserId, PACKAGE_NAMES,
+                mBackupObserverMock, mBackupManagerMonitorMock, 123)).thenReturn(456);
         mTrampoline.initializeService(UserHandle.USER_SYSTEM);
-        assertEquals(456, mTrampoline.requestBackup(PACKAGE_NAMES, mBackupObserverMock,
-                mBackupManagerMonitorMock, 123));
-        verify(mBackupManagerServiceMock).requestBackup(PACKAGE_NAMES, mBackupObserverMock,
-                mBackupManagerMonitorMock, 123);
+
+        assertEquals(456, mTrampoline.requestBackupForUser(mUserId, PACKAGE_NAMES,
+                mBackupObserverMock, mBackupManagerMonitorMock, 123));
+        verify(mBackupManagerServiceMock).requestBackup(mUserId, PACKAGE_NAMES,
+                mBackupObserverMock, mBackupManagerMonitorMock, 123);
+    }
+
+    @Test
+    public void requestBackup_forwardedToCallingUserId() throws RemoteException {
+        TrampolineTestable.sCallingUserId = mUserId;
+        when(mBackupManagerServiceMock.requestBackup(NON_USER_SYSTEM, PACKAGE_NAMES,
+                mBackupObserverMock, mBackupManagerMonitorMock, 123)).thenReturn(456);
+        mTrampoline.initializeService(UserHandle.USER_SYSTEM);
+
+        assertEquals(456, mTrampoline.requestBackup(PACKAGE_NAMES,
+                mBackupObserverMock, mBackupManagerMonitorMock, 123));
+        verify(mBackupManagerServiceMock).requestBackup(mUserId, PACKAGE_NAMES,
+                mBackupObserverMock, mBackupManagerMonitorMock, 123);
     }
 
     @Test
@@ -816,10 +869,22 @@
     }
 
     @Test
-    public void cancelBackups_forwarded() throws RemoteException {
+    public void cancelBackupsForUser_forwarded() throws RemoteException {
         mTrampoline.initializeService(UserHandle.USER_SYSTEM);
+
+        mTrampoline.cancelBackupsForUser(mUserId);
+
+        verify(mBackupManagerServiceMock).cancelBackups(mUserId);
+    }
+
+    @Test
+    public void cancelBackups_forwardedToCallingUserId() throws RemoteException {
+        TrampolineTestable.sCallingUserId = mUserId;
+        mTrampoline.initializeService(UserHandle.USER_SYSTEM);
+
         mTrampoline.cancelBackups();
-        verify(mBackupManagerServiceMock).cancelBackups();
+
+        verify(mBackupManagerServiceMock).cancelBackups(mUserId);
     }
 
     @Test
@@ -891,6 +956,7 @@
     private static class TrampolineTestable extends Trampoline {
         static boolean sBackupDisabled = false;
         static File sSuppressFile = null;
+        static int sCallingUserId = -1;
         static int sCallingUid = -1;
         static BackupManagerService sBackupManagerServiceMock = null;
         private int mCreateServiceCallsCount = 0;
@@ -909,6 +975,10 @@
             return sSuppressFile;
         }
 
+        protected int binderGetCallingUserId() {
+            return sCallingUserId;
+        }
+
         @Override
         protected int binderGetCallingUid() {
             return sCallingUid;
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index 8ac2930..561c61f 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -37,6 +37,7 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.internal.app.IBatteryStats;
@@ -193,4 +194,19 @@
 
         assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
     }
+
+    @MediumTest
+    public void testWasDeviceIdleFor_true() {
+        int interval = 1000;
+        mService.onUserActivity();
+        SystemClock.sleep(interval);
+        assertThat(mService.wasDeviceIdleForInternal(interval)).isTrue();
+    }
+
+    @SmallTest
+    public void testWasDeviceIdleFor_false() {
+        int interval = 1000;
+        mService.onUserActivity();
+        assertThat(mService.wasDeviceIdleForInternal(interval)).isFalse();
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/signedconfig/SignedConfigTest.java b/services/tests/servicestests/src/com/android/server/signedconfig/SignedConfigTest.java
index a9d4519..70fadd1 100644
--- a/services/tests/servicestests/src/com/android/server/signedconfig/SignedConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/signedconfig/SignedConfigTest.java
@@ -20,8 +20,11 @@
 
 import static org.junit.Assert.fail;
 
+import static java.util.Collections.emptyMap;
 import static java.util.Collections.emptySet;
 
+import android.util.ArrayMap;
+
 import androidx.test.runner.AndroidJUnit4;
 
 import com.google.common.collect.Sets;
@@ -33,6 +36,7 @@
 
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.Map;
 import java.util.Set;
 
 
@@ -46,10 +50,25 @@
         return Sets.newHashSet(values);
     }
 
+    private static <K, V> Map<K, V> mapOf(Object... keyValuePairs) {
+        if (keyValuePairs.length % 2 != 0) {
+            throw new IllegalArgumentException();
+        }
+        final int len = keyValuePairs.length / 2;
+        ArrayMap<K, V> m = new ArrayMap<>(len);
+        for (int i = 0; i < len;  ++i) {
+            m.put((K) keyValuePairs[i * 2], (V) keyValuePairs[(i * 2) + 1]);
+        }
+        return Collections.unmodifiableMap(m);
+
+    }
+
+
     @Test
     public void testParsePerSdkConfigSdkMinMax() throws JSONException, InvalidConfigException {
         JSONObject json = new JSONObject("{\"minSdk\":2, \"maxSdk\": 3, \"values\": []}");
-        SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, emptySet());
+        SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, emptySet(),
+                emptyMap());
         assertThat(config.minSdk).isEqualTo(2);
         assertThat(config.maxSdk).isEqualTo(3);
     }
@@ -58,7 +77,7 @@
     public void testParsePerSdkConfigNoMinSdk() throws JSONException {
         JSONObject json = new JSONObject("{\"maxSdk\": 3, \"values\": []}");
         try {
-            SignedConfig.parsePerSdkConfig(json, emptySet());
+            SignedConfig.parsePerSdkConfig(json, emptySet(), emptyMap());
             fail("Expected InvalidConfigException or JSONException");
         } catch (JSONException | InvalidConfigException e) {
             // expected
@@ -69,7 +88,7 @@
     public void testParsePerSdkConfigNoMaxSdk() throws JSONException {
         JSONObject json = new JSONObject("{\"minSdk\": 1, \"values\": []}");
         try {
-            SignedConfig.parsePerSdkConfig(json, emptySet());
+            SignedConfig.parsePerSdkConfig(json, emptySet(), emptyMap());
             fail("Expected InvalidConfigException or JSONException");
         } catch (JSONException | InvalidConfigException e) {
             // expected
@@ -80,7 +99,7 @@
     public void testParsePerSdkConfigNoValues() throws JSONException {
         JSONObject json = new JSONObject("{\"minSdk\": 1, \"maxSdk\": 3}");
         try {
-            SignedConfig.parsePerSdkConfig(json, emptySet());
+            SignedConfig.parsePerSdkConfig(json, emptySet(), emptyMap());
             fail("Expected InvalidConfigException or JSONException");
         } catch (JSONException | InvalidConfigException e) {
             // expected
@@ -88,10 +107,10 @@
     }
 
     @Test
-    public void testParsePerSdkConfigSdkNullMinSdk() throws JSONException, InvalidConfigException {
+    public void testParsePerSdkConfigSdkNullMinSdk() throws JSONException {
         JSONObject json = new JSONObject("{\"minSdk\":null, \"maxSdk\": 3, \"values\": []}");
         try {
-            SignedConfig.parsePerSdkConfig(json, emptySet());
+            SignedConfig.parsePerSdkConfig(json, emptySet(), emptyMap());
             fail("Expected InvalidConfigException or JSONException");
         } catch (JSONException | InvalidConfigException e) {
             // expected
@@ -99,10 +118,10 @@
     }
 
     @Test
-    public void testParsePerSdkConfigSdkNullMaxSdk() throws JSONException, InvalidConfigException {
+    public void testParsePerSdkConfigSdkNullMaxSdk() throws JSONException {
         JSONObject json = new JSONObject("{\"minSdk\":1, \"maxSdk\": null, \"values\": []}");
         try {
-            SignedConfig.parsePerSdkConfig(json, emptySet());
+            SignedConfig.parsePerSdkConfig(json, emptySet(), emptyMap());
             fail("Expected InvalidConfigException or JSONException");
         } catch (JSONException | InvalidConfigException e) {
             // expected
@@ -113,7 +132,7 @@
     public void testParsePerSdkConfigNullValues() throws JSONException {
         JSONObject json = new JSONObject("{\"minSdk\": 1, \"maxSdk\": 3, \"values\": null}");
         try {
-            SignedConfig.parsePerSdkConfig(json, emptySet());
+            SignedConfig.parsePerSdkConfig(json, emptySet(), emptyMap());
             fail("Expected InvalidConfigException or JSONException");
         } catch (JSONException | InvalidConfigException e) {
             // expected
@@ -124,7 +143,8 @@
     public void testParsePerSdkConfigZeroValues()
             throws JSONException, InvalidConfigException {
         JSONObject json = new JSONObject("{\"minSdk\": 1, \"maxSdk\": 3, \"values\": []}");
-        SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, setOf("a", "b"));
+        SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, setOf("a", "b"),
+                emptyMap());
         assertThat(config.values).hasSize(0);
     }
 
@@ -133,18 +153,30 @@
             throws JSONException, InvalidConfigException {
         JSONObject json = new JSONObject(
                 "{\"minSdk\": 1, \"maxSdk\": 1, \"values\": [{\"key\":\"a\", \"value\": \"1\"}]}");
-        SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, setOf("a", "b"));
+        SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, setOf("a", "b"),
+                emptyMap());
         assertThat(config.values).containsExactly("a", "1");
     }
 
     @Test
+    public void testParsePerSdkConfigSingleKeyNullValue()
+            throws JSONException, InvalidConfigException {
+        JSONObject json = new JSONObject(
+                "{\"minSdk\": 1, \"maxSdk\": 1, \"values\": [{\"key\":\"a\", \"value\": null}]}");
+        SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, setOf("a", "b"),
+                emptyMap());
+        assertThat(config.values.keySet()).containsExactly("a");
+        assertThat(config.values.get("a")).isNull();
+    }
+
+    @Test
     public void testParsePerSdkConfigMultiKeys()
             throws JSONException, InvalidConfigException {
         JSONObject json = new JSONObject(
                 "{\"minSdk\": 1, \"maxSdk\": 1, \"values\": [{\"key\":\"a\", \"value\": \"1\"}, "
                         + "{\"key\":\"c\", \"value\": \"2\"}]}");
         SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(
-                json, setOf("a", "b", "c"));
+                json, setOf("a", "b", "c"), emptyMap());
         assertThat(config.values).containsExactly("a", "1", "c", "2");
     }
 
@@ -153,7 +185,7 @@
         JSONObject json = new JSONObject(
                 "{\"minSdk\": 1, \"maxSdk\": 1, \"values\": [{\"key\":\"a\", \"value\": \"1\"}]}");
         try {
-            SignedConfig.parsePerSdkConfig(json, setOf("b"));
+            SignedConfig.parsePerSdkConfig(json, setOf("b"), emptyMap());
             fail("Expected InvalidConfigException or JSONException");
         } catch (JSONException | InvalidConfigException e) {
             // expected
@@ -161,11 +193,67 @@
     }
 
     @Test
+    public void testParsePerSdkConfigSingleKeyWithMap()
+            throws JSONException, InvalidConfigException {
+        JSONObject json = new JSONObject(
+                "{\"minSdk\": 1, \"maxSdk\": 1, \"values\": [{\"key\":\"a\", \"value\": \"1\"}]}");
+        SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, setOf("a"),
+                mapOf("a", mapOf("1", "one")));
+        assertThat(config.values).containsExactly("a", "one");
+    }
+
+    @Test
+    public void testParsePerSdkConfigSingleKeyWithMapInvalidValue() throws JSONException {
+        JSONObject json = new JSONObject(
+                "{\"minSdk\": 1, \"maxSdk\": 1, \"values\": [{\"key\":\"a\", \"value\": \"2\"}]}");
+        try {
+            SignedConfig.parsePerSdkConfig(json, setOf("b"), mapOf("a", mapOf("1", "one")));
+            fail("Expected InvalidConfigException");
+        } catch (InvalidConfigException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testParsePerSdkConfigMultiKeysWithMap()
+            throws JSONException, InvalidConfigException {
+        JSONObject json = new JSONObject(
+                "{\"minSdk\": 1, \"maxSdk\": 1, \"values\": [{\"key\":\"a\", \"value\": \"1\"},"
+                + "{\"key\":\"b\", \"value\": \"1\"}]}");
+        SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, setOf("a", "b"),
+                mapOf("a", mapOf("1", "one")));
+        assertThat(config.values).containsExactly("a", "one", "b", "1");
+    }
+
+    @Test
+    public void testParsePerSdkConfigSingleKeyWithMapToNull()
+            throws JSONException, InvalidConfigException {
+        JSONObject json = new JSONObject(
+                "{\"minSdk\": 1, \"maxSdk\": 1, \"values\": [{\"key\":\"a\", \"value\": \"1\"}]}");
+        SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, setOf("a"),
+                mapOf("a", mapOf("1", null)));
+        assertThat(config.values).containsExactly("a", null);
+    }
+
+    @Test
+    public void testParsePerSdkConfigSingleKeyWithMapFromNull()
+            throws JSONException, InvalidConfigException {
+        assertThat(mapOf(null, "allitnil")).containsExactly(null, "allitnil");
+        assertThat(mapOf(null, "allitnil").containsKey(null)).isTrue();
+        JSONObject json = new JSONObject(
+                "{\"minSdk\": 1, \"maxSdk\": 1, \"values\": [{\"key\":\"a\", \"value\": null}]}");
+        SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, setOf("a"),
+                mapOf("a", mapOf(null, "allitnil")));
+        assertThat(config.values).containsExactly("a", "allitnil");
+    }
+
+    @Test
     public void testParsePerSdkConfigSingleKeyNoValue()
             throws JSONException, InvalidConfigException {
         JSONObject json = new JSONObject(
                 "{\"minSdk\": 1, \"maxSdk\": 1, \"values\": [{\"key\":\"a\"}]}");
-        SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, setOf("a", "b"));
+        SignedConfig.PerSdkConfig config = SignedConfig.parsePerSdkConfig(json, setOf("a", "b"),
+                emptyMap());
         assertThat(config.values).containsExactly("a", null);
     }
 
@@ -173,7 +261,7 @@
     public void testParsePerSdkConfigValuesInvalid() throws JSONException  {
         JSONObject json = new JSONObject("{\"minSdk\": 1, \"maxSdk\": 1,  \"values\": \"foo\"}");
         try {
-            SignedConfig.parsePerSdkConfig(json, emptySet());
+            SignedConfig.parsePerSdkConfig(json, emptySet(), emptyMap());
             fail("Expected InvalidConfigException or JSONException");
         } catch (JSONException | InvalidConfigException e) {
             // expected
@@ -184,7 +272,7 @@
     public void testParsePerSdkConfigConfigEntryInvalid() throws JSONException {
         JSONObject json = new JSONObject("{\"minSdk\": 1, \"maxSdk\": 1,  \"values\": [1, 2]}");
         try {
-            SignedConfig.parsePerSdkConfig(json, emptySet());
+            SignedConfig.parsePerSdkConfig(json, emptySet(), emptyMap());
             fail("Expected InvalidConfigException or JSONException");
         } catch (JSONException | InvalidConfigException e) {
             // expected
@@ -195,7 +283,7 @@
     public void testParsePerSdkConfigConfigEntryNull() throws JSONException {
         JSONObject json = new JSONObject("{\"minSdk\": 1, \"maxSdk\": 1,  \"values\": [null]}");
         try {
-            SignedConfig.parsePerSdkConfig(json, emptySet());
+            SignedConfig.parsePerSdkConfig(json, emptySet(), emptyMap());
             fail("Expected InvalidConfigException or JSONException");
         } catch (JSONException | InvalidConfigException e) {
             // expected
@@ -205,14 +293,15 @@
     @Test
     public void testParseVersion() throws InvalidConfigException {
         SignedConfig config = SignedConfig.parse(
-                "{\"version\": 1, \"config\": []}", emptySet());
+                "{\"version\": 1, \"config\": []}", emptySet(), emptyMap());
         assertThat(config.version).isEqualTo(1);
     }
 
     @Test
     public void testParseVersionInvalid() {
         try {
-            SignedConfig.parse("{\"version\": \"notanint\", \"config\": []}", emptySet());
+            SignedConfig.parse("{\"version\": \"notanint\", \"config\": []}", emptySet(),
+                    emptyMap());
             fail("Expected InvalidConfigException");
         } catch (InvalidConfigException e) {
             //expected
@@ -222,7 +311,7 @@
     @Test
     public void testParseNoVersion() {
         try {
-            SignedConfig.parse("{\"config\": []}", emptySet());
+            SignedConfig.parse("{\"config\": []}", emptySet(), emptyMap());
             fail("Expected InvalidConfigException");
         } catch (InvalidConfigException e) {
             //expected
@@ -232,7 +321,7 @@
     @Test
     public void testParseNoConfig() {
         try {
-            SignedConfig.parse("{\"version\": 1}", emptySet());
+            SignedConfig.parse("{\"version\": 1}", emptySet(), emptyMap());
             fail("Expected InvalidConfigException");
         } catch (InvalidConfigException e) {
             //expected
@@ -242,7 +331,7 @@
     @Test
     public void testParseConfigNull() {
         try {
-            SignedConfig.parse("{\"version\": 1, \"config\": null}", emptySet());
+            SignedConfig.parse("{\"version\": 1, \"config\": null}", emptySet(), emptyMap());
             fail("Expected InvalidConfigException");
         } catch (InvalidConfigException e) {
             //expected
@@ -252,7 +341,7 @@
     @Test
     public void testParseVersionNull() {
         try {
-            SignedConfig.parse("{\"version\": null, \"config\": []}", emptySet());
+            SignedConfig.parse("{\"version\": null, \"config\": []}", emptySet(), emptyMap());
             fail("Expected InvalidConfigException");
         } catch (InvalidConfigException e) {
             //expected
@@ -262,7 +351,7 @@
     @Test
     public void testParseConfigInvalidEntry() {
         try {
-            SignedConfig.parse("{\"version\": 1, \"config\": [{}]}", emptySet());
+            SignedConfig.parse("{\"version\": 1, \"config\": [{}]}", emptySet(), emptyMap());
             fail("Expected InvalidConfigException");
         } catch (InvalidConfigException e) {
             //expected
@@ -273,7 +362,7 @@
     public void testParseSdkConfigSingle() throws InvalidConfigException {
         SignedConfig config = SignedConfig.parse(
                 "{\"version\": 1, \"config\":[{\"minSdk\": 1, \"maxSdk\": 1, \"values\": []}]}",
-                emptySet());
+                emptySet(), emptyMap());
         assertThat(config.perSdkConfig).hasSize(1);
     }
 
@@ -281,7 +370,8 @@
     public void testParseSdkConfigMultiple() throws InvalidConfigException {
         SignedConfig config = SignedConfig.parse(
                 "{\"version\": 1, \"config\":[{\"minSdk\": 1, \"maxSdk\": 1, \"values\": []}, "
-                        + "{\"minSdk\": 2, \"maxSdk\": 2, \"values\": []}]}", emptySet());
+                        + "{\"minSdk\": 2, \"maxSdk\": 2, \"values\": []}]}", emptySet(),
+                emptyMap());
         assertThat(config.perSdkConfig).hasSize(2);
     }
 
@@ -314,7 +404,6 @@
         SignedConfig config = new SignedConfig(0, Arrays.asList(sdk13, sdk46));
         assertThat(config.getMatchingConfig(2)).isEqualTo(sdk13);
     }
-
     @Test
     public void testGetMatchingConfigNoMatch() {
         SignedConfig.PerSdkConfig sdk1 = new SignedConfig.PerSdkConfig(
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index d950360..527a1ee 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -20,6 +20,7 @@
 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
 import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
 import static android.app.NotificationManager.EXTRA_BLOCKED_STATE;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
 import static android.app.NotificationManager.IMPORTANCE_HIGH;
 import static android.app.NotificationManager.IMPORTANCE_LOW;
 import static android.app.NotificationManager.IMPORTANCE_MAX;
@@ -183,7 +184,7 @@
     Resources mResources;
 
     private NotificationChannel mTestNotificationChannel = new NotificationChannel(
-            TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT);
+            TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT);
     @Mock
     private NotificationListeners mListeners;
     @Mock private NotificationAssistants mAssistants;
@@ -238,6 +239,11 @@
         protected void reportUserInteraction(NotificationRecord r) {
             return;
         }
+
+        @Override
+        protected void handleSavePolicyFile() {
+            return;
+        }
     }
 
     private class TestableToastCallback extends ITransientNotification.Stub {
@@ -425,7 +431,7 @@
     @Test
     public void testCreateNotificationChannels_SingleChannel() throws Exception {
         final NotificationChannel channel =
-                new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
+                new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
         mBinderService.createNotificationChannels(PKG,
                 new ParceledListSlice(Arrays.asList(channel)));
         final NotificationChannel createdChannel =
@@ -447,9 +453,9 @@
     @Test
     public void testCreateNotificationChannels_TwoChannels() throws Exception {
         final NotificationChannel channel1 =
-                new NotificationChannel("id1", "name", NotificationManager.IMPORTANCE_DEFAULT);
+                new NotificationChannel("id1", "name", IMPORTANCE_DEFAULT);
         final NotificationChannel channel2 =
-                new NotificationChannel("id2", "name", NotificationManager.IMPORTANCE_DEFAULT);
+                new NotificationChannel("id2", "name", IMPORTANCE_DEFAULT);
         mBinderService.createNotificationChannels(PKG,
                 new ParceledListSlice(Arrays.asList(channel1, channel2)));
         assertTrue(mBinderService.getNotificationChannel(PKG, "id1") != null);
@@ -460,7 +466,7 @@
     public void testCreateNotificationChannels_SecondCreateDoesNotChangeImportance()
             throws Exception {
         final NotificationChannel channel =
-                new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
+                new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
         mBinderService.createNotificationChannels(PKG,
                 new ParceledListSlice(Arrays.asList(channel)));
 
@@ -471,14 +477,14 @@
                 new ParceledListSlice(Arrays.asList(dupeChannel)));
         final NotificationChannel createdChannel =
                 mBinderService.getNotificationChannel(PKG, "id");
-        assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance());
+        assertEquals(IMPORTANCE_DEFAULT, createdChannel.getImportance());
     }
 
     @Test
     public void testCreateNotificationChannels_SecondCreateAllowedToDowngradeImportance()
             throws Exception {
         final NotificationChannel channel =
-                new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
+                new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
         mBinderService.createNotificationChannels(PKG,
                 new ParceledListSlice(Arrays.asList(channel)));
 
@@ -496,7 +502,7 @@
     public void testCreateNotificationChannels_CannotDowngradeImportanceIfAlreadyUpdated()
             throws Exception {
         final NotificationChannel channel =
-                new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
+                new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
         mBinderService.createNotificationChannels(PKG,
                 new ParceledListSlice(Arrays.asList(channel)));
 
@@ -519,14 +525,14 @@
     public void testCreateNotificationChannels_IdenticalChannelsInListIgnoresSecond()
             throws Exception {
         final NotificationChannel channel1 =
-                new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
+                new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
         final NotificationChannel channel2 =
                 new NotificationChannel("id", "name", IMPORTANCE_HIGH);
         mBinderService.createNotificationChannels(PKG,
                 new ParceledListSlice(Arrays.asList(channel1, channel2)));
         final NotificationChannel createdChannel =
                 mBinderService.getNotificationChannel(PKG, "id");
-        assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance());
+        assertEquals(IMPORTANCE_DEFAULT, createdChannel.getImportance());
     }
 
     @Test
@@ -751,13 +757,18 @@
     @Test
     public void testBlockedNotifications_blockedByAssistant() throws Exception {
         when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
+        when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
 
         NotificationChannel channel = new NotificationChannel("id", "name",
                 NotificationManager.IMPORTANCE_HIGH);
         NotificationRecord r = generateNotificationRecord(channel);
         mService.addEnqueuedNotification(r);
 
-        r.setAssistantImportance(IMPORTANCE_NONE);
+        Bundle bundle = new Bundle();
+        bundle.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_NONE);
+        Adjustment adjustment = new Adjustment(
+                r.sbn.getPackageName(), r.getKey(), bundle, "", r.getUser().getIdentifier());
+        mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
 
         NotificationManagerService.PostNotificationRunnable runnable =
                 mService.new PostNotificationRunnable(r.getKey());
@@ -1809,7 +1820,6 @@
         mListener = mock(ManagedServices.ManagedServiceInfo.class);
         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
         when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
-
         try {
             mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
                     null, PKG, Process.myUserHandle());
@@ -2613,7 +2623,7 @@
     }
 
     @Test
-    public void testAssistantIBlockingTriggersCancel() throws Exception {
+    public void testAssistantBlockingTriggersCancel() throws Exception {
         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
         mService.addNotification(r);
         NotificationManagerService.WorkerHandler handler = mock(
@@ -2653,6 +2663,43 @@
     }
 
     @Test
+    public void testApplyEnqueuedAdjustmentFromAssistant_importance_onTime() throws Exception {
+        final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+        mService.addEnqueuedNotification(r);
+        NotificationManagerService.WorkerHandler handler = mock(
+                NotificationManagerService.WorkerHandler.class);
+        mService.setHandler(handler);
+        when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
+
+        Bundle signals = new Bundle();
+        signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_LOW);
+        Adjustment adjustment = new Adjustment(
+                r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
+        mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
+
+        assertEquals(IMPORTANCE_LOW, r.getImportance());
+    }
+
+    @Test
+    public void testApplyEnqueuedAdjustmentFromAssistant_importance_tooLate() throws Exception {
+        final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+        mService.addNotification(r);
+        NotificationManagerService.WorkerHandler handler = mock(
+                NotificationManagerService.WorkerHandler.class);
+        mService.setHandler(handler);
+        when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
+
+        Bundle signals = new Bundle();
+        signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_LOW);
+        Adjustment adjustment = new Adjustment(
+                r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
+        mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
+
+        assertEquals(IMPORTANCE_DEFAULT, r.getImportance());
+        assertFalse(r.hasAdjustment(Adjustment.KEY_IMPORTANCE));
+    }
+
+    @Test
     public void testApplyEnqueuedAdjustmentFromAssistant_crossUser() throws Exception {
         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
         mService.addEnqueuedNotification(r);
@@ -2852,7 +2899,7 @@
     @Test
     public void updateUriPermissions_update() throws Exception {
         NotificationChannel c = new NotificationChannel(
-                TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT);
+                TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT);
         c.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT);
         Message message1 = new Message("", 0, "");
         message1.setData("",
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
index 8690110..0eeeeed 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
@@ -760,6 +760,7 @@
         NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
 
         record.setAssistantImportance(IMPORTANCE_LOW);
+        record.calculateImportance();
         assertEquals(IMPORTANCE_LOW, record.getImportance());
 
         // assistant ignored if user expressed preference
@@ -767,6 +768,7 @@
         channel.lockFields(USER_LOCKED_IMPORTANCE);
 
         record.setAssistantImportance(IMPORTANCE_LOW);
+        record.calculateImportance();
         assertEquals(channel.getImportance(), record.getImportance());
     }
 
@@ -779,6 +781,7 @@
         NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
 
         record.setAssistantImportance(IMPORTANCE_LOW);
+        record.calculateImportance();
         assertEquals(IMPORTANCE_LOW, record.getImportance());
 
         record.updateNotificationChannel(
diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java
index 613ba00..904d55e 100644
--- a/services/usb/java/com/android/server/usb/UsbHostManager.java
+++ b/services/usb/java/com/android/server/usb/UsbHostManager.java
@@ -32,7 +32,9 @@
 import android.service.usb.UsbHostManagerProto;
 import android.service.usb.UsbIsHeadsetProto;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.Slog;
+import android.util.StatsLog;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.IndentingPrintWriter;
@@ -86,6 +88,7 @@
     private int mNumConnects;    // TOTAL # of connect/disconnect
     private final LinkedList<ConnectionRecord> mConnections = new LinkedList<ConnectionRecord>();
     private ConnectionRecord mLastConnect;
+    private final ArrayMap<String, ConnectionRecord> mConnected = new ArrayMap<>();
 
     /*
      * ConnectionRecord
@@ -300,6 +303,11 @@
         if (mode != ConnectionRecord.DISCONNECT) {
             mLastConnect = rec;
         }
+        if (mode == ConnectionRecord.CONNECT) {
+            mConnected.put(deviceAddress, rec);
+        } else if (mode == ConnectionRecord.DISCONNECT) {
+            mConnected.remove(deviceAddress);
+        }
     }
 
     private void logUsbDevice(UsbDescriptorParser descriptorParser) {
@@ -408,6 +416,14 @@
                 // Tracking
                 addConnectionRecord(deviceAddress, ConnectionRecord.CONNECT,
                         parser.getRawDescriptors());
+
+                // Stats collection
+                if (parser.hasAudioInterface()) {
+                    StatsLog.write(StatsLog.USB_DEVICE_ATTACHED, newDevice.getVendorId(),
+                            newDevice.getProductId(), parser.hasAudioInterface(),
+                            parser.hasHIDInterface(), parser.hasStorageInterface(),
+                            StatsLog.USB_DEVICE_ATTACHED__STATE__STATE_CONNECTED, 0);
+                }
             }
         }
 
@@ -432,9 +448,22 @@
                 mUsbAlsaManager.usbDeviceRemoved(deviceAddress);
                 mSettingsManager.usbDeviceRemoved(device);
                 getCurrentUserSettings().usbDeviceRemoved(device);
-
+                ConnectionRecord current = mConnected.get(deviceAddress);
                 // Tracking
                 addConnectionRecord(deviceAddress, ConnectionRecord.DISCONNECT, null);
+
+                if (current != null) {
+                    UsbDescriptorParser parser = new UsbDescriptorParser(deviceAddress,
+                            current.mDescriptors);
+                    if (parser.hasAudioInterface()) {
+                        // Stats collection
+                        StatsLog.write(StatsLog.USB_DEVICE_ATTACHED, device.getVendorId(),
+                                device.getProductId(), parser.hasAudioInterface(),
+                                parser.hasHIDInterface(),  parser.hasStorageInterface(),
+                                StatsLog.USB_DEVICE_ATTACHED__STATE__STATE_DISCONNECTED,
+                                System.currentTimeMillis() - current.mTimestamp);
+                    }
+                }
             } else {
                 Slog.d(TAG, "Removed device at " + deviceAddress + " was already gone");
             }
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index 33da403..96618f5 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -41,12 +41,14 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.service.usb.UsbPortInfoProto;
 import android.service.usb.UsbPortManagerProto;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Slog;
+import android.util.StatsLog;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.IndentingPrintWriter;
@@ -54,6 +56,7 @@
 import com.android.server.FgThread;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.NoSuchElementException;
 
 /**
@@ -117,6 +120,10 @@
     private final ArrayMap<String, RawPortInfo> mSimulatedPorts =
             new ArrayMap<>();
 
+    // Maintains the current connected status of the port.
+    // Uploads logs only when the connection status is changes.
+    private final HashMap<String, Boolean> mConnected = new HashMap<>();
+
     public UsbPortManager(Context context) {
         mContext = context;
         try {
@@ -700,6 +707,18 @@
         // Guard against possible reentrance by posting the broadcast from the handler
         // instead of from within the critical section.
         mHandler.post(() -> mContext.sendBroadcastAsUser(intent, UserHandle.ALL));
+
+        // Log to statsd
+        if (!mConnected.containsKey(portInfo.mUsbPort.getId())
+                || (mConnected.get(portInfo.mUsbPort.getId())
+                != portInfo.mUsbPortStatus.isConnected())) {
+            mConnected.put(portInfo.mUsbPort.getId(), portInfo.mUsbPortStatus.isConnected());
+            StatsLog.write(StatsLog.USB_CONNECTOR_STATE_CHANGED,
+                    portInfo.mUsbPortStatus.isConnected()
+                    ? StatsLog.USB_CONNECTOR_STATE_CHANGED__STATE__STATE_CONNECTED :
+                    StatsLog.USB_CONNECTOR_STATE_CHANGED__STATE__STATE_DISCONNECTED,
+                    portInfo.mUsbPort.getId(), portInfo.mLastConnectDurationMillis);
+        }
     }
 
     private static void logAndPrint(int priority, IndentingPrintWriter pw, String msg) {
@@ -746,7 +765,12 @@
         public boolean mCanChangeMode;
         public boolean mCanChangePowerRole;
         public boolean mCanChangeDataRole;
-        public int mDisposition; // default initialized to 0 which means added
+        // default initialized to 0 which means added
+        public int mDisposition;
+        // Tracks elapsedRealtime() of when the port was connected
+        public long mConnectedAtMillis;
+        // 0 when port is connected. Else reports the last connected duration
+        public long mLastConnectDurationMillis;
 
         public PortInfo(String portId, int supportedModes) {
             mUsbPort = new UsbPort(portId, supportedModes);
@@ -756,6 +780,8 @@
                 int currentPowerRole, boolean canChangePowerRole,
                 int currentDataRole, boolean canChangeDataRole,
                 int supportedRoleCombinations) {
+            boolean dispositionChanged = false;
+
             mCanChangeMode = canChangeMode;
             mCanChangePowerRole = canChangePowerRole;
             mCanChangeDataRole = canChangeDataRole;
@@ -767,9 +793,18 @@
                     != supportedRoleCombinations) {
                 mUsbPortStatus = new UsbPortStatus(currentMode, currentPowerRole, currentDataRole,
                         supportedRoleCombinations);
-                return true;
+                dispositionChanged = true;
             }
-            return false;
+
+            if (mUsbPortStatus.isConnected() && mConnectedAtMillis == 0) {
+                mConnectedAtMillis = SystemClock.elapsedRealtime();
+                mLastConnectDurationMillis = 0;
+            } else if (!mUsbPortStatus.isConnected() && mConnectedAtMillis != 0) {
+                mLastConnectDurationMillis = SystemClock.elapsedRealtime() - mConnectedAtMillis;
+                mConnectedAtMillis = 0;
+            }
+
+            return dispositionChanged;
         }
 
         void dump(@NonNull DualDumpOutputStream dump, @NonNull String idName, long id) {
@@ -782,6 +817,10 @@
                     mCanChangePowerRole);
             dump.write("can_change_data_role", UsbPortInfoProto.CAN_CHANGE_DATA_ROLE,
                     mCanChangeDataRole);
+            dump.write("connected_at_millis",
+                    UsbPortInfoProto.CONNECTED_AT_MILLIS, mConnectedAtMillis);
+            dump.write("last_connect_duration_millis",
+                    UsbPortInfoProto.LAST_CONNECT_DURATION_MILLIS, mLastConnectDurationMillis);
 
             dump.end(token);
         }
@@ -791,7 +830,9 @@
             return "port=" + mUsbPort + ", status=" + mUsbPortStatus
                     + ", canChangeMode=" + mCanChangeMode
                     + ", canChangePowerRole=" + mCanChangePowerRole
-                    + ", canChangeDataRole=" + mCanChangeDataRole;
+                    + ", canChangeDataRole=" + mCanChangeDataRole
+                    + ", connectedAtMillis=" + mConnectedAtMillis
+                    + ", lastConnectDurationMillis=" + mLastConnectDurationMillis;
         }
     }
 
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 143b323..d64efea 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -305,6 +305,8 @@
      */
     void handleCallIntent(in Intent intent);
 
+    void setTestDefaultCallRedirectionApp(String packageName);
+
     void setTestDefaultCallScreeningApp(String packageName);
 
     void addOrRemoveTestCallCompanionApp(String packageName, boolean isAdded);
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 2c06c47..aa2a69d 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -19,6 +19,7 @@
 import static android.net.NetworkPolicyManager.OVERRIDE_CONGESTED;
 import static android.net.NetworkPolicyManager.OVERRIDE_UNMETERED;
 
+import android.Manifest;
 import android.annotation.CallbackExecutor;
 import android.annotation.DurationMillisLong;
 import android.annotation.NonNull;
@@ -52,6 +53,7 @@
 import android.os.ServiceManager;
 import android.telephony.euicc.EuiccManager;
 import android.telephony.ims.ImsMmTelManager;
+import android.text.TextUtils;
 import android.util.DisplayMetrics;
 import android.util.Log;
 
@@ -67,6 +69,7 @@
 import java.util.Locale;
 import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 /**
  * SubscriptionManager is the application interface to SubscriptionController
@@ -2405,16 +2408,21 @@
      * together, some of them may be invisible to the users, etc.
      *
      * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
-     * permission or can manage all subscriptions in the list, according to their
-     * acess rules.
+     * permission or had carrier privilege permission on the subscriptions:
+     * {@link TelephonyManager#hasCarrierPrivileges(int)} or
+     * {@link #canManageSubscription(SubscriptionInfo)}
+     *
+     * @throws SecurityException if the caller doesn't meet the requirements
+     *             outlined above.
      *
      * @param subIdList list of subId that will be in the same group
      * @return groupUUID a UUID assigned to the subscription group. It returns
      * null if fails.
      *
      */
+    @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
-    public String setSubscriptionGroup(int[] subIdList) {
+    public @Nullable String setSubscriptionGroup(@NonNull int[] subIdList) {
         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
         if (VDBG) {
             logd("[setSubscriptionGroup]+ subIdList:" + Arrays.toString(subIdList));
@@ -2434,6 +2442,80 @@
     }
 
     /**
+     * Remove a list of subscriptions from their subscription group.
+     * See {@link #setSubscriptionGroup(int[])} for more details.
+     *
+     * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
+     * permission or had carrier privilege permission on the subscriptions:
+     * {@link TelephonyManager#hasCarrierPrivileges(int)} or
+     * {@link #canManageSubscription(SubscriptionInfo)}
+     *
+     * @throws SecurityException if the caller doesn't meet the requirements
+     *             outlined above.
+     *
+     * @param subIdList list of subId that need removing from their groups.
+     * @return whether the operation succeeds.
+     *
+     */
+    @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public boolean removeSubscriptionsFromGroup(@NonNull int[] subIdList) {
+        String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+        if (VDBG) {
+            logd("[removeSubscriptionsFromGroup]+ subIdList:" + Arrays.toString(subIdList));
+        }
+
+        try {
+            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+            if (iSub != null) {
+                return iSub.removeSubscriptionsFromGroup(subIdList, pkgForDebug);
+            }
+        } catch (RemoteException ex) {
+            // ignore it
+        }
+
+        return false;
+    }
+
+    /**
+     * Get subscriptionInfo list of subscriptions that are in the same group of given subId.
+     * See {@link #setSubscriptionGroup(int[])} for more details.
+     *
+     * Caller will either have {@link android.Manifest.permission#READ_PHONE_STATE}
+     * permission or had carrier privilege permission on the subscription.
+     * {@link TelephonyManager#hasCarrierPrivileges(int)}
+     *
+     * @throws SecurityException if the caller doesn't meet the requirements
+     *             outlined above.
+     *
+     * @param subId of which list of subInfo from the same group will be returned.
+     * @return list of subscriptionInfo that belong to the same group, including the given
+     * subscription itself. It will return null if the subscription doesn't exist or it
+     * doesn't belong to any group.
+     *
+     */
+    @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
+    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+    public @Nullable List<SubscriptionInfo> getSubscriptionsInGroup(int subId) {
+        String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+        if (VDBG) {
+            logd("[getSubscriptionsInGroup]+ subId:" + subId);
+        }
+
+        List<SubscriptionInfo> result = null;
+        try {
+            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+            if (iSub != null) {
+                result = iSub.getSubscriptionsInGroup(subId, pkgForDebug);
+            }
+        } catch (RemoteException ex) {
+            // ignore it
+        }
+
+        return result;
+    }
+
+    /**
      * Set metered by simInfo index
      *
      * @param isMetered whether it’s a metered subscription.
@@ -2448,6 +2530,42 @@
                 (iSub)-> iSub.setMetered(isMetered, subId));
     }
 
+    /**
+     * Whether system UI should hide a subscription. If it's a bundled opportunistic
+     * subscription, it shouldn't show up in anywhere in Settings app, dialer app,
+     * or status bar.
+     *
+     * @param info the subscriptionInfo to check against.
+     * @return true if this subscription should be hidden.
+     *
+     * @hide
+     */
+    public static boolean shouldHideSubscription(SubscriptionInfo info) {
+        return (info != null && !TextUtils.isEmpty(info.getGroupUuid()) && info.isOpportunistic());
+    }
+
+    /**
+     * Return a list of subscriptions that are available and visible to the user.
+     * Used by Settings app to show a list of subscriptions for user to pick.
+     *
+     * <p>
+     * Permissions android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE is required
+     * for getSelectableSubscriptionInfoList to be invoked.
+     * @return list of user selectable subscriptions.
+     *
+     * @hide
+     */
+    public @Nullable List<SubscriptionInfo> getSelectableSubscriptionInfoList() {
+        List<SubscriptionInfo> availableList = getAvailableSubscriptionInfoList();
+        if (availableList == null) {
+            return null;
+        } else {
+            return getAvailableSubscriptionInfoList().stream()
+                    .filter(subInfo -> !shouldHideSubscription(subInfo))
+                    .collect(Collectors.toList());
+        }
+    }
+
     private interface CallISubMethodHelper {
         int callMethod(ISub iSub) throws RemoteException;
     }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 422e66d..33f8567 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -6632,7 +6632,7 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony.getCarrierPrivilegeStatus(mSubId) ==
+                return telephony.getCarrierPrivilegeStatus(subId) ==
                     CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
             }
         } catch (RemoteException ex) {
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index a1afc08..8d148c3 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -969,7 +969,7 @@
      */
     public String toString() {
         StringBuilder sb = new StringBuilder();
-        sb.append("[ApnSettingV5] ")
+        sb.append("[ApnSettingV6] ")
                 .append(mEntryName)
                 .append(", ").append(mId)
                 .append(", ").append(mOperatorNumeric)
@@ -996,6 +996,7 @@
         sb.append(", ").append(mPermanentFailed);
         sb.append(", ").append(mNetworkTypeBitmask);
         sb.append(", ").append(mApnSetId);
+        sb.append(", ").append(mCarrierId);
         return sb.toString();
     }
 
diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java
index 8fcdb6e..f124595 100644
--- a/telephony/java/android/telephony/ims/ImsReasonInfo.java
+++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java
@@ -16,11 +16,15 @@
 
 package android.telephony.ims;
 
+import android.annotation.IntDef;
 import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * This class enables an application to get details on why a method call failed.
  *
@@ -30,158 +34,292 @@
 public final class ImsReasonInfo implements Parcelable {
 
     /**
-     * Specific code of each types
+     * The Reason is unspecified.
      */
     public static final int CODE_UNSPECIFIED = 0;
 
-    /**
-     * LOCAL
-     */
+
+    // LOCAL
+
     // IMS -> Telephony
-    // The passed argument is an invalid
+    /**
+     * The passed argument is invalid.
+     */
     public static final int CODE_LOCAL_ILLEGAL_ARGUMENT = 101;
-    // The operation is invoked in invalid call state
+    /**
+     * The operation was invoked while in an invalid call state.
+     */
     public static final int CODE_LOCAL_ILLEGAL_STATE = 102;
-    // IMS service internal error
+    /**
+     * IMS service internal error
+     */
     public static final int CODE_LOCAL_INTERNAL_ERROR = 103;
-    // IMS service goes down (service connection is lost)
+    /**
+     * ImsService has crashed (service connection is lost).
+     */
     public static final int CODE_LOCAL_IMS_SERVICE_DOWN = 106;
-    // No pending incoming call exists
+    /**
+     * No pending incoming call exists
+     */
     public static final int CODE_LOCAL_NO_PENDING_CALL = 107;
-    // IMS Call ended during conference merge process
+    /**
+     * IMS Call ended during conference merge process
+     */
     public static final int CODE_LOCAL_ENDED_BY_CONFERENCE_MERGE = 108;
 
     // IMS -> Telephony
-    // Service unavailable; by power off
+    /**
+     * Service unavailable; radio power off
+     */
     public static final int CODE_LOCAL_POWER_OFF = 111;
-    // Service unavailable; by low battery
+    /**
+     * Service unavailable; low battery
+     */
     public static final int CODE_LOCAL_LOW_BATTERY = 112;
-    // Service unavailable; by out of service (data service state)
+    /**
+     * Service unavailable; out of service (data service state)
+     */
     public static final int CODE_LOCAL_NETWORK_NO_SERVICE = 121;
-    // Service unavailable; by no LTE coverage
-    // (VoLTE is not supported even though IMS is registered)
+    /**
+     * Service unavailable; no LTE coverage
+     * (VoLTE is not supported even though IMS is registered)
+     */
     public static final int CODE_LOCAL_NETWORK_NO_LTE_COVERAGE = 122;
-    // Service unavailable; by located in roaming area
+    /**
+     * Service unavailable; located in roaming area
+     */
     public static final int CODE_LOCAL_NETWORK_ROAMING = 123;
-    // Service unavailable; by IP changed
+    /**
+     * Service unavailable; IP changed
+     */
     public static final int CODE_LOCAL_NETWORK_IP_CHANGED = 124;
-    // Service unavailable; other
+    /**
+     * Service unavailable; for an unspecified reason
+     */
     public static final int CODE_LOCAL_SERVICE_UNAVAILABLE = 131;
-    // Service unavailable; IMS connection is lost (IMS is not registered)
+    /**
+     * Service unavailable; IMS is not registered
+     */
     public static final int CODE_LOCAL_NOT_REGISTERED = 132;
 
     // IMS <-> Telephony
-    // Max call exceeded
+    /**
+     * Maximum number of simultaneous calls exceeded
+     */
     public static final int CODE_LOCAL_CALL_EXCEEDED = 141;
     // IMS <- Telephony
-    // Call busy
+    /**
+     * The call is busy.
+     */
     public static final int CODE_LOCAL_CALL_BUSY = 142;
-    // Call decline
+    /**
+     * The Call has been declined locally on this device.
+     */
     public static final int CODE_LOCAL_CALL_DECLINE = 143;
     // IMS -> Telephony
-    // SRVCC is in progress
+    /**
+     * Can not complete call; an SRVCC is in progress.
+     */
     public static final int CODE_LOCAL_CALL_VCC_ON_PROGRESSING = 144;
-    // Resource reservation is failed (QoS precondition)
+    /**
+     * Can not complete call; resource reservation is failed (QoS precondition)
+     */
     public static final int CODE_LOCAL_CALL_RESOURCE_RESERVATION_FAILED = 145;
-    // Retry CS call; VoLTE service can't be provided by the network or remote end
-    // Resolve the extra code(EXTRA_CODE_CALL_RETRY_*) if the below code is set
+    /**
+     * VoLTE service can't be provided by the network or remote end, retry the call.
+     * Resolve the extra code provided in (EXTRA_CODE_CALL_RETRY_*) if the below code is set
+     */
     public static final int CODE_LOCAL_CALL_CS_RETRY_REQUIRED = 146;
-    // Retry VoLTE call; VoLTE service can't be provided by the network temporarily
+    /**
+     * VoLTE service can't be provided by the network temporarily, retry the call.
+     */
     public static final int CODE_LOCAL_CALL_VOLTE_RETRY_REQUIRED = 147;
-    // IMS call is already terminated (in TERMINATED state)
+    /**
+     * IMS call is already terminated (in TERMINATED state).
+     */
     public static final int CODE_LOCAL_CALL_TERMINATED = 148;
-    // Handover not feasible
+    /**
+     * Call was disconnected because a handover is not feasible due to network conditions.
+     */
     public static final int CODE_LOCAL_HO_NOT_FEASIBLE = 149;
 
-    /**
+    /*
      * TIMEOUT (IMS -> Telephony)
      */
-    // 1xx waiting timer is expired after sending INVITE request (MO only)
+    /**
+     * 1xx waiting timer is expired after sending INVITE request (MO calls only)
+     */
     public static final int CODE_TIMEOUT_1XX_WAITING = 201;
-    // User no answer during call setup operation (MO/MT)
-    // MO : 200 OK to INVITE request is not received,
-    // MT : No action from user after alerting the call
+    /**
+     * User didn't answer during call setup operation (MO/MT)
+     * MO : 200 OK to INVITE request is not received,
+     * MT : No action from user after alerting the call
+     */
     public static final int CODE_TIMEOUT_NO_ANSWER = 202;
-    // User no answer during call update operation (MO/MT)
-    // MO : 200 OK to re-INVITE request is not received,
-    // MT : No action from user after alerting the call
+    /**
+     * User no answer during call update operation (MO/MT)
+     * MO : 200 OK to re-INVITE request is not received,
+     * MT : No action from user after alerting the call
+     */
     public static final int CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE = 203;
 
-    //Call was blocked by call barring
+    /**
+     * The call was blocked by call barring configuration.
+     */
     public static final int CODE_CALL_BARRED = 240;
 
-    //Call failures for FDN
+    /**
+     * The operation is restricted to fixed dialing numbers only.
+     */
     public static final int CODE_FDN_BLOCKED = 241;
 
-    // Network does not accept the emergency call request because IMEI was used as identification
-    // and this capability is not supported by the network.
+    /**
+     * Network rejected the emergency call request because IMEI was used as identification
+     * and this capability is not supported by the network.
+     */
     public static final int CODE_IMEI_NOT_ACCEPTED = 243;
 
     //STK CC errors
+    /**
+     * Stk Call Control modified DIAL request to USSD request.
+     */
     public static final int CODE_DIAL_MODIFIED_TO_USSD = 244;
+    /**
+     * Stk Call Control modified DIAL request to SS request.
+     */
     public static final int CODE_DIAL_MODIFIED_TO_SS = 245;
+    /**
+     * Stk Call Control modified DIAL request to DIAL with modified data.
+     */
     public static final int CODE_DIAL_MODIFIED_TO_DIAL = 246;
+    /**
+     * Stk Call Control modified DIAL request to Video DIAL request.
+     */
     public static final int CODE_DIAL_MODIFIED_TO_DIAL_VIDEO = 247;
+    /**
+     * Stk Call Control modified Video DIAL request to DIAL request.
+     */
     public static final int CODE_DIAL_VIDEO_MODIFIED_TO_DIAL = 248;
+    /**
+     * Stk Call Control modified Video DIAL request to Video DIAL request.
+     */
     public static final int CODE_DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO = 249;
+    /**
+     * Stk Call Control modified Video DIAL request to SS request.
+     */
     public static final int CODE_DIAL_VIDEO_MODIFIED_TO_SS = 250;
+    /**
+     * Stk Call Control modified Video DIAL request to USSD request.
+     */
     public static final int CODE_DIAL_VIDEO_MODIFIED_TO_USSD = 251;
 
-    /**
+    /*
      * STATUSCODE (SIP response code) (IMS -> Telephony)
      */
     // 3xx responses
-    // SIP request is redirected
+    /**
+     * SIP 3xx response: SIP request is redirected
+     */
     public static final int CODE_SIP_REDIRECTED = 321;
     // 4xx responses
-    // 400 : Bad Request
+    /**
+     * Sip 400 response : Bad Request
+     */
     public static final int CODE_SIP_BAD_REQUEST = 331;
-    // 403 : Forbidden
+    /**
+     * Sip 403 response : Forbidden
+     */
     public static final int CODE_SIP_FORBIDDEN = 332;
-    // 404 : Not Found
+    /**
+     * Sip 404 response : Not Found
+     */
     public static final int CODE_SIP_NOT_FOUND = 333;
-    // 415 : Unsupported Media Type
-    // 416 : Unsupported URI Scheme
-    // 420 : Bad Extension
+    /**
+     * Not supported, because of one of the following:
+     * SIP response 415 : Unsupported Media Type,
+     * SIP response 416 : Unsupported URI Scheme,
+     * SIP response 420 : Bad Extension
+     */
     public static final int CODE_SIP_NOT_SUPPORTED = 334;
-    // 408 : Request Timeout
+    /**
+     * SIP response 408 : Request Timeout.
+     */
     public static final int CODE_SIP_REQUEST_TIMEOUT = 335;
-    // 480 : Temporarily Unavailable
+    /**
+     * SIP response 480 : Temporarily Unavailable
+     */
     public static final int CODE_SIP_TEMPRARILY_UNAVAILABLE = 336;
-    // 484 : Address Incomplete
+    /**
+     * SIP response 484 : Address Incomplete
+     */
     public static final int CODE_SIP_BAD_ADDRESS = 337;
-    // 486 : Busy Here
-    // 600 : Busy Everywhere
+    /**
+     * Returned a busy response, may be one of the following:
+     * SIP response 486 : Busy Here,
+     * SIP response 600 : Busy Everywhere
+     */
     public static final int CODE_SIP_BUSY = 338;
-    // 487 : Request Terminated
+    /**
+     * SIP response 487 : Request Terminated
+     */
     public static final int CODE_SIP_REQUEST_CANCELLED = 339;
-    // 406 : Not Acceptable
-    // 488 : Not Acceptable Here
-    // 606 : Not Acceptable
+    /**
+     * Received a not acceptable response, will be one of the following:
+     * SIP response 406 : Not Acceptable
+     * SIP response 488 : Not Acceptable Here
+     * SIP response 606 : Not Acceptable
+     */
     public static final int CODE_SIP_NOT_ACCEPTABLE = 340;
-    // 410 : Gone
-    // 604 : Does Not Exist Anywhere
+    /**
+     * Received a not acceptable response, will be one of the following:
+     * SIP response 410 : Gone
+     * SIP response 604 : Does Not Exist Anywhere
+     */
     public static final int CODE_SIP_NOT_REACHABLE = 341;
-    // Others
+    /**
+     * Received another unspecified error SIP response from the client.
+     */
     public static final int CODE_SIP_CLIENT_ERROR = 342;
-    // 481 Transaction Does Not Exist
+    /**
+     * SIP response 481: Transaction Does Not Exist
+     */
     public static final int CODE_SIP_TRANSACTION_DOES_NOT_EXIST = 343;
     // 5xx responses
-    // 501 : Server Internal Error
+    /**
+     * SIP response 501 : Server Internal Error
+     */
     public static final int CODE_SIP_SERVER_INTERNAL_ERROR = 351;
-    // 503 : Service Unavailable
+    /**
+     * SIP response 503 : Service Unavailable
+     */
     public static final int CODE_SIP_SERVICE_UNAVAILABLE = 352;
-    // 504 : Server Time-out
+    /**
+     * SIP response 504 : Server Time-out
+     */
     public static final int CODE_SIP_SERVER_TIMEOUT = 353;
-    // Others
+    /**
+     * Received an unspecified SIP server error response.
+     */
     public static final int CODE_SIP_SERVER_ERROR = 354;
     // 6xx responses
-    // 603 : Decline
+    /**
+     * 603 : Decline
+     */
     public static final int CODE_SIP_USER_REJECTED = 361;
-    // Others
+    /**
+     * Unspecified 6xx error.
+     */
     public static final int CODE_SIP_GLOBAL_ERROR = 362;
-    // Emergency failure
+
+    /**
+     * Emergency call failed in the modem with a temporary fail cause and should be redialed on this
+     * slot.
+     */
     public static final int CODE_EMERGENCY_TEMP_FAILURE = 363;
+    /**
+     * Emergency call failed in the modem with a permanent fail cause and should not be redialed on
+     * this slot. If there are any other slots available for emergency calling, try those.
+     */
     public static final int CODE_EMERGENCY_PERM_FAILURE = 364;
 
     /**
@@ -193,82 +331,149 @@
      */
     public static final int CODE_SIP_USER_MARKED_UNWANTED = 365;
 
-    /**
+    /*
      * MEDIA (IMS -> Telephony)
      */
-    // Media resource initialization failed
+    /**
+     * Media resource initialization failed
+     */
     public static final int CODE_MEDIA_INIT_FAILED = 401;
-    // RTP timeout (no audio / video traffic in the session)
+    /**
+     * RTP timeout (no audio / video traffic in the session)
+     */
     public static final int CODE_MEDIA_NO_DATA = 402;
-    // Media is not supported; so dropped the call
+    /**
+     * Media is not supported; so dropped the call
+     */
     public static final int CODE_MEDIA_NOT_ACCEPTABLE = 403;
-    // Unknown media related errors
+    /**
+     * Unspecified media related error.
+     */
     public static final int CODE_MEDIA_UNSPECIFIED = 404;
 
-    /**
+    /*
      * USER
      */
     // Telephony -> IMS
-    // User triggers the call end
+    /**
+     * User triggers the call to be terminated.
+     */
     public static final int CODE_USER_TERMINATED = 501;
-    // No action while an incoming call is ringing
+    /**
+     * No action was taken while an incoming call was ringing.
+     */
     public static final int CODE_USER_NOANSWER = 502;
-    // User ignores an incoming call
+    /**
+     * User ignored an incoming call.
+     */
     public static final int CODE_USER_IGNORE = 503;
-    // User declines an incoming call
+    /**
+     * User declined an incoming call.
+     */
     public static final int CODE_USER_DECLINE = 504;
-    // Device declines/ends a call due to low battery
+    /**
+     * Device declined/ended a call due to a low battery condition.
+     */
     public static final int CODE_LOW_BATTERY = 505;
-    // Device declines call due to blacklisted call ID
+    /**
+     * Device declined a call due to a blacklisted caller ID.
+     */
     public static final int CODE_BLACKLISTED_CALL_ID = 506;
     // IMS -> Telephony
-    // The call is terminated by the network or remote user
+    /**
+     * The call has been terminated by the network or remote user.
+     */
     public static final int CODE_USER_TERMINATED_BY_REMOTE = 510;
 
-    /**
-     * Extra codes for the specific code value
-     * This value can be referred when the code is CODE_LOCAL_CALL_CS_RETRY_REQUIRED.
-     */
-    // Try to connect CS call; normal
-    public static final int EXTRA_CODE_CALL_RETRY_NORMAL = 1;
-    // Try to connect CS call without the notification to user
-    public static final int EXTRA_CODE_CALL_RETRY_SILENT_REDIAL = 2;
-    // Try to connect CS call by the settings of the menu
-    public static final int EXTRA_CODE_CALL_RETRY_BY_SETTINGS = 3;
-
-    /**
+    /*
      * UT
      */
+    /**
+     * UT is currently not supported on this device.
+     */
     public static final int CODE_UT_NOT_SUPPORTED = 801;
+    /**
+     * UT services are currently not available on this device.
+     */
     public static final int CODE_UT_SERVICE_UNAVAILABLE = 802;
+    /**
+     * The requested UT operation is not allowed.
+     */
     public static final int CODE_UT_OPERATION_NOT_ALLOWED = 803;
+    /**
+     * The UT request resulted in a network error.
+     */
     public static final int CODE_UT_NETWORK_ERROR = 804;
+    /**
+     * The password entered for UT operations does not match the stored password.
+     */
     public static final int CODE_UT_CB_PASSWORD_MISMATCH = 821;
     //STK CC errors
+    /**
+     * Sim Toolkit Call Control modified the UT operation to a dial command.
+     */
     public static final int CODE_UT_SS_MODIFIED_TO_DIAL = 822;
+    /**
+     * Sim Toolkit Call Control modified the UT operation to a USSD command.
+     */
     public static final int CODE_UT_SS_MODIFIED_TO_USSD = 823;
+    /**
+     * Sim Toolkit Call Control modified the UT operation to another supplementary service command.
+     */
     public static final int CODE_UT_SS_MODIFIED_TO_SS = 824;
+    /**
+     * Sim Toolkit Call Control modified the UT operation to a video call dial command.
+     */
     public static final int CODE_UT_SS_MODIFIED_TO_DIAL_VIDEO = 825;
 
+    /**@hide*/
+    @IntDef(value = {
+            CODE_UT_NOT_SUPPORTED,
+            CODE_UT_SERVICE_UNAVAILABLE,
+            CODE_UT_OPERATION_NOT_ALLOWED,
+            CODE_UT_NETWORK_ERROR,
+            CODE_UT_CB_PASSWORD_MISMATCH,
+            CODE_UT_SS_MODIFIED_TO_DIAL,
+            CODE_UT_SS_MODIFIED_TO_USSD,
+            CODE_UT_SS_MODIFIED_TO_SS,
+            CODE_UT_SS_MODIFIED_TO_DIAL_VIDEO
+    }, prefix = "CODE_UT_")
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface UtReason {}
+
     /**
-     * ECBM
+     * Emergency callback mode is not supported.
      */
     public static final int CODE_ECBM_NOT_SUPPORTED = 901;
 
     /**
-     * Fail code used to indicate that Multi-endpoint is not supported by the Ims framework.
+     * Fail code used to indicate that Multi-endpoint is not supported by the IMS framework.
      */
     public static final int CODE_MULTIENDPOINT_NOT_SUPPORTED = 902;
 
     /**
-     * Ims Registration error code
+     * IMS Registration error code
      */
     public static final int CODE_REGISTRATION_ERROR = 1000;
 
-    /**
+    /*
      * CALL DROP error codes (Call could drop because of many reasons like Network not available,
      *  handover, failed, etc)
      */
+    /**
+     * MT call has ended due to a release from the network because the call was answered elsewhere.
+     */
+    public static final int CODE_ANSWERED_ELSEWHERE = 1014;
+
+    /**
+     * For MultiEndpoint - Call Pull request has failed.
+     */
+    public static final int CODE_CALL_PULL_OUT_OF_SYNC = 1015;
+
+    /**
+     * For MultiEndpoint - Call has been pulled from primary to secondary.
+     */
+    public static final int CODE_CALL_END_CAUSE_CALL_PULL = 1016;
 
     /**
      * CALL DROP error code for the case when a device is ePDG capable and when the user is on an
@@ -279,46 +484,35 @@
     public static final int CODE_CALL_DROP_IWLAN_TO_LTE_UNAVAILABLE = 1100;
 
     /**
-     * MT call has ended due to a release from the network
-     * because the call was answered elsewhere
-     */
-    public static final int CODE_ANSWERED_ELSEWHERE = 1014;
-
-    /**
-     * For MultiEndpoint - Call Pull request has failed
-     */
-    public static final int CODE_CALL_PULL_OUT_OF_SYNC = 1015;
-
-    /**
-     * For MultiEndpoint - Call has been pulled from primary to secondary
-     */
-    public static final int CODE_CALL_END_CAUSE_CALL_PULL = 1016;
-
-    /**
-     * Supplementary services (HOLD/RESUME) failure error codes.
-     * Values for Supplemetary services failure - Failed, Cancelled and Re-Invite collision.
+     * Supplementary Services (HOLD/RESUME) - the command failed.
      */
     public static final int CODE_SUPP_SVC_FAILED = 1201;
+    /**
+     * Supplementary Services (HOLD/RESUME) - the command was cancelled.
+     */
     public static final int CODE_SUPP_SVC_CANCELLED = 1202;
+    /**
+     * Supplementary Services (HOLD/RESUME) - the command resulted in a re-invite collision.
+     */
     public static final int CODE_SUPP_SVC_REINVITE_COLLISION = 1203;
 
     /**
-     * DPD Procedure received no response or send failed
+     * DPD Procedure received no response or send failed.
      */
     public static final int CODE_IWLAN_DPD_FAILURE = 1300;
 
     /**
-     * Establishment of the ePDG Tunnel Failed
+     * Establishment of the ePDG Tunnel Failed.
      */
     public static final int CODE_EPDG_TUNNEL_ESTABLISH_FAILURE = 1400;
 
     /**
-     * Re-keying of the ePDG Tunnel Failed; may not always result in teardown
+     * Re-keying of the ePDG Tunnel Failed; may not always result in teardown.
      */
     public static final int CODE_EPDG_TUNNEL_REKEY_FAILURE = 1401;
 
     /**
-     * Connection to the packet gateway is lost
+     * Connection to the packet gateway is lost.
      */
     public static final int CODE_EPDG_TUNNEL_LOST_CONNECTION = 1402;
 
@@ -571,8 +765,10 @@
      */
     public static final int CODE_REJECT_ONGOING_CS_CALL = 1621;
 
-    /* OEM specific error codes. To be used by OEMs when they don't want to
-   reveal error code which would be replaced by ERROR_UNSPECIFIED */
+    /*
+     * OEM specific error codes. To be used by OEMs when they don't want to reveal error code which
+     * would be replaced by ERROR_UNSPECIFIED.
+     */
     public static final int CODE_OEM_CAUSE_1 = 0xf001;
     public static final int CODE_OEM_CAUSE_2 = 0xf002;
     public static final int CODE_OEM_CAUSE_3 = 0xf003;
@@ -597,6 +793,33 @@
             = "Forbidden. Not Authorized for Service";
 
 
+    /*
+     * Extra codes for the specific code value
+     * This value can be referred when the code is CODE_LOCAL_CALL_CS_RETRY_REQUIRED.
+     */
+    /**
+     * An extra that may be populated when the {@link CODE_LOCAL_CALL_CS_RETRY_REQUIRED} result has
+     * been returned.
+     * <p>
+     * Try to connect the call using CS
+     */
+    public static final int EXTRA_CODE_CALL_RETRY_NORMAL = 1;
+    /**
+     * An extra that may be populated when the {@link CODE_LOCAL_CALL_CS_RETRY_REQUIRED} result has
+     * been returned.
+     * <p>
+     * Try to connect the call using CS and do not notify the user.
+     */
+    public static final int EXTRA_CODE_CALL_RETRY_SILENT_REDIAL = 2;
+    /**
+     * An extra that may be populated when the {@link CODE_LOCAL_CALL_CS_RETRY_REQUIRED} result has
+     * been returned.
+     * <p>
+     * Try to connect the call using CS by using the settings.
+     */
+    public static final int EXTRA_CODE_CALL_RETRY_BY_SETTINGS = 3;
+
+
     // For main reason code
     /** @hide */
     @UnsupportedAppUsage
@@ -638,29 +861,28 @@
     }
 
     /**
-     *
+     * @return an integer representing more information about the completion of an operation.
      */
     public int getCode() {
         return mCode;
     }
 
     /**
-     *
+     * @return an optional OEM specified code that provides extra information.
      */
     public int getExtraCode() {
         return mExtraCode;
     }
 
     /**
-     *
+     * @return an optional OEM specified string that provides extra information about the operation
+     * result.
      */
     public String getExtraMessage() {
         return mExtraMessage;
     }
 
     /**
-     * Returns the string format of {@link ImsReasonInfo}
-     *
      * @return the string format of {@link ImsReasonInfo}
      */
     public String toString() {
diff --git a/telephony/java/android/telephony/ims/ImsSsData.java b/telephony/java/android/telephony/ims/ImsSsData.java
index db5ba47..3a82517 100644
--- a/telephony/java/android/telephony/ims/ImsSsData.java
+++ b/telephony/java/android/telephony/ims/ImsSsData.java
@@ -65,6 +65,17 @@
     public static final int SS_INCOMING_BARRING_DN = 21;
     public static final int SS_INCOMING_BARRING_ANONYMOUS = 22;
 
+
+    /**@hide*/
+    @IntDef(flag = true, prefix = {"SS_"}, value = {
+            SS_ACTIVATION,
+            SS_DEACTIVATION,
+            SS_INTERROGATION,
+            SS_REGISTRATION,
+            SS_ERASURE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RequestType{}
+
     //Supplementary Service Request Types
     public static final int SS_ACTIVATION = 0;
     public static final int SS_DEACTIVATION = 1;
@@ -72,6 +83,17 @@
     public static final int SS_REGISTRATION = 3;
     public static final int SS_ERASURE = 4;
 
+    /**@hide*/
+    @IntDef(flag = true, prefix = {"SS_"}, value = {
+            SS_ALL_TELE_AND_BEARER_SERVICES,
+            SS_ALL_TELESEVICES,
+            SS_TELEPHONY,
+            SS_ALL_DATA_TELESERVICES,
+            SS_SMS_SERVICES,
+            SS_ALL_TELESERVICES_EXCEPT_SMS})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TeleserviceType{}
+
     // Supplementary Service Teleservice Type
     public static final int SS_ALL_TELE_AND_BEARER_SERVICES = 0;
     public static final int SS_ALL_TELESEVICES = 1;
@@ -191,21 +213,6 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface ServiceType{}
 
-    /** @hide */
-    @IntDef(flag = true, prefix = { "SERVICE_CLASS" }, value = {
-            SERVICE_CLASS_NONE,
-            SERVICE_CLASS_VOICE,
-            SERVICE_CLASS_DATA,
-            SERVICE_CLASS_FAX,
-            SERVICE_CLASS_SMS,
-            SERVICE_CLASS_DATA_CIRCUIT_SYNC,
-            SERVICE_CLASS_DATA_CIRCUIT_ASYNC,
-            SERVICE_CLASS_DATA_PACKET_ACCESS,
-            SERVICE_CLASS_DATA_PAD
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ServiceClass{}
-
     /**
      * The Service type of this Supplementary service.
      * @hide
@@ -221,7 +228,7 @@
      *     {@link #SS_ERASURE}
      * @hide
      */
-    public final int requestType;
+    public final @RequestType int requestType;
 
     /**
      * Supplementary Service teleservice type:
@@ -234,14 +241,14 @@
      *
      * @hide
      */
-    public final int teleserviceType;
+    public final @TeleserviceType int teleserviceType;
 
     /**
      * Supplementary Service service class.
      *
      * @hide
      */
-    public final @ServiceClass int serviceClass;
+    public final @ServiceClassFlags int serviceClass;
 
     /**
      * Result of Supplementary Service operation. Valid values are:
@@ -285,7 +292,7 @@
          * @see #build()
          */
         public Builder(@ServiceType int serviceType, int requestType, int teleserviceType,
-                @ServiceClass int serviceClass, int result) {
+                @ServiceClassFlags int serviceClass, int result) {
             mImsSsData = new ImsSsData(serviceType, requestType, teleserviceType, serviceClass,
                     result);
         }
@@ -294,7 +301,7 @@
          * Set the array of {@link ImsSsInfo}s that are associated with this supplementary service
          * data.
          */
-        public Builder setSuppServiceInfo(@NonNull ImsSsInfo[] imsSsInfos) {
+        public @NonNull Builder setSuppServiceInfo(@NonNull ImsSsInfo[] imsSsInfos) {
             mImsSsData.mImsSsInfo = imsSsInfos;
             return this;
         }
@@ -303,7 +310,8 @@
          * Set the array of {@link ImsCallForwardInfo}s that are associated with this supplementary
          * service data.
          */
-        public Builder setCallForwardingInfo(@NonNull ImsCallForwardInfo[] imsCallForwardInfos) {
+        public @NonNull Builder setCallForwardingInfo(
+                @NonNull ImsCallForwardInfo[] imsCallForwardInfos) {
             mImsSsData.mCfInfo = imsCallForwardInfos;
             return this;
         }
@@ -311,7 +319,7 @@
         /**
          * @return an {@link ImsSsData} containing optional parameters.
          */
-        public ImsSsData build() {
+        public @NonNull ImsSsData build() {
             return mImsSsData;
         }
     }
@@ -337,7 +345,7 @@
      *               success, or ImsReasonInfo code if the result is a failure.
      */
     public ImsSsData(@ServiceType int serviceType, int requestType, int teleserviceType,
-            @ServiceClass int serviceClass, int result) {
+            @ServiceClassFlags int serviceClass, int result) {
         this.serviceType = serviceType;
         this.requestType = requestType;
         this.teleserviceType = teleserviceType;
@@ -449,14 +457,9 @@
     }
 
     /**
-     * Supplementary Service request Type:
-     *     {@link #SS_ACTIVATION),
-     *     {@link #SS_DEACTIVATION},
-     *     {@link #SS_INTERROGATION},
-     *     {@link #SS_REGISTRATION},
-     *     {@link #SS_ERASURE}
+     * Supplementary Service request Type.
      */
-    public int getRequestType() {
+    public @RequestType int getRequestType() {
         return requestType;
     }
 
@@ -468,31 +471,25 @@
     }
 
     /**
-     * Supplementary Service teleservice type:
-     *     {@link #SS_ALL_TELE_AND_BEARER_SERVICES},
-     *     {@link #SS_ALL_TELESEVICES},
-     *     {@link #SS_TELEPHONY},
-     *     {@link #SS_ALL_DATA_TELESERVICES},
-     *     {@link #SS_SMS_SERVICES},
-     *     {@link #SS_ALL_TELESERVICES_EXCEPT_SMS}
+     * Supplementary Service teleservice type.
      */
-    public int getTeleserviceType() {
+    public @TeleserviceType int getTeleserviceType() {
         return teleserviceType;
     }
 
     /**
      * Supplementary Service service class.
      */
-    public @ServiceClass int getServiceClass() {
+    public @ServiceClassFlags int getServiceClass() {
         return serviceClass;
     }
 
     /**
      * Result of Supplementary Service operation. Valid values are:
      *     {@link #RESULT_SUCCESS} if the result is success, or
-     *     {@link ImsReasonInfo} CODE_* code if the result is a failure.
+     *     {@link ImsReasonInfo.UtReason} code if the result is a failure.
      */
-    public int getResult() {
+    public @ImsReasonInfo.UtReason int getResult() {
         return result;
     }
 
diff --git a/telephony/java/android/telephony/ims/ImsSsInfo.java b/telephony/java/android/telephony/ims/ImsSsInfo.java
index 0af6e62..031f9e1 100644
--- a/telephony/java/android/telephony/ims/ImsSsInfo.java
+++ b/telephony/java/android/telephony/ims/ImsSsInfo.java
@@ -82,6 +82,7 @@
      */
     public static final int SERVICE_PROVISIONED = 1;
 
+    /**@hide*/
     @IntDef(value = {
             CLIR_OUTGOING_DEFAULT,
             CLIR_OUTGOING_INVOCATION,
@@ -141,6 +142,7 @@
      */
     public static final int CLIR_STATUS_TEMPORARILY_ALLOWED = 4;
 
+    /**@hide*/
     @IntDef(value = {
             CLIR_STATUS_NOT_PROVISIONED,
             CLIR_STATUS_PROVISIONED_PERMANENT,
@@ -184,7 +186,7 @@
          * Set the ICB number for IMS call barring.
          * @param number The number in E.164 international format.
          */
-        public Builder setIncomingCommunicationBarringNumber(@NonNull String number) {
+        public @NonNull Builder setIncomingCommunicationBarringNumber(@NonNull String number) {
             mImsSsInfo.mIcbNum = number;
             return this;
         }
@@ -192,7 +194,7 @@
         /**
          * Set the provisioning status for a Supplementary Service interrogation response.
          */
-        public Builder setProvisionStatus(@ServiceProvisionStatus int provisionStatus) {
+        public @NonNull Builder setProvisionStatus(@ServiceProvisionStatus int provisionStatus) {
             mImsSsInfo.mProvisionStatus = provisionStatus;
             return this;
         }
@@ -201,7 +203,7 @@
          * Set the Calling Line Identification Restriction (CLIR) status for a supplementary service
          * interrogation response.
          */
-        public Builder setClirInterrogationStatus(@ClirInterrogationStatus int status) {
+        public @NonNull Builder setClirInterrogationStatus(@ClirInterrogationStatus int status) {
             mImsSsInfo.mClirInterrogationStatus = status;
             return this;
         }
@@ -209,7 +211,7 @@
         /**
          * Set the Calling line identification Restriction (CLIR) state for outgoing calls.
          */
-        public Builder setClirOutgoingState(@ClirOutgoingState int state) {
+        public @NonNull Builder setClirOutgoingState(@ClirOutgoingState int state) {
             mImsSsInfo.mClirOutgoingState = state;
             return this;
         }
@@ -217,7 +219,7 @@
         /**
          * @return a built {@link ImsSsInfo} containing optional the parameters that were set.
          */
-        public ImsSsInfo build() {
+        public @NonNull ImsSsInfo build() {
             return mImsSsInfo;
         }
     }
diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java
index 0abe45c..13539b8 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -17,6 +17,7 @@
 package com.android.internal.telephony;
 
 import android.annotation.UnsupportedAppUsage;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.database.Cursor;
@@ -32,15 +33,15 @@
 import android.provider.ContactsContract.RawContacts;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.Rlog;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
 
-import com.android.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder;
 import com.android.i18n.phonenumbers.NumberParseException;
 import com.android.i18n.phonenumbers.PhoneNumberUtil;
 import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber;
-import android.telephony.SubscriptionManager;
+import com.android.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder;
 
 import java.util.Locale;
 
@@ -112,6 +113,9 @@
     public Uri contactRefUri;
     public String lookupKey;
 
+    public ComponentName preferredPhoneAccountComponent;
+    public String preferredPhoneAccountId;
+
     public long userType;
 
     /**
@@ -264,6 +268,17 @@
                     info.contactDisplayPhotoUri = null;
                 }
 
+                columnIndex = cursor.getColumnIndex(Data.PREFERRED_PHONE_ACCOUNT_COMPONENT_NAME);
+                if ((columnIndex != -1) && (cursor.getString(columnIndex) != null)) {
+                    info.preferredPhoneAccountComponent =
+                            ComponentName.unflattenFromString(cursor.getString(columnIndex));
+                }
+
+                columnIndex = cursor.getColumnIndex(Data.PREFERRED_PHONE_ACCOUNT_ID);
+                if ((columnIndex != -1) && (cursor.getString(columnIndex) != null)) {
+                    info.preferredPhoneAccountId = cursor.getString(columnIndex);
+                }
+
                 // look for the custom ringtone, create from the string stored
                 // in the database.
                 // An empty string ("") in the database indicates a silent ringtone,
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index f9db4b0..65d1a920 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -210,6 +210,10 @@
      */
     List<SubscriptionInfo> getOpportunisticSubscriptions(String callingPackage);
 
+    boolean removeSubscriptionsFromGroup(in int[] subIdList, String callingPackage);
+
+    List<SubscriptionInfo> getSubscriptionsInGroup(int subId, String callingPackage);
+
     int getSlotIndex(int subId);
 
     int[] getSubId(int slotIndex);
diff --git a/tests/net/java/android/net/NetworkCapabilitiesTest.java b/tests/net/java/android/net/NetworkCapabilitiesTest.java
index 50aef1d..84f7359 100644
--- a/tests/net/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/java/android/net/NetworkCapabilitiesTest.java
@@ -474,7 +474,7 @@
                 new StringNetworkSpecifier("specs"));
         try {
             nc2.addTransportType(TRANSPORT_WIFI);
-            fail("Cannot set NetworkSpecifier on a NetworkCapability with multiple transports!");
+            fail("Cannot set a second TransportType of a network which has a NetworkSpecifier!");
         } catch (IllegalStateException expected) {
             // empty
         }
@@ -500,16 +500,23 @@
             // empty
         });
         NetworkCapabilities nc2 = new NetworkCapabilities();
+        // new TransportInfo so that object is not #equals to nc1's TransportInfo (that's where
+        // combine fails)
         nc2.setTransportInfo(new TransportInfo() {
             // empty
         });
 
         try {
             nc1.combineCapabilities(nc2);
-            fail("Should not be able to combine NetworkCaabilities which contain TransportInfos");
+            fail("Should not be able to combine NetworkCabilities which contain TransportInfos");
         } catch (IllegalStateException expected) {
             // empty
         }
+
+        // verify that can combine with identical TransportInfo objects
+        NetworkCapabilities nc3 = new NetworkCapabilities();
+        nc3.setTransportInfo(nc1.getTransportInfo());
+        nc1.combineCapabilities(nc3);
     }
 
     private void assertEqualsThroughMarshalling(NetworkCapabilities netCap) {
diff --git a/tools/aapt2/configuration/ConfigurationParser_test.cpp b/tools/aapt2/configuration/ConfigurationParser_test.cpp
index 3a71e83..2ef8b99 100644
--- a/tools/aapt2/configuration/ConfigurationParser_test.cpp
+++ b/tools/aapt2/configuration/ConfigurationParser_test.cpp
@@ -230,7 +230,7 @@
                                       test::ParseConfigOrDie("fr"), test::ParseConfigOrDie("de")));
   ASSERT_TRUE(a1.android_sdk);
   ASSERT_TRUE(a1.android_sdk.value().min_sdk_version);
-  EXPECT_EQ(a1.android_sdk.value().min_sdk_version, 19l);
+  EXPECT_EQ(a1.android_sdk.value().min_sdk_version, 19L);
   EXPECT_THAT(a1.textures, SizeIs(1ul));
   EXPECT_THAT(a1.features, SizeIs(1ul));
 
@@ -250,7 +250,7 @@
                           test::ParseConfigOrDie("fr-rCA")));
   ASSERT_TRUE(a2.android_sdk);
   ASSERT_TRUE(a2.android_sdk.value().min_sdk_version);
-  EXPECT_EQ(a2.android_sdk.value().min_sdk_version, 19l);
+  EXPECT_EQ(a2.android_sdk.value().min_sdk_version, 19L);
   EXPECT_THAT(a2.textures, SizeIs(1ul));
   EXPECT_THAT(a2.features, SizeIs(1ul));
 }
diff --git a/tools/localedata/extract_icu_data.py b/tools/localedata/extract_icu_data.py
index 9dceba2..6b4c346 100755
--- a/tools/localedata/extract_icu_data.py
+++ b/tools/localedata/extract_icu_data.py
@@ -155,7 +155,7 @@
     print
     print 'std::unordered_set<uint64_t> REPRESENTATIVE_LOCALES({'
     for locale in sorted(representative_locales):
-        print '    0x%08Xllu, // %s' % (
+        print '    0x%08XLLU, // %s' % (
             pack_to_uint64(locale),
             locale)
     print '});'
diff --git a/tools/processors/view_inspector/OWNERS b/tools/processors/view_inspector/OWNERS
new file mode 100644
index 0000000..0473f54
--- /dev/null
+++ b/tools/processors/view_inspector/OWNERS
@@ -0,0 +1,3 @@
+alanv@google.com
+ashleyrose@google.com
+aurimas@google.com
\ No newline at end of file
diff --git a/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectableClassModel.java b/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectableClassModel.java
index f0b0ff6..579745d 100644
--- a/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectableClassModel.java
+++ b/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectableClassModel.java
@@ -18,16 +18,20 @@
 
 import com.squareup.javapoet.ClassName;
 
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Optional;
 
 /**
  * Model of an inspectable class derived from annotations.
  *
- * This class does not use any {javax.lang.model} objects to facilitate building models for testing
- * {@link InspectionCompanionGenerator}.
+ * This class does not use any {@code javax.lang.model} objects to facilitate building models for
+ * testing {@link InspectionCompanionGenerator}.
  */
 public final class InspectableClassModel {
     private final ClassName mClassName;
+    private final Map<String, Property> mPropertyMap;
     private Optional<String> mNodeName = Optional.empty();
 
     /**
@@ -35,6 +39,7 @@
      */
     public InspectableClassModel(ClassName className) {
         mClassName = className;
+        mPropertyMap = new HashMap<>();
     }
 
     public ClassName getClassName() {
@@ -48,4 +53,148 @@
     public void setNodeName(Optional<String> nodeName) {
         mNodeName = nodeName;
     }
+
+    /**
+     * Add a property to the model, replacing an existing property of the same name.
+     *
+     * @param property The property to add or replace
+     */
+    public void putProperty(Property property) {
+        mPropertyMap.put(property.getName(), property);
+    }
+
+    /**
+     * Get a property by name.
+     *
+     * @param name The name of the property
+     * @return The property or an empty optional
+     */
+    public Optional<Property> getProperty(String name) {
+        return Optional.of(mPropertyMap.get(name));
+    }
+
+    /**
+     * Get all the properties defined on this model.
+     *
+     * @return An un-ordered collection of properties
+     */
+    public Collection<Property> getAllProperties() {
+        return mPropertyMap.values();
+    }
+
+    /**
+     * Model an inspectable property
+     */
+    public static final class Property {
+        private final String mName;
+        private String mGetter;
+        private Type mType;
+        private boolean mAttributeIdInferrableFromR = true;
+        private int mAttributeId = 0;
+
+        public Property(String name) {
+            mName = name;
+        }
+
+        public int getAttributeId() {
+            return mAttributeId;
+        }
+
+        /**
+         * Set the attribute ID, and mark the attribute ID as non-inferrable.
+         *
+         * @param attributeId The attribute ID for this property
+         */
+        public void setAttributeId(int attributeId) {
+            mAttributeIdInferrableFromR = false;
+            mAttributeId = attributeId;
+        }
+
+        public boolean isAttributeIdInferrableFromR() {
+            return mAttributeIdInferrableFromR;
+        }
+
+        public void setAttributeIdInferrableFromR(boolean attributeIdInferrableFromR) {
+            mAttributeIdInferrableFromR = attributeIdInferrableFromR;
+        }
+
+        public String getName() {
+            return mName;
+        }
+
+        public String getGetter() {
+            return mGetter;
+        }
+
+        public void setGetter(String getter) {
+            mGetter = getter;
+        }
+
+        public Type getType() {
+            return mType;
+        }
+
+        public void setType(Type type) {
+            mType = type;
+        }
+
+        public enum Type {
+            /** Primitive or boxed {@code boolean} */
+            BOOLEAN,
+
+            /** Primitive or boxed {@code byte} */
+            BYTE,
+
+            /** Primitive or boxed {@code char} */
+            CHAR,
+
+            /** Primitive or boxed {@code double} */
+            DOUBLE,
+
+            /** Primitive or boxed {@code float} */
+            FLOAT,
+
+            /** Primitive or boxed {@code int} */
+            INT,
+
+            /** Primitive or boxed {@code long} */
+            LONG,
+
+            /** Primitive or boxed {@code short} */
+            SHORT,
+
+            /** Any other object */
+            OBJECT,
+
+            /**
+             * A color object or packed color {@code int} or {@code long}.
+             *
+             * @see android.graphics.Color
+             * @see android.annotation.ColorInt
+             * @see android.annotation.ColorLong
+             */
+            COLOR,
+
+            /**
+             * An {@code int} packed with a gravity specification
+             *
+             * @see android.view.Gravity
+             */
+            GRAVITY,
+
+            /**
+             * An enumeration packed into an {@code int}.
+             *
+             * @see android.view.inspector.IntEnumMapping
+             */
+            INT_ENUM,
+
+            /**
+             * Non-exclusive or partially-exclusive flags packed into an {@code int}.
+             *
+             * @see android.view.inspector.IntFlagMapping
+             */
+            INT_FLAG
+        }
+    }
 }
diff --git a/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java b/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java
index fe0153d..3b85dbb 100644
--- a/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java
+++ b/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java
@@ -16,13 +16,23 @@
 
 package android.processor.view.inspector;
 
+import android.processor.view.inspector.InspectableClassModel.Property;
+
 import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.CodeBlock;
+import com.squareup.javapoet.FieldSpec;
 import com.squareup.javapoet.JavaFile;
 import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.NameAllocator;
 import com.squareup.javapoet.ParameterizedTypeName;
+import com.squareup.javapoet.TypeName;
 import com.squareup.javapoet.TypeSpec;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.NoSuchElementException;
 import java.util.Optional;
 
 import javax.annotation.processing.Filer;
@@ -36,10 +46,62 @@
     private final Class mRequestingClass;
 
     /**
+     * The class name for {@code R.java}.
+     */
+    private static final ClassName R_CLASS_NAME = ClassName.get("android", "R");
+
+    /**
+     * The class name of {@link android.content.res.ResourceId}.
+     */
+    private static final ClassName RESOURCE_ID_CLASS_NAME = ClassName.get(
+            "android.content.res", "ResourceId");
+
+    /**
+     * The class name of {@link android.view.inspector.InspectionCompanion}.
+     */
+    private static final ClassName INSPECTION_COMPANION = ClassName.get(
+            "android.view.inspector", "InspectionCompanion");
+
+    /**
+     * The class name of {@link android.view.inspector.PropertyMapper}.
+     */
+    private static final ClassName PROPERTY_MAPPER = ClassName.get(
+            "android.view.inspector", "PropertyMapper");
+
+    /**
+     * The class name of {@link android.view.inspector.PropertyReader}.
+     */
+    private static final ClassName PROPERTY_READER = ClassName.get(
+            "android.view.inspector", "PropertyReader");
+
+    /**
+     * The {@code mPropertiesMapped} field.
+     */
+    private static final FieldSpec M_PROPERTIES_MAPPED = FieldSpec
+            .builder(TypeName.BOOLEAN, "mPropertiesMapped", Modifier.PRIVATE)
+            .initializer("false")
+            .addJavadoc(
+                    "Set by {@link #mapProperties($T)} once properties have been mapped.\n",
+                    PROPERTY_MAPPER)
+            .build();
+
+    /**
+     * The suffix of the generated class name after the class's binary name.
+     */
+    private static final String GENERATED_CLASS_SUFFIX = "$$InspectionCompanion";
+
+    /**
+     * The null resource ID.
+     *
+     * @see android.content.res.ResourceId#ID_NULL
+     */
+    private static final int NO_ID = 0;
+
+    /**
      * @param filer A filer to write the generated source to
      * @param requestingClass A class object representing the class that invoked the generator
      */
-    public InspectionCompanionGenerator(final Filer filer, final Class requestingClass) {
+    public InspectionCompanionGenerator(Filer filer, Class requestingClass) {
         mFiler = filer;
         mRequestingClass = requestingClass;
     }
@@ -77,17 +139,24 @@
      * @return A TypeSpec of the inspection companion
      */
     private TypeSpec generateTypeSpec(InspectableClassModel model) {
+        final List<PropertyIdField> propertyIdFields = generatePropertyIdFields(model);
+
         TypeSpec.Builder builder = TypeSpec
                 .classBuilder(generateClassName(model))
                 .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
                 .addSuperinterface(ParameterizedTypeName.get(
-                        ClassName.get("android.view.inspector", "InspectionCompanion"),
-                        model.getClassName()))
+                        INSPECTION_COMPANION, model.getClassName()))
                 .addJavadoc("Inspection companion for {@link $T}.\n\n", model.getClassName())
                 .addJavadoc("Generated by {@link $T}\n", getClass())
                 .addJavadoc("on behalf of {@link $T}.\n", mRequestingClass)
-                .addMethod(generateMapProperties(model))
-                .addMethod(generateReadProperties(model));
+                .addField(M_PROPERTIES_MAPPED);
+
+        for (PropertyIdField propertyIdField : propertyIdFields) {
+            builder.addField(propertyIdField.mFieldSpec);
+        }
+
+        builder.addMethod(generateMapProperties(propertyIdFields))
+                .addMethod(generateReadProperties(model, propertyIdFields));
 
         generateGetNodeName(model).ifPresent(builder::addMethod);
 
@@ -95,6 +164,42 @@
     }
 
     /**
+     * Build a list of {@link PropertyIdField}'s for a model.
+     *
+     * To insure idempotency of the generated code, this method sorts the list of properties
+     * alphabetically by name.
+     *
+     * A {@link NameAllocator} is used to ensure that the field names are valid Java identifiers,
+     * and it prevents overlaps in names by suffixing them as needed.
+     *
+     * @param model The model to get properties from
+     * @return A list of properties and fields
+     */
+    private List<PropertyIdField> generatePropertyIdFields(InspectableClassModel model) {
+        final NameAllocator nameAllocator = new NameAllocator();
+        final List<Property> sortedProperties = new ArrayList<>(model.getAllProperties());
+        final List<PropertyIdField> propertyIdFields = new ArrayList<>(sortedProperties.size());
+
+        sortedProperties.sort(Comparator.comparing(Property::getName));
+
+        for (Property property : sortedProperties) {
+            // Format a property to a member field name like "someProperty" -> "mSomePropertyId"
+            final String memberName = String.format(
+                    "m%s%sId",
+                    property.getName().substring(0, 1).toUpperCase(),
+                    property.getName().substring(1));
+            final FieldSpec fieldSpec = FieldSpec
+                    .builder(TypeName.INT, nameAllocator.newName(memberName), Modifier.PRIVATE)
+                    .addJavadoc("Property ID of {@code $L}.\n", property.getName())
+                    .build();
+
+            propertyIdFields.add(new PropertyIdField(fieldSpec, property));
+        }
+
+        return propertyIdFields;
+    }
+
+    /**
      * Generate a method definition for
      * {@link android.view.inspector.InspectionCompanion#getNodeName()}, if needed.
      *
@@ -119,21 +224,19 @@
      * {@link android.view.inspector.InspectionCompanion#mapProperties(
      * android.view.inspector.PropertyMapper)}.
      *
-     * TODO: implement
-     *
-     * @param model The model to generate from
+     * @param propertyIdFields A list of properties to map to ID fields
      * @return The method definition
      */
-    private MethodSpec generateMapProperties(InspectableClassModel model) {
-        final ClassName propertyMapper = ClassName.get(
-                "android.view.inspector", "PropertyMapper");
-
-        return MethodSpec.methodBuilder("mapProperties")
+    private MethodSpec generateMapProperties(List<PropertyIdField> propertyIdFields) {
+        final MethodSpec.Builder builder = MethodSpec.methodBuilder("mapProperties")
                 .addAnnotation(Override.class)
                 .addModifiers(Modifier.PUBLIC)
-                .addParameter(propertyMapper, "propertyMapper")
-                // TODO: add method body
-                .build();
+                .addParameter(PROPERTY_MAPPER, "propertyMapper");
+
+        propertyIdFields.forEach(p -> builder.addStatement(generatePropertyMapperInvocation(p)));
+        builder.addStatement("$N = true", M_PROPERTIES_MAPPED);
+
+        return builder.build();
     }
 
     /**
@@ -141,21 +244,91 @@
      * {@link android.view.inspector.InspectionCompanion#readProperties(
      * Object, android.view.inspector.PropertyReader)}.
      *
-     * TODO: implement
-     *
      * @param model The model to generate from
+     * @param propertyIdFields A list of properties and ID fields to read from
      * @return The method definition
      */
-    private MethodSpec generateReadProperties(InspectableClassModel model) {
-        final ClassName propertyReader = ClassName.get(
-                "android.view.inspector", "PropertyReader");
-
-        return MethodSpec.methodBuilder("readProperties")
+    private MethodSpec generateReadProperties(
+            InspectableClassModel model,
+            List<PropertyIdField> propertyIdFields) {
+        final MethodSpec.Builder builder =  MethodSpec.methodBuilder("readProperties")
                 .addAnnotation(Override.class)
                 .addModifiers(Modifier.PUBLIC)
                 .addParameter(model.getClassName(), "inspectable")
-                .addParameter(propertyReader, "propertyReader")
-                // TODO: add method body
+                .addParameter(PROPERTY_READER, "propertyReader")
+                .addCode(generatePropertyMapInitializationCheck());
+
+        for (PropertyIdField propertyIdField : propertyIdFields) {
+            builder.addStatement(
+                    "propertyReader.read$L($N, inspectable.$L())",
+                    methodSuffixForPropertyType(propertyIdField.mProperty.getType()),
+                    propertyIdField.mFieldSpec,
+                    propertyIdField.mProperty.getGetter());
+        }
+
+        return builder.build();
+    }
+
+    /**
+     * Generate a statement maps a property with a {@link android.view.inspector.PropertyMapper}.
+     *
+     * @param propertyIdField The property model and ID field to generate from
+     * @return A statement that invokes property mapper method
+     */
+    private CodeBlock generatePropertyMapperInvocation(PropertyIdField propertyIdField) {
+        final CodeBlock.Builder builder = CodeBlock.builder();
+        final Property property = propertyIdField.mProperty;
+        final FieldSpec fieldSpec = propertyIdField.mFieldSpec;
+
+        builder.add(
+                "$N = propertyMapper.map$L($S,$W",
+                fieldSpec,
+                methodSuffixForPropertyType(property.getType()),
+                property.getName());
+
+        if (property.isAttributeIdInferrableFromR()) {
+            builder.add("$T.attr.$L", R_CLASS_NAME, property.getName());
+        } else {
+            if (property.getAttributeId() == NO_ID) {
+                builder.add("$T.ID_NULL", RESOURCE_ID_CLASS_NAME);
+            } else {
+                builder.add("$L", String.format("0x%08x", property.getAttributeId()));
+            }
+        }
+
+        switch (property.getType()) {
+            case INT_ENUM:
+                throw new RuntimeException("IntEnumMapping generation not implemented");
+            case INT_FLAG:
+                throw new RuntimeException("IntFlagMapping generation not implemented");
+            default:
+                builder.add(")");
+                break;
+        }
+
+        return builder.build();
+    }
+
+    /**
+     * Generate a check that throws
+     * {@link android.view.inspector.InspectionCompanion.UninitializedPropertyMapException}
+     * if the properties haven't been initialized.
+     *
+     * <pre>
+     *     if (!mPropertiesMapped) {
+     *         throw new InspectionCompanion.UninitializedPropertyMapException();
+     *     }
+     * </pre>
+     *
+     * @return A codeblock containing the property map initialization check
+     */
+    private CodeBlock generatePropertyMapInitializationCheck() {
+        return CodeBlock.builder()
+                .beginControlFlow("if (!$N)", M_PROPERTIES_MAPPED)
+                .addStatement(
+                        "throw new $T()",
+                        INSPECTION_COMPANION.nestedClass("UninitializedPropertyMapException"))
+                .endControlFlow()
                 .build();
     }
 
@@ -163,19 +336,71 @@
      * Generate the final class name for the inspection companion from the model's class name.
      *
      * The generated class is added to the same package as the source class. If the class in the
-     * model is a nested class, the nested class names are joined with {"$"}. The suffix
-     * {"$$InspectionCompanion"} is always added the the generated name. E.g.: For modeled class
-     * {com.example.Outer.Inner}, the generated class name will be
-     * {com.example.Outer$Inner$$InspectionCompanion}.
+     * model is a nested class, the nested class names are joined with {@code "$"}. The suffix
+     * {@code "$$InspectionCompanion"} is always added the the generated name. E.g.: For modeled
+     * class {@code com.example.Outer.Inner}, the generated class name will be
+     * {@code com.example.Outer$Inner$$InspectionCompanion}.
      *
      * @param model The model to generate from
      * @return A class name for the generated inspection companion class
      */
-    private ClassName generateClassName(final InspectableClassModel model) {
+    private static ClassName generateClassName(InspectableClassModel model) {
         final ClassName className = model.getClassName();
 
         return ClassName.get(
                 className.packageName(),
-                String.join("$", className.simpleNames()) + "$$InspectionCompanion");
+                String.join("$", className.simpleNames()) + GENERATED_CLASS_SUFFIX);
+    }
+
+    /**
+     * Get the suffix for a {@code map} or {@code read} method for a property type.
+     *
+     * @param type The requested property type
+     * @return A method suffix
+     */
+    private static String methodSuffixForPropertyType(Property.Type type) {
+        switch (type) {
+            case BOOLEAN:
+                return "Boolean";
+            case BYTE:
+                return "Byte";
+            case CHAR:
+                return "Char";
+            case DOUBLE:
+                return "Double";
+            case FLOAT:
+                return "Float";
+            case INT:
+                return "Int";
+            case LONG:
+                return "Long";
+            case SHORT:
+                return "Short";
+            case OBJECT:
+                return "Object";
+            case COLOR:
+                return "Color";
+            case GRAVITY:
+                return "Gravity";
+            case INT_ENUM:
+                return "IntEnum";
+            case INT_FLAG:
+                return "IntFlag";
+            default:
+                throw new NoSuchElementException(String.format("No such property type, %s", type));
+        }
+    }
+
+    /**
+     * Value class that holds a {@link Property} and a {@link FieldSpec} for that property.
+     */
+    private static final class PropertyIdField {
+        private final FieldSpec mFieldSpec;
+        private final Property mProperty;
+
+        private PropertyIdField(FieldSpec fieldSpec, Property property) {
+            mFieldSpec = fieldSpec;
+            mProperty = property;
+        }
     }
 }
diff --git a/tools/processors/view_inspector/test/java/android/processor/view/inspector/InspectionCompanionGeneratorTest.java b/tools/processors/view_inspector/test/java/android/processor/view/inspector/InspectionCompanionGeneratorTest.java
index c02b0bd..f639719 100644
--- a/tools/processors/view_inspector/test/java/android/processor/view/inspector/InspectionCompanionGeneratorTest.java
+++ b/tools/processors/view_inspector/test/java/android/processor/view/inspector/InspectionCompanionGeneratorTest.java
@@ -16,6 +16,8 @@
 
 package android.processor.view.inspector;
 
+import android.processor.view.inspector.InspectableClassModel.Property;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.TestCase.fail;
@@ -61,6 +63,54 @@
         assertGeneratedFileEquals("NestedClass");
     }
 
+    @Test
+    public void testSimpleProperties() {
+        addProperty("boolean", Property.Type.BOOLEAN, "getBoolean");
+        addProperty("byte", Property.Type.BYTE, "getByte");
+        addProperty("char", Property.Type.CHAR, "getChar");
+        addProperty("double", Property.Type.DOUBLE, "getDouble");
+        addProperty("float", Property.Type.FLOAT, "getFloat");
+        addProperty("int", Property.Type.INT, "getInt");
+        addProperty("long", Property.Type.LONG, "getLong");
+        addProperty("short", Property.Type.SHORT, "getShort");
+
+        addProperty("object", Property.Type.OBJECT, "getObject");
+        addProperty("color", Property.Type.COLOR, "getColor");
+        addProperty("gravity", Property.Type.GRAVITY, "getGravity");
+
+        assertGeneratedFileEquals("SimpleProperties");
+    }
+
+    @Test
+    public void testNoAttributeId() {
+        final Property property = new Property("noAttributeProperty");
+        property.setType(Property.Type.INT);
+        property.setGetter("getNoAttributeProperty");
+        property.setAttributeIdInferrableFromR(false);
+        mModel.putProperty(property);
+
+        assertGeneratedFileEquals("NoAttributeId");
+    }
+
+    @Test
+    public void testSuppliedAttributeId() {
+        final Property property = new Property("suppliedAttributeProperty");
+        property.setType(Property.Type.INT);
+        property.setGetter("getSuppliedAttributeProperty");
+        property.setAttributeId(0xdecafbad);
+        mModel.putProperty(property);
+
+        assertGeneratedFileEquals("SuppliedAttributeId");
+    }
+
+    private Property addProperty(String name, Property.Type type, String getter) {
+        final Property property = new Property(name);
+        property.setType(type);
+        property.setGetter(getter);
+        mModel.putProperty(property);
+        return property;
+    }
+
     private void assertGeneratedFileEquals(String fileName) {
         assertEquals(
                 loadTextResource(String.format(RESOURCE_PATH_TEMPLATE, fileName)),
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NestedClass.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NestedClass.java.txt
index e5fb6a2..2fc242c 100644
--- a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NestedClass.java.txt
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NestedClass.java.txt
@@ -12,11 +12,20 @@
  * on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
  */
 public final class Outer$Inner$$InspectionCompanion implements InspectionCompanion<Outer.Inner> {
+    /**
+     * Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
+     */
+    private boolean mPropertiesMapped = false;
+
     @Override
     public void mapProperties(PropertyMapper propertyMapper) {
+        mPropertiesMapped = true;
     }
 
     @Override
     public void readProperties(Outer.Inner inspectable, PropertyReader propertyReader) {
+        if (!mPropertiesMapped) {
+            throw new InspectionCompanion.UninitializedPropertyMapException();
+        }
     }
 }
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NoAttributeId.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NoAttributeId.java.txt
new file mode 100644
index 0000000..277e840
--- /dev/null
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NoAttributeId.java.txt
@@ -0,0 +1,39 @@
+package com.android.inspectable;
+
+import android.content.res.ResourceId;
+import android.view.inspector.InspectionCompanion;
+import android.view.inspector.PropertyMapper;
+import android.view.inspector.PropertyReader;
+import java.lang.Override;
+
+/**
+ * Inspection companion for {@link TestInspectable}.
+ *
+ * Generated by {@link android.processor.view.inspector.InspectionCompanionGenerator}
+ * on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
+ */
+public final class TestInspectable$$InspectionCompanion implements InspectionCompanion<TestInspectable> {
+    /**
+     * Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
+     */
+    private boolean mPropertiesMapped = false;
+
+    /**
+     * Property ID of {@code noAttributeProperty}.
+     */
+    private int mNoAttributePropertyId;
+
+    @Override
+    public void mapProperties(PropertyMapper propertyMapper) {
+        mNoAttributePropertyId = propertyMapper.mapInt("noAttributeProperty", ResourceId.ID_NULL);
+        mPropertiesMapped = true;
+    }
+
+    @Override
+    public void readProperties(TestInspectable inspectable, PropertyReader propertyReader) {
+        if (!mPropertiesMapped) {
+            throw new InspectionCompanion.UninitializedPropertyMapException();
+        }
+        propertyReader.readInt(mNoAttributePropertyId, inspectable.getNoAttributeProperty());
+    }
+}
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NodeName.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NodeName.java.txt
index a334f50..1142548 100644
--- a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NodeName.java.txt
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/NodeName.java.txt
@@ -13,12 +13,21 @@
  * on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
  */
 public final class TestInspectable$$InspectionCompanion implements InspectionCompanion<TestInspectable> {
+    /**
+     * Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
+     */
+    private boolean mPropertiesMapped = false;
+
     @Override
     public void mapProperties(PropertyMapper propertyMapper) {
+        mPropertiesMapped = true;
     }
 
     @Override
     public void readProperties(TestInspectable inspectable, PropertyReader propertyReader) {
+        if (!mPropertiesMapped) {
+            throw new InspectionCompanion.UninitializedPropertyMapException();
+        }
     }
 
     @Override
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SimpleProperties.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SimpleProperties.java.txt
new file mode 100644
index 0000000..57eb080
--- /dev/null
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SimpleProperties.java.txt
@@ -0,0 +1,109 @@
+package com.android.inspectable;
+
+import android.R;
+import android.view.inspector.InspectionCompanion;
+import android.view.inspector.PropertyMapper;
+import android.view.inspector.PropertyReader;
+import java.lang.Override;
+
+/**
+ * Inspection companion for {@link TestInspectable}.
+ *
+ * Generated by {@link android.processor.view.inspector.InspectionCompanionGenerator}
+ * on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
+ */
+public final class TestInspectable$$InspectionCompanion implements InspectionCompanion<TestInspectable> {
+    /**
+     * Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
+     */
+    private boolean mPropertiesMapped = false;
+
+    /**
+     * Property ID of {@code boolean}.
+     */
+    private int mBooleanId;
+
+    /**
+     * Property ID of {@code byte}.
+     */
+    private int mByteId;
+
+    /**
+     * Property ID of {@code char}.
+     */
+    private int mCharId;
+
+    /**
+     * Property ID of {@code color}.
+     */
+    private int mColorId;
+
+    /**
+     * Property ID of {@code double}.
+     */
+    private int mDoubleId;
+
+    /**
+     * Property ID of {@code float}.
+     */
+    private int mFloatId;
+
+    /**
+     * Property ID of {@code gravity}.
+     */
+    private int mGravityId;
+
+    /**
+     * Property ID of {@code int}.
+     */
+    private int mIntId;
+
+    /**
+     * Property ID of {@code long}.
+     */
+    private int mLongId;
+
+    /**
+     * Property ID of {@code object}.
+     */
+    private int mObjectId;
+
+    /**
+     * Property ID of {@code short}.
+     */
+    private int mShortId;
+
+    @Override
+    public void mapProperties(PropertyMapper propertyMapper) {
+        mBooleanId = propertyMapper.mapBoolean("boolean", R.attr.boolean);
+        mByteId = propertyMapper.mapByte("byte", R.attr.byte);
+        mCharId = propertyMapper.mapChar("char", R.attr.char);
+        mColorId = propertyMapper.mapColor("color", R.attr.color);
+        mDoubleId = propertyMapper.mapDouble("double", R.attr.double);
+        mFloatId = propertyMapper.mapFloat("float", R.attr.float);
+        mGravityId = propertyMapper.mapGravity("gravity", R.attr.gravity);
+        mIntId = propertyMapper.mapInt("int", R.attr.int);
+        mLongId = propertyMapper.mapLong("long", R.attr.long);
+        mObjectId = propertyMapper.mapObject("object", R.attr.object);
+        mShortId = propertyMapper.mapShort("short", R.attr.short);
+        mPropertiesMapped = true;
+    }
+
+    @Override
+    public void readProperties(TestInspectable inspectable, PropertyReader propertyReader) {
+        if (!mPropertiesMapped) {
+            throw new InspectionCompanion.UninitializedPropertyMapException();
+        }
+        propertyReader.readBoolean(mBooleanId, inspectable.getBoolean());
+        propertyReader.readByte(mByteId, inspectable.getByte());
+        propertyReader.readChar(mCharId, inspectable.getChar());
+        propertyReader.readColor(mColorId, inspectable.getColor());
+        propertyReader.readDouble(mDoubleId, inspectable.getDouble());
+        propertyReader.readFloat(mFloatId, inspectable.getFloat());
+        propertyReader.readGravity(mGravityId, inspectable.getGravity());
+        propertyReader.readInt(mIntId, inspectable.getInt());
+        propertyReader.readLong(mLongId, inspectable.getLong());
+        propertyReader.readObject(mObjectId, inspectable.getObject());
+        propertyReader.readShort(mShortId, inspectable.getShort());
+    }
+}
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SuppliedAttributeId.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SuppliedAttributeId.java.txt
new file mode 100644
index 0000000..6b6ce21
--- /dev/null
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SuppliedAttributeId.java.txt
@@ -0,0 +1,39 @@
+package com.android.inspectable;
+
+import android.view.inspector.InspectionCompanion;
+import android.view.inspector.PropertyMapper;
+import android.view.inspector.PropertyReader;
+import java.lang.Override;
+
+/**
+ * Inspection companion for {@link TestInspectable}.
+ *
+ * Generated by {@link android.processor.view.inspector.InspectionCompanionGenerator}
+ * on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
+ */
+public final class TestInspectable$$InspectionCompanion implements InspectionCompanion<TestInspectable> {
+    /**
+     * Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
+     */
+    private boolean mPropertiesMapped = false;
+
+    /**
+     * Property ID of {@code suppliedAttributeProperty}.
+     */
+    private int mSuppliedAttributePropertyId;
+
+    @Override
+    public void mapProperties(PropertyMapper propertyMapper) {
+        mSuppliedAttributePropertyId = propertyMapper.mapInt("suppliedAttributeProperty",
+                0xdecafbad);
+        mPropertiesMapped = true;
+    }
+
+    @Override
+    public void readProperties(TestInspectable inspectable, PropertyReader propertyReader) {
+        if (!mPropertiesMapped) {
+            throw new InspectionCompanion.UninitializedPropertyMapException();
+        }
+        propertyReader.readInt(mSuppliedAttributePropertyId, inspectable.getSuppliedAttributeProperty());
+    }
+}