Snap for 7510676 from cfe4767b40382e293c69d5c6eb05696b9e638ba8 to sc-release

Change-Id: Ia0e2c83398ba59022d550016dbb9eafd8ef5f8a8
diff --git a/Android.bp b/Android.bp
index 71023bf..08efa8e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -103,8 +103,9 @@
         ":android.hardware.security.secureclock-V1-java-source",
         ":android.security.apc-java-source",
         ":android.security.authorization-java-source",
+        ":android.security.legacykeystore-java-source",
         ":android.security.maintenance-java-source",
-        ":android.security.vpnprofilestore-java-source",
+        ":android.security.metrics-java-source",
         ":android.system.keystore2-V1-java-source",
         ":credstore_aidl",
         ":dumpstate_aidl",
diff --git a/apex/appsearch/Android.bp b/apex/appsearch/Android.bp
index 8278426..ac97e04 100644
--- a/apex/appsearch/Android.bp
+++ b/apex/appsearch/Android.bp
@@ -50,6 +50,20 @@
     name: "com.android.appsearch-bootclasspath-fragment",
     contents: ["framework-appsearch"],
     apex_available: ["com.android.appsearch"],
+
+    // The bootclasspath_fragments that provide APIs on which this depends.
+    fragments: [
+        {
+            apex: "com.android.art",
+            module: "art-bootclasspath-fragment",
+        },
+    ],
+
+    // Additional stubs libraries that this fragment's contents use which are
+    // not provided by another bootclasspath_fragment.
+    additional_stubs: [
+        "android-non-updatable",
+    ],
 }
 
 // Encapsulate the contributions made by the com.android.appsearch to the systemserverclasspath.
diff --git a/apex/jobscheduler/framework/java/android/app/AlarmManager.java b/apex/jobscheduler/framework/java/android/app/AlarmManager.java
index 4843415..9c0c365 100644
--- a/apex/jobscheduler/framework/java/android/app/AlarmManager.java
+++ b/apex/jobscheduler/framework/java/android/app/AlarmManager.java
@@ -494,6 +494,9 @@
      * exact alarms, rescheduling each time as described above. Legacy applications
      * whose {@code targetSdkVersion} is earlier than API 19 will continue to have all
      * of their alarms, including repeating alarms, treated as exact.
+     * <p>Apps targeting {@link Build.VERSION_CODES#S} will need to set the flag
+     * {@link PendingIntent#FLAG_MUTABLE} on the {@link PendingIntent} being used to set this alarm,
+     * if they want the alarm count to be supplied with the key {@link Intent#EXTRA_ALARM_COUNT}.
      *
      * @param type type of alarm.
      * @param triggerAtMillis time in milliseconds that the alarm should first
@@ -516,6 +519,7 @@
      * @see #ELAPSED_REALTIME_WAKEUP
      * @see #RTC
      * @see #RTC_WAKEUP
+     * @see Intent#EXTRA_ALARM_COUNT
      */
     public void setRepeating(@AlarmType int type, long triggerAtMillis,
             long intervalMillis, PendingIntent operation) {
@@ -1004,6 +1008,9 @@
      * been available since API 3, your application can safely call it and be
      * assured that it will get similar behavior on both current and older versions
      * of Android.
+     * <p>Apps targeting {@link Build.VERSION_CODES#S} will need to set the flag
+     * {@link PendingIntent#FLAG_MUTABLE} on the {@link PendingIntent} being used to set this alarm,
+     * if they want the alarm count to be supplied with the key {@link Intent#EXTRA_ALARM_COUNT}.
      *
      * @param type type of alarm.
      * @param triggerAtMillis time in milliseconds that the alarm should first
@@ -1038,6 +1045,7 @@
      * @see #INTERVAL_HOUR
      * @see #INTERVAL_HALF_DAY
      * @see #INTERVAL_DAY
+     * @see Intent#EXTRA_ALARM_COUNT
      */
     public void setInexactRepeating(@AlarmType int type, long triggerAtMillis,
             long intervalMillis, PendingIntent operation) {
@@ -1286,22 +1294,31 @@
 
     /**
      * Called to check if the caller can schedule exact alarms.
+     * Your app schedules exact alarms when it calls any of the {@code setExact...} or
+     * {@link #setAlarmClock(AlarmClockInfo, PendingIntent) setAlarmClock} API methods.
      * <p>
-     * Apps targeting {@link Build.VERSION_CODES#S} or higher can schedule exact alarms if they
-     * have the {@link Manifest.permission#SCHEDULE_EXACT_ALARM} permission. These apps can also
+     * Apps targeting {@link Build.VERSION_CODES#S} or higher can schedule exact alarms only if they
+     * have the {@link Manifest.permission#SCHEDULE_EXACT_ALARM} permission or they are on the
+     * device's power-save exemption list.
+     * These apps can also
      * start {@link android.provider.Settings#ACTION_REQUEST_SCHEDULE_EXACT_ALARM} to
-     * request this from the user.
+     * request this permission from the user.
      * <p>
      * Apps targeting lower sdk versions, can always schedule exact alarms.
      *
-     * @return {@code true} if the caller can schedule exact alarms.
+     * @return {@code true} if the caller can schedule exact alarms, {@code false} otherwise.
      * @see android.provider.Settings#ACTION_REQUEST_SCHEDULE_EXACT_ALARM
      * @see #setExact(int, long, PendingIntent)
      * @see #setExactAndAllowWhileIdle(int, long, PendingIntent)
      * @see #setAlarmClock(AlarmClockInfo, PendingIntent)
+     * @see android.os.PowerManager#isIgnoringBatteryOptimizations(String)
      */
     public boolean canScheduleExactAlarms() {
-        return hasScheduleExactAlarm(mContext.getOpPackageName(), mContext.getUserId());
+        try {
+            return mService.canScheduleExactAlarms(mContext.getOpPackageName());
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
     }
 
     /**
diff --git a/apex/jobscheduler/framework/java/android/app/IAlarmManager.aidl b/apex/jobscheduler/framework/java/android/app/IAlarmManager.aidl
index cd7c1e8..9d11ca4 100644
--- a/apex/jobscheduler/framework/java/android/app/IAlarmManager.aidl
+++ b/apex/jobscheduler/framework/java/android/app/IAlarmManager.aidl
@@ -41,6 +41,7 @@
     @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     AlarmManager.AlarmClockInfo getNextAlarmClock(int userId);
     long currentNetworkTimeMillis();
+    boolean canScheduleExactAlarms(String packageName);
     boolean hasScheduleExactAlarm(String packageName, int userId);
     int getConfigVersion();
 }
diff --git a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
index 42e953b..a1a46af 100644
--- a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
+++ b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
@@ -190,6 +190,8 @@
      * @hide
      */
     public static final int REASON_TEMP_ALLOWED_WHILE_IN_USE = 70;
+    /** @hide */
+    public static final int REASON_CURRENT_INPUT_METHOD = 71;
 
     /* BG-FGS-launch is allowed by temp-allow-list or system-allow-list.
        Reason code for temp and system allow list starts here.
@@ -381,6 +383,7 @@
             REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD,
             REASON_OP_ACTIVATE_VPN,
             REASON_OP_ACTIVATE_PLATFORM_VPN,
+            REASON_CURRENT_INPUT_METHOD,
             REASON_TEMP_ALLOWED_WHILE_IN_USE,
             // temp and system allow list reasons.
             REASON_GEOFENCING,
@@ -649,6 +652,8 @@
                 return "OP_ACTIVATE_VPN";
             case REASON_OP_ACTIVATE_PLATFORM_VPN:
                 return "OP_ACTIVATE_PLATFORM_VPN";
+            case REASON_CURRENT_INPUT_METHOD:
+                return "CURRENT_INPUT_METHOD";
             case REASON_TEMP_ALLOWED_WHILE_IN_USE:
                 return "TEMP_ALLOWED_WHILE_IN_USE";
             case REASON_GEOFENCING:
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 70e548d..ed80ddb 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -1740,7 +1740,7 @@
                     if (!isExactAlarmChangeEnabled(a.packageName, UserHandle.getUserId(a.uid))) {
                         return false;
                     }
-                    return a.alarmClock != null || !isExemptFromExactAlarmPermission(a.uid);
+                    return !isExemptFromExactAlarmPermission(a.uid);
                 };
                 removeAlarmsInternalLocked(whichAlarms, REMOVE_REASON_EXACT_PERMISSION_REVOKED);
             }
@@ -2414,6 +2414,7 @@
     /**
      * Returns true if the given uid does not require SCHEDULE_EXACT_ALARM to set exact,
      * allow-while-idle alarms.
+     * Note: It is ok to call this method without the lock {@link #mLock} held.
      */
     boolean isExemptFromExactAlarmPermission(int uid) {
         return (UserHandle.isSameApp(mSystemUiUid, uid)
@@ -2515,7 +2516,7 @@
                     idleOptions = allowWhileIdle ? mOptsWithFgs.toBundle() : null;
                 }
                 if (needsPermission && !hasScheduleExactAlarmInternal(callingPackage, callingUid)) {
-                    if (alarmClock != null || !isExemptFromExactAlarmPermission(callingUid)) {
+                    if (!isExemptFromExactAlarmPermission(callingUid)) {
                         final String errorMessage = "Caller " + callingPackage + " needs to hold "
                                 + Manifest.permission.SCHEDULE_EXACT_ALARM + " to set "
                                 + "exact alarms.";
@@ -2527,10 +2528,16 @@
                     } else {
                         allowListed = true;
                     }
-                    // If the app is on the full system power allow-list (not except-idle), or we're
-                    // in a soft failure mode, we still allow the alarms.
-                    // We give temporary allowlist to allow-while-idle alarms but without FGS
-                    // capability. Note that apps that are in the power allow-list do not need it.
+                    // If the app is on the full system power allow-list (not except-idle), or the
+                    // user-elected allow-list, or we're in a soft failure mode, we still allow the
+                    // alarms.
+                    // In both cases, ALLOW_WHILE_IDLE alarms get a lower quota equivalent to what
+                    // pre-S apps got. Note that user-allow-listed apps don't use the flag
+                    // ALLOW_WHILE_IDLE.
+                    // We grant temporary allow-list to allow-while-idle alarms but without FGS
+                    // capability. AlarmClock alarms do not get the temporary allow-list. This is
+                    // consistent with pre-S behavior. Note that apps that are in either of the
+                    // power-save allow-lists do not need it.
                     idleOptions = allowWhileIdle ? mOptsWithoutFgs.toBundle() : null;
                     lowerQuota = allowWhileIdle;
                 }
@@ -2561,6 +2568,22 @@
         }
 
         @Override
+        public boolean canScheduleExactAlarms(String packageName) {
+            final int callingUid = mInjector.getCallingUid();
+            final int userId = UserHandle.getUserId(callingUid);
+            final int packageUid = mPackageManagerInternal.getPackageUid(packageName, 0, userId);
+            if (callingUid != packageUid) {
+                throw new SecurityException("Uid " + callingUid
+                        + " cannot query canScheduleExactAlarms for package " + packageName);
+            }
+            if (!isExactAlarmChangeEnabled(packageName, userId)) {
+                return true;
+            }
+            return isExemptFromExactAlarmPermission(packageUid)
+                    || hasScheduleExactAlarmInternal(packageName, packageUid);
+        }
+
+        @Override
         public boolean hasScheduleExactAlarm(String packageName, int userId) {
             final int callingUid = mInjector.getCallingUid();
             if (UserHandle.getUserId(callingUid) != userId) {
@@ -2572,9 +2595,6 @@
                 throw new SecurityException("Uid " + callingUid
                         + " cannot query hasScheduleExactAlarm for uid " + uid);
             }
-            if (!isExactAlarmChangeEnabled(packageName, userId)) {
-                return true;
-            }
             return (uid > 0) ? hasScheduleExactAlarmInternal(packageName, uid) : false;
         }
 
@@ -3577,17 +3597,14 @@
      * This is not expected to get called frequently.
      */
     void removeExactAlarmsOnPermissionRevokedLocked(int uid, String packageName) {
-        Slog.w(TAG, "Package " + packageName + ", uid " + uid + " lost SCHEDULE_EXACT_ALARM!");
-        if (!isExactAlarmChangeEnabled(packageName, UserHandle.getUserId(uid))) {
+        if (isExemptFromExactAlarmPermission(uid)
+                || !isExactAlarmChangeEnabled(packageName, UserHandle.getUserId(uid))) {
             return;
         }
+        Slog.w(TAG, "Package " + packageName + ", uid " + uid + " lost SCHEDULE_EXACT_ALARM!");
 
-        final Predicate<Alarm> whichAlarms = a -> {
-            if (a.uid == uid && a.packageName.equals(packageName) && a.windowLength == 0) {
-                return a.alarmClock != null || !isExemptFromExactAlarmPermission(uid);
-            }
-            return false;
-        };
+        final Predicate<Alarm> whichAlarms = a -> (a.uid == uid && a.packageName.equals(packageName)
+                && a.windowLength == 0);
         removeAlarmsInternalLocked(whichAlarms, REMOVE_REASON_EXACT_PERMISSION_REVOKED);
 
         if (mConstants.KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED) {
diff --git a/boot/hiddenapi/hiddenapi-max-target-o.txt b/boot/hiddenapi/hiddenapi-max-target-o.txt
index 770547e..0ec918b 100644
--- a/boot/hiddenapi/hiddenapi-max-target-o.txt
+++ b/boot/hiddenapi/hiddenapi-max-target-o.txt
@@ -31612,12 +31612,6 @@
 Landroid/media/MediaSession2$CommandButton;->getProvider()Landroid/media/update/MediaSession2Provider$CommandButtonProvider;
 Landroid/media/MediaSession2$CommandButton;->isEnabled()Z
 Landroid/media/MediaSession2$CommandButton;->mProvider:Landroid/media/update/MediaSession2Provider$CommandButtonProvider;
-Landroid/media/MediaSession2$ControllerInfo;-><init>(Landroid/content/Context;IILjava/lang/String;Landroid/os/IInterface;)V
-Landroid/media/MediaSession2$ControllerInfo;->getPackageName()Ljava/lang/String;
-Landroid/media/MediaSession2$ControllerInfo;->getProvider()Landroid/media/update/MediaSession2Provider$ControllerInfoProvider;
-Landroid/media/MediaSession2$ControllerInfo;->getUid()I
-Landroid/media/MediaSession2$ControllerInfo;->isTrusted()Z
-Landroid/media/MediaSession2$ControllerInfo;->mProvider:Landroid/media/update/MediaSession2Provider$ControllerInfoProvider;
 Landroid/media/MediaSession2$OnDataSourceMissingHelper;->onDataSourceMissing(Landroid/media/MediaSession2;Landroid/media/MediaItem2;)Landroid/media/DataSourceDesc;
 Landroid/media/MediaSession2$SessionCallback;-><init>()V
 Landroid/media/MediaSession2$SessionCallback;->onBufferingStateChanged(Landroid/media/MediaSession2;Landroid/media/MediaPlayerBase;Landroid/media/MediaItem2;I)V
@@ -35333,159 +35327,6 @@
 Landroid/mtp/MtpStorageManager;->sDebug:Z
 Landroid/mtp/MtpStorageManager;->setSubdirectories(Ljava/util/Set;)V
 Landroid/mtp/MtpStorageManager;->TAG:Ljava/lang/String;
-Landroid/net/CaptivePortal;-><init>(Landroid/os/IBinder;)V
-Landroid/net/CaptivePortal;->APP_RETURN_DISMISSED:I
-Landroid/net/CaptivePortal;->APP_RETURN_UNWANTED:I
-Landroid/net/CaptivePortal;->APP_RETURN_WANTED_AS_IS:I
-Landroid/net/CaptivePortal;->mBinder:Landroid/os/IBinder;
-Landroid/net/CaptivePortal;->useNetwork()V
-Landroid/net/ConnectivityManager$CallbackHandler;->DBG:Z
-Landroid/net/ConnectivityManager$CallbackHandler;->getObject(Landroid/os/Message;Ljava/lang/Class;)Ljava/lang/Object;
-Landroid/net/ConnectivityManager$CallbackHandler;->TAG:Ljava/lang/String;
-Landroid/net/ConnectivityManager$Errors;->TOO_MANY_REQUESTS:I
-Landroid/net/ConnectivityManager$LegacyRequest;-><init>()V
-Landroid/net/ConnectivityManager$LegacyRequest;->clearDnsBinding()V
-Landroid/net/ConnectivityManager$LegacyRequest;->currentNetwork:Landroid/net/Network;
-Landroid/net/ConnectivityManager$LegacyRequest;->delay:I
-Landroid/net/ConnectivityManager$LegacyRequest;->expireSequenceNumber:I
-Landroid/net/ConnectivityManager$LegacyRequest;->networkCallback:Landroid/net/ConnectivityManager$NetworkCallback;
-Landroid/net/ConnectivityManager$LegacyRequest;->networkCapabilities:Landroid/net/NetworkCapabilities;
-Landroid/net/ConnectivityManager$LegacyRequest;->networkRequest:Landroid/net/NetworkRequest;
-Landroid/net/ConnectivityManager$NetworkCallback;->networkRequest:Landroid/net/NetworkRequest;
-Landroid/net/ConnectivityManager$NetworkCallback;->onAvailable(Landroid/net/Network;Landroid/net/NetworkCapabilities;Landroid/net/LinkProperties;)V
-Landroid/net/ConnectivityManager$NetworkCallback;->onNetworkResumed(Landroid/net/Network;)V
-Landroid/net/ConnectivityManager$NetworkCallback;->onNetworkSuspended(Landroid/net/Network;)V
-Landroid/net/ConnectivityManager$NetworkCallback;->onPreCheck(Landroid/net/Network;)V
-Landroid/net/ConnectivityManager$PacketKeepalive;->BINDER_DIED:I
-Landroid/net/ConnectivityManager$PacketKeepalive;->ERROR_HARDWARE_ERROR:I
-Landroid/net/ConnectivityManager$PacketKeepalive;->ERROR_HARDWARE_UNSUPPORTED:I
-Landroid/net/ConnectivityManager$PacketKeepalive;->ERROR_INVALID_INTERVAL:I
-Landroid/net/ConnectivityManager$PacketKeepalive;->ERROR_INVALID_IP_ADDRESS:I
-Landroid/net/ConnectivityManager$PacketKeepalive;->ERROR_INVALID_LENGTH:I
-Landroid/net/ConnectivityManager$PacketKeepalive;->ERROR_INVALID_NETWORK:I
-Landroid/net/ConnectivityManager$PacketKeepalive;->ERROR_INVALID_PORT:I
-Landroid/net/ConnectivityManager$PacketKeepalive;->mCallback:Landroid/net/ConnectivityManager$PacketKeepaliveCallback;
-Landroid/net/ConnectivityManager$PacketKeepalive;->MIN_INTERVAL:I
-Landroid/net/ConnectivityManager$PacketKeepalive;->mLooper:Landroid/os/Looper;
-Landroid/net/ConnectivityManager$PacketKeepalive;->mMessenger:Landroid/os/Messenger;
-Landroid/net/ConnectivityManager$PacketKeepalive;->mNetwork:Landroid/net/Network;
-Landroid/net/ConnectivityManager$PacketKeepalive;->mSlot:Ljava/lang/Integer;
-Landroid/net/ConnectivityManager$PacketKeepalive;->NATT_PORT:I
-Landroid/net/ConnectivityManager$PacketKeepalive;->NO_KEEPALIVE:I
-Landroid/net/ConnectivityManager$PacketKeepalive;->stopLooper()V
-Landroid/net/ConnectivityManager$PacketKeepalive;->SUCCESS:I
-Landroid/net/ConnectivityManager$PacketKeepalive;->TAG:Ljava/lang/String;
-Landroid/net/ConnectivityManager$TooManyRequestsException;-><init>()V
-Landroid/net/ConnectivityManager;-><init>(Landroid/content/Context;Landroid/net/IConnectivityManager;)V
-Landroid/net/ConnectivityManager;->ACTION_CAPTIVE_PORTAL_TEST_COMPLETED:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->ACTION_DATA_ACTIVITY_CHANGE:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->ACTION_PROMPT_LOST_VALIDATION:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->ACTION_PROMPT_UNVALIDATED:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->ALREADY_UNREGISTERED:Landroid/net/NetworkRequest;
-Landroid/net/ConnectivityManager;->BASE:I
-Landroid/net/ConnectivityManager;->CALLBACK_AVAILABLE:I
-Landroid/net/ConnectivityManager;->CALLBACK_CAP_CHANGED:I
-Landroid/net/ConnectivityManager;->CALLBACK_IP_CHANGED:I
-Landroid/net/ConnectivityManager;->CALLBACK_LOSING:I
-Landroid/net/ConnectivityManager;->CALLBACK_LOST:I
-Landroid/net/ConnectivityManager;->CALLBACK_PRECHECK:I
-Landroid/net/ConnectivityManager;->CALLBACK_RESUMED:I
-Landroid/net/ConnectivityManager;->CALLBACK_SUSPENDED:I
-Landroid/net/ConnectivityManager;->CALLBACK_UNAVAIL:I
-Landroid/net/ConnectivityManager;->checkCallbackNotNull(Landroid/net/ConnectivityManager$NetworkCallback;)V
-Landroid/net/ConnectivityManager;->checkLegacyRoutingApiAccess()V
-Landroid/net/ConnectivityManager;->checkMobileProvisioning(I)I
-Landroid/net/ConnectivityManager;->checkPendingIntentNotNull(Landroid/app/PendingIntent;)V
-Landroid/net/ConnectivityManager;->checkTimeout(I)V
-Landroid/net/ConnectivityManager;->CONNECTIVITY_ACTION_SUPL:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->convertServiceException(Landroid/os/ServiceSpecificException;)Ljava/lang/RuntimeException;
-Landroid/net/ConnectivityManager;->enforceChangePermission(Landroid/content/Context;)V
-Landroid/net/ConnectivityManager;->enforceTetherChangePermission(Landroid/content/Context;Ljava/lang/String;)V
-Landroid/net/ConnectivityManager;->expireRequest(Landroid/net/NetworkCapabilities;I)V
-Landroid/net/ConnectivityManager;->EXPIRE_LEGACY_REQUEST:I
-Landroid/net/ConnectivityManager;->EXTRA_ACTIVE_LOCAL_ONLY:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->EXTRA_ADD_TETHER_TYPE:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->EXTRA_CAPTIVE_PORTAL_PROBE_SPEC:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->EXTRA_CAPTIVE_PORTAL_USER_AGENT:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->EXTRA_DEVICE_TYPE:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->EXTRA_INET_CONDITION:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->EXTRA_IS_ACTIVE:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->EXTRA_IS_CAPTIVE_PORTAL:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->EXTRA_PROVISION_CALLBACK:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->EXTRA_REALTIME_NS:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->EXTRA_REM_TETHER_TYPE:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->EXTRA_RUN_PROVISION:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->EXTRA_SET_ALARM:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->factoryReset()V
-Landroid/net/ConnectivityManager;->findRequestForFeature(Landroid/net/NetworkCapabilities;)Landroid/net/NetworkRequest;
-Landroid/net/ConnectivityManager;->getActiveNetworkForUid(I)Landroid/net/Network;
-Landroid/net/ConnectivityManager;->getActiveNetworkForUid(IZ)Landroid/net/Network;
-Landroid/net/ConnectivityManager;->getActiveNetworkInfoForUid(IZ)Landroid/net/NetworkInfo;
-Landroid/net/ConnectivityManager;->getAlwaysOnVpnPackageForUser(I)Ljava/lang/String;
-Landroid/net/ConnectivityManager;->getCallbackName(I)Ljava/lang/String;
-Landroid/net/ConnectivityManager;->getDefaultHandler()Landroid/net/ConnectivityManager$CallbackHandler;
-Landroid/net/ConnectivityManager;->getGlobalProxy()Landroid/net/ProxyInfo;
-Landroid/net/ConnectivityManager;->getInstanceOrNull()Landroid/net/ConnectivityManager;
-Landroid/net/ConnectivityManager;->getMobileProvisioningUrl()Ljava/lang/String;
-Landroid/net/ConnectivityManager;->getNetworkInfoForUid(Landroid/net/Network;IZ)Landroid/net/NetworkInfo;
-Landroid/net/ConnectivityManager;->getNetworkManagementService()Landroid/os/INetworkManagementService;
-Landroid/net/ConnectivityManager;->getNetworkPolicyManager()Landroid/net/INetworkPolicyManager;
-Landroid/net/ConnectivityManager;->getProxyForNetwork(Landroid/net/Network;)Landroid/net/ProxyInfo;
-Landroid/net/ConnectivityManager;->getTetheredDhcpRanges()[Ljava/lang/String;
-Landroid/net/ConnectivityManager;->inferLegacyTypeForNetworkCapabilities(Landroid/net/NetworkCapabilities;)I
-Landroid/net/ConnectivityManager;->isAlwaysOnVpnPackageSupportedForUser(ILjava/lang/String;)Z
-Landroid/net/ConnectivityManager;->isNetworkTypeWifi(I)Z
-Landroid/net/ConnectivityManager;->legacyTypeForNetworkCapabilities(Landroid/net/NetworkCapabilities;)I
-Landroid/net/ConnectivityManager;->LISTEN:I
-Landroid/net/ConnectivityManager;->MAX_NETWORK_TYPE:I
-Landroid/net/ConnectivityManager;->MAX_RADIO_TYPE:I
-Landroid/net/ConnectivityManager;->mContext:Landroid/content/Context;
-Landroid/net/ConnectivityManager;->MIN_NETWORK_TYPE:I
-Landroid/net/ConnectivityManager;->mNetworkActivityListeners:Landroid/util/ArrayMap;
-Landroid/net/ConnectivityManager;->mNMService:Landroid/os/INetworkManagementService;
-Landroid/net/ConnectivityManager;->mNPManager:Landroid/net/INetworkPolicyManager;
-Landroid/net/ConnectivityManager;->MULTIPATH_PREFERENCE_UNMETERED:I
-Landroid/net/ConnectivityManager;->NETID_UNSET:I
-Landroid/net/ConnectivityManager;->networkCapabilitiesForType(I)Landroid/net/NetworkCapabilities;
-Landroid/net/ConnectivityManager;->PRIVATE_DNS_DEFAULT_MODE_FALLBACK:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->PRIVATE_DNS_MODE_OFF:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->PRIVATE_DNS_MODE_OPPORTUNISTIC:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->PRIVATE_DNS_MODE_PROVIDER_HOSTNAME:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->registerNetworkAgent(Landroid/os/Messenger;Landroid/net/NetworkInfo;Landroid/net/LinkProperties;Landroid/net/NetworkCapabilities;ILandroid/net/NetworkMisc;)I
-Landroid/net/ConnectivityManager;->renewRequestLocked(Landroid/net/ConnectivityManager$LegacyRequest;)V
-Landroid/net/ConnectivityManager;->reportInetCondition(II)V
-Landroid/net/ConnectivityManager;->REQUEST:I
-Landroid/net/ConnectivityManager;->requestNetwork(Landroid/net/NetworkRequest;Landroid/net/ConnectivityManager$NetworkCallback;IILandroid/os/Handler;)V
-Landroid/net/ConnectivityManager;->REQUEST_ID_UNSET:I
-Landroid/net/ConnectivityManager;->sCallbackHandler:Landroid/net/ConnectivityManager$CallbackHandler;
-Landroid/net/ConnectivityManager;->sCallbacks:Ljava/util/HashMap;
-Landroid/net/ConnectivityManager;->sendExpireMsgForFeature(Landroid/net/NetworkCapabilities;II)V
-Landroid/net/ConnectivityManager;->sendRequestForNetwork(Landroid/net/NetworkCapabilities;Landroid/net/ConnectivityManager$NetworkCallback;IIILandroid/net/ConnectivityManager$CallbackHandler;)Landroid/net/NetworkRequest;
-Landroid/net/ConnectivityManager;->setAcceptUnvalidated(Landroid/net/Network;ZZ)V
-Landroid/net/ConnectivityManager;->setAlwaysOnVpnPackageForUser(ILjava/lang/String;Z)Z
-Landroid/net/ConnectivityManager;->setAvoidUnvalidated(Landroid/net/Network;)V
-Landroid/net/ConnectivityManager;->setGlobalProxy(Landroid/net/ProxyInfo;)V
-Landroid/net/ConnectivityManager;->setProvisioningNotificationVisible(ZILjava/lang/String;)V
-Landroid/net/ConnectivityManager;->sInstance:Landroid/net/ConnectivityManager;
-Landroid/net/ConnectivityManager;->sLegacyTypeToCapability:Landroid/util/SparseIntArray;
-Landroid/net/ConnectivityManager;->sLegacyTypeToTransport:Landroid/util/SparseIntArray;
-Landroid/net/ConnectivityManager;->startCaptivePortalApp(Landroid/net/Network;)V
-Landroid/net/ConnectivityManager;->TAG:Ljava/lang/String;
-Landroid/net/ConnectivityManager;->TETHERING_INVALID:I
-Landroid/net/ConnectivityManager;->TETHER_ERROR_DISABLE_NAT_ERROR:I
-Landroid/net/ConnectivityManager;->TETHER_ERROR_ENABLE_NAT_ERROR:I
-Landroid/net/ConnectivityManager;->TETHER_ERROR_IFACE_CFG_ERROR:I
-Landroid/net/ConnectivityManager;->TETHER_ERROR_MASTER_ERROR:I
-Landroid/net/ConnectivityManager;->TETHER_ERROR_NO_ERROR:I
-Landroid/net/ConnectivityManager;->TETHER_ERROR_PROVISION_FAILED:I
-Landroid/net/ConnectivityManager;->TETHER_ERROR_SERVICE_UNAVAIL:I
-Landroid/net/ConnectivityManager;->TETHER_ERROR_TETHER_IFACE_ERROR:I
-Landroid/net/ConnectivityManager;->TETHER_ERROR_UNAVAIL_IFACE:I
-Landroid/net/ConnectivityManager;->TETHER_ERROR_UNKNOWN_IFACE:I
-Landroid/net/ConnectivityManager;->TETHER_ERROR_UNSUPPORTED:I
-Landroid/net/ConnectivityManager;->TETHER_ERROR_UNTETHER_IFACE_ERROR:I
-Landroid/net/ConnectivityManager;->unsupportedStartingFrom(I)V
-Landroid/net/ConnectivityManager;->updateLockdownVpn()Z
 Landroid/net/ConnectivityMetricsEvent;-><init>()V
 Landroid/net/ConnectivityMetricsEvent;-><init>(Landroid/os/Parcel;)V
 Landroid/net/ConnectivityMetricsEvent;->CREATOR:Landroid/os/Parcelable$Creator;
@@ -35494,12 +35335,6 @@
 Landroid/net/ConnectivityMetricsEvent;->netId:I
 Landroid/net/ConnectivityMetricsEvent;->timestamp:J
 Landroid/net/ConnectivityMetricsEvent;->transports:J
-Landroid/net/ConnectivityThread$Singleton;-><init>()V
-Landroid/net/ConnectivityThread$Singleton;->INSTANCE:Landroid/net/ConnectivityThread;
-Landroid/net/ConnectivityThread;-><init>()V
-Landroid/net/ConnectivityThread;->createInstance()Landroid/net/ConnectivityThread;
-Landroid/net/ConnectivityThread;->get()Landroid/net/ConnectivityThread;
-Landroid/net/ConnectivityThread;->getInstanceLooper()Landroid/os/Looper;
 Landroid/net/Credentials;->gid:I
 Landroid/net/Credentials;->pid:I
 Landroid/net/Credentials;->uid:I
@@ -35510,9 +35345,6 @@
 Landroid/net/DataUsageRequest;->REQUEST_ID_UNSET:I
 Landroid/net/DataUsageRequest;->template:Landroid/net/NetworkTemplate;
 Landroid/net/DataUsageRequest;->thresholdInBytes:J
-Landroid/net/DhcpInfo;-><init>(Landroid/net/DhcpInfo;)V
-Landroid/net/DhcpInfo;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/net/DhcpInfo;->putAddress(Ljava/lang/StringBuffer;I)V
 Landroid/net/DhcpResults;->addDns(Ljava/lang/String;)Z
 Landroid/net/DhcpResults;->clear()V
 Landroid/net/DhcpResults;->CREATOR:Landroid/os/Parcelable$Creator;
@@ -35566,224 +35398,6 @@
 Landroid/net/http/X509TrustManagerExtensions;->mDelegate:Lcom/android/org/conscrypt/TrustManagerImpl;
 Landroid/net/http/X509TrustManagerExtensions;->mIsSameTrustConfiguration:Ljava/lang/reflect/Method;
 Landroid/net/http/X509TrustManagerExtensions;->mTrustManager:Ljavax/net/ssl/X509TrustManager;
-Landroid/net/ICaptivePortal$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/net/ICaptivePortal$Stub$Proxy;->appResponse(I)V
-Landroid/net/ICaptivePortal$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/net/ICaptivePortal$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/net/ICaptivePortal$Stub;-><init>()V
-Landroid/net/ICaptivePortal$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/ICaptivePortal;
-Landroid/net/ICaptivePortal$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/net/ICaptivePortal$Stub;->TRANSACTION_appResponse:I
-Landroid/net/ICaptivePortal;->appResponse(I)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->addVpnAddress(Ljava/lang/String;I)Z
-Landroid/net/IConnectivityManager$Stub$Proxy;->checkMobileProvisioning(I)I
-Landroid/net/IConnectivityManager$Stub$Proxy;->establishVpn(Lcom/android/internal/net/VpnConfig;)Landroid/os/ParcelFileDescriptor;
-Landroid/net/IConnectivityManager$Stub$Proxy;->factoryReset()V
-Landroid/net/IConnectivityManager$Stub$Proxy;->getActiveNetwork()Landroid/net/Network;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getActiveNetworkForUid(IZ)Landroid/net/Network;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getActiveNetworkInfoForUid(IZ)Landroid/net/NetworkInfo;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getActiveNetworkQuotaInfo()Landroid/net/NetworkQuotaInfo;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getAllNetworkState()[Landroid/net/NetworkState;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getAllVpnInfo()[Lcom/android/internal/net/VpnInfo;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getAlwaysOnVpnPackage(I)Ljava/lang/String;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getCaptivePortalServerUrl()Ljava/lang/String;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getDefaultNetworkCapabilitiesForUser(I)[Landroid/net/NetworkCapabilities;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getGlobalProxy()Landroid/net/ProxyInfo;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getLastTetherError(Ljava/lang/String;)I
-Landroid/net/IConnectivityManager$Stub$Proxy;->getLegacyVpnInfo(I)Lcom/android/internal/net/LegacyVpnInfo;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getLinkProperties(Landroid/net/Network;)Landroid/net/LinkProperties;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getLinkPropertiesForType(I)Landroid/net/LinkProperties;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getMobileProvisioningUrl()Ljava/lang/String;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getMultipathPreference(Landroid/net/Network;)I
-Landroid/net/IConnectivityManager$Stub$Proxy;->getNetworkCapabilities(Landroid/net/Network;)Landroid/net/NetworkCapabilities;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getNetworkForType(I)Landroid/net/Network;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getNetworkInfo(I)Landroid/net/NetworkInfo;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getNetworkInfoForUid(Landroid/net/Network;IZ)Landroid/net/NetworkInfo;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getNetworkWatchlistConfigHash()[B
-Landroid/net/IConnectivityManager$Stub$Proxy;->getProxyForNetwork(Landroid/net/Network;)Landroid/net/ProxyInfo;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getRestoreDefaultNetworkDelay(I)I
-Landroid/net/IConnectivityManager$Stub$Proxy;->getTetherableBluetoothRegexs()[Ljava/lang/String;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getTetherableWifiRegexs()[Ljava/lang/String;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getTetheredDhcpRanges()[Ljava/lang/String;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getTetheringErroredIfaces()[Ljava/lang/String;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getVpnConfig(I)Lcom/android/internal/net/VpnConfig;
-Landroid/net/IConnectivityManager$Stub$Proxy;->isActiveNetworkMetered()Z
-Landroid/net/IConnectivityManager$Stub$Proxy;->isAlwaysOnVpnPackageSupported(ILjava/lang/String;)Z
-Landroid/net/IConnectivityManager$Stub$Proxy;->isNetworkSupported(I)Z
-Landroid/net/IConnectivityManager$Stub$Proxy;->isTetheringSupported(Ljava/lang/String;)Z
-Landroid/net/IConnectivityManager$Stub$Proxy;->listenForNetwork(Landroid/net/NetworkCapabilities;Landroid/os/Messenger;Landroid/os/IBinder;)Landroid/net/NetworkRequest;
-Landroid/net/IConnectivityManager$Stub$Proxy;->pendingListenForNetwork(Landroid/net/NetworkCapabilities;Landroid/app/PendingIntent;)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->pendingRequestForNetwork(Landroid/net/NetworkCapabilities;Landroid/app/PendingIntent;)Landroid/net/NetworkRequest;
-Landroid/net/IConnectivityManager$Stub$Proxy;->prepareVpn(Ljava/lang/String;Ljava/lang/String;I)Z
-Landroid/net/IConnectivityManager$Stub$Proxy;->registerNetworkAgent(Landroid/os/Messenger;Landroid/net/NetworkInfo;Landroid/net/LinkProperties;Landroid/net/NetworkCapabilities;ILandroid/net/NetworkMisc;)I
-Landroid/net/IConnectivityManager$Stub$Proxy;->registerNetworkFactory(Landroid/os/Messenger;Ljava/lang/String;)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->releaseNetworkRequest(Landroid/net/NetworkRequest;)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->releasePendingNetworkRequest(Landroid/app/PendingIntent;)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->removeVpnAddress(Ljava/lang/String;I)Z
-Landroid/net/IConnectivityManager$Stub$Proxy;->reportInetCondition(II)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->reportNetworkConnectivity(Landroid/net/Network;Z)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->requestBandwidthUpdate(Landroid/net/Network;)Z
-Landroid/net/IConnectivityManager$Stub$Proxy;->requestNetwork(Landroid/net/NetworkCapabilities;Landroid/os/Messenger;ILandroid/os/IBinder;I)Landroid/net/NetworkRequest;
-Landroid/net/IConnectivityManager$Stub$Proxy;->requestRouteToHostAddress(I[B)Z
-Landroid/net/IConnectivityManager$Stub$Proxy;->setAcceptUnvalidated(Landroid/net/Network;ZZ)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->setAirplaneMode(Z)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->setAlwaysOnVpnPackage(ILjava/lang/String;Z)Z
-Landroid/net/IConnectivityManager$Stub$Proxy;->setAvoidUnvalidated(Landroid/net/Network;)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->setGlobalProxy(Landroid/net/ProxyInfo;)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->setProvisioningNotificationVisible(ZILjava/lang/String;)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->setUnderlyingNetworksForVpn([Landroid/net/Network;)Z
-Landroid/net/IConnectivityManager$Stub$Proxy;->setUsbTethering(ZLjava/lang/String;)I
-Landroid/net/IConnectivityManager$Stub$Proxy;->setVpnPackageAuthorization(Ljava/lang/String;IZ)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->startCaptivePortalApp(Landroid/net/Network;)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->startLegacyVpn(Lcom/android/internal/net/VpnProfile;)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->startNattKeepalive(Landroid/net/Network;ILandroid/os/Messenger;Landroid/os/IBinder;Ljava/lang/String;ILjava/lang/String;)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->startTethering(ILandroid/os/ResultReceiver;ZLjava/lang/String;)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->stopKeepalive(Landroid/net/Network;I)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->stopTethering(ILjava/lang/String;)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->tether(Ljava/lang/String;Ljava/lang/String;)I
-Landroid/net/IConnectivityManager$Stub$Proxy;->unregisterNetworkFactory(Landroid/os/Messenger;)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->untether(Ljava/lang/String;Ljava/lang/String;)I
-Landroid/net/IConnectivityManager$Stub$Proxy;->updateLockdownVpn()Z
-Landroid/net/IConnectivityManager$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_addVpnAddress:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_checkMobileProvisioning:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_establishVpn:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_factoryReset:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getActiveLinkProperties:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getActiveNetwork:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getActiveNetworkForUid:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getActiveNetworkInfo:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getActiveNetworkInfoForUid:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getActiveNetworkQuotaInfo:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getAllNetworkInfo:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getAllNetworks:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getAllNetworkState:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getAllVpnInfo:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getAlwaysOnVpnPackage:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getCaptivePortalServerUrl:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getDefaultNetworkCapabilitiesForUser:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getGlobalProxy:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getLastTetherError:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getLegacyVpnInfo:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getLinkProperties:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getLinkPropertiesForType:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getMobileProvisioningUrl:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getMultipathPreference:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getNetworkCapabilities:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getNetworkForType:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getNetworkInfo:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getNetworkInfoForUid:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getNetworkWatchlistConfigHash:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getProxyForNetwork:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getRestoreDefaultNetworkDelay:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getTetherableBluetoothRegexs:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getTetherableIfaces:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getTetherableUsbRegexs:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getTetherableWifiRegexs:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getTetheredDhcpRanges:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getTetheredIfaces:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getTetheringErroredIfaces:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_getVpnConfig:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_isActiveNetworkMetered:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_isAlwaysOnVpnPackageSupported:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_isNetworkSupported:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_isTetheringSupported:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_listenForNetwork:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_pendingListenForNetwork:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_pendingRequestForNetwork:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_prepareVpn:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_registerNetworkAgent:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_registerNetworkFactory:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_releaseNetworkRequest:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_releasePendingNetworkRequest:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_removeVpnAddress:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_reportInetCondition:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_reportNetworkConnectivity:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_requestBandwidthUpdate:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_requestNetwork:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_requestRouteToHostAddress:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_setAcceptUnvalidated:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_setAirplaneMode:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_setAlwaysOnVpnPackage:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_setAvoidUnvalidated:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_setGlobalProxy:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_setProvisioningNotificationVisible:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_setUnderlyingNetworksForVpn:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_setUsbTethering:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_setVpnPackageAuthorization:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_startCaptivePortalApp:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_startLegacyVpn:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_startNattKeepalive:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_startTethering:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_stopKeepalive:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_stopTethering:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_tether:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_unregisterNetworkFactory:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_untether:I
-Landroid/net/IConnectivityManager$Stub;->TRANSACTION_updateLockdownVpn:I
-Landroid/net/IConnectivityManager;->addVpnAddress(Ljava/lang/String;I)Z
-Landroid/net/IConnectivityManager;->checkMobileProvisioning(I)I
-Landroid/net/IConnectivityManager;->establishVpn(Lcom/android/internal/net/VpnConfig;)Landroid/os/ParcelFileDescriptor;
-Landroid/net/IConnectivityManager;->factoryReset()V
-Landroid/net/IConnectivityManager;->getActiveNetwork()Landroid/net/Network;
-Landroid/net/IConnectivityManager;->getActiveNetworkForUid(IZ)Landroid/net/Network;
-Landroid/net/IConnectivityManager;->getActiveNetworkInfoForUid(IZ)Landroid/net/NetworkInfo;
-Landroid/net/IConnectivityManager;->getActiveNetworkQuotaInfo()Landroid/net/NetworkQuotaInfo;
-Landroid/net/IConnectivityManager;->getAllNetworks()[Landroid/net/Network;
-Landroid/net/IConnectivityManager;->getAllVpnInfo()[Lcom/android/internal/net/VpnInfo;
-Landroid/net/IConnectivityManager;->getAlwaysOnVpnPackage(I)Ljava/lang/String;
-Landroid/net/IConnectivityManager;->getCaptivePortalServerUrl()Ljava/lang/String;
-Landroid/net/IConnectivityManager;->getDefaultNetworkCapabilitiesForUser(I)[Landroid/net/NetworkCapabilities;
-Landroid/net/IConnectivityManager;->getGlobalProxy()Landroid/net/ProxyInfo;
-Landroid/net/IConnectivityManager;->getLegacyVpnInfo(I)Lcom/android/internal/net/LegacyVpnInfo;
-Landroid/net/IConnectivityManager;->getLinkProperties(Landroid/net/Network;)Landroid/net/LinkProperties;
-Landroid/net/IConnectivityManager;->getLinkPropertiesForType(I)Landroid/net/LinkProperties;
-Landroid/net/IConnectivityManager;->getMobileProvisioningUrl()Ljava/lang/String;
-Landroid/net/IConnectivityManager;->getMultipathPreference(Landroid/net/Network;)I
-Landroid/net/IConnectivityManager;->getNetworkCapabilities(Landroid/net/Network;)Landroid/net/NetworkCapabilities;
-Landroid/net/IConnectivityManager;->getNetworkForType(I)Landroid/net/Network;
-Landroid/net/IConnectivityManager;->getNetworkInfoForUid(Landroid/net/Network;IZ)Landroid/net/NetworkInfo;
-Landroid/net/IConnectivityManager;->getNetworkWatchlistConfigHash()[B
-Landroid/net/IConnectivityManager;->getProxyForNetwork(Landroid/net/Network;)Landroid/net/ProxyInfo;
-Landroid/net/IConnectivityManager;->getRestoreDefaultNetworkDelay(I)I
-Landroid/net/IConnectivityManager;->getTetherableBluetoothRegexs()[Ljava/lang/String;
-Landroid/net/IConnectivityManager;->getTetheredDhcpRanges()[Ljava/lang/String;
-Landroid/net/IConnectivityManager;->getVpnConfig(I)Lcom/android/internal/net/VpnConfig;
-Landroid/net/IConnectivityManager;->isActiveNetworkMetered()Z
-Landroid/net/IConnectivityManager;->isAlwaysOnVpnPackageSupported(ILjava/lang/String;)Z
-Landroid/net/IConnectivityManager;->isNetworkSupported(I)Z
-Landroid/net/IConnectivityManager;->isTetheringSupported(Ljava/lang/String;)Z
-Landroid/net/IConnectivityManager;->listenForNetwork(Landroid/net/NetworkCapabilities;Landroid/os/Messenger;Landroid/os/IBinder;)Landroid/net/NetworkRequest;
-Landroid/net/IConnectivityManager;->pendingListenForNetwork(Landroid/net/NetworkCapabilities;Landroid/app/PendingIntent;)V
-Landroid/net/IConnectivityManager;->pendingRequestForNetwork(Landroid/net/NetworkCapabilities;Landroid/app/PendingIntent;)Landroid/net/NetworkRequest;
-Landroid/net/IConnectivityManager;->prepareVpn(Ljava/lang/String;Ljava/lang/String;I)Z
-Landroid/net/IConnectivityManager;->registerNetworkAgent(Landroid/os/Messenger;Landroid/net/NetworkInfo;Landroid/net/LinkProperties;Landroid/net/NetworkCapabilities;ILandroid/net/NetworkMisc;)I
-Landroid/net/IConnectivityManager;->registerNetworkFactory(Landroid/os/Messenger;Ljava/lang/String;)V
-Landroid/net/IConnectivityManager;->releaseNetworkRequest(Landroid/net/NetworkRequest;)V
-Landroid/net/IConnectivityManager;->releasePendingNetworkRequest(Landroid/app/PendingIntent;)V
-Landroid/net/IConnectivityManager;->removeVpnAddress(Ljava/lang/String;I)Z
-Landroid/net/IConnectivityManager;->reportNetworkConnectivity(Landroid/net/Network;Z)V
-Landroid/net/IConnectivityManager;->requestBandwidthUpdate(Landroid/net/Network;)Z
-Landroid/net/IConnectivityManager;->requestNetwork(Landroid/net/NetworkCapabilities;Landroid/os/Messenger;ILandroid/os/IBinder;I)Landroid/net/NetworkRequest;
-Landroid/net/IConnectivityManager;->requestRouteToHostAddress(I[B)Z
-Landroid/net/IConnectivityManager;->setAcceptUnvalidated(Landroid/net/Network;ZZ)V
-Landroid/net/IConnectivityManager;->setAlwaysOnVpnPackage(ILjava/lang/String;Z)Z
-Landroid/net/IConnectivityManager;->setAvoidUnvalidated(Landroid/net/Network;)V
-Landroid/net/IConnectivityManager;->setGlobalProxy(Landroid/net/ProxyInfo;)V
-Landroid/net/IConnectivityManager;->setProvisioningNotificationVisible(ZILjava/lang/String;)V
-Landroid/net/IConnectivityManager;->setUnderlyingNetworksForVpn([Landroid/net/Network;)Z
-Landroid/net/IConnectivityManager;->setUsbTethering(ZLjava/lang/String;)I
-Landroid/net/IConnectivityManager;->setVpnPackageAuthorization(Ljava/lang/String;IZ)V
-Landroid/net/IConnectivityManager;->startCaptivePortalApp(Landroid/net/Network;)V
-Landroid/net/IConnectivityManager;->startNattKeepalive(Landroid/net/Network;ILandroid/os/Messenger;Landroid/os/IBinder;Ljava/lang/String;ILjava/lang/String;)V
-Landroid/net/IConnectivityManager;->startTethering(ILandroid/os/ResultReceiver;ZLjava/lang/String;)V
-Landroid/net/IConnectivityManager;->stopKeepalive(Landroid/net/Network;I)V
-Landroid/net/IConnectivityManager;->stopTethering(ILjava/lang/String;)V
-Landroid/net/IConnectivityManager;->tether(Ljava/lang/String;Ljava/lang/String;)I
-Landroid/net/IConnectivityManager;->unregisterNetworkFactory(Landroid/os/Messenger;)V
-Landroid/net/IConnectivityManager;->untether(Ljava/lang/String;Ljava/lang/String;)I
-Landroid/net/IConnectivityManager;->updateLockdownVpn()Z
 Landroid/net/IEthernetManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/net/IEthernetManager$Stub$Proxy;->addListener(Landroid/net/IEthernetServiceListener;)V
 Landroid/net/IEthernetManager$Stub$Proxy;->getAvailableInterfaces()[Ljava/lang/String;
@@ -36300,41 +35914,6 @@
 Landroid/net/InterfaceConfiguration;->mHwAddr:Ljava/lang/String;
 Landroid/net/InterfaceConfiguration;->setHardwareAddress(Ljava/lang/String;)V
 Landroid/net/InterfaceConfiguration;->validateFlag(Ljava/lang/String;)V
-Landroid/net/IpConfiguration$IpAssignment;->DHCP:Landroid/net/IpConfiguration$IpAssignment;
-Landroid/net/IpConfiguration$IpAssignment;->UNASSIGNED:Landroid/net/IpConfiguration$IpAssignment;
-Landroid/net/IpConfiguration$IpAssignment;->valueOf(Ljava/lang/String;)Landroid/net/IpConfiguration$IpAssignment;
-Landroid/net/IpConfiguration$IpAssignment;->values()[Landroid/net/IpConfiguration$IpAssignment;
-Landroid/net/IpConfiguration$ProxySettings;->PAC:Landroid/net/IpConfiguration$ProxySettings;
-Landroid/net/IpConfiguration$ProxySettings;->STATIC:Landroid/net/IpConfiguration$ProxySettings;
-Landroid/net/IpConfiguration$ProxySettings;->UNASSIGNED:Landroid/net/IpConfiguration$ProxySettings;
-Landroid/net/IpConfiguration$ProxySettings;->valueOf(Ljava/lang/String;)Landroid/net/IpConfiguration$ProxySettings;
-Landroid/net/IpConfiguration$ProxySettings;->values()[Landroid/net/IpConfiguration$ProxySettings;
-Landroid/net/IpConfiguration;-><init>()V
-Landroid/net/IpConfiguration;-><init>(Landroid/net/IpConfiguration;)V
-Landroid/net/IpConfiguration;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/net/IpConfiguration;->getHttpProxy()Landroid/net/ProxyInfo;
-Landroid/net/IpConfiguration;->getIpAssignment()Landroid/net/IpConfiguration$IpAssignment;
-Landroid/net/IpConfiguration;->getProxySettings()Landroid/net/IpConfiguration$ProxySettings;
-Landroid/net/IpConfiguration;->getStaticIpConfiguration()Landroid/net/StaticIpConfiguration;
-Landroid/net/IpConfiguration;->init(Landroid/net/IpConfiguration$IpAssignment;Landroid/net/IpConfiguration$ProxySettings;Landroid/net/StaticIpConfiguration;Landroid/net/ProxyInfo;)V
-Landroid/net/IpConfiguration;->ipAssignment:Landroid/net/IpConfiguration$IpAssignment;
-Landroid/net/IpConfiguration;->proxySettings:Landroid/net/IpConfiguration$ProxySettings;
-Landroid/net/IpConfiguration;->setHttpProxy(Landroid/net/ProxyInfo;)V
-Landroid/net/IpConfiguration;->setIpAssignment(Landroid/net/IpConfiguration$IpAssignment;)V
-Landroid/net/IpConfiguration;->setProxySettings(Landroid/net/IpConfiguration$ProxySettings;)V
-Landroid/net/IpConfiguration;->setStaticIpConfiguration(Landroid/net/StaticIpConfiguration;)V
-Landroid/net/IpConfiguration;->staticIpConfiguration:Landroid/net/StaticIpConfiguration;
-Landroid/net/IpConfiguration;->TAG:Ljava/lang/String;
-Landroid/net/IpPrefix;-><init>(Ljava/lang/String;)V
-Landroid/net/IpPrefix;-><init>(Ljava/net/InetAddress;I)V
-Landroid/net/IpPrefix;-><init>([BI)V
-Landroid/net/IpPrefix;->address:[B
-Landroid/net/IpPrefix;->checkAndMaskAddressAndPrefixLength()V
-Landroid/net/IpPrefix;->containsPrefix(Landroid/net/IpPrefix;)Z
-Landroid/net/IpPrefix;->isIPv4()Z
-Landroid/net/IpPrefix;->isIPv6()Z
-Landroid/net/IpPrefix;->lengthComparator()Ljava/util/Comparator;
-Landroid/net/IpPrefix;->prefixLength:I
 Landroid/net/IpSecAlgorithm;->checkValidOrThrow(Ljava/lang/String;II)V
 Landroid/net/IpSecAlgorithm;->CRYPT_NULL:Ljava/lang/String;
 Landroid/net/IpSecAlgorithm;->equals(Landroid/net/IpSecAlgorithm;Landroid/net/IpSecAlgorithm;)Z
@@ -36516,73 +36095,6 @@
 Landroid/net/ITetheringStatsProvider;->getTetherStats(I)Landroid/net/NetworkStats;
 Landroid/net/ITetheringStatsProvider;->QUOTA_UNLIMITED:I
 Landroid/net/ITetheringStatsProvider;->setInterfaceQuota(Ljava/lang/String;J)V
-Landroid/net/KeepalivePacketData$InvalidPacketException;-><init>(I)V
-Landroid/net/KeepalivePacketData$InvalidPacketException;->error:I
-Landroid/net/KeepalivePacketData;-><init>(Landroid/os/Parcel;)V
-Landroid/net/KeepalivePacketData;-><init>(Ljava/net/InetAddress;ILjava/net/InetAddress;I[B)V
-Landroid/net/KeepalivePacketData;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/net/KeepalivePacketData;->dstAddress:Ljava/net/InetAddress;
-Landroid/net/KeepalivePacketData;->dstPort:I
-Landroid/net/KeepalivePacketData;->getPacket()[B
-Landroid/net/KeepalivePacketData;->IPV4_HEADER_LENGTH:I
-Landroid/net/KeepalivePacketData;->mPacket:[B
-Landroid/net/KeepalivePacketData;->nattKeepalivePacket(Ljava/net/InetAddress;ILjava/net/InetAddress;I)Landroid/net/KeepalivePacketData;
-Landroid/net/KeepalivePacketData;->srcAddress:Ljava/net/InetAddress;
-Landroid/net/KeepalivePacketData;->srcPort:I
-Landroid/net/KeepalivePacketData;->TAG:Ljava/lang/String;
-Landroid/net/KeepalivePacketData;->UDP_HEADER_LENGTH:I
-Landroid/net/LinkAddress;-><init>(Ljava/lang/String;II)V
-Landroid/net/LinkAddress;-><init>(Ljava/net/InetAddress;III)V
-Landroid/net/LinkAddress;-><init>(Ljava/net/InterfaceAddress;)V
-Landroid/net/LinkAddress;->flags:I
-Landroid/net/LinkAddress;->init(Ljava/net/InetAddress;III)V
-Landroid/net/LinkAddress;->isGlobalPreferred()Z
-Landroid/net/LinkAddress;->isIPv4()Z
-Landroid/net/LinkAddress;->isIPv6ULA()Z
-Landroid/net/LinkAddress;->scope:I
-Landroid/net/LinkAddress;->scopeForUnicastAddress(Ljava/net/InetAddress;)I
-Landroid/net/LinkProperties$CompareResult;-><init>()V
-Landroid/net/LinkProperties$CompareResult;-><init>(Ljava/util/Collection;Ljava/util/Collection;)V
-Landroid/net/LinkProperties$CompareResult;->added:Ljava/util/List;
-Landroid/net/LinkProperties$CompareResult;->removed:Ljava/util/List;
-Landroid/net/LinkProperties$ProvisioningChange;->valueOf(Ljava/lang/String;)Landroid/net/LinkProperties$ProvisioningChange;
-Landroid/net/LinkProperties;->addValidatedPrivateDnsServer(Ljava/net/InetAddress;)Z
-Landroid/net/LinkProperties;->compareAddresses(Landroid/net/LinkProperties;)Landroid/net/LinkProperties$CompareResult;
-Landroid/net/LinkProperties;->compareAllInterfaceNames(Landroid/net/LinkProperties;)Landroid/net/LinkProperties$CompareResult;
-Landroid/net/LinkProperties;->compareAllRoutes(Landroid/net/LinkProperties;)Landroid/net/LinkProperties$CompareResult;
-Landroid/net/LinkProperties;->compareDnses(Landroid/net/LinkProperties;)Landroid/net/LinkProperties$CompareResult;
-Landroid/net/LinkProperties;->compareValidatedPrivateDnses(Landroid/net/LinkProperties;)Landroid/net/LinkProperties$CompareResult;
-Landroid/net/LinkProperties;->ensureDirectlyConnectedRoutes()V
-Landroid/net/LinkProperties;->findLinkAddressIndex(Landroid/net/LinkAddress;)I
-Landroid/net/LinkProperties;->getValidatedPrivateDnsServers()Ljava/util/List;
-Landroid/net/LinkProperties;->hasIPv4AddressOnInterface(Ljava/lang/String;)Z
-Landroid/net/LinkProperties;->isIdenticalMtu(Landroid/net/LinkProperties;)Z
-Landroid/net/LinkProperties;->isIdenticalPrivateDns(Landroid/net/LinkProperties;)Z
-Landroid/net/LinkProperties;->isIdenticalTcpBufferSizes(Landroid/net/LinkProperties;)Z
-Landroid/net/LinkProperties;->isIdenticalValidatedPrivateDnses(Landroid/net/LinkProperties;)Z
-Landroid/net/LinkProperties;->isIPv4Provisioned()Z
-Landroid/net/LinkProperties;->isValidMtu(IZ)Z
-Landroid/net/LinkProperties;->MAX_MTU:I
-Landroid/net/LinkProperties;->mDnses:Ljava/util/ArrayList;
-Landroid/net/LinkProperties;->mDomains:Ljava/lang/String;
-Landroid/net/LinkProperties;->mHttpProxy:Landroid/net/ProxyInfo;
-Landroid/net/LinkProperties;->MIN_MTU:I
-Landroid/net/LinkProperties;->MIN_MTU_V6:I
-Landroid/net/LinkProperties;->mLinkAddresses:Ljava/util/ArrayList;
-Landroid/net/LinkProperties;->mMtu:I
-Landroid/net/LinkProperties;->mPrivateDnsServerName:Ljava/lang/String;
-Landroid/net/LinkProperties;->mRoutes:Ljava/util/ArrayList;
-Landroid/net/LinkProperties;->mStackedLinks:Ljava/util/Hashtable;
-Landroid/net/LinkProperties;->mTcpBufferSizes:Ljava/lang/String;
-Landroid/net/LinkProperties;->mUsePrivateDns:Z
-Landroid/net/LinkProperties;->mValidatedPrivateDnses:Ljava/util/ArrayList;
-Landroid/net/LinkProperties;->removeLinkAddress(Landroid/net/LinkAddress;)Z
-Landroid/net/LinkProperties;->removeStackedLink(Ljava/lang/String;)Z
-Landroid/net/LinkProperties;->removeValidatedPrivateDnsServer(Ljava/net/InetAddress;)Z
-Landroid/net/LinkProperties;->routeWithInterface(Landroid/net/RouteInfo;)Landroid/net/RouteInfo;
-Landroid/net/LinkProperties;->setPrivateDnsServerName(Ljava/lang/String;)V
-Landroid/net/LinkProperties;->setUsePrivateDns(Z)V
-Landroid/net/LinkProperties;->setValidatedPrivateDnsServers(Ljava/util/Collection;)V
 Landroid/net/LinkQualityInfo;-><init>()V
 Landroid/net/LinkQualityInfo;->CREATOR:Landroid/os/Parcelable$Creator;
 Landroid/net/LinkQualityInfo;->getDataSampleDuration()I
@@ -36671,29 +36183,6 @@
 Landroid/net/LocalSocketImpl;->writeba_native([BIILjava/io/FileDescriptor;)V
 Landroid/net/LocalSocketImpl;->writeMonitor:Ljava/lang/Object;
 Landroid/net/LocalSocketImpl;->write_native(ILjava/io/FileDescriptor;)V
-Landroid/net/MacAddress;-><init>(J)V
-Landroid/net/MacAddress;->BASE_GOOGLE_MAC:Landroid/net/MacAddress;
-Landroid/net/MacAddress;->byteAddrFromLongAddr(J)[B
-Landroid/net/MacAddress;->byteAddrFromStringAddr(Ljava/lang/String;)[B
-Landroid/net/MacAddress;->createRandomUnicastAddress()Landroid/net/MacAddress;
-Landroid/net/MacAddress;->createRandomUnicastAddress(Landroid/net/MacAddress;Ljava/util/Random;)Landroid/net/MacAddress;
-Landroid/net/MacAddress;->createRandomUnicastAddressWithGoogleBase()Landroid/net/MacAddress;
-Landroid/net/MacAddress;->ETHER_ADDR_BROADCAST:[B
-Landroid/net/MacAddress;->ETHER_ADDR_LEN:I
-Landroid/net/MacAddress;->isMacAddress([B)Z
-Landroid/net/MacAddress;->isMulticastAddress()Z
-Landroid/net/MacAddress;->LOCALLY_ASSIGNED_MASK:J
-Landroid/net/MacAddress;->longAddrFromByteAddr([B)J
-Landroid/net/MacAddress;->longAddrFromStringAddr(Ljava/lang/String;)J
-Landroid/net/MacAddress;->macAddressType([B)I
-Landroid/net/MacAddress;->mAddr:J
-Landroid/net/MacAddress;->MULTICAST_MASK:J
-Landroid/net/MacAddress;->NIC_MASK:J
-Landroid/net/MacAddress;->OUI_MASK:J
-Landroid/net/MacAddress;->stringAddrFromByteAddr([B)Ljava/lang/String;
-Landroid/net/MacAddress;->stringAddrFromLongAddr(J)Ljava/lang/String;
-Landroid/net/MacAddress;->TYPE_UNKNOWN:I
-Landroid/net/MacAddress;->VALID_LONG_MASK:J
 Landroid/net/MailTo;-><init>()V
 Landroid/net/MailTo;->BODY:Ljava/lang/String;
 Landroid/net/MailTo;->CC:Ljava/lang/String;
@@ -36952,666 +36441,6 @@
 Landroid/net/MobileLinkQualityInfo;->mLteSignalStrength:I
 Landroid/net/MobileLinkQualityInfo;->mMobileNetworkType:I
 Landroid/net/MobileLinkQualityInfo;->mRssi:I
-Landroid/net/Network$NetworkBoundSocketFactory;->connectToHost(Ljava/lang/String;ILjava/net/SocketAddress;)Ljava/net/Socket;
-Landroid/net/Network$NetworkBoundSocketFactory;->mNetId:I
-Landroid/net/Network;-><init>(Landroid/net/Network;)V
-Landroid/net/Network;->getNetIdForResolv()I
-Landroid/net/Network;->HANDLE_MAGIC:J
-Landroid/net/Network;->HANDLE_MAGIC_SIZE:I
-Landroid/net/Network;->httpKeepAlive:Z
-Landroid/net/Network;->httpKeepAliveDurationMs:J
-Landroid/net/Network;->httpMaxConnections:I
-Landroid/net/Network;->maybeInitUrlConnectionFactory()V
-Landroid/net/Network;->mLock:Ljava/lang/Object;
-Landroid/net/Network;->mNetworkBoundSocketFactory:Landroid/net/Network$NetworkBoundSocketFactory;
-Landroid/net/Network;->mPrivateDnsBypass:Z
-Landroid/net/Network;->mUrlConnectionFactory:Lcom/android/okhttp/internalandroidapi/HttpURLConnectionFactory;
-Landroid/net/Network;->setPrivateDnsBypass(Z)V
-Landroid/net/Network;->writeToProto(Landroid/util/proto/ProtoOutputStream;J)V
-Landroid/net/NetworkAgent;-><init>(Landroid/os/Looper;Landroid/content/Context;Ljava/lang/String;Landroid/net/NetworkInfo;Landroid/net/NetworkCapabilities;Landroid/net/LinkProperties;I)V
-Landroid/net/NetworkAgent;-><init>(Landroid/os/Looper;Landroid/content/Context;Ljava/lang/String;Landroid/net/NetworkInfo;Landroid/net/NetworkCapabilities;Landroid/net/LinkProperties;ILandroid/net/NetworkMisc;)V
-Landroid/net/NetworkAgent;->BASE:I
-Landroid/net/NetworkAgent;->BW_REFRESH_MIN_WIN_MS:J
-Landroid/net/NetworkAgent;->CMD_PREVENT_AUTOMATIC_RECONNECT:I
-Landroid/net/NetworkAgent;->CMD_REPORT_NETWORK_STATUS:I
-Landroid/net/NetworkAgent;->CMD_REQUEST_BANDWIDTH_UPDATE:I
-Landroid/net/NetworkAgent;->CMD_SAVE_ACCEPT_UNVALIDATED:I
-Landroid/net/NetworkAgent;->CMD_SET_SIGNAL_STRENGTH_THRESHOLDS:I
-Landroid/net/NetworkAgent;->CMD_START_PACKET_KEEPALIVE:I
-Landroid/net/NetworkAgent;->CMD_STOP_PACKET_KEEPALIVE:I
-Landroid/net/NetworkAgent;->CMD_SUSPECT_BAD:I
-Landroid/net/NetworkAgent;->DBG:Z
-Landroid/net/NetworkAgent;->EVENT_NETWORK_CAPABILITIES_CHANGED:I
-Landroid/net/NetworkAgent;->EVENT_NETWORK_INFO_CHANGED:I
-Landroid/net/NetworkAgent;->EVENT_NETWORK_PROPERTIES_CHANGED:I
-Landroid/net/NetworkAgent;->EVENT_NETWORK_SCORE_CHANGED:I
-Landroid/net/NetworkAgent;->EVENT_PACKET_KEEPALIVE:I
-Landroid/net/NetworkAgent;->EVENT_SET_EXPLICITLY_SELECTED:I
-Landroid/net/NetworkAgent;->explicitlySelected(Z)V
-Landroid/net/NetworkAgent;->INVALID_NETWORK:I
-Landroid/net/NetworkAgent;->log(Ljava/lang/String;)V
-Landroid/net/NetworkAgent;->LOG_TAG:Ljava/lang/String;
-Landroid/net/NetworkAgent;->mAsyncChannel:Lcom/android/internal/util/AsyncChannel;
-Landroid/net/NetworkAgent;->mContext:Landroid/content/Context;
-Landroid/net/NetworkAgent;->mLastBwRefreshTime:J
-Landroid/net/NetworkAgent;->mPollLcePending:Ljava/util/concurrent/atomic/AtomicBoolean;
-Landroid/net/NetworkAgent;->mPollLceScheduled:Z
-Landroid/net/NetworkAgent;->mPreConnectedQueue:Ljava/util/ArrayList;
-Landroid/net/NetworkAgent;->netId:I
-Landroid/net/NetworkAgent;->networkStatus(ILjava/lang/String;)V
-Landroid/net/NetworkAgent;->onPacketKeepaliveEvent(II)V
-Landroid/net/NetworkAgent;->pollLceData()V
-Landroid/net/NetworkAgent;->preventAutomaticReconnect()V
-Landroid/net/NetworkAgent;->queueOrSendMessage(III)V
-Landroid/net/NetworkAgent;->queueOrSendMessage(IIILjava/lang/Object;)V
-Landroid/net/NetworkAgent;->queueOrSendMessage(ILjava/lang/Object;)V
-Landroid/net/NetworkAgent;->queueOrSendMessage(Landroid/os/Message;)V
-Landroid/net/NetworkAgent;->REDIRECT_URL_KEY:Ljava/lang/String;
-Landroid/net/NetworkAgent;->saveAcceptUnvalidated(Z)V
-Landroid/net/NetworkAgent;->sendLinkProperties(Landroid/net/LinkProperties;)V
-Landroid/net/NetworkAgent;->sendNetworkCapabilities(Landroid/net/NetworkCapabilities;)V
-Landroid/net/NetworkAgent;->sendNetworkScore(I)V
-Landroid/net/NetworkAgent;->setSignalStrengthThresholds([I)V
-Landroid/net/NetworkAgent;->startPacketKeepalive(Landroid/os/Message;)V
-Landroid/net/NetworkAgent;->stopPacketKeepalive(Landroid/os/Message;)V
-Landroid/net/NetworkAgent;->unwanted()V
-Landroid/net/NetworkAgent;->VALID_NETWORK:I
-Landroid/net/NetworkAgent;->VDBG:Z
-Landroid/net/NetworkAgent;->WIFI_BASE_SCORE:I
-Landroid/net/NetworkBadging;-><init>()V
-Landroid/net/NetworkBadging;->getBadgedWifiSignalResource(I)I
-Landroid/net/NetworkBadging;->getWifiSignalResource(I)I
-Landroid/net/NetworkCapabilities$NameOf;->nameOf(I)Ljava/lang/String;
-Landroid/net/NetworkCapabilities;->addUnwantedCapability(I)V
-Landroid/net/NetworkCapabilities;->appendStringRepresentationOfBitMaskToStringBuilder(Ljava/lang/StringBuilder;JLandroid/net/NetworkCapabilities$NameOf;Ljava/lang/String;)V
-Landroid/net/NetworkCapabilities;->appliesToUid(I)Z
-Landroid/net/NetworkCapabilities;->appliesToUidRange(Landroid/net/UidRange;)Z
-Landroid/net/NetworkCapabilities;->capabilityNameOf(I)Ljava/lang/String;
-Landroid/net/NetworkCapabilities;->capabilityNamesOf([I)Ljava/lang/String;
-Landroid/net/NetworkCapabilities;->checkValidCapability(I)V
-Landroid/net/NetworkCapabilities;->checkValidTransportType(I)V
-Landroid/net/NetworkCapabilities;->clearAll()V
-Landroid/net/NetworkCapabilities;->combineCapabilities(Landroid/net/NetworkCapabilities;)V
-Landroid/net/NetworkCapabilities;->combineLinkBandwidths(Landroid/net/NetworkCapabilities;)V
-Landroid/net/NetworkCapabilities;->combineNetCapabilities(Landroid/net/NetworkCapabilities;)V
-Landroid/net/NetworkCapabilities;->combineSignalStrength(Landroid/net/NetworkCapabilities;)V
-Landroid/net/NetworkCapabilities;->combineSpecifiers(Landroid/net/NetworkCapabilities;)V
-Landroid/net/NetworkCapabilities;->combineSSIDs(Landroid/net/NetworkCapabilities;)V
-Landroid/net/NetworkCapabilities;->combineTransportTypes(Landroid/net/NetworkCapabilities;)V
-Landroid/net/NetworkCapabilities;->combineUids(Landroid/net/NetworkCapabilities;)V
-Landroid/net/NetworkCapabilities;->DEFAULT_CAPABILITIES:J
-Landroid/net/NetworkCapabilities;->describeFirstNonRequestableCapability()Ljava/lang/String;
-Landroid/net/NetworkCapabilities;->describeImmutableDifferences(Landroid/net/NetworkCapabilities;)Ljava/lang/String;
-Landroid/net/NetworkCapabilities;->equalRequestableCapabilities(Landroid/net/NetworkCapabilities;)Z
-Landroid/net/NetworkCapabilities;->equalsLinkBandwidths(Landroid/net/NetworkCapabilities;)Z
-Landroid/net/NetworkCapabilities;->equalsNetCapabilities(Landroid/net/NetworkCapabilities;)Z
-Landroid/net/NetworkCapabilities;->equalsNetCapabilitiesRequestable(Landroid/net/NetworkCapabilities;)Z
-Landroid/net/NetworkCapabilities;->equalsSignalStrength(Landroid/net/NetworkCapabilities;)Z
-Landroid/net/NetworkCapabilities;->equalsSpecifier(Landroid/net/NetworkCapabilities;)Z
-Landroid/net/NetworkCapabilities;->equalsSSID(Landroid/net/NetworkCapabilities;)Z
-Landroid/net/NetworkCapabilities;->equalsTransportTypes(Landroid/net/NetworkCapabilities;)Z
-Landroid/net/NetworkCapabilities;->equalsUids(Landroid/net/NetworkCapabilities;)Z
-Landroid/net/NetworkCapabilities;->FORCE_RESTRICTED_CAPABILITIES:J
-Landroid/net/NetworkCapabilities;->getSSID()Ljava/lang/String;
-Landroid/net/NetworkCapabilities;->getUids()Ljava/util/Set;
-Landroid/net/NetworkCapabilities;->getUnwantedCapabilities()[I
-Landroid/net/NetworkCapabilities;->hasUnwantedCapability(I)Z
-Landroid/net/NetworkCapabilities;->INVALID_UID:I
-Landroid/net/NetworkCapabilities;->isValidCapability(I)Z
-Landroid/net/NetworkCapabilities;->isValidTransport(I)Z
-Landroid/net/NetworkCapabilities;->LINK_BANDWIDTH_UNSPECIFIED:I
-Landroid/net/NetworkCapabilities;->maxBandwidth(II)I
-Landroid/net/NetworkCapabilities;->MAX_NET_CAPABILITY:I
-Landroid/net/NetworkCapabilities;->MAX_TRANSPORT:I
-Landroid/net/NetworkCapabilities;->maybeMarkCapabilitiesRestricted()V
-Landroid/net/NetworkCapabilities;->mEstablishingVpnAppUid:I
-Landroid/net/NetworkCapabilities;->minBandwidth(II)I
-Landroid/net/NetworkCapabilities;->MIN_NET_CAPABILITY:I
-Landroid/net/NetworkCapabilities;->MIN_TRANSPORT:I
-Landroid/net/NetworkCapabilities;->mLinkDownBandwidthKbps:I
-Landroid/net/NetworkCapabilities;->mLinkUpBandwidthKbps:I
-Landroid/net/NetworkCapabilities;->mNetworkSpecifier:Landroid/net/NetworkSpecifier;
-Landroid/net/NetworkCapabilities;->mSSID:Ljava/lang/String;
-Landroid/net/NetworkCapabilities;->mTransportTypes:J
-Landroid/net/NetworkCapabilities;->mUids:Landroid/util/ArraySet;
-Landroid/net/NetworkCapabilities;->mUnwantedNetworkCapabilities:J
-Landroid/net/NetworkCapabilities;->MUTABLE_CAPABILITIES:J
-Landroid/net/NetworkCapabilities;->NON_REQUESTABLE_CAPABILITIES:J
-Landroid/net/NetworkCapabilities;->removeTransportType(I)Landroid/net/NetworkCapabilities;
-Landroid/net/NetworkCapabilities;->RESTRICTED_CAPABILITIES:J
-Landroid/net/NetworkCapabilities;->satisfiedByImmutableNetworkCapabilities(Landroid/net/NetworkCapabilities;)Z
-Landroid/net/NetworkCapabilities;->satisfiedByLinkBandwidths(Landroid/net/NetworkCapabilities;)Z
-Landroid/net/NetworkCapabilities;->satisfiedByNetCapabilities(Landroid/net/NetworkCapabilities;Z)Z
-Landroid/net/NetworkCapabilities;->satisfiedByNetworkCapabilities(Landroid/net/NetworkCapabilities;)Z
-Landroid/net/NetworkCapabilities;->satisfiedByNetworkCapabilities(Landroid/net/NetworkCapabilities;Z)Z
-Landroid/net/NetworkCapabilities;->satisfiedBySignalStrength(Landroid/net/NetworkCapabilities;)Z
-Landroid/net/NetworkCapabilities;->satisfiedBySpecifier(Landroid/net/NetworkCapabilities;)Z
-Landroid/net/NetworkCapabilities;->satisfiedBySSID(Landroid/net/NetworkCapabilities;)Z
-Landroid/net/NetworkCapabilities;->satisfiedByTransportTypes(Landroid/net/NetworkCapabilities;)Z
-Landroid/net/NetworkCapabilities;->satisfiedByUids(Landroid/net/NetworkCapabilities;)Z
-Landroid/net/NetworkCapabilities;->set(Landroid/net/NetworkCapabilities;)V
-Landroid/net/NetworkCapabilities;->setCapabilities([I)V
-Landroid/net/NetworkCapabilities;->setCapabilities([I[I)V
-Landroid/net/NetworkCapabilities;->setCapability(IZ)Landroid/net/NetworkCapabilities;
-Landroid/net/NetworkCapabilities;->setEstablishingVpnAppUid(I)V
-Landroid/net/NetworkCapabilities;->setLinkDownstreamBandwidthKbps(I)Landroid/net/NetworkCapabilities;
-Landroid/net/NetworkCapabilities;->setLinkUpstreamBandwidthKbps(I)Landroid/net/NetworkCapabilities;
-Landroid/net/NetworkCapabilities;->setNetworkSpecifier(Landroid/net/NetworkSpecifier;)Landroid/net/NetworkCapabilities;
-Landroid/net/NetworkCapabilities;->setSingleUid(I)Landroid/net/NetworkCapabilities;
-Landroid/net/NetworkCapabilities;->setSSID(Ljava/lang/String;)Landroid/net/NetworkCapabilities;
-Landroid/net/NetworkCapabilities;->setTransportType(IZ)Landroid/net/NetworkCapabilities;
-Landroid/net/NetworkCapabilities;->setTransportTypes([I)V
-Landroid/net/NetworkCapabilities;->setUids(Ljava/util/Set;)Landroid/net/NetworkCapabilities;
-Landroid/net/NetworkCapabilities;->SIGNAL_STRENGTH_UNSPECIFIED:I
-Landroid/net/NetworkCapabilities;->TAG:Ljava/lang/String;
-Landroid/net/NetworkCapabilities;->transportNameOf(I)Ljava/lang/String;
-Landroid/net/NetworkCapabilities;->TRANSPORT_NAMES:[Ljava/lang/String;
-Landroid/net/NetworkCapabilities;->UNRESTRICTED_CAPABILITIES:J
-Landroid/net/NetworkCapabilities;->writeToProto(Landroid/util/proto/ProtoOutputStream;J)V
-Landroid/net/NetworkCapabilitiesProto;-><init>()V
-Landroid/net/NetworkCapabilitiesProto;->CAN_REPORT_SIGNAL_STRENGTH:J
-Landroid/net/NetworkCapabilitiesProto;->CAPABILITIES:J
-Landroid/net/NetworkCapabilitiesProto;->LINK_DOWN_BANDWIDTH_KBPS:J
-Landroid/net/NetworkCapabilitiesProto;->LINK_UP_BANDWIDTH_KBPS:J
-Landroid/net/NetworkCapabilitiesProto;->NETWORK_SPECIFIER:J
-Landroid/net/NetworkCapabilitiesProto;->NET_CAPABILITY_CAPTIVE_PORTAL:I
-Landroid/net/NetworkCapabilitiesProto;->NET_CAPABILITY_CBS:I
-Landroid/net/NetworkCapabilitiesProto;->NET_CAPABILITY_DUN:I
-Landroid/net/NetworkCapabilitiesProto;->NET_CAPABILITY_EIMS:I
-Landroid/net/NetworkCapabilitiesProto;->NET_CAPABILITY_FOREGROUND:I
-Landroid/net/NetworkCapabilitiesProto;->NET_CAPABILITY_FOTA:I
-Landroid/net/NetworkCapabilitiesProto;->NET_CAPABILITY_IA:I
-Landroid/net/NetworkCapabilitiesProto;->NET_CAPABILITY_IMS:I
-Landroid/net/NetworkCapabilitiesProto;->NET_CAPABILITY_INTERNET:I
-Landroid/net/NetworkCapabilitiesProto;->NET_CAPABILITY_MMS:I
-Landroid/net/NetworkCapabilitiesProto;->NET_CAPABILITY_NOT_METERED:I
-Landroid/net/NetworkCapabilitiesProto;->NET_CAPABILITY_NOT_RESTRICTED:I
-Landroid/net/NetworkCapabilitiesProto;->NET_CAPABILITY_NOT_ROAMING:I
-Landroid/net/NetworkCapabilitiesProto;->NET_CAPABILITY_NOT_VPN:I
-Landroid/net/NetworkCapabilitiesProto;->NET_CAPABILITY_RCS:I
-Landroid/net/NetworkCapabilitiesProto;->NET_CAPABILITY_SUPL:I
-Landroid/net/NetworkCapabilitiesProto;->NET_CAPABILITY_TRUSTED:I
-Landroid/net/NetworkCapabilitiesProto;->NET_CAPABILITY_VALIDATED:I
-Landroid/net/NetworkCapabilitiesProto;->NET_CAPABILITY_WIFI_P2P:I
-Landroid/net/NetworkCapabilitiesProto;->NET_CAPABILITY_XCAP:I
-Landroid/net/NetworkCapabilitiesProto;->SIGNAL_STRENGTH:J
-Landroid/net/NetworkCapabilitiesProto;->TRANSPORTS:J
-Landroid/net/NetworkCapabilitiesProto;->TRANSPORT_BLUETOOTH:I
-Landroid/net/NetworkCapabilitiesProto;->TRANSPORT_CELLULAR:I
-Landroid/net/NetworkCapabilitiesProto;->TRANSPORT_ETHERNET:I
-Landroid/net/NetworkCapabilitiesProto;->TRANSPORT_LOWPAN:I
-Landroid/net/NetworkCapabilitiesProto;->TRANSPORT_VPN:I
-Landroid/net/NetworkCapabilitiesProto;->TRANSPORT_WIFI:I
-Landroid/net/NetworkCapabilitiesProto;->TRANSPORT_WIFI_AWARE:I
-Landroid/net/NetworkConfig;-><init>(Ljava/lang/String;)V
-Landroid/net/NetworkConfig;->dependencyMet:Z
-Landroid/net/NetworkConfig;->isDefault()Z
-Landroid/net/NetworkConfig;->name:Ljava/lang/String;
-Landroid/net/NetworkConfig;->priority:I
-Landroid/net/NetworkConfig;->radio:I
-Landroid/net/NetworkConfig;->restoreTime:I
-Landroid/net/NetworkConfig;->type:I
-Landroid/net/NetworkFactory$NetworkRequestInfo;->request:Landroid/net/NetworkRequest;
-Landroid/net/NetworkFactory$NetworkRequestInfo;->requested:Z
-Landroid/net/NetworkFactory$NetworkRequestInfo;->score:I
-Landroid/net/NetworkFactory;->acceptRequest(Landroid/net/NetworkRequest;I)Z
-Landroid/net/NetworkFactory;->addNetworkRequest(Landroid/net/NetworkRequest;I)V
-Landroid/net/NetworkFactory;->BASE:I
-Landroid/net/NetworkFactory;->CMD_CANCEL_REQUEST:I
-Landroid/net/NetworkFactory;->CMD_REQUEST_NETWORK:I
-Landroid/net/NetworkFactory;->CMD_SET_FILTER:I
-Landroid/net/NetworkFactory;->CMD_SET_SCORE:I
-Landroid/net/NetworkFactory;->DBG:Z
-Landroid/net/NetworkFactory;->evalRequest(Landroid/net/NetworkFactory$NetworkRequestInfo;)V
-Landroid/net/NetworkFactory;->evalRequests()V
-Landroid/net/NetworkFactory;->getRequestCount()I
-Landroid/net/NetworkFactory;->handleAddRequest(Landroid/net/NetworkRequest;I)V
-Landroid/net/NetworkFactory;->handleRemoveRequest(Landroid/net/NetworkRequest;)V
-Landroid/net/NetworkFactory;->handleSetFilter(Landroid/net/NetworkCapabilities;)V
-Landroid/net/NetworkFactory;->handleSetScore(I)V
-Landroid/net/NetworkFactory;->log(Ljava/lang/String;)V
-Landroid/net/NetworkFactory;->LOG_TAG:Ljava/lang/String;
-Landroid/net/NetworkFactory;->mCapabilityFilter:Landroid/net/NetworkCapabilities;
-Landroid/net/NetworkFactory;->mContext:Landroid/content/Context;
-Landroid/net/NetworkFactory;->mMessenger:Landroid/os/Messenger;
-Landroid/net/NetworkFactory;->mNetworkRequests:Landroid/util/SparseArray;
-Landroid/net/NetworkFactory;->mRefCount:I
-Landroid/net/NetworkFactory;->mScore:I
-Landroid/net/NetworkFactory;->needNetworkFor(Landroid/net/NetworkRequest;I)V
-Landroid/net/NetworkFactory;->reevaluateAllRequests()V
-Landroid/net/NetworkFactory;->register()V
-Landroid/net/NetworkFactory;->releaseNetworkFor(Landroid/net/NetworkRequest;)V
-Landroid/net/NetworkFactory;->removeNetworkRequest(Landroid/net/NetworkRequest;)V
-Landroid/net/NetworkFactory;->setCapabilityFilter(Landroid/net/NetworkCapabilities;)V
-Landroid/net/NetworkFactory;->startNetwork()V
-Landroid/net/NetworkFactory;->stopNetwork()V
-Landroid/net/NetworkFactory;->unregister()V
-Landroid/net/NetworkFactory;->VDBG:Z
-Landroid/net/NetworkIdentity;-><init>(IILjava/lang/String;Ljava/lang/String;ZZZ)V
-Landroid/net/NetworkIdentity;->buildNetworkIdentity(Landroid/content/Context;Landroid/net/NetworkState;Z)Landroid/net/NetworkIdentity;
-Landroid/net/NetworkIdentity;->COMBINE_SUBTYPE_ENABLED:Z
-Landroid/net/NetworkIdentity;->compareTo(Landroid/net/NetworkIdentity;)I
-Landroid/net/NetworkIdentity;->getDefaultNetwork()Z
-Landroid/net/NetworkIdentity;->getMetered()Z
-Landroid/net/NetworkIdentity;->getNetworkId()Ljava/lang/String;
-Landroid/net/NetworkIdentity;->getRoaming()Z
-Landroid/net/NetworkIdentity;->getSubscriberId()Ljava/lang/String;
-Landroid/net/NetworkIdentity;->getSubType()I
-Landroid/net/NetworkIdentity;->getType()I
-Landroid/net/NetworkIdentity;->mDefaultNetwork:Z
-Landroid/net/NetworkIdentity;->mMetered:Z
-Landroid/net/NetworkIdentity;->mNetworkId:Ljava/lang/String;
-Landroid/net/NetworkIdentity;->mRoaming:Z
-Landroid/net/NetworkIdentity;->mSubscriberId:Ljava/lang/String;
-Landroid/net/NetworkIdentity;->mSubType:I
-Landroid/net/NetworkIdentity;->mType:I
-Landroid/net/NetworkIdentity;->scrubSubscriberId(Ljava/lang/String;)Ljava/lang/String;
-Landroid/net/NetworkIdentity;->scrubSubscriberId([Ljava/lang/String;)[Ljava/lang/String;
-Landroid/net/NetworkIdentity;->SUBTYPE_COMBINED:I
-Landroid/net/NetworkIdentity;->TAG:Ljava/lang/String;
-Landroid/net/NetworkIdentity;->writeToProto(Landroid/util/proto/ProtoOutputStream;J)V
-Landroid/net/NetworkInfo;->mDetailedState:Landroid/net/NetworkInfo$DetailedState;
-Landroid/net/NetworkInfo;->mExtraInfo:Ljava/lang/String;
-Landroid/net/NetworkInfo;->mIsAvailable:Z
-Landroid/net/NetworkInfo;->mIsFailover:Z
-Landroid/net/NetworkInfo;->mIsRoaming:Z
-Landroid/net/NetworkInfo;->mNetworkType:I
-Landroid/net/NetworkInfo;->mReason:Ljava/lang/String;
-Landroid/net/NetworkInfo;->mState:Landroid/net/NetworkInfo$State;
-Landroid/net/NetworkInfo;->mSubtype:I
-Landroid/net/NetworkInfo;->mSubtypeName:Ljava/lang/String;
-Landroid/net/NetworkInfo;->mTypeName:Ljava/lang/String;
-Landroid/net/NetworkInfo;->setExtraInfo(Ljava/lang/String;)V
-Landroid/net/NetworkInfo;->setType(I)V
-Landroid/net/NetworkInfo;->stateMap:Ljava/util/EnumMap;
-Landroid/net/NetworkKey;-><init>(Landroid/os/Parcel;)V
-Landroid/net/NetworkKey;->createFromScanResult(Landroid/net/wifi/ScanResult;)Landroid/net/NetworkKey;
-Landroid/net/NetworkKey;->createFromWifiInfo(Landroid/net/wifi/WifiInfo;)Landroid/net/NetworkKey;
-Landroid/net/NetworkKey;->TAG:Ljava/lang/String;
-Landroid/net/NetworkMisc;-><init>()V
-Landroid/net/NetworkMisc;-><init>(Landroid/net/NetworkMisc;)V
-Landroid/net/NetworkMisc;->acceptUnvalidated:Z
-Landroid/net/NetworkMisc;->allowBypass:Z
-Landroid/net/NetworkMisc;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/net/NetworkMisc;->explicitlySelected:Z
-Landroid/net/NetworkMisc;->provisioningNotificationDisabled:Z
-Landroid/net/NetworkMisc;->subscriberId:Ljava/lang/String;
-Landroid/net/NetworkPolicy;-><init>(Landroid/net/NetworkTemplate;ILjava/lang/String;JJZ)V
-Landroid/net/NetworkPolicy;-><init>(Landroid/net/NetworkTemplate;Landroid/util/RecurrenceRule;JJJJJZZ)V
-Landroid/net/NetworkPolicy;-><init>(Landroid/net/NetworkTemplate;Landroid/util/RecurrenceRule;JJJJZZ)V
-Landroid/net/NetworkPolicy;-><init>(Landroid/os/Parcel;)V
-Landroid/net/NetworkPolicy;->buildRule(ILjava/time/ZoneId;)Landroid/util/RecurrenceRule;
-Landroid/net/NetworkPolicy;->cycleIterator()Ljava/util/Iterator;
-Landroid/net/NetworkPolicy;->cycleRule:Landroid/util/RecurrenceRule;
-Landroid/net/NetworkPolicy;->CYCLE_NONE:I
-Landroid/net/NetworkPolicy;->DEFAULT_MTU:J
-Landroid/net/NetworkPolicy;->getBytesForBackup()[B
-Landroid/net/NetworkPolicy;->getNetworkPolicyFromBackup(Ljava/io/DataInputStream;)Landroid/net/NetworkPolicy;
-Landroid/net/NetworkPolicy;->hasCycle()Z
-Landroid/net/NetworkPolicy;->lastLimitSnooze:J
-Landroid/net/NetworkPolicy;->lastRapidSnooze:J
-Landroid/net/NetworkPolicy;->lastWarningSnooze:J
-Landroid/net/NetworkPolicy;->LIMIT_DISABLED:J
-Landroid/net/NetworkPolicy;->SNOOZE_NEVER:J
-Landroid/net/NetworkPolicy;->VERSION_INIT:I
-Landroid/net/NetworkPolicy;->VERSION_RAPID:I
-Landroid/net/NetworkPolicy;->VERSION_RULE:I
-Landroid/net/NetworkPolicy;->WARNING_DISABLED:J
-Landroid/net/NetworkPolicyManager$Listener;-><init>()V
-Landroid/net/NetworkPolicyManager$Listener;->onMeteredIfacesChanged([Ljava/lang/String;)V
-Landroid/net/NetworkPolicyManager$Listener;->onRestrictBackgroundChanged(Z)V
-Landroid/net/NetworkPolicyManager$Listener;->onSubscriptionOverride(III)V
-Landroid/net/NetworkPolicyManager$Listener;->onUidPoliciesChanged(II)V
-Landroid/net/NetworkPolicyManager$Listener;->onUidRulesChanged(II)V
-Landroid/net/NetworkPolicyManager;-><init>(Landroid/content/Context;Landroid/net/INetworkPolicyManager;)V
-Landroid/net/NetworkPolicyManager;->addUidPolicy(II)V
-Landroid/net/NetworkPolicyManager;->ALLOW_PLATFORM_APP_POLICY:Z
-Landroid/net/NetworkPolicyManager;->cycleIterator(Landroid/net/NetworkPolicy;)Ljava/util/Iterator;
-Landroid/net/NetworkPolicyManager;->EXTRA_NETWORK_TEMPLATE:Ljava/lang/String;
-Landroid/net/NetworkPolicyManager;->factoryReset(Ljava/lang/String;)V
-Landroid/net/NetworkPolicyManager;->FIREWALL_CHAIN_DOZABLE:I
-Landroid/net/NetworkPolicyManager;->FIREWALL_CHAIN_NAME_DOZABLE:Ljava/lang/String;
-Landroid/net/NetworkPolicyManager;->FIREWALL_CHAIN_NAME_NONE:Ljava/lang/String;
-Landroid/net/NetworkPolicyManager;->FIREWALL_CHAIN_NAME_POWERSAVE:Ljava/lang/String;
-Landroid/net/NetworkPolicyManager;->FIREWALL_CHAIN_NAME_STANDBY:Ljava/lang/String;
-Landroid/net/NetworkPolicyManager;->FIREWALL_CHAIN_NONE:I
-Landroid/net/NetworkPolicyManager;->FIREWALL_CHAIN_POWERSAVE:I
-Landroid/net/NetworkPolicyManager;->FIREWALL_CHAIN_STANDBY:I
-Landroid/net/NetworkPolicyManager;->FIREWALL_RULE_ALLOW:I
-Landroid/net/NetworkPolicyManager;->FIREWALL_RULE_DEFAULT:I
-Landroid/net/NetworkPolicyManager;->FIREWALL_RULE_DENY:I
-Landroid/net/NetworkPolicyManager;->FIREWALL_TYPE_BLACKLIST:I
-Landroid/net/NetworkPolicyManager;->FIREWALL_TYPE_WHITELIST:I
-Landroid/net/NetworkPolicyManager;->FOREGROUND_THRESHOLD_STATE:I
-Landroid/net/NetworkPolicyManager;->isProcStateAllowedWhileIdleOrPowerSaveMode(I)Z
-Landroid/net/NetworkPolicyManager;->isProcStateAllowedWhileOnRestrictBackground(I)Z
-Landroid/net/NetworkPolicyManager;->isUidValidForPolicy(Landroid/content/Context;I)Z
-Landroid/net/NetworkPolicyManager;->MASK_ALL_NETWORKS:I
-Landroid/net/NetworkPolicyManager;->MASK_METERED_NETWORKS:I
-Landroid/net/NetworkPolicyManager;->mContext:Landroid/content/Context;
-Landroid/net/NetworkPolicyManager;->OVERRIDE_CONGESTED:I
-Landroid/net/NetworkPolicyManager;->OVERRIDE_UNMETERED:I
-Landroid/net/NetworkPolicyManager;->POLICY_ALLOW_METERED_BACKGROUND:I
-Landroid/net/NetworkPolicyManager;->POLICY_NONE:I
-Landroid/net/NetworkPolicyManager;->POLICY_REJECT_METERED_BACKGROUND:I
-Landroid/net/NetworkPolicyManager;->removeUidPolicy(II)V
-Landroid/net/NetworkPolicyManager;->resolveNetworkId(Landroid/net/wifi/WifiConfiguration;)Ljava/lang/String;
-Landroid/net/NetworkPolicyManager;->resolveNetworkId(Ljava/lang/String;)Ljava/lang/String;
-Landroid/net/NetworkPolicyManager;->RULE_ALLOW_ALL:I
-Landroid/net/NetworkPolicyManager;->RULE_ALLOW_METERED:I
-Landroid/net/NetworkPolicyManager;->RULE_NONE:I
-Landroid/net/NetworkPolicyManager;->RULE_REJECT_ALL:I
-Landroid/net/NetworkPolicyManager;->RULE_REJECT_METERED:I
-Landroid/net/NetworkPolicyManager;->RULE_TEMPORARY_ALLOW_METERED:I
-Landroid/net/NetworkPolicyManager;->setNetworkPolicies([Landroid/net/NetworkPolicy;)V
-Landroid/net/NetworkPolicyManager;->uidPoliciesToString(I)Ljava/lang/String;
-Landroid/net/NetworkPolicyManager;->uidRulesToString(I)Ljava/lang/String;
-Landroid/net/NetworkProto;-><init>()V
-Landroid/net/NetworkProto;->NET_ID:J
-Landroid/net/NetworkQuotaInfo;-><init>()V
-Landroid/net/NetworkQuotaInfo;-><init>(Landroid/os/Parcel;)V
-Landroid/net/NetworkQuotaInfo;->NO_LIMIT:J
-Landroid/net/NetworkRecommendationProvider$ServiceWrapper;->enforceCallingPermission()V
-Landroid/net/NetworkRecommendationProvider$ServiceWrapper;->execute(Ljava/lang/Runnable;)V
-Landroid/net/NetworkRecommendationProvider$ServiceWrapper;->mContext:Landroid/content/Context;
-Landroid/net/NetworkRecommendationProvider$ServiceWrapper;->mExecutor:Ljava/util/concurrent/Executor;
-Landroid/net/NetworkRecommendationProvider$ServiceWrapper;->mHandler:Landroid/os/Handler;
-Landroid/net/NetworkRecommendationProvider$ServiceWrapper;->requestScores([Landroid/net/NetworkKey;)V
-Landroid/net/NetworkRecommendationProvider;->mService:Landroid/os/IBinder;
-Landroid/net/NetworkRecommendationProvider;->TAG:Ljava/lang/String;
-Landroid/net/NetworkRecommendationProvider;->VERBOSE:Z
-Landroid/net/NetworkRequest$Builder;->addUnwantedCapability(I)Landroid/net/NetworkRequest$Builder;
-Landroid/net/NetworkRequest$Builder;->mNetworkCapabilities:Landroid/net/NetworkCapabilities;
-Landroid/net/NetworkRequest$Builder;->setCapabilities(Landroid/net/NetworkCapabilities;)Landroid/net/NetworkRequest$Builder;
-Landroid/net/NetworkRequest$Builder;->setLinkDownstreamBandwidthKbps(I)Landroid/net/NetworkRequest$Builder;
-Landroid/net/NetworkRequest$Builder;->setLinkUpstreamBandwidthKbps(I)Landroid/net/NetworkRequest$Builder;
-Landroid/net/NetworkRequest$Builder;->setUids(Ljava/util/Set;)Landroid/net/NetworkRequest$Builder;
-Landroid/net/NetworkRequest$Type;->BACKGROUND_REQUEST:Landroid/net/NetworkRequest$Type;
-Landroid/net/NetworkRequest$Type;->LISTEN:Landroid/net/NetworkRequest$Type;
-Landroid/net/NetworkRequest$Type;->NONE:Landroid/net/NetworkRequest$Type;
-Landroid/net/NetworkRequest$Type;->REQUEST:Landroid/net/NetworkRequest$Type;
-Landroid/net/NetworkRequest$Type;->TRACK_DEFAULT:Landroid/net/NetworkRequest$Type;
-Landroid/net/NetworkRequest$Type;->valueOf(Ljava/lang/String;)Landroid/net/NetworkRequest$Type;
-Landroid/net/NetworkRequest$Type;->values()[Landroid/net/NetworkRequest$Type;
-Landroid/net/NetworkRequest;-><init>(Landroid/net/NetworkCapabilities;IILandroid/net/NetworkRequest$Type;)V
-Landroid/net/NetworkRequest;-><init>(Landroid/net/NetworkRequest;)V
-Landroid/net/NetworkRequest;->hasUnwantedCapability(I)Z
-Landroid/net/NetworkRequest;->isBackgroundRequest()Z
-Landroid/net/NetworkRequest;->isForegroundRequest()Z
-Landroid/net/NetworkRequest;->isListen()Z
-Landroid/net/NetworkRequest;->isRequest()Z
-Landroid/net/NetworkRequest;->type:Landroid/net/NetworkRequest$Type;
-Landroid/net/NetworkRequest;->typeToProtoEnum(Landroid/net/NetworkRequest$Type;)I
-Landroid/net/NetworkRequest;->writeToProto(Landroid/util/proto/ProtoOutputStream;J)V
-Landroid/net/NetworkRequestProto;-><init>()V
-Landroid/net/NetworkRequestProto;->LEGACY_TYPE:J
-Landroid/net/NetworkRequestProto;->NETWORK_CAPABILITIES:J
-Landroid/net/NetworkRequestProto;->REQUEST_ID:J
-Landroid/net/NetworkRequestProto;->TYPE:J
-Landroid/net/NetworkRequestProto;->TYPE_BACKGROUND_REQUEST:I
-Landroid/net/NetworkRequestProto;->TYPE_LISTEN:I
-Landroid/net/NetworkRequestProto;->TYPE_NONE:I
-Landroid/net/NetworkRequestProto;->TYPE_REQUEST:I
-Landroid/net/NetworkRequestProto;->TYPE_TRACK_DEFAULT:I
-Landroid/net/NetworkRequestProto;->TYPE_UNKNOWN:I
-Landroid/net/NetworkScoreManager;-><init>(Landroid/content/Context;)V
-Landroid/net/NetworkScoreManager;->CACHE_FILTER_CURRENT_NETWORK:I
-Landroid/net/NetworkScoreManager;->CACHE_FILTER_NONE:I
-Landroid/net/NetworkScoreManager;->CACHE_FILTER_SCAN_RESULTS:I
-Landroid/net/NetworkScoreManager;->getActiveScorer()Landroid/net/NetworkScorerAppData;
-Landroid/net/NetworkScoreManager;->getAllValidScorers()Ljava/util/List;
-Landroid/net/NetworkScoreManager;->isCallerActiveScorer(I)Z
-Landroid/net/NetworkScoreManager;->mContext:Landroid/content/Context;
-Landroid/net/NetworkScoreManager;->mService:Landroid/net/INetworkScoreService;
-Landroid/net/NetworkScoreManager;->NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID_META_DATA:Ljava/lang/String;
-Landroid/net/NetworkScoreManager;->RECOMMENDATIONS_ENABLED_FORCED_OFF:I
-Landroid/net/NetworkScoreManager;->RECOMMENDATIONS_ENABLED_OFF:I
-Landroid/net/NetworkScoreManager;->RECOMMENDATIONS_ENABLED_ON:I
-Landroid/net/NetworkScoreManager;->RECOMMENDATION_SERVICE_LABEL_META_DATA:Ljava/lang/String;
-Landroid/net/NetworkScoreManager;->registerNetworkScoreCache(ILandroid/net/INetworkScoreCache;)V
-Landroid/net/NetworkScoreManager;->registerNetworkScoreCache(ILandroid/net/INetworkScoreCache;I)V
-Landroid/net/NetworkScoreManager;->requestScores([Landroid/net/NetworkKey;)Z
-Landroid/net/NetworkScoreManager;->unregisterNetworkScoreCache(ILandroid/net/INetworkScoreCache;)V
-Landroid/net/NetworkScoreManager;->USE_OPEN_WIFI_PACKAGE_META_DATA:Ljava/lang/String;
-Landroid/net/NetworkScorerAppData;-><init>(ILandroid/content/ComponentName;Ljava/lang/String;Landroid/content/ComponentName;Ljava/lang/String;)V
-Landroid/net/NetworkScorerAppData;-><init>(Landroid/os/Parcel;)V
-Landroid/net/NetworkScorerAppData;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/net/NetworkScorerAppData;->getEnableUseOpenWifiActivity()Landroid/content/ComponentName;
-Landroid/net/NetworkScorerAppData;->getNetworkAvailableNotificationChannelId()Ljava/lang/String;
-Landroid/net/NetworkScorerAppData;->getRecommendationServiceComponent()Landroid/content/ComponentName;
-Landroid/net/NetworkScorerAppData;->getRecommendationServiceLabel()Ljava/lang/String;
-Landroid/net/NetworkScorerAppData;->getRecommendationServicePackageName()Ljava/lang/String;
-Landroid/net/NetworkScorerAppData;->mEnableUseOpenWifiActivity:Landroid/content/ComponentName;
-Landroid/net/NetworkScorerAppData;->mNetworkAvailableNotificationChannelId:Ljava/lang/String;
-Landroid/net/NetworkScorerAppData;->mRecommendationService:Landroid/content/ComponentName;
-Landroid/net/NetworkScorerAppData;->mRecommendationServiceLabel:Ljava/lang/String;
-Landroid/net/NetworkScorerAppData;->packageUid:I
-Landroid/net/NetworkSpecifier;-><init>()V
-Landroid/net/NetworkSpecifier;->assertValidFromUid(I)V
-Landroid/net/NetworkSpecifier;->satisfiedBy(Landroid/net/NetworkSpecifier;)Z
-Landroid/net/NetworkState;-><init>(Landroid/net/NetworkInfo;Landroid/net/LinkProperties;Landroid/net/NetworkCapabilities;Landroid/net/Network;Ljava/lang/String;Ljava/lang/String;)V
-Landroid/net/NetworkState;->EMPTY:Landroid/net/NetworkState;
-Landroid/net/NetworkState;->linkProperties:Landroid/net/LinkProperties;
-Landroid/net/NetworkState;->networkCapabilities:Landroid/net/NetworkCapabilities;
-Landroid/net/NetworkState;->networkId:Ljava/lang/String;
-Landroid/net/NetworkState;->networkInfo:Landroid/net/NetworkInfo;
-Landroid/net/NetworkState;->SANITY_CHECK_ROAMING:Z
-Landroid/net/NetworkState;->subscriberId:Ljava/lang/String;
-Landroid/net/NetworkStats$Entry;-><init>(JJJJJ)V
-Landroid/net/NetworkStats$Entry;-><init>(Ljava/lang/String;IIIIIIJJJJJ)V
-Landroid/net/NetworkStats$Entry;-><init>(Ljava/lang/String;IIIJJJJJ)V
-Landroid/net/NetworkStats$Entry;->add(Landroid/net/NetworkStats$Entry;)V
-Landroid/net/NetworkStats$Entry;->defaultNetwork:I
-Landroid/net/NetworkStats$Entry;->isEmpty()Z
-Landroid/net/NetworkStats$Entry;->isNegative()Z
-Landroid/net/NetworkStats$Entry;->metered:I
-Landroid/net/NetworkStats$Entry;->operations:J
-Landroid/net/NetworkStats$Entry;->roaming:I
-Landroid/net/NetworkStats$NonMonotonicObserver;->foundNonMonotonic(Landroid/net/NetworkStats;ILandroid/net/NetworkStats;ILjava/lang/Object;)V
-Landroid/net/NetworkStats$NonMonotonicObserver;->foundNonMonotonic(Landroid/net/NetworkStats;ILjava/lang/Object;)V
-Landroid/net/NetworkStats;->addIfaceValues(Ljava/lang/String;JJJJ)Landroid/net/NetworkStats;
-Landroid/net/NetworkStats;->addTrafficToApplications(ILjava/lang/String;Ljava/lang/String;Landroid/net/NetworkStats$Entry;Landroid/net/NetworkStats$Entry;)Landroid/net/NetworkStats$Entry;
-Landroid/net/NetworkStats;->addValues(Landroid/net/NetworkStats$Entry;)Landroid/net/NetworkStats;
-Landroid/net/NetworkStats;->addValues(Ljava/lang/String;IIIIIIJJJJJ)Landroid/net/NetworkStats;
-Landroid/net/NetworkStats;->addValues(Ljava/lang/String;IIIJJJJJ)Landroid/net/NetworkStats;
-Landroid/net/NetworkStats;->apply464xlatAdjustments(Landroid/net/NetworkStats;Landroid/net/NetworkStats;Ljava/util/Map;)V
-Landroid/net/NetworkStats;->apply464xlatAdjustments(Ljava/util/Map;)V
-Landroid/net/NetworkStats;->CLATD_INTERFACE_PREFIX:Ljava/lang/String;
-Landroid/net/NetworkStats;->clear()V
-Landroid/net/NetworkStats;->combineValues(Ljava/lang/String;IIIJJJJJ)Landroid/net/NetworkStats;
-Landroid/net/NetworkStats;->combineValues(Ljava/lang/String;IIJJJJJ)Landroid/net/NetworkStats;
-Landroid/net/NetworkStats;->deductTrafficFromVpnApp(ILjava/lang/String;Landroid/net/NetworkStats$Entry;)V
-Landroid/net/NetworkStats;->defaultNetworkToString(I)Ljava/lang/String;
-Landroid/net/NetworkStats;->DEFAULT_NETWORK_ALL:I
-Landroid/net/NetworkStats;->DEFAULT_NETWORK_NO:I
-Landroid/net/NetworkStats;->DEFAULT_NETWORK_YES:I
-Landroid/net/NetworkStats;->dump(Ljava/lang/String;Ljava/io/PrintWriter;)V
-Landroid/net/NetworkStats;->elapsedRealtime:J
-Landroid/net/NetworkStats;->filter(I[Ljava/lang/String;I)V
-Landroid/net/NetworkStats;->findIndex(Ljava/lang/String;IIIIII)I
-Landroid/net/NetworkStats;->findIndexHinted(Ljava/lang/String;IIIIIII)I
-Landroid/net/NetworkStats;->getElapsedRealtime()J
-Landroid/net/NetworkStats;->getElapsedRealtimeAge()J
-Landroid/net/NetworkStats;->getTotal(Landroid/net/NetworkStats$Entry;Ljava/util/HashSet;)Landroid/net/NetworkStats$Entry;
-Landroid/net/NetworkStats;->getTotal(Landroid/net/NetworkStats$Entry;Ljava/util/HashSet;IZ)Landroid/net/NetworkStats$Entry;
-Landroid/net/NetworkStats;->getTotalPackets()J
-Landroid/net/NetworkStats;->getUniqueIfaces()[Ljava/lang/String;
-Landroid/net/NetworkStats;->groupedByIface()Landroid/net/NetworkStats;
-Landroid/net/NetworkStats;->groupedByUid()Landroid/net/NetworkStats;
-Landroid/net/NetworkStats;->IFACE_ALL:Ljava/lang/String;
-Landroid/net/NetworkStats;->INTERFACES_ALL:[Ljava/lang/String;
-Landroid/net/NetworkStats;->internalSize()I
-Landroid/net/NetworkStats;->IPV4V6_HEADER_DELTA:I
-Landroid/net/NetworkStats;->meteredToString(I)Ljava/lang/String;
-Landroid/net/NetworkStats;->METERED_ALL:I
-Landroid/net/NetworkStats;->METERED_NO:I
-Landroid/net/NetworkStats;->METERED_YES:I
-Landroid/net/NetworkStats;->migrateTun(ILjava/lang/String;Ljava/lang/String;)Z
-Landroid/net/NetworkStats;->roamingToString(I)Ljava/lang/String;
-Landroid/net/NetworkStats;->ROAMING_ALL:I
-Landroid/net/NetworkStats;->ROAMING_NO:I
-Landroid/net/NetworkStats;->ROAMING_YES:I
-Landroid/net/NetworkStats;->setElapsedRealtime(J)V
-Landroid/net/NetworkStats;->setMatches(II)Z
-Landroid/net/NetworkStats;->setToCheckinString(I)Ljava/lang/String;
-Landroid/net/NetworkStats;->setToString(I)Ljava/lang/String;
-Landroid/net/NetworkStats;->setValues(ILandroid/net/NetworkStats$Entry;)V
-Landroid/net/NetworkStats;->SET_ALL:I
-Landroid/net/NetworkStats;->SET_DBG_VPN_IN:I
-Landroid/net/NetworkStats;->SET_DBG_VPN_OUT:I
-Landroid/net/NetworkStats;->SET_DEBUG_START:I
-Landroid/net/NetworkStats;->SET_DEFAULT:I
-Landroid/net/NetworkStats;->SET_FOREGROUND:I
-Landroid/net/NetworkStats;->spliceOperationsFrom(Landroid/net/NetworkStats;)V
-Landroid/net/NetworkStats;->STATS_PER_IFACE:I
-Landroid/net/NetworkStats;->STATS_PER_UID:I
-Landroid/net/NetworkStats;->subtract(Landroid/net/NetworkStats;)Landroid/net/NetworkStats;
-Landroid/net/NetworkStats;->subtract(Landroid/net/NetworkStats;Landroid/net/NetworkStats;Landroid/net/NetworkStats$NonMonotonicObserver;Ljava/lang/Object;)Landroid/net/NetworkStats;
-Landroid/net/NetworkStats;->subtract(Landroid/net/NetworkStats;Landroid/net/NetworkStats;Landroid/net/NetworkStats$NonMonotonicObserver;Ljava/lang/Object;Landroid/net/NetworkStats;)Landroid/net/NetworkStats;
-Landroid/net/NetworkStats;->TAG:Ljava/lang/String;
-Landroid/net/NetworkStats;->tagToString(I)Ljava/lang/String;
-Landroid/net/NetworkStats;->TAG_ALL:I
-Landroid/net/NetworkStats;->TAG_NONE:I
-Landroid/net/NetworkStats;->tunAdjustmentInit(ILjava/lang/String;Ljava/lang/String;Landroid/net/NetworkStats$Entry;Landroid/net/NetworkStats$Entry;)V
-Landroid/net/NetworkStats;->tunGetPool(Landroid/net/NetworkStats$Entry;Landroid/net/NetworkStats$Entry;)Landroid/net/NetworkStats$Entry;
-Landroid/net/NetworkStats;->tunSubtract(ILandroid/net/NetworkStats;Landroid/net/NetworkStats$Entry;)V
-Landroid/net/NetworkStats;->UID_ALL:I
-Landroid/net/NetworkStats;->withoutUids([I)Landroid/net/NetworkStats;
-Landroid/net/NetworkStatsHistory$DataStreamUtils;-><init>()V
-Landroid/net/NetworkStatsHistory$DataStreamUtils;->readFullLongArray(Ljava/io/DataInputStream;)[J
-Landroid/net/NetworkStatsHistory$DataStreamUtils;->readVarLong(Ljava/io/DataInputStream;)J
-Landroid/net/NetworkStatsHistory$DataStreamUtils;->readVarLongArray(Ljava/io/DataInputStream;)[J
-Landroid/net/NetworkStatsHistory$DataStreamUtils;->writeVarLong(Ljava/io/DataOutputStream;J)V
-Landroid/net/NetworkStatsHistory$DataStreamUtils;->writeVarLongArray(Ljava/io/DataOutputStream;[JI)V
-Landroid/net/NetworkStatsHistory$Entry;-><init>()V
-Landroid/net/NetworkStatsHistory$Entry;->activeTime:J
-Landroid/net/NetworkStatsHistory$Entry;->operations:J
-Landroid/net/NetworkStatsHistory$Entry;->UNKNOWN:J
-Landroid/net/NetworkStatsHistory$ParcelUtils;-><init>()V
-Landroid/net/NetworkStatsHistory$ParcelUtils;->readLongArray(Landroid/os/Parcel;)[J
-Landroid/net/NetworkStatsHistory$ParcelUtils;->writeLongArray(Landroid/os/Parcel;[JI)V
-Landroid/net/NetworkStatsHistory;-><init>(JI)V
-Landroid/net/NetworkStatsHistory;-><init>(JII)V
-Landroid/net/NetworkStatsHistory;-><init>(Landroid/net/NetworkStatsHistory;J)V
-Landroid/net/NetworkStatsHistory;-><init>(Ljava/io/DataInputStream;)V
-Landroid/net/NetworkStatsHistory;->activeTime:[J
-Landroid/net/NetworkStatsHistory;->addLong([JIJ)V
-Landroid/net/NetworkStatsHistory;->bucketCount:I
-Landroid/net/NetworkStatsHistory;->bucketDuration:J
-Landroid/net/NetworkStatsHistory;->bucketStart:[J
-Landroid/net/NetworkStatsHistory;->clear()V
-Landroid/net/NetworkStatsHistory;->dump(Lcom/android/internal/util/IndentingPrintWriter;Z)V
-Landroid/net/NetworkStatsHistory;->dumpCheckin(Ljava/io/PrintWriter;)V
-Landroid/net/NetworkStatsHistory;->ensureBuckets(JJ)V
-Landroid/net/NetworkStatsHistory;->estimateResizeBuckets(J)I
-Landroid/net/NetworkStatsHistory;->FIELD_ACTIVE_TIME:I
-Landroid/net/NetworkStatsHistory;->FIELD_ALL:I
-Landroid/net/NetworkStatsHistory;->FIELD_OPERATIONS:I
-Landroid/net/NetworkStatsHistory;->FIELD_RX_BYTES:I
-Landroid/net/NetworkStatsHistory;->FIELD_RX_PACKETS:I
-Landroid/net/NetworkStatsHistory;->FIELD_TX_BYTES:I
-Landroid/net/NetworkStatsHistory;->FIELD_TX_PACKETS:I
-Landroid/net/NetworkStatsHistory;->generateRandom(JJJ)V
-Landroid/net/NetworkStatsHistory;->generateRandom(JJJJJJJLjava/util/Random;)V
-Landroid/net/NetworkStatsHistory;->getBucketDuration()J
-Landroid/net/NetworkStatsHistory;->getIndexAfter(J)I
-Landroid/net/NetworkStatsHistory;->getLong([JIJ)J
-Landroid/net/NetworkStatsHistory;->getTotalBytes()J
-Landroid/net/NetworkStatsHistory;->insertBucket(IJ)V
-Landroid/net/NetworkStatsHistory;->intersects(JJ)Z
-Landroid/net/NetworkStatsHistory;->operations:[J
-Landroid/net/NetworkStatsHistory;->randomLong(Ljava/util/Random;JJ)J
-Landroid/net/NetworkStatsHistory;->recordData(JJJJ)V
-Landroid/net/NetworkStatsHistory;->recordData(JJLandroid/net/NetworkStats$Entry;)V
-Landroid/net/NetworkStatsHistory;->recordHistory(Landroid/net/NetworkStatsHistory;JJ)V
-Landroid/net/NetworkStatsHistory;->removeBucketsBefore(J)V
-Landroid/net/NetworkStatsHistory;->rxBytes:[J
-Landroid/net/NetworkStatsHistory;->rxPackets:[J
-Landroid/net/NetworkStatsHistory;->setLong([JIJ)V
-Landroid/net/NetworkStatsHistory;->setValues(ILandroid/net/NetworkStatsHistory$Entry;)V
-Landroid/net/NetworkStatsHistory;->totalBytes:J
-Landroid/net/NetworkStatsHistory;->txBytes:[J
-Landroid/net/NetworkStatsHistory;->txPackets:[J
-Landroid/net/NetworkStatsHistory;->VERSION_ADD_ACTIVE:I
-Landroid/net/NetworkStatsHistory;->VERSION_ADD_PACKETS:I
-Landroid/net/NetworkStatsHistory;->VERSION_INIT:I
-Landroid/net/NetworkStatsHistory;->writeToProto(Landroid/util/proto/ProtoOutputStream;J)V
-Landroid/net/NetworkStatsHistory;->writeToProto(Landroid/util/proto/ProtoOutputStream;J[JI)V
-Landroid/net/NetworkStatsHistory;->writeToStream(Ljava/io/DataOutputStream;)V
-Landroid/net/NetworkTemplate;-><init>(ILjava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V
-Landroid/net/NetworkTemplate;-><init>(ILjava/lang/String;[Ljava/lang/String;Ljava/lang/String;III)V
-Landroid/net/NetworkTemplate;-><init>(Landroid/os/Parcel;)V
-Landroid/net/NetworkTemplate;->BACKUP_VERSION:I
-Landroid/net/NetworkTemplate;->buildTemplateBluetooth()Landroid/net/NetworkTemplate;
-Landroid/net/NetworkTemplate;->buildTemplateProxy()Landroid/net/NetworkTemplate;
-Landroid/net/NetworkTemplate;->buildTemplateWifi(Ljava/lang/String;)Landroid/net/NetworkTemplate;
-Landroid/net/NetworkTemplate;->forceAllNetworkTypes()V
-Landroid/net/NetworkTemplate;->getBytesForBackup()[B
-Landroid/net/NetworkTemplate;->getMatchRuleName(I)Ljava/lang/String;
-Landroid/net/NetworkTemplate;->getNetworkId()Ljava/lang/String;
-Landroid/net/NetworkTemplate;->getNetworkTemplateFromBackup(Ljava/io/DataInputStream;)Landroid/net/NetworkTemplate;
-Landroid/net/NetworkTemplate;->isKnownMatchRule(I)Z
-Landroid/net/NetworkTemplate;->isMatchRuleMobile()Z
-Landroid/net/NetworkTemplate;->isPersistable()Z
-Landroid/net/NetworkTemplate;->matches(Landroid/net/NetworkIdentity;)Z
-Landroid/net/NetworkTemplate;->matchesBluetooth(Landroid/net/NetworkIdentity;)Z
-Landroid/net/NetworkTemplate;->matchesDefaultNetwork(Landroid/net/NetworkIdentity;)Z
-Landroid/net/NetworkTemplate;->matchesEthernet(Landroid/net/NetworkIdentity;)Z
-Landroid/net/NetworkTemplate;->matchesMetered(Landroid/net/NetworkIdentity;)Z
-Landroid/net/NetworkTemplate;->matchesMobile(Landroid/net/NetworkIdentity;)Z
-Landroid/net/NetworkTemplate;->matchesMobileWildcard(Landroid/net/NetworkIdentity;)Z
-Landroid/net/NetworkTemplate;->matchesProxy(Landroid/net/NetworkIdentity;)Z
-Landroid/net/NetworkTemplate;->matchesRoaming(Landroid/net/NetworkIdentity;)Z
-Landroid/net/NetworkTemplate;->matchesSubscriberId(Ljava/lang/String;)Z
-Landroid/net/NetworkTemplate;->matchesWifi(Landroid/net/NetworkIdentity;)Z
-Landroid/net/NetworkTemplate;->matchesWifiWildcard(Landroid/net/NetworkIdentity;)Z
-Landroid/net/NetworkTemplate;->MATCH_BLUETOOTH:I
-Landroid/net/NetworkTemplate;->MATCH_ETHERNET:I
-Landroid/net/NetworkTemplate;->MATCH_MOBILE:I
-Landroid/net/NetworkTemplate;->MATCH_MOBILE_WILDCARD:I
-Landroid/net/NetworkTemplate;->MATCH_PROXY:I
-Landroid/net/NetworkTemplate;->MATCH_WIFI:I
-Landroid/net/NetworkTemplate;->MATCH_WIFI_WILDCARD:I
-Landroid/net/NetworkTemplate;->mDefaultNetwork:I
-Landroid/net/NetworkTemplate;->mMatchRule:I
-Landroid/net/NetworkTemplate;->mMatchSubscriberIds:[Ljava/lang/String;
-Landroid/net/NetworkTemplate;->mMetered:I
-Landroid/net/NetworkTemplate;->mNetworkId:Ljava/lang/String;
-Landroid/net/NetworkTemplate;->mRoaming:I
-Landroid/net/NetworkTemplate;->mSubscriberId:Ljava/lang/String;
-Landroid/net/NetworkTemplate;->sForceAllNetworkTypes:Z
-Landroid/net/NetworkTemplate;->TAG:Ljava/lang/String;
-Landroid/net/NetworkUtils;-><init>()V
-Landroid/net/NetworkUtils;->addressTypeMatches(Ljava/net/InetAddress;Ljava/net/InetAddress;)Z
-Landroid/net/NetworkUtils;->bindProcessToNetwork(I)Z
-Landroid/net/NetworkUtils;->bindProcessToNetworkForHostResolution(I)Z
-Landroid/net/NetworkUtils;->bindSocketToNetwork(II)I
-Landroid/net/NetworkUtils;->deduplicatePrefixSet(Ljava/util/TreeSet;)Ljava/util/TreeSet;
-Landroid/net/NetworkUtils;->getBoundNetworkForProcess()I
-Landroid/net/NetworkUtils;->getNetworkPart(Ljava/net/InetAddress;I)Ljava/net/InetAddress;
-Landroid/net/NetworkUtils;->hexToInet6Address(Ljava/lang/String;)Ljava/net/InetAddress;
-Landroid/net/NetworkUtils;->inetAddressToInt(Ljava/net/Inet4Address;)I
-Landroid/net/NetworkUtils;->makeStrings(Ljava/util/Collection;)[Ljava/lang/String;
-Landroid/net/NetworkUtils;->maskRawAddress([BI)V
-Landroid/net/NetworkUtils;->netmaskIntToPrefixLength(I)I
-Landroid/net/NetworkUtils;->parcelInetAddress(Landroid/os/Parcel;Ljava/net/InetAddress;I)V
-Landroid/net/NetworkUtils;->parseIpAndMask(Ljava/lang/String;)Landroid/util/Pair;
-Landroid/net/NetworkUtils;->protectFromVpn(I)Z
-Landroid/net/NetworkUtils;->queryUserAccess(II)Z
-Landroid/net/NetworkUtils;->routedIPv4AddressCount(Ljava/util/TreeSet;)J
-Landroid/net/NetworkUtils;->routedIPv6AddressCount(Ljava/util/TreeSet;)Ljava/math/BigInteger;
-Landroid/net/NetworkUtils;->setupRaSocket(Ljava/io/FileDescriptor;I)V
-Landroid/net/NetworkUtils;->TAG:Ljava/lang/String;
-Landroid/net/NetworkUtils;->unparcelInetAddress(Landroid/os/Parcel;)Ljava/net/InetAddress;
-Landroid/net/NetworkWatchlistManager;-><init>(Landroid/content/Context;)V
-Landroid/net/NetworkWatchlistManager;-><init>(Landroid/content/Context;Lcom/android/internal/net/INetworkWatchlistManager;)V
-Landroid/net/NetworkWatchlistManager;->getWatchlistConfigHash()[B
-Landroid/net/NetworkWatchlistManager;->mContext:Landroid/content/Context;
-Landroid/net/NetworkWatchlistManager;->mNetworkWatchlistManager:Lcom/android/internal/net/INetworkWatchlistManager;
-Landroid/net/NetworkWatchlistManager;->reloadWatchlist()V
-Landroid/net/NetworkWatchlistManager;->reportWatchlistIfNecessary()V
-Landroid/net/NetworkWatchlistManager;->SHARED_MEMORY_TAG:Ljava/lang/String;
-Landroid/net/NetworkWatchlistManager;->TAG:Ljava/lang/String;
 Landroid/net/nsd/DnsSdTxtRecord;-><init>()V
 Landroid/net/nsd/DnsSdTxtRecord;-><init>(Landroid/net/nsd/DnsSdTxtRecord;)V
 Landroid/net/nsd/DnsSdTxtRecord;-><init>([B)V
@@ -37727,43 +36556,6 @@
 Landroid/net/Proxy;->setHttpProxySystemProperty(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/net/Uri;)V
 Landroid/net/Proxy;->TAG:Ljava/lang/String;
 Landroid/net/Proxy;->validate(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
-Landroid/net/ProxyInfo;-><init>(Landroid/net/ProxyInfo;)V
-Landroid/net/ProxyInfo;-><init>(Landroid/net/Uri;)V
-Landroid/net/ProxyInfo;-><init>(Landroid/net/Uri;I)V
-Landroid/net/ProxyInfo;-><init>(Ljava/lang/String;)V
-Landroid/net/ProxyInfo;-><init>(Ljava/lang/String;ILjava/lang/String;[Ljava/lang/String;)V
-Landroid/net/ProxyInfo;->getExclusionListAsString()Ljava/lang/String;
-Landroid/net/ProxyInfo;->getSocketAddress()Ljava/net/InetSocketAddress;
-Landroid/net/ProxyInfo;->isValid()Z
-Landroid/net/ProxyInfo;->LOCAL_EXCL_LIST:Ljava/lang/String;
-Landroid/net/ProxyInfo;->LOCAL_HOST:Ljava/lang/String;
-Landroid/net/ProxyInfo;->LOCAL_PORT:I
-Landroid/net/ProxyInfo;->makeProxy()Ljava/net/Proxy;
-Landroid/net/ProxyInfo;->mExclusionList:Ljava/lang/String;
-Landroid/net/ProxyInfo;->mHost:Ljava/lang/String;
-Landroid/net/ProxyInfo;->mPacFileUrl:Landroid/net/Uri;
-Landroid/net/ProxyInfo;->mParsedExclusionList:[Ljava/lang/String;
-Landroid/net/ProxyInfo;->mPort:I
-Landroid/net/ProxyInfo;->setExclusionList(Ljava/lang/String;)V
-Landroid/net/RouteInfo;-><init>(Landroid/net/IpPrefix;)V
-Landroid/net/RouteInfo;-><init>(Landroid/net/IpPrefix;I)V
-Landroid/net/RouteInfo;-><init>(Landroid/net/IpPrefix;Ljava/net/InetAddress;)V
-Landroid/net/RouteInfo;-><init>(Landroid/net/IpPrefix;Ljava/net/InetAddress;Ljava/lang/String;I)V
-Landroid/net/RouteInfo;-><init>(Landroid/net/LinkAddress;)V
-Landroid/net/RouteInfo;->getDestinationLinkAddress()Landroid/net/LinkAddress;
-Landroid/net/RouteInfo;->getType()I
-Landroid/net/RouteInfo;->isHostRoute()Z
-Landroid/net/RouteInfo;->isIPv4Default()Z
-Landroid/net/RouteInfo;->isIPv6Default()Z
-Landroid/net/RouteInfo;->makeHostRoute(Ljava/net/InetAddress;Ljava/lang/String;)Landroid/net/RouteInfo;
-Landroid/net/RouteInfo;->makeHostRoute(Ljava/net/InetAddress;Ljava/net/InetAddress;Ljava/lang/String;)Landroid/net/RouteInfo;
-Landroid/net/RouteInfo;->mDestination:Landroid/net/IpPrefix;
-Landroid/net/RouteInfo;->mHasGateway:Z
-Landroid/net/RouteInfo;->mInterface:Ljava/lang/String;
-Landroid/net/RouteInfo;->mType:I
-Landroid/net/RouteInfo;->RTN_THROW:I
-Landroid/net/RouteInfo;->RTN_UNICAST:I
-Landroid/net/RouteInfo;->RTN_UNREACHABLE:I
 Landroid/net/RssiCurve;-><init>(Landroid/os/Parcel;)V
 Landroid/net/RssiCurve;->DEFAULT_ACTIVE_NETWORK_RSSI_BOOST:I
 Landroid/net/rtp/AudioCodec;-><init>(ILjava/lang/String;Ljava/lang/String;)V
@@ -38034,11 +36826,6 @@
 Landroid/net/SSLSessionCache;-><init>(Ljava/lang/Object;)V
 Landroid/net/SSLSessionCache;->install(Landroid/net/SSLSessionCache;Ljavax/net/ssl/SSLContext;)V
 Landroid/net/SSLSessionCache;->TAG:Ljava/lang/String;
-Landroid/net/StaticIpConfiguration;-><init>(Landroid/net/StaticIpConfiguration;)V
-Landroid/net/StaticIpConfiguration;->clear()V
-Landroid/net/StaticIpConfiguration;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/net/StaticIpConfiguration;->readFromParcel(Landroid/net/StaticIpConfiguration;Landroid/os/Parcel;)V
-Landroid/net/StaticIpConfiguration;->toLinkProperties(Ljava/lang/String;)Landroid/net/LinkProperties;
 Landroid/net/StringNetworkSpecifier;-><init>(Ljava/lang/String;)V
 Landroid/net/StringNetworkSpecifier;->CREATOR:Landroid/os/Parcelable$Creator;
 Landroid/net/StringNetworkSpecifier;->satisfiedBy(Landroid/net/NetworkSpecifier;)Z
@@ -38077,15 +36864,6 @@
 Landroid/net/TrafficStats;->TYPE_TX_PACKETS:I
 Landroid/net/TrafficStats;->UID_REMOVED:I
 Landroid/net/TrafficStats;->UID_TETHERING:I
-Landroid/net/UidRange;-><init>(II)V
-Landroid/net/UidRange;->contains(I)Z
-Landroid/net/UidRange;->containsRange(Landroid/net/UidRange;)Z
-Landroid/net/UidRange;->count()I
-Landroid/net/UidRange;->createForUser(I)Landroid/net/UidRange;
-Landroid/net/UidRange;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/net/UidRange;->getStartUser()I
-Landroid/net/UidRange;->start:I
-Landroid/net/UidRange;->stop:I
 Landroid/net/Uri$AbstractHierarchicalUri;-><init>()V
 Landroid/net/Uri$AbstractHierarchicalUri;->getUserInfoPart()Landroid/net/Uri$Part;
 Landroid/net/Uri$AbstractHierarchicalUri;->host:Ljava/lang/String;
diff --git a/boot/hiddenapi/hiddenapi-unsupported.txt b/boot/hiddenapi/hiddenapi-unsupported.txt
index 0265df5..002d42d 100644
--- a/boot/hiddenapi/hiddenapi-unsupported.txt
+++ b/boot/hiddenapi/hiddenapi-unsupported.txt
@@ -167,16 +167,6 @@
 Landroid/media/IMediaScannerService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IMediaScannerService;
 Landroid/media/session/ISessionManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/session/ISessionManager;
 Landroid/media/tv/ITvRemoteProvider$Stub;-><init>()V
-Landroid/net/IConnectivityManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/net/IConnectivityManager$Stub$Proxy;->getActiveLinkProperties()Landroid/net/LinkProperties;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getActiveNetworkInfo()Landroid/net/NetworkInfo;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getAllNetworkInfo()[Landroid/net/NetworkInfo;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getAllNetworks()[Landroid/net/Network;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getTetherableIfaces()[Ljava/lang/String;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getTetherableUsbRegexs()[Ljava/lang/String;
-Landroid/net/IConnectivityManager$Stub$Proxy;->getTetheredIfaces()[Ljava/lang/String;
-Landroid/net/IConnectivityManager$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/net/IConnectivityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/IConnectivityManager;
 Landroid/net/INetworkManagementEventObserver$Stub;-><init>()V
 Landroid/net/INetworkPolicyManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkPolicyManager;
 Landroid/net/INetworkScoreService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkScoreService;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 034ad8e..00ba55c 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -36,7 +36,6 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.UserIdInt;
 import android.app.assist.AssistContent;
 import android.app.assist.AssistStructure;
 import android.app.backup.BackupAgent;
@@ -62,7 +61,6 @@
 import android.content.ContentProvider;
 import android.content.ContentResolver;
 import android.content.Context;
-import android.content.Context.CreatePackageOptions;
 import android.content.IContentProvider;
 import android.content.IIntentReceiver;
 import android.content.Intent;
@@ -73,7 +71,6 @@
 import android.content.pm.InstrumentationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.ApplicationInfoFlags;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.PermissionInfo;
@@ -1172,6 +1169,7 @@
         }
 
         public void scheduleApplicationInfoChanged(ApplicationInfo ai) {
+            mResourcesManager.updatePendingAppInfoUpdates(ai);
             mH.removeMessages(H.APPLICATION_INFO_CHANGED, ai);
             sendMessage(H.APPLICATION_INFO_CHANGED, ai);
         }
@@ -2376,22 +2374,16 @@
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
-            @CreatePackageOptions int flags) {
+            int flags) {
         return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId());
     }
 
     public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
-            @CreatePackageOptions int flags, @UserIdInt int userId) {
-        return getPackageInfo(packageName, compatInfo, flags, userId, 0 /* packageFlags */);
-    }
-
-    public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
-            @CreatePackageOptions int flags, @UserIdInt int userId,
-            @ApplicationInfoFlags int packageFlags) {
+            int flags, int userId) {
         final boolean differentUser = (UserHandle.myUserId() != userId);
         ApplicationInfo ai = PackageManager.getApplicationInfoAsUserCached(
                 packageName,
-                packageFlags | PackageManager.GET_SHARED_LIBRARY_FILES
+                PackageManager.GET_SHARED_LIBRARY_FILES
                 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
                 (userId < 0) ? UserHandle.myUserId() : userId);
         synchronized (mResourcesManager) {
@@ -2434,7 +2426,7 @@
 
     @UnsupportedAppUsage(trackingBug = 171933273)
     public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
-            @CreatePackageOptions int flags) {
+            int flags) {
         boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
         boolean securityViolation = includeCode && ai.uid != 0
                 && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 16b6ea5..5e99c79 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -26,7 +26,6 @@
 import android.annotation.Nullable;
 import android.annotation.UiContext;
 import android.compat.annotation.UnsupportedAppUsage;
-import android.content.AttributionSource;
 import android.content.AutofillOptions;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -48,7 +47,6 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.ApplicationInfoFlags;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.AssetManager;
 import android.content.res.CompatResources;
@@ -62,6 +60,7 @@
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.content.AttributionSource;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
@@ -2494,13 +2493,6 @@
     @Override
     public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
             throws NameNotFoundException {
-        return createPackageContextAsUser(packageName, flags, user, 0 /* packageFlags */);
-    }
-
-    @Override
-    public Context createPackageContextAsUser(
-            @NonNull String packageName, @CreatePackageOptions int flags, @NonNull UserHandle user,
-            @ApplicationInfoFlags int packageFlags) throws PackageManager.NameNotFoundException {
         if (packageName.equals("system") || packageName.equals("android")) {
             // The system resources are loaded in every application, so we can safely copy
             // the context without reloading Resources.
@@ -2511,7 +2503,7 @@
         }
 
         LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(),
-                flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier(), packageFlags);
+                flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier());
         if (pi != null) {
             ContextImpl c = new ContextImpl(this, mMainThread, pi, mParams,
                     mAttributionSource.getAttributionTag(),
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 506dfe09f..6454d20 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -6344,11 +6344,10 @@
             ApplicationInfo applicationInfo = n.extras.getParcelable(
                     EXTRA_BUILDER_APPLICATION_INFO);
             Context builderContext;
-            if (applicationInfo != null && applicationInfo.packageName != null) {
+            if (applicationInfo != null) {
                 try {
-                    builderContext = context.createPackageContextAsUser(applicationInfo.packageName,
-                            Context.CONTEXT_RESTRICTED,
-                            UserHandle.getUserHandleForUid(applicationInfo.uid));
+                    builderContext = context.createApplicationContext(applicationInfo,
+                            Context.CONTEXT_RESTRICTED);
                 } catch (NameNotFoundException e) {
                     Log.e(TAG, "ApplicationInfo " + applicationInfo + " not found");
                     builderContext = context;  // try with our context
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index e469b1f..dfd1e2b 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -98,6 +98,12 @@
     private int mResDisplayId = DEFAULT_DISPLAY;
 
     /**
+     * ApplicationInfo changes that need to be applied to Resources when the next configuration
+     * change occurs.
+     */
+    private ArrayList<ApplicationInfo> mPendingAppInfoUpdates;
+
+    /**
      * A mapping of ResourceImpls and their configurations. These are heavy weight objects
      * which should be reused as much as possible.
      */
@@ -988,7 +994,7 @@
      * @param classLoader The classloader to use for the Resources object.
      *                    If null, {@link ClassLoader#getSystemClassLoader()} is used.
      * @return A Resources object that gets updated when
-     *         {@link #applyConfigurationToResourcesLocked(Configuration, CompatibilityInfo)}
+     *         {@link #applyConfigurationToResources(Configuration, CompatibilityInfo)}
      *         is called.
      */
     @Nullable
@@ -1115,8 +1121,8 @@
     /**
      * Updates an Activity's Resources object with overrideConfig. The Resources object
      * that was previously returned by {@link #getResources(IBinder, String, String[], String[],
-     * String[], Integer, Configuration, CompatibilityInfo, ClassLoader, List)} is still valid and
-     * will have the updated configuration.
+     * String[], String[], Integer, Configuration, CompatibilityInfo, ClassLoader, List)} is still
+     * valid and will have the updated configuration.
      *
      * @param activityToken The Activity token.
      * @param overrideConfig The configuration override to update.
@@ -1267,6 +1273,22 @@
         return newKey;
     }
 
+    public void updatePendingAppInfoUpdates(@NonNull ApplicationInfo appInfo) {
+        synchronized (mLock) {
+            if (mPendingAppInfoUpdates == null) {
+                mPendingAppInfoUpdates = new ArrayList<>();
+            }
+            // Clear previous app info changes for the package to prevent multiple ResourcesImpl
+            // recreations when only the last recreation will be used.
+            for (int i = mPendingAppInfoUpdates.size() - 1; i >= 0; i--) {
+                if (appInfo.sourceDir.equals(mPendingAppInfoUpdates.get(i).sourceDir)) {
+                    mPendingAppInfoUpdates.remove(i);
+                }
+            }
+            mPendingAppInfoUpdates.add(appInfo);
+        }
+    }
+
     public final boolean applyConfigurationToResources(@NonNull Configuration config,
             @Nullable CompatibilityInfo compat) {
         return applyConfigurationToResources(config, compat, null /* adjustments */);
@@ -1280,7 +1302,18 @@
                 Trace.traceBegin(Trace.TRACE_TAG_RESOURCES,
                         "ResourcesManager#applyConfigurationToResources");
 
-                if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
+                final boolean assetsUpdated = mPendingAppInfoUpdates != null
+                        && config.assetsSeq > mResConfiguration.assetsSeq;
+                if (assetsUpdated) {
+                    for (int i = 0, n = mPendingAppInfoUpdates.size(); i < n; i++) {
+                        final ApplicationInfo appInfo = mPendingAppInfoUpdates.get(i);
+                        applyNewResourceDirs(appInfo, new String[]{appInfo.sourceDir});
+                    }
+                    mPendingAppInfoUpdates = null;
+                }
+
+                if (!assetsUpdated && !mResConfiguration.isOtherSeqNewer(config)
+                        && compat == null) {
                     if (DEBUG || DEBUG_CONFIGURATION) {
                         Slog.v(TAG, "Skipping new config: curSeq="
                                 + mResConfiguration.seq + ", newSeq=" + config.seq);
@@ -1320,7 +1353,7 @@
                     }
                 }
 
-                return changes != 0;
+                return assetsUpdated || changes != 0;
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
             }
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index 3b11a19..ba3fc1e 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -37,7 +37,6 @@
 import android.os.Bundle;
 import android.os.CancellationSignal;
 import android.os.Parcelable;
-import android.os.UserHandle;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Pair;
@@ -719,10 +718,9 @@
     protected Context getRemoteContext() {
         try {
             // Return if cloned successfully, otherwise default
-            final ApplicationInfo info = mInfo.providerInfo.applicationInfo;
-            Context newContext = mContext.createPackageContextAsUser(info.packageName,
-                    Context.CONTEXT_RESTRICTED,
-                    UserHandle.getUserHandleForUid(info.uid));
+            Context newContext = mContext.createApplicationContext(
+                    mInfo.providerInfo.applicationInfo,
+                    Context.CONTEXT_RESTRICTED);
             if (mColorResources != null) {
                 mColorResources.apply(newContext);
             }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 9c60f43..c02dcfd 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -46,7 +46,6 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.ApplicationInfoFlags;
 import android.content.res.AssetManager;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
@@ -6269,23 +6268,6 @@
     }
 
     /**
-     * Similar to {@link #createPackageContextAsUser(String, int, UserHandle)}, but also allows
-     * specifying the flags used to retrieve the {@link ApplicationInfo} of the package.
-     *
-     * @hide
-     */
-    @NonNull
-    public Context createPackageContextAsUser(
-            @NonNull String packageName, @CreatePackageOptions int flags, @NonNull UserHandle user,
-            @ApplicationInfoFlags int packageFlags)
-            throws PackageManager.NameNotFoundException {
-        if (Build.IS_ENG) {
-            throw new IllegalStateException("createPackageContextAsUser not overridden!");
-        }
-        return this;
-    }
-
-    /**
      * Similar to {@link #createPackageContext(String, int)}, but for the own package with a
      * different {@link UserHandle}. For example, {@link #getContentResolver()}
      * will open any {@link Uri} as the given user.
@@ -6304,18 +6286,10 @@
     /**
      * Creates a context given an {@link android.content.pm.ApplicationInfo}.
      *
-     * @deprecated use {@link #createPackageContextAsUser(String, int, UserHandle, int)}
-     *             If an application caches an ApplicationInfo and uses it to call this method,
-     *             the app will not get the most recent version of Runtime Resource Overlays for
-     *             that application. To make things worse, the LoadedApk stored in
-     *             {@code ActivityThread#mResourcePackages} is updated using the old ApplicationInfo
-     *             causing further uses of the cached LoadedApk to return outdated information.
-     *
      * @hide
      */
     @SuppressWarnings("HiddenAbstractMethod")
     @UnsupportedAppUsage
-    @Deprecated
     public abstract Context createApplicationContext(ApplicationInfo application,
             @CreatePackageOptions int flags) throws PackageManager.NameNotFoundException;
 
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index cf0dc8c..6324d0e 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -1009,14 +1009,6 @@
 
     /** @hide */
     @Override
-    public Context createPackageContextAsUser(String packageName, int flags, UserHandle user,
-            int packageFlags)
-            throws PackageManager.NameNotFoundException {
-        return mBase.createPackageContextAsUser(packageName, flags, user, packageFlags);
-    }
-
-    /** @hide */
-    @Override
     public Context createContextAsUser(UserHandle user, @CreatePackageOptions int flags) {
         return mBase.createContextAsUser(user, flags);
     }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 688483a..9e35a32 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -5736,12 +5736,20 @@
     public static final String EXTRA_REPLACING = "android.intent.extra.REPLACING";
 
     /**
-     * Used as an int extra field in {@link android.app.AlarmManager} intents
+     * Used as an int extra field in {@link android.app.AlarmManager} pending intents
      * to tell the application being invoked how many pending alarms are being
-     * delievered with the intent.  For one-shot alarms this will always be 1.
+     * delivered with the intent.  For one-shot alarms this will always be 1.
      * For recurring alarms, this might be greater than 1 if the device was
      * asleep or powered off at the time an earlier alarm would have been
      * delivered.
+     *
+     * <p>Note: You must supply a <b>mutable</b> {@link android.app.PendingIntent} to
+     * {@code AlarmManager} while setting your alarms to be able to read this value on receiving
+     * them. <em>Mutability of pending intents must be explicitly specified by apps targeting
+     * {@link Build.VERSION_CODES#S} or higher</em>.
+     *
+     * @see android.app.PendingIntent#FLAG_MUTABLE
+     *
      */
     public static final String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT";
 
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index 65ce1e7..dd2080b 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -61,7 +61,7 @@
     public static final int MAX_SAFE_LABEL_LENGTH = 1000;
 
     /** @hide */
-    public static final float DEFAULT_MAX_LABEL_SIZE_PX = 500f;
+    public static final float DEFAULT_MAX_LABEL_SIZE_PX = 1000f;
 
     /**
      * Remove {@link Character#isWhitespace(int) whitespace} and non-breaking spaces from the edges
diff --git a/core/java/android/content/pm/TEST_MAPPING b/core/java/android/content/pm/TEST_MAPPING
index 1eb4504..8bc3734 100644
--- a/core/java/android/content/pm/TEST_MAPPING
+++ b/core/java/android/content/pm/TEST_MAPPING
@@ -49,9 +49,6 @@
           "include-filter": "android.appsecurity.cts.AppSecurityTests#testPermissionDiffCert"
         }
       ]
-    },
-    {
-      "name": "CtsPackageManagerBootTestCases"
     }
   ]
 }
diff --git a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
index e665d0f..4721f3e 100644
--- a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
@@ -209,7 +209,8 @@
             FINGERPRINT_ACQUIRED_VENDOR,
             FINGERPRINT_ACQUIRED_START,
             FINGERPRINT_ACQUIRED_UNKNOWN,
-            FINGERPRINT_ACQUIRED_IMMOBILE})
+            FINGERPRINT_ACQUIRED_IMMOBILE,
+            FINGERPRINT_ACQUIRED_TOO_BRIGHT})
     @Retention(RetentionPolicy.SOURCE)
     @interface FingerprintAcquired {}
 
@@ -287,6 +288,13 @@
     int FINGERPRINT_ACQUIRED_IMMOBILE = 9;
 
     /**
+     * For sensors that require illumination, such as optical under-display fingerprint sensors,
+     * the image was too bright to be used for matching.
+     * @hide
+     */
+    int FINGERPRINT_ACQUIRED_TOO_BRIGHT = 10;
+
+    /**
      * @hide
      */
     int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 68dd6234..c104eeb 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -1420,6 +1420,9 @@
             case FINGERPRINT_ACQUIRED_IMMOBILE:
                 return context.getString(
                     com.android.internal.R.string.fingerprint_acquired_immobile);
+            case FINGERPRINT_ACQUIRED_TOO_BRIGHT:
+                return context.getString(
+                   com.android.internal.R.string.fingerprint_acquired_too_bright);
             case FINGERPRINT_ACQUIRED_VENDOR: {
                 String[] msgArray = context.getResources().getStringArray(
                         com.android.internal.R.array.fingerprint_acquired_vendor);
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 863d71f..8e4a68e 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -434,8 +434,11 @@
     public Context getPackageContext(Context context) {
         if (mContext == null) {
             try {
-                mContext = context.createPackageContextAsUser(pkg, Context.CONTEXT_RESTRICTED, user,
-                        PackageManager.MATCH_UNINSTALLED_PACKAGES);
+                ApplicationInfo ai = context.getPackageManager()
+                        .getApplicationInfoAsUser(pkg, PackageManager.MATCH_UNINSTALLED_PACKAGES,
+                                getUserId());
+                mContext = context.createApplicationContext(ai,
+                        Context.CONTEXT_RESTRICTED);
             } catch (PackageManager.NameNotFoundException e) {
                 mContext = null;
             }
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index a1ffe34..d39b56d 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -621,7 +621,11 @@
      * The instance of {@link ServiceState} passed as an argument here will have various levels of
      * location information stripped from it depending on the location permissions that your app
      * holds. Only apps holding the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission will
-     * receive all the information in {@link ServiceState}.
+     * receive all the information in {@link ServiceState}, otherwise the cellIdentity will be null
+     * if apps only holding the {@link Manifest.permission#ACCESS_COARSE_LOCATION} permission.
+     * Network operator name in long/short alphanumeric format and numeric id will be null if apps
+     * holding neither {@link android.Manifest.permission#ACCESS_FINE_LOCATION} nor
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
      *
      * @see ServiceState#STATE_EMERGENCY_ONLY
      * @see ServiceState#STATE_IN_SERVICE
diff --git a/core/java/android/telephony/TelephonyCallback.java b/core/java/android/telephony/TelephonyCallback.java
index 1a25c8b..dd4de0a 100644
--- a/core/java/android/telephony/TelephonyCallback.java
+++ b/core/java/android/telephony/TelephonyCallback.java
@@ -663,7 +663,12 @@
          * levels of location information stripped from it depending on the location permissions
          * that your app holds.
          * Only apps holding the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission will
-         * receive all the information in {@link ServiceState}.
+         * receive all the information in {@link ServiceState}, otherwise the cellIdentity
+         * will be null if apps only holding the {@link Manifest.permission#ACCESS_COARSE_LOCATION}
+         * permission.
+         * Network operator name in long/short alphanumeric format and numeric id will be null if
+         * apps holding neither {@link android.Manifest.permission#ACCESS_FINE_LOCATION} nor
+         * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
          *
          * @see ServiceState#STATE_EMERGENCY_ONLY
          * @see ServiceState#STATE_IN_SERVICE
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index e0a7bf2..4cf5532 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -773,7 +773,7 @@
 
     void notifyContextUpdated(int sessionId, @Nullable ContentCaptureContext context) {
         mHandler.post(() -> sendEvent(new ContentCaptureEvent(sessionId, TYPE_CONTEXT_UPDATED)
-                .setClientContext(context)));
+                .setClientContext(context), FORCE_FLUSH));
     }
 
     @Override
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index 8d27cde..cf6807e 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -33,7 +33,6 @@
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.Trace;
-import android.os.UserHandle;
 import android.util.AndroidRuntimeException;
 import android.util.ArraySet;
 import android.util.Log;
@@ -468,12 +467,9 @@
             sTimestamps.mCreateContextStart = SystemClock.uptimeMillis();
             try {
                 // Construct an app context to load the Java code into the current app.
-                Context webViewContext = initialApplication.createPackageContextAsUser(
-                        ai.packageName,
-                        Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY,
-                        UserHandle.getUserHandleForUid(ai.uid),
-                        PackageManager.MATCH_UNINSTALLED_PACKAGES
-                                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING);
+                Context webViewContext = initialApplication.createApplicationContext(
+                        ai,
+                        Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
                 sPackageInfo = newPackageInfo;
                 return webViewContext;
             } finally {
diff --git a/core/java/android/widget/AnalogClock.java b/core/java/android/widget/AnalogClock.java
index d596626..9c12850 100644
--- a/core/java/android/widget/AnalogClock.java
+++ b/core/java/android/widget/AnalogClock.java
@@ -111,7 +111,9 @@
 
         mSecondsHandFps = AppGlobals.getIntCoreSetting(
                 WidgetFlags.KEY_ANALOG_CLOCK_SECONDS_HAND_FPS,
-                WidgetFlags.ANALOG_CLOCK_SECONDS_HAND_FPS_DEFAULT);
+                context.getResources()
+                        .getInteger(com.android.internal.R.integer
+                                .config_defaultAnalogClockSecondsHandFps));
 
         final TypedArray a = context.obtainStyledAttributes(
                 attrs, com.android.internal.R.styleable.AnalogClock, defStyleAttr, defStyleRes);
@@ -720,7 +722,7 @@
         canvas.restore();
 
         final Drawable secondHand = mSecondHand;
-        if (secondHand != null) {
+        if (secondHand != null && mSecondsHandFps > 0) {
             canvas.save();
             canvas.rotate(mSeconds / 60.0f * 360.0f, x, y);
 
@@ -752,7 +754,10 @@
         // n positions between two given numbers, where n is the number of ticks per second. This
         // ensures the second hand advances by a consistent distance despite our handler callbacks
         // occurring at inconsistent frequencies.
-        mSeconds = Math.round(rawSeconds * mSecondsHandFps) / (float) mSecondsHandFps;
+        mSeconds =
+                mSecondsHandFps <= 0
+                        ? rawSeconds
+                        : Math.round(rawSeconds * mSecondsHandFps) / (float) mSecondsHandFps;
         mMinutes = localTime.getMinute() + mSeconds / 60.0f;
         mHour = localTime.getHour() + mMinutes / 60.0f;
         mChanged = true;
@@ -789,7 +794,7 @@
             LocalTime localTime = zonedDateTime.toLocalTime();
 
             long millisUntilNextTick;
-            if (mSecondHand == null) {
+            if (mSecondHand == null || mSecondsHandFps <= 0) {
                 // If there's no second hand, then tick at the start of the next minute.
                 //
                 // This must be done with ZonedDateTime as opposed to LocalDateTime to ensure proper
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 8a044fd..e827f0a 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -5831,9 +5831,8 @@
                 return context;
             }
             try {
-                return context.createPackageContextAsUser(mApplication.packageName,
-                        Context.CONTEXT_RESTRICTED,
-                        UserHandle.getUserHandleForUid(mApplication.uid));
+                return context.createApplicationContext(mApplication,
+                        Context.CONTEXT_RESTRICTED);
             } catch (NameNotFoundException e) {
                 Log.e(LOG_TAG, "Package name " + mApplication.packageName + " not found");
             }
diff --git a/core/java/android/widget/WidgetFlags.java b/core/java/android/widget/WidgetFlags.java
index 0971268..fb40ee5 100644
--- a/core/java/android/widget/WidgetFlags.java
+++ b/core/java/android/widget/WidgetFlags.java
@@ -207,9 +207,6 @@
     public static final String KEY_ANALOG_CLOCK_SECONDS_HAND_FPS =
             "widget__analog_clock_seconds_hand_fps";
 
-    /** Default value for the flag {@link #ANALOG_CLOCK_SECONDS_HAND_FPS}. */
-    public static final int ANALOG_CLOCK_SECONDS_HAND_FPS_DEFAULT = 1;
-
     private WidgetFlags() {
     }
 }
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 7000ed7..a6bf3cf 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -1186,7 +1186,7 @@
 
         final DisplayResolveInfo dri = new DisplayResolveInfo(
                 originalIntent, ri, getString(R.string.screenshot_edit), "", resolveIntent, null);
-        dri.setDisplayIcon(getDrawable(R.drawable.ic_menu_edit));
+        dri.setDisplayIcon(getDrawable(R.drawable.ic_screenshot_edit));
         return dri;
     }
 
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index c74c39a..10750b6 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -40,7 +40,6 @@
 import android.os.incremental.IncrementalStorage;
 import android.system.ErrnoException;
 import android.system.Os;
-import android.util.ArraySet;
 import android.util.Slog;
 
 import dalvik.system.CloseGuard;
@@ -551,18 +550,4 @@
         }
         return false;
     }
-
-    /**
-     * Wait for all native library extraction to complete for the passed storages.
-     *
-     * @param incrementalStorages A list of the storages to wait for.
-     */
-    public static void waitForNativeBinariesExtraction(
-            ArraySet<IncrementalStorage> incrementalStorages) {
-        for (int i = 0; i < incrementalStorages.size(); ++i) {
-            IncrementalStorage storage = incrementalStorages.valueAtUnchecked(i);
-            storage.waitForNativeBinariesExtraction();
-        }
-    }
-
 }
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index dab3e9f..be059a1 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -191,6 +191,11 @@
     @VisibleForTesting
     public static final int WAKE_LOCK_WEIGHT = 50;
 
+    public static final int RESET_REASON_CORRUPT_FILE = 1;
+    public static final int RESET_REASON_ADB_COMMAND = 2;
+    public static final int RESET_REASON_FULL_CHARGE = 3;
+    public static final int RESET_REASON_MEASURED_ENERGY_BUCKETS_CHANGE = 4;
+
     protected Clocks mClocks;
 
     private final AtomicFile mStatsFile;
@@ -348,8 +353,9 @@
 
         /**
          * Callback invoked immediately prior to resetting battery stats.
+         * @param resetReason One of the RESET_REASON_* constants.
          */
-        void prepareForBatteryStatsReset();
+        void prepareForBatteryStatsReset(int resetReason);
     }
 
     private BatteryResetListener mBatteryResetListener;
@@ -747,6 +753,7 @@
     // CPU update, even if we aren't currently running wake locks.
     boolean mDistributeWakelockCpu;
 
+    private boolean mSystemReady;
     boolean mShuttingDown;
 
     final HistoryEventTracker mActiveEvents = new HistoryEventTracker();
@@ -11210,7 +11217,7 @@
         long uptimeUs = mSecUptime * 1000;
         long mSecRealtime = mClocks.elapsedRealtime();
         long realtimeUs = mSecRealtime * 1000;
-        resetAllStatsLocked(mSecUptime, mSecRealtime);
+        resetAllStatsLocked(mSecUptime, mSecRealtime, RESET_REASON_ADB_COMMAND);
         mDischargeStartLevel = mHistoryCur.batteryLevel;
         pullPendingStateUpdatesLocked();
         addHistoryRecordLocked(mSecRealtime, mSecUptime);
@@ -11239,9 +11246,10 @@
         initActiveHistoryEventsLocked(mSecRealtime, mSecUptime);
     }
 
-    private void resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis) {
+    private void resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis,
+            int resetReason) {
         if (mBatteryResetListener != null) {
-            mBatteryResetListener.prepareForBatteryStatsReset();
+            mBatteryResetListener.prepareForBatteryStatsReset(resetReason);
         }
 
         final long uptimeUs = uptimeMillis * 1000;
@@ -13477,6 +13485,13 @@
         return false;
     }
 
+    /**
+     * Notifies BatteryStatsImpl that the system server is ready.
+     */
+    public void onSystemReady() {
+        mSystemReady = true;
+    }
+
     @GuardedBy("this")
     protected void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime,
             final boolean onBattery, final int oldStatus, final int level, final int chargeUah) {
@@ -13493,10 +13508,17 @@
             // battery was last full, or the level is at 100, or
             // we have gone through a significant charge (from a very low
             // level to a now very high level).
+            // Also, we will reset the stats if battery got partially charged
+            // and discharged repeatedly without ever reaching the full charge.
+            // This reset is done in order to prevent stats sessions from going on forever.
+            // Exceedingly long battery sessions would lead to an overflow of
+            // data structures such as mWakeupReasonStats.
             boolean reset = false;
-            if (!mNoAutoReset && (oldStatus == BatteryManager.BATTERY_STATUS_FULL
+            if (!mNoAutoReset && mSystemReady
+                    && (oldStatus == BatteryManager.BATTERY_STATUS_FULL
                     || level >= 90
-                    || (mDischargeCurrentLevel < 20 && level >= 80))) {
+                    || (mDischargeCurrentLevel < 20 && level >= 80)
+                    || getHighDischargeAmountSinceCharge() >= 200)) {
                 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus
                         + " dischargeLevel=" + mDischargeCurrentLevel
                         + " lowAmount=" + getLowDischargeAmountSinceCharge()
@@ -13534,7 +13556,7 @@
                     });
                 }
                 doWrite = true;
-                resetAllStatsLocked(mSecUptime, mSecRealtime);
+                resetAllStatsLocked(mSecUptime, mSecRealtime, RESET_REASON_FULL_CHARGE);
                 if (chargeUah > 0 && level > 0) {
                     // Only use the reported coulomb charge value if it is supported and reported.
                     mEstimatedBatteryCapacityMah = (int) ((chargeUah / 1000) / (level / 100.0));
@@ -14502,7 +14524,8 @@
                     ? null : new MeasuredEnergyStats(supportedStandardBuckets, customBucketNames);
             // Supported power buckets changed since last boot.
             // Existing data is no longer reliable.
-            resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime());
+            resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(),
+                    RESET_REASON_MEASURED_ENERGY_BUCKETS_CHANGE);
         }
     }
 
@@ -14949,7 +14972,8 @@
             }
         } catch (Exception e) {
             Slog.e(TAG, "Error reading battery statistics", e);
-            resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime());
+            resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(),
+                    RESET_REASON_CORRUPT_FILE);
         } finally {
             stats.recycle();
         }
diff --git a/core/java/com/android/internal/os/BatteryUsageStatsStore.java b/core/java/com/android/internal/os/BatteryUsageStatsStore.java
index 5c97602..fd54b32 100644
--- a/core/java/com/android/internal/os/BatteryUsageStatsStore.java
+++ b/core/java/com/android/internal/os/BatteryUsageStatsStore.java
@@ -69,6 +69,7 @@
 
     private final Context mContext;
     private final BatteryStatsImpl mBatteryStats;
+    private boolean mSystemReady;
     private final File mStoreDir;
     private final File mLockFile;
     private final AtomicFile mConfigFile;
@@ -95,7 +96,18 @@
         mBatteryUsageStatsProvider = new BatteryUsageStatsProvider(mContext, mBatteryStats);
     }
 
-    private void prepareForBatteryStatsReset() {
+    /**
+     * Notifies BatteryUsageStatsStore that the system server is ready.
+     */
+    public void onSystemReady() {
+        mSystemReady = true;
+    }
+
+    private void prepareForBatteryStatsReset(int resetReason) {
+        if (resetReason == BatteryStatsImpl.RESET_REASON_CORRUPT_FILE || !mSystemReady) {
+            return;
+        }
+
         final List<BatteryUsageStats> stats =
                 mBatteryUsageStatsProvider.getBatteryUsageStats(BATTERY_USAGE_STATS_QUERY);
         if (stats.isEmpty()) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 64b8a1a..14d200d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1663,11 +1663,6 @@
     <permission android:name="android.permission.INSTALL_LOCATION_TIME_ZONE_PROVIDER_SERVICE"
         android:protectionLevel="signature|privileged" />
 
-    <!-- The system server uses this permission to install a default secondary location time zone
-         provider.
-    -->
-    <uses-permission android:name="android.permission.INSTALL_LOCATION_TIME_ZONE_PROVIDER_SERVICE"/>
-
     <!-- @SystemApi @hide Allows an application to bind to a android.service.TimeZoneProviderService
          for the purpose of detecting the device's time zone. This prevents arbitrary clients
          connecting to the time zone provider service. The system server checks that the provider's
@@ -5809,10 +5804,6 @@
              android:label="@string/sensor_notification_service"/>
     <!-- Attribution for Twilight service. -->
     <attribution android:tag="TwilightService" android:label="@string/twilight_service"/>
-    <!-- Attribution for the Offline LocationTimeZoneProvider, used to detect time zone using
-         on-device data -->
-    <attribution android:tag="OfflineLocationTimeZoneProviderService"
-                 android:label="@string/offline_location_time_zone_detection_service_attribution"/>
     <!-- Attribution for Gnss Time Update service. -->
     <attribution android:tag="GnssTimeUpdateService"
                  android:label="@string/gnss_time_update_service"/>
@@ -6292,19 +6283,6 @@
             </intent-filter>
         </service>
 
-        <!-- AOSP configures a default secondary LocationTimeZoneProvider that uses an on-device
-             data set from the com.android.geotz APEX. -->
-        <service android:name="com.android.timezone.location.provider.OfflineLocationTimeZoneProviderService"
-                 android:enabled="@bool/config_enableSecondaryLocationTimeZoneProvider"
-                 android:permission="android.permission.BIND_TIME_ZONE_PROVIDER_SERVICE"
-                 android:exported="false">
-            <intent-filter>
-                <action android:name="android.service.timezone.SecondaryLocationTimeZoneProviderService" />
-            </intent-filter>
-            <meta-data android:name="serviceVersion" android:value="1" />
-            <meta-data android:name="serviceIsMultiuser" android:value="true" />
-        </service>
-
         <provider
             android:name="com.android.server.textclassifier.IconsContentProvider"
             android:authorities="com.android.textclassifier.icons"
diff --git a/core/res/res/drawable/chooser_action_button_bg.xml b/core/res/res/drawable/chooser_action_button_bg.xml
index 18bbd93..518d51a 100644
--- a/core/res/res/drawable/chooser_action_button_bg.xml
+++ b/core/res/res/drawable/chooser_action_button_bg.xml
@@ -23,8 +23,9 @@
             android:insetRight="0dp"
             android:insetBottom="8dp">
             <shape android:shape="rectangle">
-                <corners android:radius="16dp" />
-                <solid android:color="@color/system_neutral2_100" />
+                <corners android:radius="8dp" />
+                <stroke android:width="1dp"
+                    android:color="?android:attr/colorAccentPrimaryVariant"/>
             </shape>
         </inset>
     </item>
diff --git a/core/res/res/drawable/ic_screenshot_edit.xml b/core/res/res/drawable/ic_screenshot_edit.xml
new file mode 100644
index 0000000..2d9148f
--- /dev/null
+++ b/core/res/res/drawable/ic_screenshot_edit.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24.0dp"
+    android:height="24.0dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M20.41,4.94l-1.35,-1.35c-0.78,-0.78 -2.05,-0.78 -2.83,0l0,0L3,16.82V21h4.18L20.41,7.77C21.2,6.99 21.2,5.72 20.41,4.94zM6.41,19.06L5,19v-1.36l9.82,-9.82l1.41,1.41L6.41,19.06z"/>
+</vector>
\ No newline at end of file
diff --git a/core/res/res/layout/chooser_action_button.xml b/core/res/res/layout/chooser_action_button.xml
index def429e..2b68ccc 100644
--- a/core/res/res/layout/chooser_action_button.xml
+++ b/core/res/res/layout/chooser_action_button.xml
@@ -19,13 +19,13 @@
     android:paddingStart="12dp"
     android:paddingEnd="12dp"
     android:drawablePadding="8dp"
-    android:textColor="@color/text_color_primary_device_default_light"
+    android:textColor="?android:attr/textColorPrimary"
     android:textSize="12sp"
     android:maxWidth="192dp"
     android:singleLine="true"
     android:clickable="true"
     android:background="@drawable/chooser_action_button_bg"
-    android:drawableTint="@color/text_color_primary_device_default_light"
+    android:drawableTint="?android:attr/textColorPrimary"
     android:drawableTintMode="src_in"
     style="?android:attr/borderlessButtonStyle"
     />
diff --git a/core/res/res/layout/chooser_grid.xml b/core/res/res/layout/chooser_grid.xml
index 10683b1..90caacc 100644
--- a/core/res/res/layout/chooser_grid.xml
+++ b/core/res/res/layout/chooser_grid.xml
@@ -51,6 +51,7 @@
                   android:paddingBottom="@dimen/chooser_view_spacing"
                   android:paddingLeft="24dp"
                   android:paddingRight="24dp"
+                  android:visibility="gone"
                   android:layout_below="@id/drag"
                   android:layout_centerHorizontal="true"/>
     </RelativeLayout>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 39e3021..664c314 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -614,8 +614,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ليست هناك بصمات إصبع مسجَّلة."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"لا يحتوي هذا الجهاز على مستشعِر بصمات إصبع."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"تم إيقاف جهاز الاستشعار مؤقتًا."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"لا يمكن استخدام مستشعر بصمات الإصبع. يُرجى التواصل مع مقدِّم خدمات إصلاح."</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"الإصبع <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"استخدام بصمة الإصبع"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"استخدام بصمة الإصبع أو قفل الشاشة"</string>
@@ -631,12 +630,9 @@
     <string name="face_setup_notification_content" msgid="5463999831057751676">"يمكنك فتح قفل هاتفك بمجرّد النظر إلى الشاشة."</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"إعداد المزيد من الطرق لفتح قفل الجهاز"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"انقر لإضافة بصمة إصبع."</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"فتح الجهاز ببصمة الإصبع"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"لا يمكن استخدام مستشعر بصمات الإصبع"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"يُرجى التواصل مع مقدِّم خدمات إصلاح."</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"تعذّر تسجيل بيانات دقيقة للوجه. حاول مرة أخرى."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"ساطع للغاية. تجربة مستوى سطوع أقلّ."</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"الصورة معتمة للغاية. يُرجى زيادة السطوع."</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index ad3d746..a55785f 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -602,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"কোনো ফিংগাৰপ্ৰিণ্ট যোগ কৰা নহ\'ল।"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইচটোত ফিংগাৰপ্ৰিণ্ট ছেন্সৰ নাই।"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ছেন্সৰটো সাময়িকভাৱে অক্ষম হৈ আছে।"</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰ ব্যৱহাৰ কৰিব নোৱাৰি। মেৰামতি সেৱা প্ৰদানকাৰী কোনো প্ৰতিষ্ঠানলৈ যাওক"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> আঙুলি"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ফিংগাৰপ্ৰিণ্ট অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"</string>
@@ -613,20 +612,15 @@
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ফিংগাৰপ্ৰিণ্ট আইকন"</string>
     <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"মুখাৱয়বৰ দ্বাৰা আনলক কৰাৰ সুবিধা"</string>
-    <!-- no translation found for face_recalibrate_notification_title (2524791952735579082) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_content (3064513770251355594) -->
-    <skip />
+    <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"মুখাৱয়বৰ দ্বাৰা আনলক কৰাৰ সুবিধাটোৰ ব্যৱহাৰ কৰোঁতে সমস্যা হৈছে"</string>
+    <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"আপোনাৰ মুখাৱয়বৰ মডেলটো মচিবলৈ টিপক, তাৰ পাছত পুনৰ আপোনাৰ মুখাৱয়ব যোগ দিয়ক"</string>
     <string name="face_setup_notification_title" msgid="8843461561970741790">"মুখাৱয়বৰে আনলক কৰাৰ সুবিধাটো ছেট আপ কৰক"</string>
     <string name="face_setup_notification_content" msgid="5463999831057751676">"আপোনাৰ ফ’নটোলৈ চাই সেইটো আনলক কৰক"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"আনলক কৰাৰ অধিক উপায় ছেট আপ কৰক"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"এটা ফিংগাৰপ্ৰিণ্ট যোগ দিবলৈ টিপক"</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"ফিংগাৰপ্ৰিণ্টৰ দ্বাৰা আনলক কৰা সুবিধা"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰ ব্যৱহাৰ কৰিব নোৱাৰি"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"মেৰামতি সেৱা প্ৰদানকাৰী কোনো প্ৰতিষ্ঠানলৈ যাওক।"</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"সঠিক মুখমণ্ডলৰ ডেটা কেপচাৰ নহ’ল। আকৌ চেষ্টা কৰক।"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"অতি উজ্জ্বল। ইয়াতকৈ কম পোহৰৰ উৎস ব্যৱহাৰ কৰক।"</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"অতি আন্ধাৰ। উজ্জ্বল লাইট ব্যৱহাৰ কৰক।"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 85f1b47..a9b8ccb 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -602,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Barmaq izi qeydə alınmayıb."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda barmaq izi sensoru yoxdur."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor müvəqqəti deaktivdir."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Barmaq izi sensorundan istifadə etmək mümkün deyil. Təmir provayderini ziyarət edin"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Barmaq <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Barmaq izini istifadə edin"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Barmaq izi və ya ekran kilidindən istifadə edin"</string>
@@ -619,12 +618,9 @@
     <string name="face_setup_notification_content" msgid="5463999831057751676">"Telefona baxaraq onu kiliddən çıxarın"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Kiliddən çıxarmağın daha çox yolunu ayarlayın"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Barmaq izi əlavə etmək üçün toxunun"</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Barmaq izi ilə kiliddən çıxarma"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Barmaq izi sensorundan istifadə etmək mümkün deyil"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Təmir provayderini ziyarət edin."</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"Dəqiq üz datası əldə edilmədi. Yenidən cəhd edin."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Çox işıqlıdır. Daha az işıqlı şəkli sınayın."</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"Çox qaranlıqdır. Parlaq işıqdan istifadə edin."</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 003b5e5..9c5b71f 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -608,8 +608,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Адбіткі пальцаў не зарэгістраваны."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На гэтай прыладзе няма сканера адбіткаў пальцаў."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчык часова выключаны."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Не ўдалося скарыстаць сканер адбіткаў пальцаў. Звярніцеся ў сэрвісны цэнтр."</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Палец <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Выкарыстоўваць адбітак пальца"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Выкарыстоўваць адбітак пальца ці блакіроўку экрана"</string>
@@ -625,12 +624,9 @@
     <string name="face_setup_notification_content" msgid="5463999831057751676">"Разблакіруйце свой тэлефон, паглядзеўшы на яго"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Наладзьце дадатковыя спосабы разблакіроўкі"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Націсніце, каб дадаць адбітак пальца"</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Разблакіраванне адбіткам пальца"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Не ўдалося скарыстаць сканер адбіткаў пальцаў"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Звярніцеся ў сэрвісны цэнтр."</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"Не атрымалася распазнаць твар. Паўтарыце спробу."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Занадта светла. Прыглушыце асвятленне."</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"Занадта цёмна. Павялічце асвятленне."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 5af538d..ededf28 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -602,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Keine Fingerabdrücke erfasst."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dieses Gerät hat keinen Fingerabdrucksensor."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Der Sensor ist vorübergehend deaktiviert."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Der Fingerabdrucksensor kann nicht verwendet werden. Suche einen Reparaturdienstleister auf."</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Fingerabdruck verwenden"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Fingerabdruck oder Displaysperre verwenden"</string>
@@ -619,12 +618,9 @@
     <string name="face_setup_notification_content" msgid="5463999831057751676">"Entsperre dein Smartphone, indem du es ansiehst"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Weitere Möglichkeiten zum Entsperren einrichten"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Tippe, um einen Fingerabdruck hinzuzufügen"</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Entsperrung per Fingerabdruck"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Der Fingerabdrucksensor kann nicht verwendet werden"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Suche einen Reparaturdienstleister auf."</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"Gesichtsdaten nicht gut erfasst. Erneut versuchen."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Zu hell. Schwächere Beleuchtung ausprobieren."</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"Zu dunkel. Probier eine hellere Beleuchtung aus."</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index c3172a6..6e0cdaf 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -602,7 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ez da erregistratu hatz-markarik."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Gailu honek ez du hatz-marken sentsorerik."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sentsorea aldi baterako desgaitu da."</string>
-    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Ezin da erabili hatz-marken sentsorea. Jo konponketak egiten dituen hornitzaile batenera."</string>
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Ezin da erabili hatz-marken sentsorea. Jarri harremanetan konponketak egiten dituen hornitzaile batekin."</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. hatza"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Erabili hatz-marka"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Erabili hatz-marka edo pantailaren blokeoa"</string>
@@ -620,7 +620,7 @@
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Sakatu hau hatz-marka bat gehitzeko"</string>
     <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Hatz-marka bidez desblokeatzea"</string>
     <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Ezin da erabili hatz-marken sentsorea"</string>
-    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Jo konponketak egiten dituen hornitzaile batenera."</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Jarri harremanetan konponketak egiten dituen hornitzaile batekin."</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"Ezin izan dira bildu argazkiaren datu zehatzak. Saiatu berriro."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Argi gehiegi dago. Joan toki ilunago batera."</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"Ilunegi dago. Erabili argi gehiago."</string>
@@ -2061,7 +2061,7 @@
     <string name="mmcc_illegal_ms" msgid="7509650265233909445">"SIM txartela ezin da erabili ahotsa erabiltzeko"</string>
     <string name="mmcc_illegal_me" msgid="6505557881889904915">"Telefonoa ezin da erabili ahotsa erabiltzeko"</string>
     <string name="mmcc_authentication_reject_msim_template" msgid="4480853038909922153">"Ezin da erabili <xliff:g id="SIMNUMBER">%d</xliff:g> SIM txartela"</string>
-    <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="3688508325248599657">"Ez dago <xliff:g id="SIMNUMBER">%d</xliff:g> SIM txartelik"</string>
+    <string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="3688508325248599657">"Ez dago <xliff:g id="SIMNUMBER">%d</xliff:g> SIMik"</string>
     <string name="mmcc_illegal_ms_msim_template" msgid="832644375774599327">"Ezin da erabili <xliff:g id="SIMNUMBER">%d</xliff:g> SIM txartela"</string>
     <string name="mmcc_illegal_me_msim_template" msgid="4802735138861422802">"Ezin da erabili <xliff:g id="SIMNUMBER">%d</xliff:g> SIM txartela"</string>
     <string name="popup_window_default_title" msgid="6907717596694826919">"Leiho gainerakorra"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 69daf30..57b99f0 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -602,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Aucune empreinte digitale enregistrée."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aucun lecteur d\'empreinte digitale n\'est installé sur cet appareil."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Capteur temporairement désactivé."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Impossible d\'utiliser le lecteur d\'empreinte digitale. Contactez un réparateur"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utiliser l\'empreinte digitale"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utiliser votre empreinte digitale ou le verrouillage de l\'écran"</string>
@@ -619,12 +618,9 @@
     <string name="face_setup_notification_content" msgid="5463999831057751676">"Déverrouillez votre téléphone en le regardant"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configurer d\'autres méthodes de déverrouillage"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Appuyez pour ajouter une empreinte digitale"</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Déverrouillage par empreinte digitale"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Impossible d\'utiliser le lecteur d\'empreinte digitale"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Contactez un réparateur."</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"Capture du visage impossible. Réessayez."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Trop lumineux. Essayez de baisser la lumière."</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"Trop sombre. Essayez une éclairage plus lumineux."</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 6dcb8ef5..7ebd2d9 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -613,10 +613,8 @@
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ફિંગરપ્રિન્ટ આયકન"</string>
     <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"ફેસ અનલૉક"</string>
-    <!-- no translation found for face_recalibrate_notification_title (2524791952735579082) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_content (3064513770251355594) -->
-    <skip />
+    <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"ફેસ અનલૉકની સુવિધામાં સમસ્યા"</string>
+    <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"તમારા ચહેરાનું મૉડલ ડિલીટ કરવા માટે ટૅપ કરો, પછી તમારો ચહેરો ફરીથી ઉમેરો"</string>
     <string name="face_setup_notification_title" msgid="8843461561970741790">"ફેસ અનલૉક સુવિધાનું સેટઅપ કરો"</string>
     <string name="face_setup_notification_content" msgid="5463999831057751676">"તમારા ફોનની તરફ જોઈને તેને અનલૉક કરો"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"અનલૉક કરવાની બીજી રીતોનું સેટઅપ કરો"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 9a205dd..6aa2570 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -176,9 +176,9 @@
     <string name="contentServiceSync" msgid="2341041749565687871">"समन्वयन"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="5766411446676388623">"सिंक नहीं किया जा सकता"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="4562226280528716090">"बहुत ज़्यादा <xliff:g id="CONTENT_TYPE">%s</xliff:g> मिटाने की कोशिश की गई."</string>
-    <string name="low_memory" product="tablet" msgid="5557552311566179924">"टैबलेट की मेमोरी भर गई है. जगह खाली करने के लिए कुछ फ़ाइलें मिटाएं."</string>
-    <string name="low_memory" product="watch" msgid="3479447988234030194">"घड़ी की मेमोरी भर गई है. स्‍थान खाली करने के लिए कुछ फ़ाइलें मिटाएं."</string>
-    <string name="low_memory" product="tv" msgid="6663680413790323318">"Android TV डिवाइस की मेमोरी में जगह नहीं बची है. जगह बनाने के लिए कुछ फाइलें मिटाएं."</string>
+    <string name="low_memory" product="tablet" msgid="5557552311566179924">"टैबलेट का स्टोरेज भर गया है. जगह खाली करने के लिए कुछ फ़ाइलें मिटाएं."</string>
+    <string name="low_memory" product="watch" msgid="3479447988234030194">"घड़ी का स्टोरेज भर गया है. स्‍थान खाली करने के लिए कुछ फ़ाइलें मिटाएं."</string>
+    <string name="low_memory" product="tv" msgid="6663680413790323318">"Android TV डिवाइस के स्टोरेज में जगह नहीं बची है. जगह बनाने के लिए कुछ फाइलें मिटाएं."</string>
     <string name="low_memory" product="default" msgid="2539532364144025569">"फ़ोन मेमोरी भर गयी है. जगह खाली करने के लिए कुछ फ़ाइलें मिटाएं."</string>
     <plurals name="ssl_ca_cert_warning" formatted="false" msgid="2288194355006173029">
       <item quantity="one">प्रमाणपत्र अनुमतियों को इंस्टॉल किया गया</item>
@@ -408,9 +408,9 @@
     <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"यह ऐप्लिकेशन को सिस्टम के शुरू होने की प्रक्रिया पूरा होते ही अपने आप चालू होने की अनुमति देता है. इससे आपके Android TV डिवाइस को चालू होने में ज़्यादा समय लग सकता है और ऐप्लिकेशन के हमेशा चालू रहने की वजह से आपके टीवी की परफ़ॉर्मेंस पर असर पड़ सकता है."</string>
     <string name="permdesc_receiveBootCompleted" product="default" msgid="7912677044558690092">"सिस्‍टम के चालू होते ही ऐप को अपने आप शुरू होने देती है. इससे फ़ोन को चालू होने में ज़्यादा समय लग सकता है और ऐप के लगातार चलते रहने से पूरा फ़ोन धीमा हो सकता है."</string>
     <string name="permlab_broadcastSticky" msgid="4552241916400572230">"स्टिकी प्रसारण भेजें"</string>
-    <string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"ऐप्स को स्‍टिकी प्रसारण भेजने देता है, जो प्रसारण खत्म होने के बाद भी बने रहते हैं. अत्यधिक उपयोग, टैबलेट की बहुत ज़्यादा मेमोरी का उपयोग करके उसे धीमा या अस्‍थिर कर सकता है."</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"ऐप्स को स्‍टिकी प्रसारण भेजने देता है, जो प्रसारण खत्म होने के बाद भी बने रहते हैं. अत्यधिक उपयोग, टैबलेट की बहुत ज़्यादा स्टोरेज का उपयोग करके उसे धीमा या अस्‍थिर कर सकता है."</string>
     <string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"यह ऐप्लिकेशन को स्टिकी ब्रॉडकास्ट भेजने की अनुमति देता है जो ब्रॉडकास्ट खत्म होने के बाद भी बने रहते हैं. इस सुविधा के ज़्यादा इस्तेमाल से आपके Android TV डिवाइस की मेमोरी कम हो सकती है जिससे टीवी की परफ़ॉर्मेंस पर असर पड़ सकता है और उसे इस्तेमाल करने में समस्याएं आ सकती हैं."</string>
-    <string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"ऐप्स को स्‍टिकी प्रसारण भेजने देता है, जो प्रसारण खत्म होने के बाद भी बने रहते हैं. अत्यधिक उपयोग, फ़ोन की बहुत ज़्यादा मेमोरी का उपयोग करके उसे धीमा या अस्‍थिर कर सकता है."</string>
+    <string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"ऐप्स को स्‍टिकी प्रसारण भेजने देता है, जो प्रसारण खत्म होने के बाद भी बने रहते हैं. अत्यधिक उपयोग, फ़ोन की बहुत ज़्यादा स्टोरेज का उपयोग करके उसे धीमा या अस्‍थिर कर सकता है."</string>
     <string name="permlab_readContacts" msgid="8776395111787429099">"अपने संपर्क पढ़ें"</string>
     <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"यह ऐप्लिकेशन को आपके टैबलेट पर मौजूद संपर्कों का डेटा देखने की अनुमति देता है. ऐप्लिकेशन को आपके टैबलेट पर मौजूद उन खातों को ऐक्सेस करने की अनुमति भी होगी जिनसे संपर्क बनाए गए हैं. इसमें वे खाते भी शामिल हो सकते हैं जिन्हें आपके इंस्टॉल किए हुए ऐप्लिकेशन ने बनाया है. इस अनुमति के बाद, ऐप्लिकेशन आपके संपर्कों का डेटा सेव कर सकते हैं. हालांकि, नुकसान पहुंचाने वाले ऐप्लिकेशन, आपको बताए बिना ही संपर्कों का डेटा शेयर कर सकते हैं."</string>
     <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"यह ऐप्लिकेशन को आपके Android TV डिवाइस पर सेव किए संपर्कों का डेटा देखने की अनुमति देता है. ऐप्लिकेशन को आपके Android TV डिवाइस पर मौजूद उन खातों को ऐक्सेस करने की अनुमति भी होगी जिनसे संपर्क बनाए गए हैं. इसमें वे खाते भी शामिल हो सकते हैं जिन्हें आपके इंस्टॉल किए हुए ऐप्लिकेशन ने बनाया है. इस अनुमति के बाद, ऐप्लिकेशन आपके संपर्कों का डेटा सेव कर सकते हैं. हालांकि, नुकसान पहुंचाने वाले ऐप्लिकेशन, आपको बताए बिना ही संपर्कों का डेटा शेयर कर सकते हैं."</string>
@@ -602,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कोई फ़िंगरप्रिंट रजिस्टर नहीं किया गया है."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"इस डिवाइस में फ़िंगरप्रिंट सेंसर नहीं है."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेंसर कुछ समय के लिए बंद कर दिया गया है."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"फ़िंगरप्रिंट सेंसर इस्तेमाल नहीं किया जा सकता. रिपेयर की सेवा देने वाली कंपनी से संपर्क करें"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"फ़िंगरप्रिंट <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फ़िंगरप्रिंट इस्तेमाल करें"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फ़िंगरप्रिंट या स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string>
@@ -613,18 +612,15 @@
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"फ़िंगरप्रिंट आइकॉन"</string>
     <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"फ़ेस अनलॉक"</string>
-    <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"फ़ेस अनलॉक के साथ कोई समस्या है"</string>
+    <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"फ़ेस अनलॉक से जुड़ी समस्या"</string>
     <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"अपने चेहरे का मॉडल मिटाने के लिए टैप करें. इसके बाद, अपना चेहरा फिर से रजिस्टर करें"</string>
     <string name="face_setup_notification_title" msgid="8843461561970741790">"फे़स अनलॉक की सुविधा सेट अप करें"</string>
     <string name="face_setup_notification_content" msgid="5463999831057751676">"अपने फ़ोन की तरफ़ देखकर उसे अनलॉक करें"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"फ़ोन को अनलॉक करने के दूसरे तरीके सेट अप करें"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"फ़िंगरप्रिंट जोड़ने के लिए टैप करें"</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"फ़िंगरप्रिंट अनलॉक"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"फ़िंगरप्रिंट सेंसर इस्तेमाल नहीं किया जा सकता"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"फ़िंगरप्रिंट सेंसर को रिपेयर करने की सेवा देने वाली कंपनी से संपर्क करें."</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"चेहरे से जुड़ा सटीक डेटा कैप्चर नहीं किया जा सका. फिर से कोशिश करें."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"बहुत रोशनी है. हल्की रोशनी आज़माएं."</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"बहुत अंधेरा है. बेहतर रोशनी में आज़माएं."</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 5aacfa71..874d56d 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -608,8 +608,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"לא נסרקו טביעות אצבע."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"במכשיר הזה אין חיישן טביעות אצבע."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"החיישן מושבת באופן זמני."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"לא ניתן להשתמש בחיישן טביעות האצבע. צריך ליצור קשר עם ספק תיקונים"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"אצבע <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"שימוש בטביעת אצבע"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"שימוש בטביעת אצבע או בנעילת מסך"</string>
@@ -625,12 +624,9 @@
     <string name="face_setup_notification_content" msgid="5463999831057751676">"יש להביט בטלפון כדי לבטל את נעילתו"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"אפשר להגדיר דרכים נוספות לביטול נעילה"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"יש להקיש כדי להוסיף טביעת אצבע"</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"ביטול הנעילה בטביעת אצבע"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"לא ניתן להשתמש בחיישן טביעות האצבע"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"צריך ליצור קשר עם ספק תיקונים."</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"לא ניתן היה לקלוט את הפנים במדויק. יש לנסות שוב."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"בהירה מדי. צריך תאורה עדינה יותר."</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"התמונה חשוכה מדי. צריך תאורה חזקה יותר."</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 8a68fb9..d6950dee 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -602,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"თითის ანაბეჭდები რეგისტრირებული არ არის."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ამ მოწყობილობას არ აქვს თითის ანაბეჭდის სენსორი."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"სენსორი დროებით გათიშულია."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"თითის ანაბეჭდის სენსორის გამოყენება ვერ ხერხდება. ეწვიეთ შეკეთების სერვისის პროვაიდერს"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"თითი <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"გამოიყენეთ თითის ანაბეჭდი"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"გამოიყენეთ თითის ანაბეჭდი ან ეკრანის დაბლოკვა"</string>
@@ -619,12 +618,9 @@
     <string name="face_setup_notification_content" msgid="5463999831057751676">"განბლოკეთ თქვენი ტელეფონი შეხედვით"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"დააყენეთ განბლოკვის სხვა ხერხები"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"შეეხეთ თითის ანაბეჭდის დასამატებლად"</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"თითის ანაბეჭდით განბლოკვა"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"თითის ანაბეჭდის სენსორის გამოყენება ვერ ხერხდება"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"ეწვიეთ შეკეთების სერვისის პროვაიდერს."</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"სახის ზუსტი მონაცემები არ აღიბეჭდა. ცადეთ ხელახლა."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"მეტისმეტად ნათელია. ცადეთ უფრო სუსტი განათება."</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"მეტისმეტად ბნელია. ცადეთ უფრო ძლიერი განათება."</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index df6a2aa..9a283e6 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -602,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Саусақ іздері тіркелмеген."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бұл құрылғыда саусақ ізін оқу сканері жоқ."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик уақытша өшірулі."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Саусақ ізін оқу сканерін пайдалану мүмкін емес. Жөндеу қызметіне барыңыз."</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-саусақ"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Саусақ ізін пайдалану"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Саусақ ізін немесе экран құлпын пайдалану"</string>
@@ -619,12 +618,9 @@
     <string name="face_setup_notification_content" msgid="5463999831057751676">"Телефоныңызға қарап, оның құлпын ашыңыз."</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Құлыпты ашудың басқа тәсілдерін реттеу"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Саусақ ізін қосу үшін түртіңіз."</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Құлыпты саусақ ізімен ашу"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Саусақ ізін оқу сканерін пайдалану мүмкін емес"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Жөндеу қызметіне барыңыз."</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"Бет деректері дұрыс алынбады. Әрекетті қайталаңыз."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Тым ашық. Күңгірттеу жарық керек."</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"Тым қараңғы. Молырақ жарық керек."</string>
@@ -2103,7 +2099,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Жарайды"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Өшіру"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Толығырақ"</string>
-    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 жүйесінде кеңейтілген хабарландырулар функциясы бейімделетін хабарландырулар функциясын алмастырды. Бұл функция ұсынылған әрекеттер мен жауаптарды көрсетіп, хабарландыруларыңызды ретке келтіреді.\n\nОл хабарландыру мазмұнын, соның ішінде жеке ақпаратыңызды (мысалы, контакт аттары мен хабарлар) пайдалана алады. Сондай-ақ бұл функция арқылы хабарландыруларды жабуға немесе оларға жауап беруге (мысалы, телефон қоңырауларына жауап беру және \"Мазаламау\" режимін басқару) болады."</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 жүйесінде кеңейтілген хабарландырулар функциясы бейімделетін хабарландырулар функциясын алмастырды. Бұл функция ұсынылған әрекеттер мен жауаптарды көрсетіп, хабарландыруларыңызды ретке келтіреді.\n\nОл хабарландыру мазмұнын, соның ішінде жеке ақпаратыңызды (мысалы, контакт аттары мен хабарлар) пайдалана алады. Сондай-ақ бұл функция арқылы хабарландыруларды жабуға немесе оларға жауап беруге (мысалы, телефон қоңырауларына жауап беру және Мазаламау режимін басқару) болады."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Режим туралы хабарландыру"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батарея заряды азаюы мүмкін"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Батарея ұзаққа жетуі үшін, Батареяны үнемдеу режимі іске қосылды"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 17b550db..2172553 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -228,7 +228,7 @@
     <string name="reboot_to_update_prepare" msgid="6978842143587422365">"ಅಪ್‌ಡೇಟೇ ಮಾಡಲು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ..."</string>
     <string name="reboot_to_update_package" msgid="4644104795527534811">"ಅಪ್‌ಡೇಟ್ ಪ್ಯಾಕೇಜ್ ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲಾಗುತ್ತಿದೆ…"</string>
     <string name="reboot_to_update_reboot" msgid="4474726009984452312">"ಮರುಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ..."</string>
-    <string name="reboot_to_reset_title" msgid="2226229680017882787">"ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾ ಮರುಹೊಂದಿಕೆ"</string>
+    <string name="reboot_to_reset_title" msgid="2226229680017882787">"ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾ ರೀಸೆಟ್"</string>
     <string name="reboot_to_reset_message" msgid="3347690497972074356">"ಮರುಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ..."</string>
     <string name="shutdown_progress" msgid="5017145516412657345">"ಸ್ಥಗಿತಗೊಳ್ಳುತ್ತಿದೆ…"</string>
     <string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಸ್ಥಗಿತಗೊಳ್ಳುತ್ತದೆ."</string>
@@ -602,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ಯಾವುದೇ ಫಿಂಗರ್‌ಪ್ರಿಂಟ್‌ ಅನ್ನು ನೋಂದಣಿ ಮಾಡಿಲ್ಲ."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ಈ ಸಾಧನವು ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್‌‌ ಅನ್ನು ಹೊಂದಿಲ್ಲ."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ಸೆನ್ಸಾರ್ ಅನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಅನ್ನು ಬಳಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ರಿಪೇರಿ ಮಾಡುವವರನ್ನು ಸಂಪರ್ಕಿಸಿ"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ಫಿಂಗರ್ <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಬಳಸಿ"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ಫಿಂಗರ್‌ ಪ್ರಿಂಟ್ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಬಳಸಿ"</string>
@@ -619,12 +618,9 @@
     <string name="face_setup_notification_content" msgid="5463999831057751676">"ಫೋನ್ ಅನ್ನು ನೋಡುವ ಮೂಲಕ ಅನ್‌ಲಾಕ್‌ ಮಾಡಿ"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"ಅನ್‌ಲಾಕ್ ಮಾಡಲು ಹೆಚ್ಚಿನ ಮಾರ್ಗಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"ಫಿಂಗರ್‌ ಪ್ರಿಂಟ್ ಸೇರಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್‌ಲಾಕ್"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಅನ್ನು ಬಳಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"ರಿಪೇರಿ ಮಾಡುವವರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"ಸರಿಯಾಗಿ ಮುಖ ಕ್ಯಾಪ್ಚರ್ ಮಾಡಲಾಗಲಿಲ್ಲ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"ತುಂಬಾ ಪ್ರಕಾಶಮಾನವಾಗಿದೆ ಮಂದ ಪ್ರಕಾಶಮಾನವಿರುವ ಲೈಟ್ ಬಳಸಿ"</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"ತುಂಬಾ ಕಪ್ಪು ಛಾಯೆಯಿದೆ. ಪ್ರಕಾಶಮಾನವಾದ ಲೈಟಿಂಗ್ ಬಳಸಿ."</string>
@@ -741,9 +737,9 @@
     <string name="policylab_forceLock" msgid="7360335502968476434">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಮಾಡಿ"</string>
     <string name="policydesc_forceLock" msgid="1008844760853899693">"ಪರದೆಯು ಯಾವಾಗ ಮತ್ತು ಹೇಗೆ ಲಾಕ್ ಆಗಬೇಕೆಂಬುದನ್ನು ನಿಯಂತ್ರಿಸಿ."</string>
     <string name="policylab_wipeData" msgid="1359485247727537311">"ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಅಳಿಸಿ"</string>
-    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾ ಮರುಹೊಂದಿಕೆಯನ್ನು ನಿರ್ವಹಿಸುವ ಮೂಲಕ ಎಚ್ಚರಿಕೆಯನ್ನು ನೀಡದೆಯೇ ಟ್ಯಾಬ್ಲೆಟ್ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕಿ."</string>
-    <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾ ಮರುಹೊಂದಿಕೆ ಮಾಡುವ ಮೂಲಕ ಎಚ್ಚರಿಕೆ ಇಲ್ಲದೆ ನಿಮ್ಮ Android TV ಸಾಧನದ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕುತ್ತದೆ."</string>
-    <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾ ಮರುಹೊಂದಿಕೆಯನ್ನು ನಿರ್ವಹಿಸುವ ಮೂಲಕ ಎಚ್ಚರಿಕೆಯನ್ನು ನೀಡದೆಯೇ ಫೋನ್ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕಿ."</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾ ರೀಸೆಟ್ ಅನ್ನು ನಿರ್ವಹಿಸುವ ಮೂಲಕ ಎಚ್ಚರಿಕೆಯನ್ನು ನೀಡದೆಯೇ ಟ್ಯಾಬ್ಲೆಟ್ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕಿ."</string>
+    <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾ ರೀಸೆಟ್ ಮಾಡುವ ಮೂಲಕ ಎಚ್ಚರಿಕೆ ಇಲ್ಲದೆ ನಿಮ್ಮ Android TV ಸಾಧನದ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕುತ್ತದೆ."</string>
+    <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾ ರೀಸೆಟ್ ಅನ್ನು ನಿರ್ವಹಿಸುವ ಮೂಲಕ ಎಚ್ಚರಿಕೆಯನ್ನು ನೀಡದೆಯೇ ಫೋನ್ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕಿ."</string>
     <string name="policylab_wipeData_secondaryUser" msgid="413813645323433166">"ಬಳಕೆದಾರ ಡೇಟಾ ಅಳಿಸಿ"</string>
     <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"ಯಾವುದೇ ಸೂಚನೆ ಇಲ್ಲದೆ ಈ ಟ್ಯಾಬ್ಲೆಟ್‌ನಲ್ಲಿ ಈ ಬಳಕೆದಾರರ ಡೇಟಾವನ್ನು ಅಳಿಸಿ."</string>
     <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"ಎಚ್ಚರಿಕೆ ಇಲ್ಲದೆ ಈ Android TV ಸಾಧನದಲ್ಲಿನ ಈ ಬಳಕೆದಾರರ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕುತ್ತದೆ."</string>
@@ -921,9 +917,9 @@
     <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"ನಿಮ್ಮ ಅನ್‌ಲಾಕ್‌ ನಮೂನೆಯನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಚಿತ್ರಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು ಬಾರಿ ವಿಫಲ ಪ್ರಯತ್ನಗಳನ್ನು ಮಾಡಿರುವಿರಿ, Google ಸೈನ್‌ ಇನ್‌ ಬಳಸಿಕೊಂಡು ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌‌‌ ಅನ್‌ಲಾಕ್‌ ಮಾಡಲು ನಿಮ್ಮನ್ನು ಕೇಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"ನಿಮ್ಮ ಅನ್‌ಲಾಕ್‌ ನಮೂನೆಯನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಚಿತ್ರಿಸಿರುವಿರಿ. ಇನ್ನೂ <xliff:g id="NUMBER_1">%2$d</xliff:g> ಬಾರಿಯ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ನಿಮ್ಮ Google ಸೈನ್‌ ಇನ್‌ ಬಳಸಿಕೊಂಡು ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು ಅನ್‌ಲಾಕ್‌ ಮಾಡಲು ನಿಮ್ಮನ್ನು ಕೇಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"ನಿಮ್ಮ ಅನ್‌ಲಾಕ್‌ ನಮೂನೆಯನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಚಿತ್ರಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು ಬಾರಿ ವಿಫಲ ಪ್ರಯತ್ನಗಳನ್ನು ಮಾಡಿರುವಿರಿ, Google ಸೈನ್‌ ಇನ್‌ ಬಳಸಿಕೊಂಡು ನಿಮ್ಮ ಫೋನ್‌ ಅನ್‌ಲಾಕ್‌ ಮಾಡಲು ನಿಮ್ಮನ್ನು ಕೇಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಅನ್‍‍ಲಾಕ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಬಾರಿಯ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ಮರುಹೊಂದಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"ಫೋನ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಫೋನ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ರೀಸೆಟ್ ಮಾಡಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಅನ್‍‍ಲಾಕ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಬಾರಿಯ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ರೀಸೆಟ್ ಮಾಡಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"ಫೋನ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಫೋನ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ರೀಸೆಟ್ ಮಾಡಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಇದೀಗ ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಅನ್‍‍ಲಾಕ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಇದೀಗ ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ಮರುಹೊಂದಿಸಲಾಗುತ್ತದೆ."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"ಫೋನ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. ಫೋನ್ ಅನ್ನು ಇದೀಗ ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ."</string>
@@ -1679,9 +1675,9 @@
     <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"ನಿಮ್ಮ ಪಿನ್‌ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿರುವಿರಿ. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"ನಿಮ್ಮ ಪಾಸ್‍‍ವರ್ಡ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿರುವಿರಿ. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"ನಿಮ್ಮ ಅನ್‍‍ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಚಿತ್ರಿಸಿರುವಿರಿ. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ಬಳಿಕ, ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಅನ್‍‍ಲಾಕ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಬಾರಿಯ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ಮರುಹೊಂದಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"ಫೋನ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g>  ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಫೋನ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಬಳಕೆದಾರರ ಎಲ್ಲಾ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ಬಳಿಕ, ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ರೀಸೆಟ್ ಮಾಡಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಅನ್‍‍ಲಾಕ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಬಾರಿಯ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ರೀಸೆಟ್ ಮಾಡಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"ಫೋನ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g>  ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಫೋನ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ರೀಸೆಟ್ ಮಾಡಲಾಗುತ್ತದೆ ಮತ್ತು ಬಳಕೆದಾರರ ಎಲ್ಲಾ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಇದೀಗ ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಅನ್‍‍ಲಾಕ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಇದೀಗ ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್‌ಗೆ ಮರುಹೊಂದಿಸಲಾಗುತ್ತದೆ."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"ಫೋನ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. ಫೋನ್ ಅನ್ನು ಇದೀಗ ಫ್ಯಾಕ್ಟರಿ ಢೀಫಾಲ್ಟ್‌ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ."</string>
@@ -1928,7 +1924,7 @@
     <string name="zen_mode_default_events_name" msgid="2280682960128512257">"ಈವೆಂಟ್"</string>
     <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"ನಿದ್ರೆಯ ಸಮಯ"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ಧ್ವನಿ ಮ್ಯೂಟ್ ಮಾಡುತ್ತಿದ್ದಾರೆ"</string>
-    <string name="system_error_wipe_data" msgid="5910572292172208493">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಆಂತರಿಕ ಸಮಸ್ಯೆಯಿದೆ ಹಾಗೂ ನೀವು ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾವನ್ನು ಮರುಹೊಂದಿಸುವರೆಗೂ ಅದು ಅಸ್ಥಿರವಾಗಬಹುದು."</string>
+    <string name="system_error_wipe_data" msgid="5910572292172208493">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಆಂತರಿಕ ಸಮಸ್ಯೆಯಿದೆ ಹಾಗೂ ನೀವು ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾವನ್ನು ರೀಸೆಟ್ ಮಾಡುವವರೆಗೂ ಅದು ಅಸ್ಥಿರವಾಗಬಹುದು."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಆಂತರಿಕ ಸಮಸ್ಯೆಯಿದೆ. ವಿವರಗಳಿಗಾಗಿ ನಿಮ್ಮ ತಯಾರಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
     <string name="stk_cc_ussd_to_dial" msgid="3139884150741157610">"USSD ವಿನಂತಿಯನ್ನು ಸಾಮಾನ್ಯ ಕರೆಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ"</string>
     <string name="stk_cc_ussd_to_ss" msgid="4826846653052609738">"USSD ವಿನಂತಿಯನ್ನು SS ವಿನಂತಿಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 820a79c..fb79335 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -602,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Бир да манжа изи катталган эмес."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бул түзмөктө манжа изинин сенсору жок."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сенсор убактылуу өчүрүлгөн."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Манжа изинин сенсорун колдонууга болбойт. Тейлөө кызматына кайрылыңыз"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-манжа"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Манжа изин колдонуу"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Манжа изин же экрандын кулпусун колдонуу"</string>
@@ -619,12 +618,9 @@
     <string name="face_setup_notification_content" msgid="5463999831057751676">"Телефонуңузду карап туруп эле кулпусун ачып алыңыз"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Кулпусун ачуунун көбүрөөк жолдорун жөндөңүз"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Манжа изин кошуу үчүн басыңыз"</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Кулпуланган түзмөктү манжа изи менен ачуу"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Манжа изинин сенсорун колдонууга болбойт"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Тейлөө кызматына кайрылыңыз."</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"Жүзүңүз жакшы тартылган жок. Кайталап көрүңүз."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Өтө жарык. Жарыктыкты азайтып көрүңүз."</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"Өтө караңгы. Жарыгыраак жерден тартып көрүңүз."</string>
diff --git a/core/res/res/values-mcc310-mnc170-eu/strings.xml b/core/res/res/values-mcc310-mnc170-eu/strings.xml
index 7cffce7..76e30b0 100644
--- a/core/res/res/values-mcc310-mnc170-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc170-eu/strings.xml
@@ -20,7 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="5424518490295341205">"Ez dago SIM txartelik MM#2"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="5424518490295341205">"Ez dago SIMik MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="3527626511418944853">"Ez da onartzen SIM txartela MM#3"</string>
     <string name="mmcc_illegal_me" msgid="3948912590657398489">"Telefonoa ez da onartzen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc280-eu/strings.xml b/core/res/res/values-mcc310-mnc280-eu/strings.xml
index a2f0130..fbf7044 100644
--- a/core/res/res/values-mcc310-mnc280-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc280-eu/strings.xml
@@ -20,7 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="1070849538022865416">"Ez dago SIM txartelik MM#2"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="1070849538022865416">"Ez dago SIMik MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="499832197298480670">"Ez da onartzen SIM txartela MM#3"</string>
     <string name="mmcc_illegal_me" msgid="2346111479504469688">"Telefonoa ez da onartzen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc380-eu/strings.xml b/core/res/res/values-mcc310-mnc380-eu/strings.xml
index 0f2ae51b..c3fb1bc 100644
--- a/core/res/res/values-mcc310-mnc380-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc380-eu/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="mmcc_imsi_unknown_in_hlr" msgid="6178029798083341927">"Ez dago SIM txartelik MM#2"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="6178029798083341927">"Ez dago SIMik MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="6084322234976891423">"Ez da onartzen SIM txartela MM#3"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410-eu/strings.xml b/core/res/res/values-mcc310-mnc410-eu/strings.xml
index a41129a..b023bcc 100644
--- a/core/res/res/values-mcc310-mnc410-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc410-eu/strings.xml
@@ -20,7 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="8861901652350883183">"Ez dago SIM txartelik MM#2"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="8861901652350883183">"Ez dago SIMik MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="2604694337529846283">"Ez da onartzen SIM txartela MM#3"</string>
     <string name="mmcc_illegal_me" msgid="3099618295079374317">"Telefonoa ez da onartzen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc950-eu/strings.xml b/core/res/res/values-mcc310-mnc950-eu/strings.xml
index 355b551..5a34371 100644
--- a/core/res/res/values-mcc310-mnc950-eu/strings.xml
+++ b/core/res/res/values-mcc310-mnc950-eu/strings.xml
@@ -20,7 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="615419724607901560">"Ez dago SIM txartelik MM#2"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="615419724607901560">"Ez dago SIMik MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="7801541624846497489">"Ez da onartzen SIM txartela MM#3"</string>
     <string name="mmcc_illegal_me" msgid="7066936962628406316">"Telefonoa ez da onartzen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc180-eu/strings.xml b/core/res/res/values-mcc311-mnc180-eu/strings.xml
index f5d7afb..d843c4f 100644
--- a/core/res/res/values-mcc311-mnc180-eu/strings.xml
+++ b/core/res/res/values-mcc311-mnc180-eu/strings.xml
@@ -20,7 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="mmcc_imsi_unknown_in_hlr" msgid="604133804161351810">"Ez dago SIM txartelik MM#2"</string>
+    <string name="mmcc_imsi_unknown_in_hlr" msgid="604133804161351810">"Ez dago SIMik MM#2"</string>
     <string name="mmcc_illegal_ms" msgid="4073997279280371621">"Ez da onartzen SIM txartela MM#3"</string>
     <string name="mmcc_illegal_me" msgid="4936539345546223576">"Telefonoa ez da onartzen MM#6"</string>
 </resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 929d032..69c803d 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -602,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कुनै पनि फिंगरप्रिन्ट दर्ता गरिएको छैन।"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"यो डिभाइसमा कुनै पनि फिंगरप्रिन्ट सेन्सर छैन।"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"केही समयका लागि सेन्सर असक्षम पारियो।"</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"फिंगरप्रिन्ट सेन्सर प्रयोग गर्न मिल्दैन। फिंगरप्रिन्ट सेन्सर मर्मत गर्ने सेवा प्रदायक कम्पनीमा सम्पर्क गर्नुहोस्"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"औंला <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फिंगरप्रिन्ट प्रयोग गर्नुहोस्"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फिंगरप्रिन्ट वा स्क्रिन लक प्रयोग गर्नुहोस्"</string>
@@ -613,20 +612,15 @@
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"फिंगरप्रिन्ट आइकन"</string>
     <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"फेस अनलक"</string>
-    <!-- no translation found for face_recalibrate_notification_title (2524791952735579082) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_content (3064513770251355594) -->
-    <skip />
+    <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"फेस अनलक सुविधामा अनुहार दर्ता गर्ने क्रममा त्रुटि भयो"</string>
+    <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"आफ्नो फेस मोडेल मेटाउन ट्याप गर्नुहोस् अनि आफ्नो अनुहार फेरि दर्ता गर्नुहोस्"</string>
     <string name="face_setup_notification_title" msgid="8843461561970741790">"फेस अनलक सेटअप गर्नुहोस्"</string>
     <string name="face_setup_notification_content" msgid="5463999831057751676">"फोनमा हेरेकै भरमा फोन अनलक गर्नुहोस्"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"अनलक गर्ने अन्य तरिकाहरू सेटअप गर्नुहोस्"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"फिंगरप्रिन्ट हाल्न ट्याप गर्नुहोस्"</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"फिंगरप्रिन्ट अनलक"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"फिंगरप्रिन्ट सेन्सर प्रयोग गर्न मिल्दैन"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"फिंगरप्रिन्ट सेन्सर मर्मत गर्ने सेवा प्रदायक कम्पनीमा सम्पर्क गर्नुहोस्।"</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"अनुहारको सटीक डेटा खिच्न सकिएन। फेरि प्रयास गर्नुहोस्।"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"ज्यादै चम्किलो। अझ मधुरो प्रकाश प्रयोग गरी हेर्नु…"</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"ज्यादै अँध्यारो छ। अझ बढी प्रकाशमा गई हेर्नुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 7401212..867bb85 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1717,7 +1717,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sneltoets gebruiken"</string>
     <string name="color_inversion_feature_name" msgid="326050048927789012">"Kleurinversie"</string>
     <string name="color_correction_feature_name" msgid="3655077237805422597">"Kleurcorrectie"</string>
-    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Bediening met één hand"</string>
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Bediening met 1 hand"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra gedimd"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> staat aan."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> staat uit."</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 7885f67..277e0a5 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -602,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"କୌଣସି ଆଙ୍ଗୁଠି ଚିହ୍ନ ପଞ୍ଜୀକୃତ ହୋଇନାହିଁ।"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ଏହି ଡିଭାଇସ୍‌ରେ ଟିପଚିହ୍ନ ସେନ୍‍ସର୍ ନାହିଁ।"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ସେନ୍ସରକୁ ଅସ୍ଥାୟୀ ଭାବେ ଅକ୍ଷମ କରାଯାଇଛି।"</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ଟିପଚିହ୍ନ ସେନ୍ସରକୁ ବ୍ୟବହାର କରାଯାଇପାରିବ ନାହିଁ। ଏକ ମରାମତି କେନ୍ଦ୍ରକୁ ଭିଜିଟ୍ କରନ୍ତୁ"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ଆଙ୍ଗୁଠି <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ଟିପଚିହ୍ନ ବା ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
@@ -619,12 +618,9 @@
     <string name="face_setup_notification_content" msgid="5463999831057751676">"ଫୋନକୁ ଦେଖି ଏହାକୁ ଅନଲକ୍ କରନ୍ତୁ"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"ଅନଲକ୍ କରିବା ପାଇଁ ଆହୁରି ଅଧିକ ଉପାୟ ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"ଏକ ଟିପଚିହ୍ନ ଯୋଗ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"ଫିଙ୍ଗରପ୍ରିଣ୍ଟ ଅନଲକ୍"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"ଟିପଚିହ୍ନ ସେନ୍ସରକୁ ବ୍ୟବହାର କରାଯାଇପାରିବ ନାହିଁ"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"ଏକ ମରାମତି କେନ୍ଦ୍ରକୁ ଭିଜିଟ୍ କରନ୍ତୁ।"</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"ମୁହଁର ଡାଟା କ୍ୟାପଚର୍ ହେଲାନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"ଅତ୍ୟଧିକ ଉଜ୍ଵଳ। କମ୍ ଉଜ୍ବଳକରଣରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"ଅତ୍ୟଧିକ ଅନ୍ଧକାର। ଉଜ୍ବଳ ଲାଇଟ୍ ବ୍ୟବହାର କରନ୍ତୁ।"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index f5f8a55..ea94b05 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -613,10 +613,8 @@
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਪ੍ਰਤੀਕ"</string>
     <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"ਫ਼ੇਸ ਅਣਲਾਕ"</string>
-    <!-- no translation found for face_recalibrate_notification_title (2524791952735579082) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_content (3064513770251355594) -->
-    <skip />
+    <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"ਫ਼ੇਸ ਅਣਲਾਕ ਨਾਲ ਸਮੱਸਿਆ"</string>
+    <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"ਆਪਣੇ ਚਿਹਰੇ ਦਾ ਮਾਡਲ ਮਿਟਾਉਣ ਲਈ ਟੈਪ ਕਰੋ, ਫਿਰ ਆਪਣਾ ਚਿਹਰਾ ਦੁਬਾਰਾ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="face_setup_notification_title" msgid="8843461561970741790">"ਫ਼ੇਸ ਅਣਲਾਕ ਦਾ ਸੈੱਟਅੱਪ ਕਰੋ"</string>
     <string name="face_setup_notification_content" msgid="5463999831057751676">"ਆਪਣੇ ਫ਼ੋਨ ਵੱਲ ਦੇਖ ਕੇ ਇਸਨੂੰ ਅਣਲਾਕ ਕਰੋ"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"ਅਣਲਾਕ ਕਰਨ ਦੇ ਹੋਰ ਤਰੀਕਿਆਂ ਦਾ ਸੈੱਟਅੱਪ ਕਰੋ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 8e0f2b4..8ff3837 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -2165,7 +2165,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Wyłącz"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Więcej informacji"</string>
-    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"W Androidzie 12 ulepszone powiadomienia zastąpiły dotychczasowe powiadomienia adaptacyjne. Ta funkcja pokazuje sugerowane działania i odpowiedzi oraz porządkuje powiadomienia.\n\nUlepszone powiadomienia mogą czytać całą zawartość powiadomień, w tym dane osobowe takie jak nazwy kontaktów i treść wiadomości. Funkcja może też zamykać powiadomienia oraz reagować na nie, np. odbierać połączenia telefoniczne i sterować trybem Nie przeszkadzać."</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"W Androidzie 12 ulepszone powiadomienia zastąpiły dotychczasowe powiadomienia adaptacyjne. Ta funkcja pokazuje sugerowane działania i odpowiedzi oraz porządkuje powiadomienia.\n\nUlepszone powiadomienia mogą czytać całą zawartość powiadomień, w tym informacje osobiste takie jak nazwy kontaktów i treść wiadomości. Funkcja może też zamykać powiadomienia oraz reagować na nie, np. odbierać połączenia telefoniczne i sterować trybem Nie przeszkadzać."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Powiadomienie z informacją o trybie rutynowym"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Bateria może się wyczerpać przed zwykłą porą ładowania"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Włączono Oszczędzanie baterii, by wydłużyć czas pracy na baterii"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 5a37821..d4befd4 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -605,8 +605,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nu au fost înregistrate amprente."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dispozitivul nu are senzor de amprentă."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzorul este dezactivat temporar."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Nu se poate folosi senzorul de amprentă. Vizitați un furnizor de servicii de reparații."</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Degetul <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Folosiți amprenta"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Folosiți amprenta sau blocarea ecranului"</string>
@@ -622,12 +621,9 @@
     <string name="face_setup_notification_content" msgid="5463999831057751676">"Deblocați-vă telefonul uitându-vă la acesta"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configurați mai multe moduri de deblocare"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Atingeți ca să adăugați o amprentă"</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Deblocare cu amprenta"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Nu se poate folosi senzorul de amprentă"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Vizitați un furnizor de servicii de reparații."</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"Nu s-a putut fotografia fața cu precizie. Încercați din nou."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Prea luminos. Încercați o lumină mai slabă."</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"Prea întunecat. Încercați o lumină mai puternică."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 6820452..e73a3c6 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -2165,7 +2165,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"ОК"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Отключить"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Подробнее"</string>
-    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"В Android 12 адаптивные уведомления заменены улучшенными. Эта функция упорядочивает все ваши уведомления и подсказывает ответы и действия.\n\nЕй доступно содержимое всех уведомлений, в том числе имена контактов, сообщения и другие личные данные. Также эта функция может закрывать уведомления и нажимать кнопки в них, например отвечать на звонки и управлять режимом \"Не беспокоить\"."</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"В Android 12 доступны улучшенные уведомления. Эта функция упорядочивает все ваши уведомления и подсказывает ответы и действия.\n\nЕй доступно содержимое всех уведомлений, в том числе имена контактов, сообщения и другие личные данные. Также эта функция может закрывать уведомления и нажимать кнопки в них, например отвечать на звонки и управлять режимом \"Не беспокоить\"."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Уведомление о батарее"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батарея может разрядиться"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Чтобы увеличить время работы от батареи, был включен режим энергосбережения."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index f44c8d8..20a8e15 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -26,7 +26,7 @@
     <string name="gigabyteShort" msgid="7515809460261287991">"GB"</string>
     <string name="terabyteShort" msgid="1822367128583886496">"TB"</string>
     <string name="petabyteShort" msgid="5651571254228534832">"PB"</string>
-    <string name="fileSizeSuffix" msgid="4233671691980131257">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="fileSizeSuffix" msgid="4233671691980131257">"<xliff:g id="NUMBER">%1$s</xliff:g>&amp;#160;<xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="untitled" msgid="3381766946944136678">"&lt;Bez mena&gt;"</string>
     <string name="emptyPhoneNumber" msgid="5812172618020360048">"(žiadne telefónne číslo)"</string>
     <string name="unknownName" msgid="7078697621109055330">"Bez názvu"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 57c1297..1a4531f 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -602,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nuk ka asnjë gjurmë gishti të regjistruar."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kjo pajisje nuk ka sensor të gjurmës së gishtit."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensori është çaktivizuar përkohësisht."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Sensori i gjurmës së gishtit nuk mund të përdoret. Vizito një ofrues të shërbimit të riparimit"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Gishti <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Përdor gjurmën e gishtit"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Përdor gjurmën e gishtit ose kyçjen e ekranit"</string>
@@ -613,18 +612,15 @@
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona e gjurmës së gishtit"</string>
     <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Shkyçja me fytyrë"</string>
-    <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Lëshoje me \"Shkyçjen me fytyrë\""</string>
+    <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problem me \"Shkyçjen me fytyrë\""</string>
     <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Trokit për të fshirë modelin tënd të fytyrës, pastaj shtoje përsëri fytyrën tënde"</string>
     <string name="face_setup_notification_title" msgid="8843461561970741790">"Konfiguro \"Shkyçjen me fytyrë\""</string>
     <string name="face_setup_notification_content" msgid="5463999831057751676">"Shkyçe telefonin duke parë tek ai"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Konfiguri më shumë mënyra për të shkyçur"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Trokit për të shtuar një gjurmë gishti"</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Shkyçja me gjurmën e gishtit"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Sensori i gjurmës së gishtit nuk mund të përdoret"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Vizito një ofrues të shërbimit të riparimit."</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"S\'mund të regjistroheshin të dhëna të sakta të fytyrës. Provo përsëri."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Me shumë ndriçim. Provo një ndriçim më të butë."</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"Shumë i errët. Provo një ndriçim më të fortë."</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 26fa15b..dd75160 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -602,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"கைரேகைப் பதிவுகள் எதுவும் இல்லை."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"இந்தச் சாதனத்தில் கைரேகை சென்சார் இல்லை."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"சென்சார் தற்காலிகமாக முடக்கப்பட்டுள்ளது."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"கைரேகை சென்சாரைப் பயன்படுத்த முடியவில்லை. பழுதுபார்ப்புச் சேவை வழங்குநரைத் தொடர்புகொள்ளவும்"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"கைரேகை <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"கைரேகையைப் பயன்படுத்து"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"கைரேகையையோ திரைப் பூட்டையோ பயன்படுத்து"</string>
@@ -619,12 +618,9 @@
     <string name="face_setup_notification_content" msgid="5463999831057751676">"மொபைலைப் பார்ப்பதன் மூலம் அதைத் திறக்கலாம்"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"திறக்க, மேலும் பல வழிகளை அமையுங்கள்"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"கைரேகையைச் சேர்க்கத் தட்டுங்கள்"</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"கைரேகை அன்லாக்"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"கைரேகை சென்சாரைப் பயன்படுத்த முடியவில்லை"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"பழுதுபார்ப்புச் சேவை வழங்குநரைத் தொடர்புகொள்ளவும்."</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"முகம் தெளிவாகப் பதிவாகவில்லை. மீண்டும் முயலவும்."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"அதிக ஒளிர்வு. மிதமான ஒளியில் முயலவும்."</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"இருட்டாக உள்ளது. பிரகாசமான ஒளியில் முயலவும்."</string>
@@ -1871,7 +1867,7 @@
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2வது பணி <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3வது பணி <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"அகற்றும் முன் PINஐக் கேள்"</string>
-    <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"அகற்றும் முன் திறத்தல் வடிவத்தைக் கேள்"</string>
+    <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"அகற்றும் முன் அன்லாக் பேட்டர்னைக் கேள்"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"அகற்றும் முன் கடவுச்சொல்லைக் கேள்"</string>
     <string name="package_installed_device_owner" msgid="7035926868974878525">"உங்கள் நிர்வாகி நிறுவியுள்ளார்"</string>
     <string name="package_updated_device_owner" msgid="7560272363805506941">"உங்கள் நிர்வாகி புதுப்பித்துள்ளார்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 6c92268..017f4cf 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -787,7 +787,7 @@
     <item msgid="7640927178025203330">"అనుకూలం"</item>
   </string-array>
   <string-array name="organizationTypes">
-    <item msgid="6144047813304847762">"కార్యాలయం"</item>
+    <item msgid="6144047813304847762">"వర్క్"</item>
     <item msgid="7402720230065674193">"ఇతరం"</item>
     <item msgid="808230403067569648">"అనుకూలం"</item>
   </string-array>
@@ -849,7 +849,7 @@
     <string name="imProtocolIcq" msgid="2410325380427389521">"ICQ"</string>
     <string name="imProtocolJabber" msgid="7919269388889582015">"Jabber"</string>
     <string name="imProtocolNetMeeting" msgid="4985002408136148256">"NetMeeting"</string>
-    <string name="orgTypeWork" msgid="8684458700669564172">"కార్యాలయం"</string>
+    <string name="orgTypeWork" msgid="8684458700669564172">"వర్క్"</string>
     <string name="orgTypeOther" msgid="5450675258408005553">"ఇతరం"</string>
     <string name="orgTypeCustom" msgid="1126322047677329218">"అనుకూలం"</string>
     <string name="relationTypeCustom" msgid="282938315217441351">"అనుకూలం"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index b35ddab..1ea7cbf 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -602,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ไม่มีลายนิ้วมือที่ลงทะเบียน"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"อุปกรณ์นี้ไม่มีเซ็นเซอร์ลายนิ้วมือ"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ปิดใช้เซ็นเซอร์ชั่วคราวแล้ว"</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ใช้เซ็นเซอร์ลายนิ้วมือไม่ได้ โปรดติดต่อผู้ให้บริการซ่อม"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"นิ้ว <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ใช้ลายนิ้วมือ"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ใช้ลายนิ้วมือหรือการล็อกหน้าจอ"</string>
@@ -619,12 +618,9 @@
     <string name="face_setup_notification_content" msgid="5463999831057751676">"ปลดล็อกโทรศัพท์โดยมองไปที่โทรศัพท์"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"ตั้งค่าการปลดล็อกด้วยวิธีอื่น"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"แตะเพื่อเพิ่มลายนิ้วมือ"</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"ปลดล็อกด้วยลายนิ้วมือ"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"ใช้เซ็นเซอร์ลายนิ้วมือไม่ได้"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"โปรดติดต่อผู้ให้บริการซ่อม"</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"บันทึกข้อมูลใบหน้าที่ถูกต้องไม่ได้ ลองอีกครั้ง"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"สว่างเกินไป ลองหาตำแหน่งที่แสงน้อยกว่านี้"</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"มืดเกินไป ลองหาตำแหน่งที่สว่างขึ้น"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index a00b051..85624f1 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -602,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"کوئی فنگر پرنٹ مندرج شدہ نہیں ہے۔"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"اس آلہ میں فنگر پرنٹ سینسر نہیں ہے۔"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"سینسر عارضی طور غیر فعال ہے۔"</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"فنگر پرنٹ سینسر کا استعمال نہیں کر سکتے۔ ایک مرمت فراہم کنندہ کو ملاحظہ کریں"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"انگلی <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"فنگر پرنٹ استعمال کریں"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"فنگر پرنٹ یا اسکرین لاک استعمال کریں"</string>
@@ -619,12 +618,9 @@
     <string name="face_setup_notification_content" msgid="5463999831057751676">"اپنے فون کی طرف دیکھ کر اسے غیر مقفل کریں"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"غیر مقفل کرنے کے مزید طریقے سیٹ اپ کریں"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"فنگر پرنٹ شامل کرنے کیلئے تھپتھپائیں"</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"فنگر پرنٹ اَن لاک"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"فنگر پرنٹ سینسر کا استعمال نہیں کر سکتے"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"ایک مرمت فراہم کنندہ کو ملاحظہ کریں۔"</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"چہرے کا درست ڈيٹا کیپچر نہیں ہو سکا۔ پھر آزمائيں۔"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"کافی روشنی ہے۔ ہلکی روشنی میں آزمائیں۔"</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"کافی اندھیرا ہے۔ تیز روشنی میں آزمائیں۔"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 045c62d..51e2b88 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -602,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Hech qanday barmoq izi qayd qilinmagan."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu qurilmada barmoq izi skaneri mavjud emas."</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor vaqtincha faol emas."</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Barmoq izi skaneridan foydalanish imkonsiz. Xizmat koʻrsatish markaziga murojaat qiling"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Barmoq izi <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Barmoq izi ishlatish"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Barmoq izi yoki ekran qulfi"</string>
@@ -619,12 +618,9 @@
     <string name="face_setup_notification_content" msgid="5463999831057751676">"Telefoningizni yuz tekshiruvi yordamida qulfdan chiqaring"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Qulfdan chiqarishning boshqa usullarini sozlang"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Barmoq izi kiritish uchun bosing"</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Barmoq izi bilan ochish"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Barmoq izi skaneridan foydalanish imkonsiz"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Xizmat koʻrsatish markaziga murojaat qiling."</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"Yuz ravshan suratga olinmadi. Qaytadan urining."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Juda yorqin. Biroz soyaroq joy tanlang."</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"Juda qorongʻi. Atrofingizni yoriting."</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index eb23130..77b48e7 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -602,8 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未注册任何指纹。"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此设备没有指纹传感器。"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"传感器已暂时停用。"</string>
-    <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) -->
-    <skip />
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"无法使用指纹传感器。请联系维修服务提供商"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指纹"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指纹或屏幕锁定凭据"</string>
@@ -619,12 +618,9 @@
     <string name="face_setup_notification_content" msgid="5463999831057751676">"脸部对准手机即可将其解锁"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"设置更多解锁方式"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"点按即可添加指纹"</string>
-    <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) -->
-    <skip />
-    <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) -->
-    <skip />
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"指纹解锁"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"无法使用指纹传感器"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"请联系维修服务提供商。"</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"无法捕获准确的人脸数据,请重试。"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"亮度过高,请尝试使用较柔和的亮度。"</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"亮度不足,请尝试将光线调亮。"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index c2bce46..06bb2d9 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -602,7 +602,7 @@
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未註冊任何指紋"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此裝置沒有指紋感應器。"</string>
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string>
-    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"指紋感應器無法使用,請洽詢維修供應商"</string>
+    <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"無法使用指紋感應器。請諮詢維修服務供應商"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋鎖定"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指紋或螢幕鎖定"</string>
@@ -619,8 +619,8 @@
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"設定更多解鎖方法"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"輕按即可新增指紋"</string>
     <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"指紋解鎖"</string>
-    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"指紋感應器無法使用"</string>
-    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"請洽詢維修供應商。"</string>
+    <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"無法使用指紋感應器"</string>
+    <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"請諮詢維修服務供應商。"</string>
     <string name="face_acquired_insufficient" msgid="2150805835949162453">"無法擷取準確的臉容資料。請再試一次。"</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"影像太亮。請嘗試在更暗的環境下使用。"</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"影像太暗。請嘗試在更明亮的環境下使用。"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 646fbd3..8dfbdcc 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -5038,4 +5038,8 @@
     <!-- The amount of dimming to apply to wallpapers with mid range luminance. 0 displays
          the wallpaper at full brightness. 1 displays the wallpaper as fully black. -->
     <item name="config_wallpaperDimAmount" format="float" type="dimen">0.05</item>
+
+    <!-- The default number of times per second that the seconds hand on AnalogClock ticks. If set
+         to 0, the seconds hand will be disabled. -->
+    <integer name="config_defaultAnalogClockSecondsHandFps">1</integer>
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index ea935205..de7a117 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -886,7 +886,7 @@
     <dimen name="seekbar_thumb_exclusion_max_size">48dp</dimen>
 
     <!-- chooser/resolver (sharesheet) spacing -->
-    <dimen name="chooser_corner_radius">8dp</dimen>
+    <dimen name="chooser_corner_radius">16dp</dimen>
     <dimen name="chooser_row_text_option_translate">25dp</dimen>
     <dimen name="chooser_view_spacing">18dp</dimen>
     <dimen name="chooser_edge_margin_thin">16dp</dimen>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d1a5cc4..a99a220 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -444,12 +444,6 @@
     <string name="sensor_notification_service">Sensor Notification Service</string>
     <!-- Attribution for Twilight service. [CHAR LIMIT=NONE]-->
     <string name="twilight_service">Twilight Service</string>
-    <!-- Attribution for the Offline LocationTimeZoneProvider service, i.e. the service capable of
-         performing time zone detection using time zone geospatial information held on the device.
-         This text is shown in UIs related to an application name to help users and developers to
-         understand which sub-unit of an application is requesting permissions and using power.
-         [CHAR LIMIT=NONE]-->
-    <string name="offline_location_time_zone_detection_service_attribution">Time Zone Detector (No connectivity)</string>
     <!-- Attribution for Gnss Time Update service. [CHAR LIMIT=NONE]-->
     <string name="gnss_time_update_service">GNSS Time Update Service</string>
 
@@ -3964,6 +3958,8 @@
     <string name="deny">Deny</string>
     <string name="permission_request_notification_title">Permission requested</string>
     <string name="permission_request_notification_with_subtitle">Permission requested\nfor account <xliff:g id="account" example="foo@gmail.com">%s</xliff:g>.</string>
+     <!-- Title and subtitle for notification shown when app request account access (two lines) [CHAR LIMIT=NONE] -->
+    <string name="permission_request_notification_for_app_with_subtitle">Permission requested by <xliff:g id="app" example="Gmail">%1$s</xliff:g>\nfor account <xliff:g id="account" example="foo@gmail.com">%2$s</xliff:g>.</string>
 
     <!-- Message to show when an intent automatically switches users into the personal profile. -->
     <string name="forward_intent_to_owner">You\'re using this app outside of your work profile</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index c05adfd..bfd39a3 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -490,6 +490,7 @@
   <java-symbol type="integer" name="config_smartSelectionInitializedTimeoutMillis" />
   <java-symbol type="integer" name="config_smartSelectionInitializingTimeoutMillis" />
   <java-symbol type="bool" name="config_hibernationDeletesOatArtifactsEnabled"/>
+  <java-symbol type="integer" name="config_defaultAnalogClockSecondsHandFps"/>
 
   <java-symbol type="color" name="tab_indicator_text_v4" />
 
@@ -560,6 +561,7 @@
   <java-symbol type="string" name="notification_title" />
   <java-symbol type="string" name="other_networks_no_internet" />
   <java-symbol type="string" name="permission_request_notification_with_subtitle" />
+  <java-symbol type="string" name="permission_request_notification_for_app_with_subtitle" />
   <java-symbol type="string" name="prepend_shortcut_label" />
   <java-symbol type="string" name="private_dns_broken_detailed" />
   <java-symbol type="string" name="paste_as_plain_text" />
@@ -2526,6 +2528,7 @@
   <java-symbol type="string" name="fingerprint_acquired_imager_dirty" />
   <java-symbol type="string" name="fingerprint_acquired_too_slow" />
   <java-symbol type="string" name="fingerprint_acquired_too_fast" />
+  <java-symbol type="string" name="fingerprint_acquired_too_bright" />
   <java-symbol type="array" name="fingerprint_acquired_vendor" />
   <java-symbol type="string" name="fingerprint_error_canceled" />
   <java-symbol type="string" name="fingerprint_error_user_canceled" />
@@ -4165,6 +4168,7 @@
   <java-symbol type="drawable" name="ic_work_apps_off" />
   <java-symbol type="drawable" name="ic_sharing_disabled" />
   <java-symbol type="drawable" name="ic_no_apps" />
+  <java-symbol type="drawable" name="ic_screenshot_edit" />
   <java-symbol type="dimen" name="resolver_empty_state_height" />
   <java-symbol type="dimen" name="resolver_empty_state_height_with_tabs" />
   <java-symbol type="dimen" name="resolver_max_collapsed_height_with_tabs" />
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
index cbd67c8..0147cdb 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
@@ -204,6 +204,7 @@
         BatteryUsageStatsStore batteryUsageStatsStore = new BatteryUsageStatsStore(context,
                 batteryStats, new File(context.getCacheDir(), "BatteryUsageStatsProviderTest"),
                 new TestHandler(), Integer.MAX_VALUE);
+        batteryUsageStatsStore.onSystemReady();
 
         BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context,
                 batteryStats, batteryUsageStatsStore);
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java
index 961e859..083090c 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java
@@ -66,6 +66,7 @@
         mMockClocks.currentTime = currentTime;
         mBatteryStats = new MockBatteryStatsImpl(mMockClocks);
         mBatteryStats.setPowerProfile(mPowerProfile);
+        mBatteryStats.onSystemReady();
     }
 
     public BatteryUsageStatsRule setAveragePower(String key, double value) {
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsStoreTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsStoreTest.java
index 141a9fa..e478cd7 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsStoreTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsStoreTest.java
@@ -59,6 +59,7 @@
         mBatteryStats = new MockBatteryStatsImpl(mMockClocks);
         mBatteryStats.setNoAutoReset(true);
         mBatteryStats.setPowerProfile(mock(PowerProfile.class));
+        mBatteryStats.onSystemReady();
 
         Context context = InstrumentationRegistry.getContext();
 
@@ -67,6 +68,7 @@
 
         mBatteryUsageStatsStore = new BatteryUsageStatsStore(context, mBatteryStats,
                 mStoreDirectory, new TestHandler(), MAX_BATTERY_STATS_SNAPSHOT_STORAGE_BYTES);
+        mBatteryUsageStatsStore.onSystemReady();
 
         mBatteryUsageStatsProvider = new BatteryUsageStatsProvider(context, mBatteryStats);
     }
diff --git a/keystore/java/android/security/LegacyVpnProfileStore.java b/keystore/java/android/security/LegacyVpnProfileStore.java
index 1d2738e..c85b6b1 100644
--- a/keystore/java/android/security/LegacyVpnProfileStore.java
+++ b/keystore/java/android/security/LegacyVpnProfileStore.java
@@ -19,7 +19,7 @@
 import android.annotation.NonNull;
 import android.os.ServiceManager;
 import android.os.ServiceSpecificException;
-import android.security.vpnprofilestore.IVpnProfileStore;
+import android.security.legacykeystore.ILegacyKeystore;
 import android.util.Log;
 
 /**
@@ -32,14 +32,14 @@
 public class LegacyVpnProfileStore {
     private static final String TAG = "LegacyVpnProfileStore";
 
-    public static final int SYSTEM_ERROR = IVpnProfileStore.ERROR_SYSTEM_ERROR;
-    public static final int PROFILE_NOT_FOUND = IVpnProfileStore.ERROR_PROFILE_NOT_FOUND;
+    public static final int SYSTEM_ERROR = ILegacyKeystore.ERROR_SYSTEM_ERROR;
+    public static final int PROFILE_NOT_FOUND = ILegacyKeystore.ERROR_ENTRY_NOT_FOUND;
 
-    private static final String VPN_PROFILE_STORE_SERVICE_NAME = "android.security.vpnprofilestore";
+    private static final String LEGACY_KEYSTORE_SERVICE_NAME = "android.security.legacykeystore";
 
-    private static IVpnProfileStore getService() {
-        return IVpnProfileStore.Stub.asInterface(
-                    ServiceManager.checkService(VPN_PROFILE_STORE_SERVICE_NAME));
+    private static ILegacyKeystore getService() {
+        return ILegacyKeystore.Stub.asInterface(
+                    ServiceManager.checkService(LEGACY_KEYSTORE_SERVICE_NAME));
     }
 
     /**
@@ -52,7 +52,7 @@
      */
     public static boolean put(@NonNull String alias, @NonNull byte[] profile) {
         try {
-            getService().put(alias, profile);
+            getService().put(alias, ILegacyKeystore.UID_SELF, profile);
             return true;
         } catch (Exception e) {
             Log.e(TAG, "Failed to put vpn profile.", e);
@@ -71,7 +71,7 @@
      */
     public static byte[] get(@NonNull String alias) {
         try {
-            return getService().get(alias);
+            return getService().get(alias, ILegacyKeystore.UID_SELF);
         } catch (ServiceSpecificException e) {
             if (e.errorCode != PROFILE_NOT_FOUND) {
                 Log.e(TAG, "Failed to get vpn profile.", e);
@@ -90,7 +90,7 @@
      */
     public static boolean remove(@NonNull String alias) {
         try {
-            getService().remove(alias);
+            getService().remove(alias, ILegacyKeystore.UID_SELF);
             return true;
         } catch (ServiceSpecificException e) {
             if (e.errorCode != PROFILE_NOT_FOUND) {
@@ -110,7 +110,7 @@
      */
     public static @NonNull String[] list(@NonNull String prefix) {
         try {
-            final String[] aliases = getService().list(prefix);
+            final String[] aliases = getService().list(prefix, ILegacyKeystore.UID_SELF);
             for (int i = 0; i < aliases.length; ++i) {
                 aliases[i] = aliases[i].substring(prefix.length());
             }
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 69fc25a..06aaad7 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -45,10 +45,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Bovenste scherm 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Bovenste scherm 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Onderste scherm op volledig scherm"</string>
-    <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Bediening met één hand gebruiken"</string>
+    <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Bediening met 1 hand gebruiken"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Als je wilt afsluiten, swipe je omhoog vanaf de onderkant van het scherm of tik je ergens boven de app"</string>
-    <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Bediening met één hand starten"</string>
-    <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Bediening met één hand afsluiten"</string>
+    <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Bediening met 1 hand starten"</string>
+    <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Bediening met 1 hand afsluiten"</string>
     <string name="bubbles_settings_button_description" msgid="1301286017420516912">"Instellingen voor <xliff:g id="APP_NAME">%1$s</xliff:g>-bubbels"</string>
     <string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"Overloop"</string>
     <string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"Weer toevoegen aan stack"</string>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java
index 046c320..a4b866aa 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java
@@ -19,6 +19,7 @@
 import static android.util.TypedValue.COMPLEX_UNIT_DIP;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.PictureInPictureParams;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
@@ -454,6 +455,56 @@
     }
 
     /**
+     * @return the normal bounds adjusted so that they fit the menu actions.
+     */
+    public Rect adjustNormalBoundsToFitMenu(@NonNull Rect normalBounds,
+            @Nullable Size minMenuSize) {
+        if (minMenuSize == null) {
+            return normalBounds;
+        }
+        if (normalBounds.width() >= minMenuSize.getWidth()
+                && normalBounds.height() >= minMenuSize.getHeight()) {
+            // The normal bounds can fit the menu as is, no need to adjust the bounds.
+            return normalBounds;
+        }
+        final Rect adjustedNormalBounds = new Rect();
+        final boolean needsWidthAdj = minMenuSize.getWidth() > normalBounds.width();
+        final boolean needsHeightAdj = minMenuSize.getHeight() > normalBounds.height();
+        final int adjWidth;
+        final int adjHeight;
+        if (needsWidthAdj && needsHeightAdj) {
+            // Both the width and the height are too small - find the edge that needs the larger
+            // adjustment and scale that edge. The other edge will scale beyond the minMenuSize
+            // when the aspect ratio is applied.
+            final float widthScaleFactor =
+                    ((float) (minMenuSize.getWidth())) / ((float) (normalBounds.width()));
+            final float heightScaleFactor =
+                    ((float) (minMenuSize.getHeight())) / ((float) (normalBounds.height()));
+            if (widthScaleFactor > heightScaleFactor) {
+                adjWidth = minMenuSize.getWidth();
+                adjHeight = Math.round(adjWidth / mPipBoundsState.getAspectRatio());
+            } else {
+                adjHeight = minMenuSize.getHeight();
+                adjWidth = Math.round(adjHeight * mPipBoundsState.getAspectRatio());
+            }
+        } else if (needsWidthAdj) {
+            // Width is too small - use the min menu size width instead.
+            adjWidth = minMenuSize.getWidth();
+            adjHeight = Math.round(adjWidth / mPipBoundsState.getAspectRatio());
+        } else {
+            // Height is too small - use the min menu size height instead.
+            adjHeight = minMenuSize.getHeight();
+            adjWidth = Math.round(adjHeight * mPipBoundsState.getAspectRatio());
+        }
+        adjustedNormalBounds.set(0, 0, adjWidth, adjHeight);
+        // Make sure the bounds conform to the aspect ratio and min edge size.
+        transformBoundsToAspectRatio(adjustedNormalBounds,
+                mPipBoundsState.getAspectRatio(), true /* useCurrentMinEdgeSize */,
+                true /* useCurrentSize */);
+        return adjustedNormalBounds;
+    }
+
+    /**
      * Dumps internal states.
      */
     public void dump(PrintWriter pw, String prefix) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index 324a6e2..f367cd6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -722,6 +722,14 @@
         if (info.displayId != Display.DEFAULT_DISPLAY && mOnDisplayIdChangeCallback != null) {
             mOnDisplayIdChangeCallback.accept(Display.DEFAULT_DISPLAY);
         }
+
+        final PipAnimationController.PipTransitionAnimator animator =
+                mPipAnimationController.getCurrentAnimator();
+        if (animator != null) {
+            animator.removeAllUpdateListeners();
+            animator.removeAllListeners();
+            animator.cancel();
+        }
     }
 
     @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
index b1086c5..0bcd1a3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
@@ -726,12 +726,17 @@
     }
 
     private void animateToNormalSize(Runnable callback) {
+        // Save the current bounds as the user-resize bounds.
         mPipResizeGestureHandler.setUserResizeBounds(mPipBoundsState.getBounds());
-        final Rect normalBounds = new Rect(mPipBoundsState.getNormalBounds());
+
+        final Size minMenuSize = mMenuController.getEstimatedMinMenuSize();
+        final Rect normalBounds = mPipBoundsState.getNormalBounds();
+        final Rect destBounds = mPipBoundsAlgorithm.adjustNormalBoundsToFitMenu(normalBounds,
+                minMenuSize);
         Rect restoredMovementBounds = new Rect();
-        mPipBoundsAlgorithm.getMovementBounds(normalBounds,
+        mPipBoundsAlgorithm.getMovementBounds(destBounds,
                 mInsetBounds, restoredMovementBounds, mIsImeShowing ? mImeHeight : 0);
-        mSavedSnapFraction = mMotionHelper.animateToExpandedState(normalBounds,
+        mSavedSnapFraction = mMotionHelper.animateToExpandedState(destBounds,
                 mPipBoundsState.getMovementBounds(), restoredMovementBounds, callback);
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java
index a0c6d11..90f898a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java
@@ -402,6 +402,64 @@
         assertBoundsInclusionWithMargin("useDefaultBounds", defaultBounds, actualBounds);
     }
 
+    @Test
+    public void adjustNormalBoundsToFitMenu_alreadyFits() {
+        final Rect normalBounds = new Rect(0, 0, 400, 711);
+        final Size minMenuSize = new Size(396, 292);
+        mPipBoundsState.setAspectRatio(
+                ((float) normalBounds.width()) / ((float) normalBounds.height()));
+
+        final Rect bounds =
+                mPipBoundsAlgorithm.adjustNormalBoundsToFitMenu(normalBounds, minMenuSize);
+
+        assertEquals(normalBounds, bounds);
+    }
+
+    @Test
+    public void adjustNormalBoundsToFitMenu_widthTooSmall() {
+        final Rect normalBounds = new Rect(0, 0, 297, 528);
+        final Size minMenuSize = new Size(396, 292);
+        mPipBoundsState.setAspectRatio(
+                ((float) normalBounds.width()) / ((float) normalBounds.height()));
+
+        final Rect bounds =
+                mPipBoundsAlgorithm.adjustNormalBoundsToFitMenu(normalBounds, minMenuSize);
+
+        assertEquals(minMenuSize.getWidth(), bounds.width());
+        assertEquals(minMenuSize.getWidth() / mPipBoundsState.getAspectRatio(),
+                bounds.height(), 0.3f);
+    }
+
+    @Test
+    public void adjustNormalBoundsToFitMenu_heightTooSmall() {
+        final Rect normalBounds = new Rect(0, 0, 400, 280);
+        final Size minMenuSize = new Size(396, 292);
+        mPipBoundsState.setAspectRatio(
+                ((float) normalBounds.width()) / ((float) normalBounds.height()));
+
+        final Rect bounds =
+                mPipBoundsAlgorithm.adjustNormalBoundsToFitMenu(normalBounds, minMenuSize);
+
+        assertEquals(minMenuSize.getHeight(), bounds.height());
+        assertEquals(minMenuSize.getHeight() * mPipBoundsState.getAspectRatio(),
+                bounds.width(), 0.3f);
+    }
+
+    @Test
+    public void adjustNormalBoundsToFitMenu_widthAndHeightTooSmall() {
+        final Rect normalBounds = new Rect(0, 0, 350, 280);
+        final Size minMenuSize = new Size(396, 292);
+        mPipBoundsState.setAspectRatio(
+                ((float) normalBounds.width()) / ((float) normalBounds.height()));
+
+        final Rect bounds =
+                mPipBoundsAlgorithm.adjustNormalBoundsToFitMenu(normalBounds, minMenuSize);
+
+        assertEquals(minMenuSize.getWidth(), bounds.width());
+        assertEquals(minMenuSize.getWidth() / mPipBoundsState.getAspectRatio(),
+                bounds.height(), 0.3f);
+    }
+
     private void overrideDefaultAspectRatio(float aspectRatio) {
         final TestableResources res = mContext.getOrCreateTestableResources();
         res.addOverride(
diff --git a/libs/hwui/WebViewFunctorManager.cpp b/libs/hwui/WebViewFunctorManager.cpp
index 92e20c4..974c863 100644
--- a/libs/hwui/WebViewFunctorManager.cpp
+++ b/libs/hwui/WebViewFunctorManager.cpp
@@ -126,7 +126,14 @@
                 renderthread::CanvasContext::getActiveContext();
         if (activeContext != nullptr) {
             ASurfaceControl* rootSurfaceControl = activeContext->getSurfaceControl();
-            if (rootSurfaceControl) overlayParams.overlaysMode = OverlaysMode::Enabled;
+            if (rootSurfaceControl) {
+                overlayParams.overlaysMode = OverlaysMode::Enabled;
+                int32_t rgid = activeContext->getSurfaceControlGenerationId();
+                if (mParentSurfaceControlGenerationId != rgid) {
+                    reparentSurfaceControl(rootSurfaceControl);
+                    mParentSurfaceControlGenerationId = rgid;
+                }
+            }
         }
     }
 
@@ -195,6 +202,7 @@
     LOG_ALWAYS_FATAL_IF(rootSurfaceControl == nullptr, "Null root surface control!");
 
     auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
+    mParentSurfaceControlGenerationId = activeContext->getSurfaceControlGenerationId();
     mSurfaceControl = funcs.createFunc(rootSurfaceControl, "Webview Overlay SurfaceControl");
     ASurfaceTransaction* transaction = funcs.transactionCreateFunc();
     activeContext->prepareSurfaceControlForWebview();
@@ -218,6 +226,17 @@
     }
 }
 
+void WebViewFunctor::reparentSurfaceControl(ASurfaceControl* parent) {
+    ATRACE_NAME("WebViewFunctor::reparentSurfaceControl");
+    if (mSurfaceControl == nullptr) return;
+
+    auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
+    ASurfaceTransaction* transaction = funcs.transactionCreateFunc();
+    funcs.transactionReparentFunc(transaction, mSurfaceControl, parent);
+    mergeTransaction(transaction);
+    funcs.transactionDeleteFunc(transaction);
+}
+
 WebViewFunctorManager& WebViewFunctorManager::instance() {
     static WebViewFunctorManager sInstance;
     return sInstance;
diff --git a/libs/hwui/WebViewFunctorManager.h b/libs/hwui/WebViewFunctorManager.h
index a84cda5..048d1fb 100644
--- a/libs/hwui/WebViewFunctorManager.h
+++ b/libs/hwui/WebViewFunctorManager.h
@@ -85,12 +85,16 @@
     }
 
 private:
+    void reparentSurfaceControl(ASurfaceControl* parent);
+
+private:
     WebViewFunctorCallbacks mCallbacks;
     void* const mData;
     int mFunctor;
     RenderMode mMode;
     bool mHasContext = false;
     bool mCreatedHandle = false;
+    int32_t mParentSurfaceControlGenerationId = 0;
     ASurfaceControl* mSurfaceControl = nullptr;
 };
 
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 0c9711b..81cee61 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -201,6 +201,7 @@
         funcs.releaseFunc(mSurfaceControl);
     }
     mSurfaceControl = surfaceControl;
+    mSurfaceControlGenerationId++;
     mExpectSurfaceStats = surfaceControl != nullptr;
     if (mSurfaceControl != nullptr) {
         funcs.acquireFunc(mSurfaceControl);
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 3279ccb..85af3e4 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -110,6 +110,7 @@
     GrDirectContext* getGrContext() const { return mRenderThread.getGrContext(); }
 
     ASurfaceControl* getSurfaceControl() const { return mSurfaceControl; }
+    int32_t getSurfaceControlGenerationId() const { return mSurfaceControlGenerationId; }
 
     // Won't take effect until next EGLSurface creation
     void setSwapBehavior(SwapBehavior swapBehavior);
@@ -253,6 +254,9 @@
     // The SurfaceControl reference is passed from ViewRootImpl, can be set to
     // NULL to remove the reference
     ASurfaceControl* mSurfaceControl = nullptr;
+    // id to track surface control changes and WebViewFunctor uses it to determine
+    // whether reparenting is needed
+    int32_t mSurfaceControlGenerationId = 0;
     // stopped indicates the CanvasContext will reject actual redraw operations,
     // and defer repaint until it is un-stopped
     bool mStopped = false;
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 524407d..f83c0a4 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -98,6 +98,10 @@
     LOG_ALWAYS_FATAL_IF(transactionApplyFunc == nullptr,
                         "Failed to find required symbol ASurfaceTransaction_apply!");
 
+    transactionReparentFunc = (AST_reparent)dlsym(handle_, "ASurfaceTransaction_reparent");
+    LOG_ALWAYS_FATAL_IF(transactionReparentFunc == nullptr,
+                        "Failed to find required symbol transactionReparentFunc!");
+
     transactionSetVisibilityFunc =
             (AST_setVisibility)dlsym(handle_, "ASurfaceTransaction_setVisibility");
     LOG_ALWAYS_FATAL_IF(transactionSetVisibilityFunc == nullptr,
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index c5e3746..05d225b 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -94,6 +94,9 @@
 typedef ASurfaceTransaction* (*AST_create)();
 typedef void (*AST_delete)(ASurfaceTransaction* transaction);
 typedef void (*AST_apply)(ASurfaceTransaction* transaction);
+typedef void (*AST_reparent)(ASurfaceTransaction* aSurfaceTransaction,
+                             ASurfaceControl* aSurfaceControl,
+                             ASurfaceControl* newParentASurfaceControl);
 typedef void (*AST_setVisibility)(ASurfaceTransaction* transaction,
                                   ASurfaceControl* surface_control, int8_t visibility);
 typedef void (*AST_setZOrder)(ASurfaceTransaction* transaction, ASurfaceControl* surface_control,
@@ -113,6 +116,7 @@
     AST_create transactionCreateFunc;
     AST_delete transactionDeleteFunc;
     AST_apply transactionApplyFunc;
+    AST_reparent transactionReparentFunc;
     AST_setVisibility transactionSetVisibilityFunc;
     AST_setZOrder transactionSetZOrderFunc;
 };
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index c8412f2..1644ec8 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -310,6 +310,10 @@
     public static final int ENCODING_LEGACY_SHORT_ARRAY_THRESHOLD = ENCODING_OPUS;
 
     /** Audio data format: PCM 24 bit per sample packed as 3 bytes.
+     *
+     * The bytes are in little-endian order, so the least significant byte
+     * comes first in the byte array.
+     *
      * Not guaranteed to be supported by devices, may be emulated if not supported. */
     public static final int ENCODING_PCM_24BIT_PACKED = 21;
     /** Audio data format: PCM 32 bit per sample.
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
index 915cb12..628f7ee 100644
--- a/media/java/android/media/MediaRouter2Manager.java
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -221,10 +221,24 @@
         Objects.requireNonNull(packageName, "packageName must not be null");
 
         List<RoutingSessionInfo> sessions = getRoutingSessions(packageName);
-        return getAvailableRoutesForRoutingSession(sessions.get(sessions.size() - 1));
+        return getAvailableRoutes(sessions.get(sessions.size() - 1));
     }
 
     /**
+     * Gets routes that can be transferable seamlessly for an application.
+     *
+     * @param packageName the package name of the application
+     */
+    @NonNull
+    public List<MediaRoute2Info> getTransferableRoutes(@NonNull String packageName) {
+        Objects.requireNonNull(packageName, "packageName must not be null");
+
+        List<RoutingSessionInfo> sessions = getRoutingSessions(packageName);
+        return getTransferableRoutes(sessions.get(sessions.size() - 1));
+    }
+
+
+    /**
      * Gets available routes for the given routing session.
      * The returned routes can be passed to
      * {@link #transfer(RoutingSessionInfo, MediaRoute2Info)} for transferring the routing session.
@@ -232,8 +246,7 @@
      * @param sessionInfo the routing session that would be transferred
      */
     @NonNull
-    public List<MediaRoute2Info> getAvailableRoutesForRoutingSession(
-            @NonNull RoutingSessionInfo sessionInfo) {
+    public List<MediaRoute2Info> getAvailableRoutes(@NonNull RoutingSessionInfo sessionInfo) {
         Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
 
         List<MediaRoute2Info> routes = new ArrayList<>();
@@ -256,6 +269,45 @@
     }
 
     /**
+     * Gets routes that can be transferable seamlessly for the given routing session.
+     * The returned routes can be passed to
+     * {@link #transfer(RoutingSessionInfo, MediaRoute2Info)} for transferring the routing session.
+     * <p>
+     * This includes routes that are {@link RoutingSessionInfo#getTransferableRoutes() transferable}
+     * by provider itself and routes that are different playback type (e.g. local/remote)
+     * from the given routing session.
+     *
+     * @param sessionInfo the routing session that would be transferred
+     */
+    @NonNull
+    public List<MediaRoute2Info> getTransferableRoutes(@NonNull RoutingSessionInfo sessionInfo) {
+        Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
+
+        List<MediaRoute2Info> routes = new ArrayList<>();
+
+        String packageName = sessionInfo.getClientPackageName();
+        List<String> preferredFeatures = mPreferredFeaturesMap.get(packageName);
+        if (preferredFeatures == null) {
+            preferredFeatures = Collections.emptyList();
+        }
+        synchronized (mRoutesLock) {
+            for (MediaRoute2Info route : mRoutes.values()) {
+                if (sessionInfo.getSelectedRoutes().contains(route.getId())
+                        || sessionInfo.getTransferableRoutes().contains(route.getId())) {
+                    routes.add(route);
+                    continue;
+                }
+                // Add Phone -> Cast and Cast -> Phone
+                if (route.hasAnyFeatures(preferredFeatures)
+                        && (sessionInfo.isSystemSession() ^ route.isSystemRoute())) {
+                    routes.add(route);
+                }
+            }
+        }
+        return routes;
+    }
+
+    /**
      * Returns the preferred features of the specified package name.
      */
     @NonNull
diff --git a/packages/CompanionDeviceManager/res/values-az/strings.xml b/packages/CompanionDeviceManager/res/values-az/strings.xml
index 4710dbe..2ec13c5 100644
--- a/packages/CompanionDeviceManager/res/values-az/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-az/strings.xml
@@ -20,7 +20,7 @@
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; tərəfindən idarə ediləcək <xliff:g id="PROFILE_NAME">%1$s</xliff:g> seçin"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"izləyin"</string>
-    <string name="confirmation_title" msgid="8455544820286920304">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tətbiqinin &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; cihazınızı idarə etməsinə icazə verin"</string>
+    <string name="confirmation_title" msgid="8455544820286920304">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tətbiqinə &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; cihazınızı idarə etməsinə icazə verin"</string>
     <string name="profile_summary" msgid="2059360676631420073">"Bu tətbiq <xliff:g id="PROFILE_NAME">%1$s</xliff:g> profilinizi idarə etmək üçün lazımdır. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
     <string name="consent_yes" msgid="8344487259618762872">"İcazə verin"</string>
     <string name="consent_no" msgid="2640796915611404382">"İcazə verməyin"</string>
diff --git a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
index e91dd94..f04b0e3 100644
--- a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
+++ b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
@@ -18,18 +18,29 @@
 
 import android.content.Context;
 import android.content.res.TypedArray;
+import android.graphics.drawable.Animatable;
+import android.graphics.drawable.Animatable2;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 
-import androidx.annotation.VisibleForTesting;
+import androidx.annotation.RawRes;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
+import androidx.vectordrawable.graphics.drawable.Animatable2Compat;
 
 import com.airbnb.lottie.LottieAnimationView;
+import com.airbnb.lottie.LottieDrawable;
+
+import java.io.FileNotFoundException;
+import java.io.InputStream;
 
 /**
  * IllustrationPreference is a preference that can play lottie format animation
@@ -40,11 +51,32 @@
 
     private static final boolean IS_ENABLED_LOTTIE_ADAPTIVE_COLOR = false;
 
-    private int mAnimationId;
+    private int mImageResId;
     private boolean mIsAutoScale;
-    private LottieAnimationView mIllustrationView;
+    private Uri mImageUri;
+    private Drawable mImageDrawable;
     private View mMiddleGroundView;
-    private FrameLayout mMiddleGroundLayout;
+
+    private final Animatable2.AnimationCallback mAnimationCallback =
+            new Animatable2.AnimationCallback() {
+                @Override
+                public void onAnimationEnd(Drawable drawable) {
+                    ((Animatable) drawable).start();
+                }
+            };
+
+    private final Animatable2Compat.AnimationCallback mAnimationCallbackCompat =
+            new Animatable2Compat.AnimationCallback() {
+                @Override
+                public void onAnimationEnd(Drawable drawable) {
+                    ((Animatable) drawable).start();
+                }
+            };
+
+    public IllustrationPreference(Context context) {
+        super(context);
+        init(context, /* attrs= */ null);
+    }
 
     public IllustrationPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -65,10 +97,11 @@
     @Override
     public void onBindViewHolder(PreferenceViewHolder holder) {
         super.onBindViewHolder(holder);
-        if (mAnimationId == 0) {
-            Log.w(TAG, "Invalid illustration resource id.");
-            return;
-        }
+
+        final FrameLayout middleGroundLayout =
+                (FrameLayout) holder.findViewById(R.id.middleground_layout);
+        final LottieAnimationView illustrationView =
+                (LottieAnimationView) holder.findViewById(R.id.lottie_view);
 
         // To solve the problem of non-compliant illustrations, we set the frame height
         // to 300dp and set the length of the short side of the screen to
@@ -81,73 +114,208 @@
         lp.width = screenWidth < screenHeight ? screenWidth : screenHeight;
         illustrationFrame.setLayoutParams(lp);
 
-        mMiddleGroundLayout = (FrameLayout) holder.findViewById(R.id.middleground_layout);
-        mIllustrationView = (LottieAnimationView) holder.findViewById(R.id.lottie_view);
-        mIllustrationView.setAnimation(mAnimationId);
-        mIllustrationView.loop(true);
-        mIllustrationView.playAnimation();
-        if (mIsAutoScale) {
-            enableAnimationAutoScale(mIsAutoScale);
-        }
-        if (mMiddleGroundView != null) {
-            enableMiddleGroundView();
-        }
-        if (IS_ENABLED_LOTTIE_ADAPTIVE_COLOR) {
-            ColorUtils.applyDynamicColors(getContext(), mIllustrationView);
-        }
-    }
+        handleImageWithAnimation(illustrationView);
 
-    @VisibleForTesting
-    boolean isAnimating() {
-        return mIllustrationView.isAnimating();
+        if (mIsAutoScale) {
+            illustrationView.setScaleType(mIsAutoScale
+                            ? ImageView.ScaleType.CENTER_CROP
+                            : ImageView.ScaleType.CENTER_INSIDE);
+        }
+
+        handleMiddleGroundView(middleGroundLayout);
+
+        if (IS_ENABLED_LOTTIE_ADAPTIVE_COLOR) {
+            ColorUtils.applyDynamicColors(getContext(), illustrationView);
+        }
     }
 
     /**
-     * Set the middle ground view to preference. The user
+     * Sets the middle ground view to preference. The user
      * can overlay a view on top of the animation.
      */
     public void setMiddleGroundView(View view) {
-        mMiddleGroundView = view;
-        if (mMiddleGroundLayout == null) {
-            return;
+        if (view != mMiddleGroundView) {
+            mMiddleGroundView = view;
+            notifyChanged();
         }
-        enableMiddleGroundView();
     }
 
     /**
-     * Remove the middle ground view of preference.
+     * Removes the middle ground view of preference.
      */
     public void removeMiddleGroundView() {
-        if (mMiddleGroundLayout == null) {
-            return;
-        }
-        mMiddleGroundLayout.removeAllViews();
-        mMiddleGroundLayout.setVisibility(View.GONE);
+        mMiddleGroundView = null;
+        notifyChanged();
     }
 
     /**
      * Enables the auto scale feature of animation view.
      */
     public void enableAnimationAutoScale(boolean enable) {
-        mIsAutoScale = enable;
-        if (mIllustrationView == null) {
-            return;
+        if (enable != mIsAutoScale) {
+            mIsAutoScale = enable;
+            notifyChanged();
         }
-        mIllustrationView.setScaleType(
-                mIsAutoScale ? ImageView.ScaleType.CENTER_CROP : ImageView.ScaleType.CENTER_INSIDE);
     }
 
     /**
-     * Set the lottie illustration resource id.
+     * Sets the lottie illustration resource id.
      */
     public void setLottieAnimationResId(int resId) {
-        mAnimationId = resId;
+        if (resId != mImageResId) {
+            resetImageResourceCache();
+            mImageResId = resId;
+            notifyChanged();
+        }
     }
 
-    private void enableMiddleGroundView() {
-        mMiddleGroundLayout.removeAllViews();
-        mMiddleGroundLayout.addView(mMiddleGroundView);
-        mMiddleGroundLayout.setVisibility(View.VISIBLE);
+    /**
+     * Sets image drawable to display image in {@link LottieAnimationView}
+     *
+     * @param imageDrawable the drawable of an image
+     */
+    public void setImageDrawable(Drawable imageDrawable) {
+        if (imageDrawable != mImageDrawable) {
+            resetImageResourceCache();
+            mImageDrawable = imageDrawable;
+            notifyChanged();
+        }
+    }
+
+    /**
+     * Sets image uri to display image in {@link LottieAnimationView}
+     *
+     * @param imageUri the Uri of an image
+     */
+    public void setImageUri(Uri imageUri) {
+        if (imageUri != mImageUri) {
+            resetImageResourceCache();
+            mImageUri = imageUri;
+            notifyChanged();
+        }
+    }
+
+    private void resetImageResourceCache() {
+        mImageDrawable = null;
+        mImageUri = null;
+        mImageResId = 0;
+    }
+
+    private void handleMiddleGroundView(ViewGroup middleGroundLayout) {
+        middleGroundLayout.removeAllViews();
+
+        if (mMiddleGroundView != null) {
+            middleGroundLayout.addView(mMiddleGroundView);
+            middleGroundLayout.setVisibility(View.VISIBLE);
+        } else {
+            middleGroundLayout.setVisibility(View.GONE);
+        }
+    }
+
+    private void handleImageWithAnimation(LottieAnimationView illustrationView) {
+        if (mImageDrawable != null) {
+            resetAnimations(illustrationView);
+            illustrationView.setImageDrawable(mImageDrawable);
+            final Drawable drawable = illustrationView.getDrawable();
+            if (drawable != null) {
+                startAnimation(drawable);
+            }
+        }
+
+        if (mImageUri != null) {
+            resetAnimations(illustrationView);
+            illustrationView.setImageURI(mImageUri);
+            final Drawable drawable = illustrationView.getDrawable();
+            if (drawable != null) {
+                startAnimation(drawable);
+            } else {
+                // The lottie image from the raw folder also returns null because the ImageView
+                // couldn't handle it now.
+                startLottieAnimationWith(illustrationView, mImageUri);
+            }
+        }
+
+        if (mImageResId > 0) {
+            resetAnimations(illustrationView);
+            illustrationView.setImageResource(mImageResId);
+            final Drawable drawable = illustrationView.getDrawable();
+            if (drawable != null) {
+                startAnimation(drawable);
+            } else {
+                // The lottie image from the raw folder also returns null because the ImageView
+                // couldn't handle it now.
+                startLottieAnimationWith(illustrationView, mImageResId);
+            }
+        }
+    }
+
+    private void startAnimation(Drawable drawable) {
+        if (!(drawable instanceof Animatable)) {
+            return;
+        }
+
+        if (drawable instanceof Animatable2) {
+            ((Animatable2) drawable).registerAnimationCallback(mAnimationCallback);
+        } else if (drawable instanceof Animatable2Compat) {
+            ((Animatable2Compat) drawable).registerAnimationCallback(mAnimationCallbackCompat);
+        } else if (drawable instanceof AnimationDrawable) {
+            ((AnimationDrawable) drawable).setOneShot(false);
+        }
+
+        ((Animatable) drawable).start();
+    }
+
+    private static void startLottieAnimationWith(LottieAnimationView illustrationView,
+            Uri imageUri) {
+        try {
+            final InputStream inputStream =
+                    getInputStreamFromUri(illustrationView.getContext(), imageUri);
+            illustrationView.setAnimation(inputStream, /* cacheKey= */ null);
+            illustrationView.setRepeatCount(LottieDrawable.INFINITE);
+            illustrationView.playAnimation();
+        } catch (IllegalStateException e) {
+            Log.w(TAG, "Invalid illustration image uri: " + imageUri, e);
+        }
+    }
+
+    private static void startLottieAnimationWith(LottieAnimationView illustrationView,
+            @RawRes int rawRes) {
+        try {
+            illustrationView.setAnimation(rawRes);
+            illustrationView.setRepeatCount(LottieDrawable.INFINITE);
+            illustrationView.playAnimation();
+        } catch (IllegalStateException e) {
+            Log.w(TAG, "Invalid illustration resource id: " + rawRes, e);
+        }
+    }
+
+    private static void resetAnimations(LottieAnimationView illustrationView) {
+        resetAnimation(illustrationView.getDrawable());
+
+        illustrationView.cancelAnimation();
+    }
+
+    private static void resetAnimation(Drawable drawable) {
+        if (!(drawable instanceof Animatable)) {
+            return;
+        }
+
+        if (drawable instanceof Animatable2) {
+            ((Animatable2) drawable).clearAnimationCallbacks();
+        } else if (drawable instanceof Animatable2Compat) {
+            ((Animatable2Compat) drawable).clearAnimationCallbacks();
+        }
+
+        ((Animatable) drawable).stop();
+    }
+
+    private static InputStream getInputStreamFromUri(Context context, Uri uri) {
+        try {
+            return context.getContentResolver().openInputStream(uri);
+        } catch (FileNotFoundException e) {
+            Log.w(TAG, "Cannot find content uri: " + uri, e);
+            return null;
+        }
     }
 
     private void init(Context context, AttributeSet attrs) {
@@ -157,7 +325,7 @@
         if (attrs != null) {
             final TypedArray a = context.obtainStyledAttributes(attrs,
                     R.styleable.LottieAnimationView, 0 /*defStyleAttr*/, 0 /*defStyleRes*/);
-            mAnimationId = a.getResourceId(R.styleable.LottieAnimationView_lottie_rawRes, 0);
+            mImageResId = a.getResourceId(R.styleable.LottieAnimationView_lottie_rawRes, 0);
             a.recycle();
         }
     }
diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml b/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml
index 2518a6d..6e5911c 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml
@@ -36,9 +36,9 @@
             android:layout_height="wrap_content"
             android:layout_width="0dp"
             android:layout_weight="1"
-            android:layout_marginEnd="16dp"
+            android:layout_marginEnd="@dimen/settingslib_switch_title_margin"
+            android:layout_marginVertical="@dimen/settingslib_switch_title_margin"
             android:layout_gravity="center_vertical"
-            android:maxLines="2"
             android:ellipsize="end"
             android:textAppearance="?android:attr/textAppearanceListItem"
             style="@style/MainSwitchText.Settingslib" />
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml b/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml
index a386adb..16b8af6 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml
@@ -41,6 +41,9 @@
     <!-- Radius of switch bar -->
     <dimen name="settingslib_switch_bar_radius">28dp</dimen>
 
+    <!-- Size of title margin -->
+    <dimen name="settingslib_switch_title_margin">16dp</dimen>
+
     <!-- SwitchBar sub settings margin start / end -->
     <dimen name="settingslib_switchbar_subsettings_margin_start">72dp</dimen>
     <dimen name="settingslib_switchbar_subsettings_margin_end">16dp</dimen>
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
index 6b1e282..79446e4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
@@ -372,7 +372,7 @@
             Log.w(TAG, "shouldDisableMediaOutput() package name is null or empty!");
             return false;
         }
-        final List<MediaRoute2Info> infos = mRouterManager.getAvailableRoutes(packageName);
+        final List<MediaRoute2Info> infos = mRouterManager.getTransferableRoutes(packageName);
         if (infos.size() == 1) {
             final MediaRoute2Info info = infos.get(0);
             final int deviceType = info.getType();
@@ -456,7 +456,7 @@
     }
 
     private void buildAvailableRoutes() {
-        for (MediaRoute2Info route : mRouterManager.getAvailableRoutes(mPackageName)) {
+        for (MediaRoute2Info route : mRouterManager.getTransferableRoutes(mPackageName)) {
             if (DEBUG) {
                 Log.d(TAG, "buildAvailableRoutes() route : " + route.getName() + ", volume : "
                         + route.getVolume() + ", type : " + route.getType());
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java
index 89b0fe7..ea9be04 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java
@@ -18,12 +18,25 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
 import android.content.Context;
+import android.graphics.drawable.AnimatedImageDrawable;
+import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.AnimationDrawable;
+import android.net.Uri;
 import android.util.AttributeSet;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 
+import androidx.preference.PreferenceViewHolder;
+import androidx.test.core.app.ApplicationProvider;
+
 import com.airbnb.lottie.LottieAnimationView;
 
 import org.junit.Before;
@@ -33,47 +46,88 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.util.ReflectionHelpers;
 
 @RunWith(RobolectricTestRunner.class)
 public class IllustrationPreferenceTest {
 
     @Mock
-    LottieAnimationView mAnimationView;
-
-    private Context mContext;
+    private ViewGroup mRootView;
+    private Uri mImageUri;
+    private LottieAnimationView mAnimationView;
     private IllustrationPreference mPreference;
+    private PreferenceViewHolder mViewHolder;
+    private FrameLayout mMiddleGroundLayout;
+    private final Context mContext = ApplicationProvider.getApplicationContext();
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
+
+        mImageUri = new Uri.Builder().build();
+        mAnimationView = spy(new LottieAnimationView(mContext));
+        mMiddleGroundLayout = new FrameLayout(mContext);
+        final FrameLayout illustrationFrame = new FrameLayout(mContext);
+        illustrationFrame.setLayoutParams(
+                new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+                        ViewGroup.LayoutParams.WRAP_CONTENT));
+        doReturn(mMiddleGroundLayout).when(mRootView).findViewById(R.id.middleground_layout);
+        doReturn(mAnimationView).when(mRootView).findViewById(R.id.lottie_view);
+        doReturn(illustrationFrame).when(mRootView).findViewById(R.id.illustration_frame);
+        mViewHolder = spy(PreferenceViewHolder.createInstanceForTests(mRootView));
+
         final AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
         mPreference = new IllustrationPreference(mContext, attributeSet);
-        ReflectionHelpers.setField(mPreference, "mIllustrationView", mAnimationView);
     }
 
     @Test
     public void setMiddleGroundView_middleGroundView_shouldVisible() {
         final View view = new View(mContext);
-        final FrameLayout layout = new FrameLayout(mContext);
-        layout.setVisibility(View.GONE);
-        ReflectionHelpers.setField(mPreference, "mMiddleGroundView", view);
-        ReflectionHelpers.setField(mPreference, "mMiddleGroundLayout", layout);
+        mMiddleGroundLayout.setVisibility(View.GONE);
 
         mPreference.setMiddleGroundView(view);
+        mPreference.onBindViewHolder(mViewHolder);
 
-        assertThat(layout.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mMiddleGroundLayout.getVisibility()).isEqualTo(View.VISIBLE);
     }
 
     @Test
     public void enableAnimationAutoScale_shouldChangeScaleType() {
-        final LottieAnimationView animationView = new LottieAnimationView(mContext);
-        ReflectionHelpers.setField(mPreference, "mIllustrationView", animationView);
-
         mPreference.enableAnimationAutoScale(true);
+        mPreference.onBindViewHolder(mViewHolder);
 
-        assertThat(animationView.getScaleType()).isEqualTo(ImageView.ScaleType.CENTER_CROP);
+        assertThat(mAnimationView.getScaleType()).isEqualTo(ImageView.ScaleType.CENTER_CROP);
+    }
+
+    @Test
+    public void playAnimationWithUri_animatedImageDrawable_success() {
+        final AnimatedImageDrawable drawable = mock(AnimatedImageDrawable.class);
+        doReturn(drawable).when(mAnimationView).getDrawable();
+
+        mPreference.setImageUri(mImageUri);
+        mPreference.onBindViewHolder(mViewHolder);
+
+        verify(drawable).start();
+    }
+
+    @Test
+    public void playAnimationWithUri_animatedVectorDrawable_success() {
+        final AnimatedVectorDrawable drawable = mock(AnimatedVectorDrawable.class);
+        doReturn(drawable).when(mAnimationView).getDrawable();
+
+        mPreference.setImageUri(mImageUri);
+        mPreference.onBindViewHolder(mViewHolder);
+
+        verify(drawable).start();
+    }
+
+    @Test
+    public void playAnimationWithUri_animationDrawable_success() {
+        final AnimationDrawable drawable = mock(AnimationDrawable.class);
+        doReturn(drawable).when(mAnimationView).getDrawable();
+
+        mPreference.setImageUri(mImageUri);
+        mPreference.onBindViewHolder(mViewHolder);
+
+        verify(drawable).start();
     }
 }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index dd9a6ee..1e3ee22 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -1145,6 +1145,7 @@
         }
 
         enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG);
+        final String callingPackage = resolveCallingPackage();
 
         synchronized (mLock) {
             if (isSyncDisabledConfigLocked()) {
@@ -1152,7 +1153,7 @@
             }
             final int key = makeKey(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM);
             boolean success = mSettingsRegistry.setConfigSettingsLocked(key, prefix, keyValues,
-                    resolveCallingPackage());
+                    callingPackage);
             return success ? SET_ALL_RESULT_SUCCESS : SET_ALL_RESULT_FAILURE;
         }
     }
@@ -1258,6 +1259,7 @@
     private boolean mutateConfigSetting(String name, String value, String prefix,
             boolean makeDefault, int operation, int mode) {
         enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG);
+        final String callingPackage = resolveCallingPackage();
 
         // Perform the mutation.
         synchronized (mLock) {
@@ -1265,7 +1267,7 @@
                 case MUTATION_OPERATION_INSERT: {
                     return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_CONFIG,
                             UserHandle.USER_SYSTEM, name, value, null, makeDefault, true,
-                            resolveCallingPackage(), false, null,
+                            callingPackage, false, null,
                             /* overrideableByRestore */ false);
                 }
 
@@ -1276,7 +1278,7 @@
 
                 case MUTATION_OPERATION_RESET: {
                     mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_CONFIG,
-                            UserHandle.USER_SYSTEM, resolveCallingPackage(), mode, null, prefix);
+                            UserHandle.USER_SYSTEM, callingPackage, mode, null, prefix);
                 } return true;
             }
         }
@@ -1434,13 +1436,15 @@
             return false;
         }
 
+        final String callingPackage = getCallingPackage();
+
         // Perform the mutation.
         synchronized (mLock) {
             switch (operation) {
                 case MUTATION_OPERATION_INSERT: {
                     return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_GLOBAL,
                             UserHandle.USER_SYSTEM, name, value, tag, makeDefault,
-                            getCallingPackage(), forceNotify,
+                            callingPackage, forceNotify,
                             CRITICAL_GLOBAL_SETTINGS, overrideableByRestore);
                 }
 
@@ -1452,12 +1456,12 @@
                 case MUTATION_OPERATION_UPDATE: {
                     return mSettingsRegistry.updateSettingLocked(SETTINGS_TYPE_GLOBAL,
                             UserHandle.USER_SYSTEM, name, value, tag, makeDefault,
-                            getCallingPackage(), forceNotify, CRITICAL_GLOBAL_SETTINGS);
+                            callingPackage, forceNotify, CRITICAL_GLOBAL_SETTINGS);
                 }
 
                 case MUTATION_OPERATION_RESET: {
                     mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_GLOBAL,
-                            UserHandle.USER_SYSTEM, getCallingPackage(), mode, tag);
+                            UserHandle.USER_SYSTEM, callingPackage, mode, tag);
                 } return true;
             }
         }
@@ -1466,11 +1470,12 @@
     }
 
     private PackageInfo getCallingPackageInfo(int userId) {
+        final String callingPackage = getCallingPackage();
         try {
-            return mPackageManager.getPackageInfo(getCallingPackage(),
+            return mPackageManager.getPackageInfo(callingPackage,
                     PackageManager.GET_SIGNATURES, userId);
         } catch (RemoteException e) {
-            throw new IllegalStateException("Package " + getCallingPackage() + " doesn't exist");
+            throw new IllegalStateException("Package " + callingPackage + " doesn't exist");
         }
     }
 
@@ -1720,13 +1725,15 @@
             return false;
         }
 
+        final String callingPackage = getCallingPackage();
+
         // Mutate the value.
         synchronized (mLock) {
             switch (operation) {
                 case MUTATION_OPERATION_INSERT: {
                     return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_SECURE,
                             owningUserId, name, value, tag, makeDefault,
-                            getCallingPackage(), forceNotify, CRITICAL_SECURE_SETTINGS,
+                            callingPackage, forceNotify, CRITICAL_SECURE_SETTINGS,
                             overrideableByRestore);
                 }
 
@@ -1738,12 +1745,12 @@
                 case MUTATION_OPERATION_UPDATE: {
                     return mSettingsRegistry.updateSettingLocked(SETTINGS_TYPE_SECURE,
                             owningUserId, name, value, tag, makeDefault,
-                            getCallingPackage(), forceNotify, CRITICAL_SECURE_SETTINGS);
+                            callingPackage, forceNotify, CRITICAL_SECURE_SETTINGS);
                 }
 
                 case MUTATION_OPERATION_RESET: {
                     mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_SECURE,
-                            UserHandle.USER_SYSTEM, getCallingPackage(), mode, tag);
+                            UserHandle.USER_SYSTEM, callingPackage, mode, tag);
                 } return true;
             }
         }
@@ -1840,11 +1847,12 @@
 
     private boolean mutateSystemSetting(String name, String value, int runAsUserId, int operation,
             boolean overrideableByRestore) {
+        final String callingPackage = getCallingPackage();
         if (!hasWriteSecureSettingsPermission()) {
             // If the caller doesn't hold WRITE_SECURE_SETTINGS, we verify whether this
             // operation is allowed for the calling package through appops.
             if (!Settings.checkAndNoteWriteSettingsOperation(getContext(),
-                    Binder.getCallingUid(), getCallingPackage(), getCallingAttributionTag(),
+                    Binder.getCallingUid(), callingPackage, getCallingAttributionTag(),
                     true)) {
                 return false;
             }
@@ -1889,7 +1897,7 @@
                 case MUTATION_OPERATION_INSERT: {
                     validateSystemSettingValue(name, value);
                     return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_SYSTEM,
-                            owningUserId, name, value, null, false, getCallingPackage(),
+                            owningUserId, name, value, null, false, callingPackage,
                             false, null, overrideableByRestore);
                 }
 
@@ -1901,7 +1909,7 @@
                 case MUTATION_OPERATION_UPDATE: {
                     validateSystemSettingValue(name, value);
                     return mSettingsRegistry.updateSettingLocked(SETTINGS_TYPE_SYSTEM,
-                            owningUserId, name, value, null, false, getCallingPackage(),
+                            owningUserId, name, value, null, false, callingPackage,
                             false, null);
                 }
             }
@@ -2169,14 +2177,15 @@
         // user is a system permission and the app must be uninstalled in B and then installed as
         // an Instant App that situation is not realistic or supported.
         ApplicationInfo ai = null;
+        final String callingPackage = getCallingPackage();
         try {
-            ai = mPackageManager.getApplicationInfo(getCallingPackage(), 0
+            ai = mPackageManager.getApplicationInfo(callingPackage, 0
                     , UserHandle.getCallingUserId());
         } catch (RemoteException ignored) {
         }
         if (ai == null) {
             throw new IllegalStateException("Failed to lookup info for package "
-                    + getCallingPackage());
+                    + callingPackage);
         }
         return ai;
     }
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index c7b50c2..bc1d420 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -104,7 +104,6 @@
     <uses-permission android:name="android.permission.PERSISTENT_ACTIVITY" />
     <uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
     <uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
     <uses-permission android:name="android.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE" />
     <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 604310a..8963dda 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -281,6 +281,8 @@
     <!-- Permission for Smartspace. -->
     <uses-permission android:name="android.permission.MANAGE_SMARTSPACE" />
 
+    <uses-permission android:name="android.permission.READ_PEOPLE_DATA" />
+
     <protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
     <protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
     <protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />
@@ -604,7 +606,8 @@
         </activity>
 
         <activity android:name=".people.widget.LaunchConversationActivity"
-            android:windowDisablePreview="true" />
+            android:windowDisablePreview="true"
+            android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
 
         <!-- People Space Widget -->
         <receiver
@@ -630,6 +633,9 @@
             android:permission="android.permission.GET_PEOPLE_TILE_PREVIEW">
         </provider>
 
+        <service android:name=".people.PeopleBackupFollowUpJob"
+            android:permission="android.permission.BIND_JOB_SERVICE"/>
+
         <!-- a gallery of delicious treats -->
         <service
             android:name=".DessertCaseDream"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
index 9811434..29fcf57 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
@@ -57,7 +57,7 @@
             android:id="@+id/animatable_clock_view_large"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_gravity="center_horizontal"
+            android:layout_gravity="center"
             android:gravity="center_horizontal"
             android:textSize="@dimen/large_clock_text_size"
             android:fontFamily="@font/clock"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
index a957df6..02cb2bc 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
@@ -44,7 +44,7 @@
           android:id="@+id/row0"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
-          android:paddingBottom="16dp"
+          android:paddingBottom="@dimen/num_pad_entry_row_margin_bottom"
           >
             <com.android.keyguard.PasswordTextView
                     android:id="@+id/pinEntry"
@@ -192,7 +192,7 @@
              android:orientation="vertical"
              android:layout_gravity="bottom|center_horizontal"
              android:layout_marginTop="@dimen/keyguard_eca_top_margin"
-             android:layout_marginBottom="12dp"
+             android:layout_marginBottom="@dimen/keyguard_eca_bottom_margin"
              android:gravity="center_horizontal"/>
 
 </com.android.keyguard.KeyguardPINView>
diff --git a/packages/SystemUI/res-keyguard/values-sw360dp-land/dimens.xml b/packages/SystemUI/res-keyguard/values-sw360dp-land/dimens.xml
new file mode 100644
index 0000000..eb5843b
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/values-sw360dp-land/dimens.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2021, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <dimen name="num_pad_row_margin_bottom">4dp</dimen>
+    <dimen name="keyguard_eca_top_margin">4dp</dimen>
+    <dimen name="keyguard_eca_bottom_margin">4dp</dimen>
+    <dimen name="keyguard_password_height">50dp</dimen>
+    <dimen name="num_pad_entry_row_margin_bottom">4dp</dimen>
+</resources>
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index e8f7b35..7e3c87b 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -41,6 +41,7 @@
     <dimen name="keyguard_security_view_lateral_margin">20dp</dimen>
 
     <dimen name="keyguard_eca_top_margin">18dp</dimen>
+    <dimen name="keyguard_eca_bottom_margin">12dp</dimen>
 
     <!-- EmergencyCarrierArea overlap - amount to overlap the emergency button and carrier text.
          Should be 0 on devices with plenty of room (e.g. tablets) -->
@@ -88,6 +89,7 @@
 
     <!-- Spacing around each button used for PIN view -->
     <dimen name="num_pad_key_width">72dp</dimen>
+    <dimen name="num_pad_entry_row_margin_bottom">16dp</dimen>
     <dimen name="num_pad_row_margin_bottom">6dp</dimen>
     <dimen name="num_pad_key_margin_end">12dp</dimen>
 
diff --git a/packages/SystemUI/res/drawable/global_actions_popup_bg.xml b/packages/SystemUI/res/drawable/global_actions_popup_bg.xml
new file mode 100644
index 0000000..fc781a0
--- /dev/null
+++ b/packages/SystemUI/res/drawable/global_actions_popup_bg.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="?android:attr/colorBackgroundFloating" />
+    <corners
+        android:bottomLeftRadius="?android:attr/dialogCornerRadius"
+        android:topLeftRadius="?android:attr/dialogCornerRadius"
+        android:bottomRightRadius="?android:attr/dialogCornerRadius"
+        android:topRightRadius="?android:attr/dialogCornerRadius"
+        />
+</shape>
diff --git a/packages/SystemUI/res/drawable/screenshot_save_background.xml b/packages/SystemUI/res/drawable/screenshot_button_background.xml
similarity index 95%
rename from packages/SystemUI/res/drawable/screenshot_save_background.xml
rename to packages/SystemUI/res/drawable/screenshot_button_background.xml
index b61b28e..3c39fe2 100644
--- a/packages/SystemUI/res/drawable/screenshot_save_background.xml
+++ b/packages/SystemUI/res/drawable/screenshot_button_background.xml
@@ -14,7 +14,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<!-- Long screenshot save button background -->
+<!-- Long screenshot save/cancel button background -->
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
         android:color="?android:textColorPrimary">
diff --git a/packages/SystemUI/res/drawable/wallet_app_button_bg.xml b/packages/SystemUI/res/drawable/wallet_app_button_bg.xml
index 1136b9d..ecf09c2 100644
--- a/packages/SystemUI/res/drawable/wallet_app_button_bg.xml
+++ b/packages/SystemUI/res/drawable/wallet_app_button_bg.xml
@@ -14,10 +14,11 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
 -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+          xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
     <item>
         <shape android:shape="rectangle">
-            <stroke android:width="1dp" android:color="@color/GM2_grey_300"/>
+            <stroke android:width="1dp" android:color="?androidprv:attr/colorAccentSecondary"/>
             <solid android:color="@android:color/transparent"/>
             <corners android:radius="24dp"/>
         </shape>
diff --git a/packages/SystemUI/res/layout/global_screenshot_static.xml b/packages/SystemUI/res/layout/global_screenshot_static.xml
index ba46edc..665d4a0 100644
--- a/packages/SystemUI/res/layout/global_screenshot_static.xml
+++ b/packages/SystemUI/res/layout/global_screenshot_static.xml
@@ -127,6 +127,7 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:scaleType="matrix"
+        android:visibility="gone"
         app:layout_constraintStart_toStartOf="@id/global_screenshot_preview"
         app:layout_constraintTop_toTopOf="@id/global_screenshot_preview"
         android:elevation="@dimen/screenshot_preview_elevation"/>
diff --git a/packages/SystemUI/res/layout/long_screenshot.xml b/packages/SystemUI/res/layout/long_screenshot.xml
index 50f38b6..8a2c8f0 100644
--- a/packages/SystemUI/res/layout/long_screenshot.xml
+++ b/packages/SystemUI/res/layout/long_screenshot.xml
@@ -32,12 +32,27 @@
         android:text="@string/save"
         android:layout_marginStart="8dp"
         android:layout_marginTop="4dp"
-        android:background="@drawable/screenshot_save_background"
+        android:background="@drawable/screenshot_button_background"
         android:textColor="?android:textColorSecondary"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintBottom_toTopOf="@id/preview" />
 
+    <Button
+        android:id="@+id/cancel"
+        style="@android:style/Widget.DeviceDefault.Button.Colored"
+        android:layout_width="wrap_content"
+        android:layout_height="40dp"
+        android:text="@android:string/cancel"
+        android:layout_marginStart="6dp"
+        android:layout_marginTop="4dp"
+        android:background="@drawable/screenshot_button_background"
+        android:textColor="?android:textColorSecondary"
+        app:layout_constraintStart_toEndOf="@id/save"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toTopOf="@id/preview"
+    />
+
     <ImageButton
         android:id="@+id/share"
         style="@android:style/Widget.Material.Button.Borderless"
@@ -98,8 +113,9 @@
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintBottom_toBottomOf="parent"
         app:handleThickness="@dimen/screenshot_crop_handle_thickness"
-        app:handleColor="?androidprv:attr/colorAccentPrimary"
-        app:scrimColor="@color/screenshot_crop_scrim"
+        app:handleColor="?android:attr/colorAccent"
+        app:scrimColor="?android:colorBackgroundFloating"
+        app:scrimAlpha="128"
         app:containerBackgroundColor="?android:colorBackgroundFloating"
         tools:background="?android:colorBackground"
         tools:minHeight="100dp"
@@ -114,8 +130,9 @@
         app:layout_constraintTop_toTopOf="@id/preview"
         app:layout_constraintLeft_toLeftOf="parent"
         app:handleThickness="@dimen/screenshot_crop_handle_thickness"
-        app:handleColor="?androidprv:attr/colorAccentSecondary"
-        app:scrimColor="@color/screenshot_crop_scrim"
+        app:handleColor="?android:attr/colorAccent"
+        app:scrimColor="?android:colorBackgroundFloating"
+        app:scrimAlpha="128"
         app:borderThickness="4dp"
         app:borderColor="#fff"
         />
diff --git a/packages/SystemUI/res/layout/wallet_fullscreen.xml b/packages/SystemUI/res/layout/wallet_fullscreen.xml
index 71006f0..1dd400a 100644
--- a/packages/SystemUI/res/layout/wallet_fullscreen.xml
+++ b/packages/SystemUI/res/layout/wallet_fullscreen.xml
@@ -27,12 +27,24 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:background="@android:color/transparent"
-        android:navigationContentDescription="@null" />
+        android:navigationContentDescription="@null">
+        <Button
+            android:id="@+id/wallet_toolbar_app_button"
+            android:layout_width="wrap_content"
+            android:layout_height="30dp"
+            android:layout_gravity="end|center_horizontal"
+            android:paddingHorizontal="@dimen/wallet_button_horizontal_padding"
+            android:background="@drawable/wallet_app_button_bg"
+            android:text="@string/wallet_app_button_label"
+            android:textColor="?androidprv:attr/colorAccentPrimary"
+            android:textAlignment="center"
+            android:visibility="gone"/>
+    </Toolbar>
     <LinearLayout
         android:id="@+id/card_carousel_container"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:layout_marginTop="48dp"
+        android:layout_marginTop="@dimen/wallet_card_carousel_container_top_margin"
         android:orientation="vertical">
         <androidx.core.widget.NestedScrollView
             android:layout_width="match_parent"
@@ -54,6 +66,7 @@
                     android:id="@+id/label"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
+                    android:layout_marginBottom="24dp"
                     android:layout_marginHorizontal="48dp"
                     android:textColor="?androidprv:attr/textColorPrimary"
                     android:textAlignment="center"/>
@@ -67,7 +80,7 @@
                     android:transitionName="dotIndicator"
                     android:clipChildren="false"
                     android:clipToPadding="false"
-                    android:layout_marginVertical="24dp"/>
+                    android:layout_marginBottom="24dp"/>
                 <Button
                     android:id="@+id/wallet_action_button"
                     android:layout_width="wrap_content"
@@ -83,6 +96,7 @@
             </LinearLayout>
         </androidx.core.widget.NestedScrollView>
         <View
+            android:id="@+id/dynamic_placeholder"
             android:layout_width="match_parent"
             android:layout_height="0dp"
             android:layout_weight="0.1"/>
diff --git a/packages/SystemUI/res/values-h800dp/dimens.xml b/packages/SystemUI/res/values-h800dp/dimens.xml
index cfacbec..19ec8ce 100644
--- a/packages/SystemUI/res/values-h800dp/dimens.xml
+++ b/packages/SystemUI/res/values-h800dp/dimens.xml
@@ -20,4 +20,7 @@
 
     <!-- Large clock maximum font size (dp is intentional, to prevent any further scaling) -->
     <dimen name="large_clock_text_size">200dp</dimen>
+
+    <!-- With the large clock, move up slightly from the center -->
+    <dimen name="keyguard_large_clock_top_margin">-104dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index 9df9db6..34bf28a 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -64,4 +64,6 @@
     <!-- (footer_height -48dp)/2 -->
     <dimen name="controls_management_footer_top_margin">4dp</dimen>
     <dimen name="controls_management_favorites_top_margin">8dp</dimen>
+
+    <dimen name="wallet_card_carousel_container_top_margin">24dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index d2ed601..b5337d36 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -143,6 +143,8 @@
     <attr name="handleThickness" format="dimension" />
     <attr name="handleColor" format="color" />
     <attr name="scrimColor" format="color" />
+    <!-- Int [0,255] for the alpha to be applied to scrimColor -->
+    <attr name="scrimAlpha" format="integer" />
     <attr name="containerBackgroundColor" format="color" />
 
     <attr name="isVertical" format="boolean" />
@@ -179,6 +181,7 @@
         <attr name="handleThickness" />
         <attr name="handleColor" />
         <attr name="scrimColor" />
+        <attr name="scrimAlpha" />
         <attr name="containerBackgroundColor" />
     </declare-styleable>
 
@@ -186,6 +189,7 @@
         <attr name="handleThickness" />
         <attr name="handleColor" />
         <attr name="scrimColor" />
+        <attr name="scrimAlpha" />
         <attr name="borderThickness" format="dimension" />
         <attr name="borderColor" format="color" />
     </declare-styleable>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 020a100..2260d21 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -199,9 +199,6 @@
     <color name="global_screenshot_button_ripple">#1f000000</color>
     <color name="global_screenshot_background_protection_start">#40000000</color> <!-- 25% black -->
 
-    <!-- Long screenshot UI -->
-    <color name="screenshot_crop_scrim">#6444</color>
-
     <!-- GM2 colors -->
     <color name="GM2_grey_50">#F8F9FA</color>
     <color name="GM2_grey_100">#F1F3F4</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index a526803..3b4651a 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -208,7 +208,7 @@
     <dimen name="keyguard_indication_y_translation">24dp</dimen>
 
     <!-- The padding on the bottom of the notifications on the keyguard -->
-    <dimen name="keyguard_indication_bottom_padding">12sp</dimen>
+    <dimen name="keyguard_indication_bottom_padding">16sp</dimen>
 
     <!-- The padding at start and end of indication text shown on AOD -->
     <dimen name="keyguard_indication_text_padding">16dp</dimen>
@@ -743,6 +743,10 @@
     <dimen name="keyguard_clock_lock_margin">16dp</dimen>
     <!-- The amount to shift the clocks during a small/large transition -->
     <dimen name="keyguard_clock_switch_y_shift">10dp</dimen>
+    <!-- When large clock is showing, offset the smartspace by this amount -->
+    <dimen name="keyguard_smartspace_top_offset">12dp</dimen>
+    <!-- With the large clock, move up slightly from the center -->
+    <dimen name="keyguard_large_clock_top_margin">-52dp</dimen>
 
     <!-- Default line spacing multiplier between hours and minutes of the keyguard clock -->
     <item name="keyguard_clock_line_spacing_scale" type="dimen" format="float">.7</item>
@@ -1546,6 +1550,7 @@
     <dimen name="wallet_screen_header_icon_size">56dp</dimen>
     <dimen name="wallet_screen_header_view_size">80dp</dimen>
     <dimen name="card_margin">16dp</dimen>
+    <dimen name="wallet_card_carousel_container_top_margin">48dp</dimen>
     <dimen name="card_carousel_dot_offset">24dp</dimen>
     <dimen name="card_carousel_dot_unselected_radius">2dp</dimen>
     <dimen name="card_carousel_dot_selected_radius">3dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index bc1c67c..11a2f70 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1660,7 +1660,9 @@
     <!-- Label of the button underneath the card carousel prompting user unlock device. [CHAR LIMIT=NONE] -->
     <string name="wallet_action_button_label_unlock">Unlock to pay</string>
     <!-- Secondary label of the quick access wallet tile if no card. [CHAR LIMIT=NONE] -->
-    <string name="wallet_secondary_label_no_card">Not set up</string>
+    <string name="wallet_secondary_label_no_card">Add a card</string>
+    <!-- Secondary label of the quick access wallet tile if wallet is still updating. [CHAR LIMIT=NONE] -->
+    <string name="wallet_secondary_label_updating">Updating</string>
     <!-- Secondary label of the quick access wallet tile if device locked. [CHAR LIMIT=NONE] -->
     <string name="wallet_secondary_label_device_locked">Unlock to use</string>
     <!-- Message shown when an unknown failure occurred when fetching cards. [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
index 998b318..42d628a 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
@@ -82,8 +82,8 @@
         final float scale = sourceBounds.width() <= sourceBounds.height()
                 ? (float) destinationBounds.width() / sourceBounds.width()
                 : (float) destinationBounds.height() / sourceBounds.height();
-        final float left = destinationBounds.left - insets.left * scale;
-        final float top = destinationBounds.top - insets.top * scale;
+        final float left = destinationBounds.left - (insets.left + sourceBounds.left) * scale;
+        final float top = destinationBounds.top - (insets.top + sourceBounds.top) * scale;
         mTmpTransform.setScale(scale, scale);
         final float cornerRadius = getScaledCornerRadius(mTmpDestinationRect, destinationBounds);
         tx.setMatrix(leash, mTmpTransform, mTmpFloat9)
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java
index c90833c..2b35bcd 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java
@@ -345,7 +345,7 @@
                 // Create our own ClassLoader so we can use our own code as the parent.
                 ClassLoader classLoader = mManager.getClassLoader(info);
                 Context pluginContext = new PluginContextWrapper(
-                        mContext.createPackageContext(pkg, 0), classLoader);
+                        mContext.createApplicationContext(info, 0), classLoader);
                 Class<?> pluginClass = Class.forName(cls, true, classLoader);
                 // TODO: Only create the plugin before version check if we need it for
                 // legacy version check.
diff --git a/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java b/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
index 08076c1..4b3af34 100644
--- a/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
@@ -94,7 +94,9 @@
         @Override
         public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
             if (mKeyguardShowing && !mIsCharging && charging) {
-                mView.animateCharge(mIsDozing);
+                mView.animateCharge(() -> {
+                    return mStatusBarStateController.isDozing();
+                });
             }
             mIsCharging = charging;
         }
diff --git a/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.java b/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.java
index 63867c0..58b3865 100644
--- a/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.java
+++ b/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.java
@@ -196,20 +196,20 @@
                 null /* onAnimationEnd */);
     }
 
-    void animateCharge(boolean isDozing) {
+    void animateCharge(DozeStateGetter dozeStateGetter) {
         if (mTextAnimator == null || mTextAnimator.isRunning()) {
             // Skip charge animation if dozing animation is already playing.
             return;
         }
         Runnable startAnimPhase2 = () -> setTextStyle(
-                isDozing ? mDozingWeight : mLockScreenWeight/* weight */,
+                dozeStateGetter.isDozing() ? mDozingWeight : mLockScreenWeight/* weight */,
                 -1,
                 null,
                 true /* animate */,
                 CHARGE_ANIM_DURATION_PHASE_1,
                 0 /* delay */,
                 null /* onAnimationEnd */);
-        setTextStyle(isDozing ? mLockScreenWeight : mDozingWeight/* weight */,
+        setTextStyle(dozeStateGetter.isDozing() ? mLockScreenWeight : mDozingWeight/* weight */,
                 -1,
                 null,
                 true /* animate */,
@@ -279,4 +279,8 @@
                 context.getResources().getConfiguration().locale);
         return dtpg.getBestPattern(skeleton);
     }
+
+    interface DozeStateGetter {
+        boolean isDozing();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index ef052c4..a5b2509 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -57,6 +57,7 @@
     private View mKeyguardStatusArea;
     /** Mutually exclusive with mKeyguardStatusArea */
     private View mSmartspaceView;
+    private int mSmartspaceTopOffset;
 
     /**
      * Maintain state so that a newly connected plugin can be initialized.
@@ -96,6 +97,9 @@
 
         mClockSwitchYAmount = mContext.getResources().getDimensionPixelSize(
                 R.dimen.keyguard_clock_switch_y_shift);
+
+        mSmartspaceTopOffset = mContext.getResources().getDimensionPixelSize(
+                R.dimen.keyguard_smartspace_top_offset);
     }
 
     /**
@@ -193,7 +197,7 @@
             if (indexOfChild(in) == -1) addView(in);
             direction = -1;
             smartspaceYTranslation = mSmartspaceView == null ? 0
-                    : mClockFrame.getTop() - mSmartspaceView.getTop();
+                    : mClockFrame.getTop() - mSmartspaceView.getTop() + mSmartspaceTopOffset;
         } else {
             in = mClockFrame;
             out = mLargeClockFrame;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index a28d174..781f34bf 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -189,10 +189,7 @@
                     .getDimensionPixelSize(R.dimen.below_clock_padding_end);
             mSmartspaceView.setPaddingRelative(startPadding, 0, endPadding, 0);
 
-            // ... but above the large clock
-            lp = new RelativeLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
-            lp.addRule(RelativeLayout.BELOW, mSmartspaceView.getId());
-            mLargeClockFrame.setLayoutParams(lp);
+            updateClockLayout();
 
             View nic = mView.findViewById(
                     R.id.left_aligned_notification_icon_container);
@@ -235,6 +232,18 @@
      */
     public void onDensityOrFontScaleChanged() {
         mView.onDensityOrFontScaleChanged();
+
+        updateClockLayout();
+    }
+
+    private void updateClockLayout() {
+        if (mSmartspaceController.isEnabled()) {
+            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(MATCH_PARENT,
+                    MATCH_PARENT);
+            lp.topMargin = getContext().getResources().getDimensionPixelSize(
+                    R.dimen.keyguard_large_clock_top_margin);
+            mLargeClockFrame.setLayoutParams(lp);
+        }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
index 2325b55..8fc4240 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
@@ -17,16 +17,20 @@
 package com.android.keyguard;
 
 import android.content.Context;
+import android.content.res.Configuration;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.animation.AnimationUtils;
+import android.widget.LinearLayout;
 
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.settingslib.animation.AppearAnimationUtils;
 import com.android.settingslib.animation.DisappearAnimationUtils;
 import com.android.systemui.R;
 
+import java.util.List;
+
 /**
  * Displays a PIN pad for unlocking.
  */
@@ -64,6 +68,11 @@
     }
 
     @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        updateMargins();
+    }
+
+    @Override
     protected void resetState() {
     }
 
@@ -72,6 +81,33 @@
         return R.id.pinEntry;
     }
 
+    private void updateMargins() {
+        int bottomMargin = mContext.getResources().getDimensionPixelSize(
+                R.dimen.num_pad_row_margin_bottom);
+
+        for (ViewGroup vg : List.of(mRow1, mRow2, mRow3)) {
+            ((LinearLayout.LayoutParams) vg.getLayoutParams()).setMargins(0, 0, 0, bottomMargin);
+        }
+
+        bottomMargin = mContext.getResources().getDimensionPixelSize(
+                R.dimen.num_pad_entry_row_margin_bottom);
+        ((LinearLayout.LayoutParams) mRow0.getLayoutParams()).setMargins(0, 0, 0, bottomMargin);
+
+        if (mEcaView != null) {
+            int ecaTopMargin = mContext.getResources().getDimensionPixelSize(
+                    R.dimen.keyguard_eca_top_margin);
+            int ecaBottomMargin = mContext.getResources().getDimensionPixelSize(
+                    R.dimen.keyguard_eca_bottom_margin);
+            ((LinearLayout.LayoutParams) mEcaView.getLayoutParams()).setMargins(0, ecaTopMargin,
+                    0, ecaBottomMargin);
+        }
+
+        View entryView = findViewById(R.id.pinEntry);
+        ViewGroup.LayoutParams lp = entryView.getLayoutParams();
+        lp.height = mContext.getResources().getDimensionPixelSize(R.dimen.keyguard_password_height);
+        entryView.setLayoutParams(lp);
+    }
+
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
index 0d31906..099e6f4 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
@@ -17,6 +17,7 @@
 
 import android.content.Context;
 import android.content.res.ColorStateList;
+import android.content.res.Configuration;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.RippleDrawable;
 import android.graphics.drawable.VectorDrawable;
@@ -26,7 +27,6 @@
 import androidx.annotation.Nullable;
 
 import com.android.settingslib.Utils;
-import com.android.systemui.R;
 
 /**
  * Similar to the {@link NumPadKey}, but displays an image.
@@ -35,6 +35,7 @@
 
     @Nullable
     private NumPadAnimator mAnimator;
+    private int mOrientation;
 
     public NumPadButton(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -49,13 +50,21 @@
     }
 
     @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        mOrientation = newConfig.orientation;
+    }
+
+    @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 
         // Set width/height to the same value to ensure a smooth circle for the bg, but shrink
         // the height to match the old pin bouncer
         int width = getMeasuredWidth();
-        int height = mAnimator == null ? (int) (width * .75f) : width;
+
+        boolean shortenHeight = mAnimator == null
+                || mOrientation == Configuration.ORIENTATION_LANDSCAPE;
+        int height = shortenHeight ? (int) (width * .66f) : width;
 
         setMeasuredDimension(getMeasuredWidth(), height);
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
index cffa630..232c6fc 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
@@ -13,10 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package com.android.keyguard;
 
 import android.content.Context;
+import android.content.res.Configuration;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.RippleDrawable;
@@ -52,6 +52,7 @@
 
     @Nullable
     private NumPadAnimator mAnimator;
+    private int mOrientation;
 
     private View.OnClickListener mListener = new View.OnClickListener() {
         @Override
@@ -139,6 +140,11 @@
         }
     }
 
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        mOrientation = newConfig.orientation;
+    }
+
     /**
      * Reload colors from resources.
      **/
@@ -171,7 +177,10 @@
         // Set width/height to the same value to ensure a smooth circle for the bg, but shrink
         // the height to match the old pin bouncer
         int width = getMeasuredWidth();
-        int height = mAnimator == null ? (int) (width * .75f) : width;
+
+        boolean shortenHeight = mAnimator == null
+                || mOrientation == Configuration.ORIENTATION_LANDSCAPE;
+        int height = shortenHeight ? (int) (width * .66f) : width;
 
         setMeasuredDimension(getMeasuredWidth(), height);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/backup/BackupHelper.kt b/packages/SystemUI/src/com/android/systemui/backup/BackupHelper.kt
index fe31a7b..c9e67715 100644
--- a/packages/SystemUI/src/com/android/systemui/backup/BackupHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/backup/BackupHelper.kt
@@ -29,6 +29,7 @@
 import android.util.Log
 import com.android.systemui.controls.controller.AuxiliaryPersistenceWrapper
 import com.android.systemui.controls.controller.ControlsFavoritePersistenceWrapper
+import com.android.systemui.people.widget.PeopleBackupHelper
 
 /**
  * Helper for backing up elements in SystemUI
@@ -45,18 +46,29 @@
         private const val TAG = "BackupHelper"
         internal const val CONTROLS = ControlsFavoritePersistenceWrapper.FILE_NAME
         private const val NO_OVERWRITE_FILES_BACKUP_KEY = "systemui.files_no_overwrite"
+        private const val PEOPLE_TILES_BACKUP_KEY = "systemui.people.shared_preferences"
         val controlsDataLock = Any()
         const val ACTION_RESTORE_FINISHED = "com.android.systemui.backup.RESTORE_FINISHED"
         private const val PERMISSION_SELF = "com.android.systemui.permission.SELF"
     }
 
-    override fun onCreate() {
+    override fun onCreate(userHandle: UserHandle, operationType: Int) {
         super.onCreate()
         // The map in mapOf is guaranteed to be order preserving
         val controlsMap = mapOf(CONTROLS to getPPControlsFile(this))
         NoOverwriteFileBackupHelper(controlsDataLock, this, controlsMap).also {
             addHelper(NO_OVERWRITE_FILES_BACKUP_KEY, it)
         }
+
+        // Conversations widgets backup only works for system user, because widgets' information is
+        // stored in system user's SharedPreferences files and we can't open those from other users.
+        if (!userHandle.isSystem) {
+            return
+        }
+
+        val keys = PeopleBackupHelper.getFilesToBackup()
+        addHelper(PEOPLE_TILES_BACKUP_KEY, PeopleBackupHelper(
+                this, userHandle, keys.toTypedArray()))
     }
 
     override fun onRestoreFinished() {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 2d04d8d..c5a0dfb 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -147,6 +147,7 @@
     @Nullable private Runnable mCancelAodTimeoutAction;
     private boolean mScreenOn;
     private Runnable mAodInterruptRunnable;
+    private boolean mOnFingerDown;
 
     @VisibleForTesting
     public static final AudioAttributes VIBRATION_SONIFICATION_ATTRIBUTES =
@@ -596,8 +597,10 @@
     }
 
     private void updateOverlay() {
+        mExecution.assertIsMainThread();
+
         if (mServerRequest != null) {
-            showUdfpsOverlay(mServerRequest.mRequestReason);
+            showUdfpsOverlay(mServerRequest);
         } else {
             hideUdfpsOverlay();
         }
@@ -658,36 +661,37 @@
         updateOverlay();
     }
 
-    private void showUdfpsOverlay(int reason) {
-        mFgExecutor.execute(() -> {
-            if (mView == null) {
-                try {
-                    Log.v(TAG, "showUdfpsOverlay | adding window reason=" + reason);
-                    mView = (UdfpsView) mInflater.inflate(R.layout.udfps_view, null, false);
-                    mView.setSensorProperties(mSensorProps);
-                    mView.setHbmProvider(mHbmProvider);
-                    UdfpsAnimationViewController animation = inflateUdfpsAnimation(reason);
-                    animation.init();
-                    mView.setAnimationViewController(animation);
+    private void showUdfpsOverlay(@NonNull ServerRequest request) {
+        mExecution.assertIsMainThread();
+        final int reason = request.mRequestReason;
+        if (mView == null) {
+            try {
+                Log.v(TAG, "showUdfpsOverlay | adding window reason=" + reason);
+                mView = (UdfpsView) mInflater.inflate(R.layout.udfps_view, null, false);
+                mOnFingerDown = false;
+                mView.setSensorProperties(mSensorProps);
+                mView.setHbmProvider(mHbmProvider);
+                UdfpsAnimationViewController animation = inflateUdfpsAnimation(reason);
+                animation.init();
+                mView.setAnimationViewController(animation);
 
-                    // This view overlaps the sensor area, so prevent it from being selectable
-                    // during a11y.
-                    if (reason == IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR
-                            || reason == IUdfpsOverlayController.REASON_ENROLL_ENROLLING) {
-                        mView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
-                    }
-
-                    mWindowManager.addView(mView, computeLayoutParams(animation));
-                    mAccessibilityManager.addTouchExplorationStateChangeListener(
-                            mTouchExplorationStateChangeListener);
-                    updateTouchListener();
-                } catch (RuntimeException e) {
-                    Log.e(TAG, "showUdfpsOverlay | failed to add window", e);
+                // This view overlaps the sensor area, so prevent it from being selectable
+                // during a11y.
+                if (reason == IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR
+                        || reason == IUdfpsOverlayController.REASON_ENROLL_ENROLLING) {
+                    mView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
                 }
-            } else {
-                Log.v(TAG, "showUdfpsOverlay | the overlay is already showing");
+
+                mWindowManager.addView(mView, computeLayoutParams(animation));
+                mAccessibilityManager.addTouchExplorationStateChangeListener(
+                        mTouchExplorationStateChangeListener);
+                updateTouchListener();
+            } catch (RuntimeException e) {
+                Log.e(TAG, "showUdfpsOverlay | failed to add window", e);
             }
-        });
+        } else {
+            Log.v(TAG, "showUdfpsOverlay | the overlay is already showing");
+        }
     }
 
     private UdfpsAnimationViewController inflateUdfpsAnimation(int reason) {
@@ -823,6 +827,7 @@
             Log.w(TAG, "Null view in onFingerDown");
             return;
         }
+        mOnFingerDown = true;
         mFingerprintManager.onPointerDown(mSensorProps.sensorId, x, y, minor, major);
         Trace.endAsyncSection("UdfpsController.e2e.onPointerDown", 0);
         Trace.beginAsyncSection("UdfpsController.e2e.startIllumination", 0);
@@ -840,7 +845,10 @@
             Log.w(TAG, "Null view in onFingerUp");
             return;
         }
-        mFingerprintManager.onPointerUp(mSensorProps.sensorId);
+        if (mOnFingerDown) {
+            mFingerprintManager.onPointerUp(mSensorProps.sensorId);
+        }
+        mOnFingerDown = false;
         if (mView.isIlluminationRequested()) {
             mView.stopIllumination();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java
index ac4fc62..d1a103e 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java
@@ -22,7 +22,6 @@
 import android.util.LayoutDirection;
 import android.view.View;
 import android.view.View.MeasureSpec;
-import android.view.WindowManager;
 import android.widget.AdapterView;
 import android.widget.ListAdapter;
 import android.widget.ListPopupWindow;
@@ -49,11 +48,9 @@
         mContext = context;
         Resources res = mContext.getResources();
         setBackgroundDrawable(
-                res.getDrawable(R.drawable.rounded_bg_full, context.getTheme()));
+                res.getDrawable(R.drawable.global_actions_popup_bg, context.getTheme()));
         mIsDropDownMode = isDropDownMode;
 
-        // required to show above the global actions dialog
-        setWindowLayoutType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
         setInputMethodMode(INPUT_METHOD_NOT_NEEDED);
         setModal(true);
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index c84d6a8..b5fd739 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -2161,6 +2161,15 @@
             if (!mHiding
                     && !mSurfaceBehindRemoteAnimationRequested
                     && !mKeyguardStateController.isFlingingToDismissKeyguardDuringSwipeGesture()) {
+                if (finishedCallback != null) {
+                    // There will not execute animation, send a finish callback to ensure the remote
+                    // animation won't hanging there.
+                    try {
+                        finishedCallback.onAnimationFinished();
+                    } catch (RemoteException e) {
+                        Slog.w(TAG, "Failed to call onAnimationFinished", e);
+                    }
+                }
                 setShowingLocked(mShowing, true /* force */);
                 return;
             }
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleBackupFollowUpJob.java b/packages/SystemUI/src/com/android/systemui/people/PeopleBackupFollowUpJob.java
new file mode 100644
index 0000000..452484f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleBackupFollowUpJob.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.people;
+
+import static com.android.systemui.people.PeopleSpaceUtils.DEBUG;
+import static com.android.systemui.people.PeopleSpaceUtils.EMPTY_STRING;
+import static com.android.systemui.people.PeopleSpaceUtils.removeSharedPreferencesStorageForTile;
+import static com.android.systemui.people.widget.PeopleBackupHelper.isReadyForRestore;
+
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.app.people.IPeopleManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.os.PersistableBundle;
+import android.os.ServiceManager;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.systemui.people.widget.PeopleBackupHelper;
+import com.android.systemui.people.widget.PeopleTileKey;
+
+import java.time.Duration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Follow-up job that runs after a Conversations widgets restore operation. Check if shortcuts that
+ * were not available before are now available. If any shortcut doesn't become available after
+ * 1 day, we clean up its storage.
+ */
+public class PeopleBackupFollowUpJob extends JobService {
+    private static final String TAG = "PeopleBackupFollowUpJob";
+    private static final String START_DATE = "start_date";
+
+    /** Follow-up job id. */
+    public static final int JOB_ID = 74823873;
+
+    private static final long JOB_PERIODIC_DURATION = Duration.ofHours(6).toMillis();
+    private static final long CLEAN_UP_STORAGE_AFTER_DURATION = Duration.ofHours(24).toMillis();
+
+    /** SharedPreferences file name for follow-up specific storage.*/
+    public static final String SHARED_FOLLOW_UP = "shared_follow_up";
+
+    private final Object mLock = new Object();
+    private Context mContext;
+    private PackageManager mPackageManager;
+    private IPeopleManager mIPeopleManager;
+    private JobScheduler mJobScheduler;
+
+    /** Schedules a PeopleBackupFollowUpJob every 2 hours. */
+    public static void scheduleJob(Context context) {
+        JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
+        PersistableBundle bundle = new PersistableBundle();
+        bundle.putLong(START_DATE, System.currentTimeMillis());
+        JobInfo jobInfo = new JobInfo
+                .Builder(JOB_ID, new ComponentName(context, PeopleBackupFollowUpJob.class))
+                .setPeriodic(JOB_PERIODIC_DURATION)
+                .setExtras(bundle)
+                .build();
+        jobScheduler.schedule(jobInfo);
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        mContext = getApplicationContext();
+        mPackageManager = getApplicationContext().getPackageManager();
+        mIPeopleManager = IPeopleManager.Stub.asInterface(
+                ServiceManager.getService(Context.PEOPLE_SERVICE));
+        mJobScheduler = mContext.getSystemService(JobScheduler.class);
+
+    }
+
+    /** Sets necessary managers for testing. */
+    @VisibleForTesting
+    public void setManagers(Context context, PackageManager packageManager,
+            IPeopleManager iPeopleManager, JobScheduler jobScheduler) {
+        mContext = context;
+        mPackageManager = packageManager;
+        mIPeopleManager = iPeopleManager;
+        mJobScheduler = jobScheduler;
+    }
+
+    @Override
+    public boolean onStartJob(JobParameters params) {
+        if (DEBUG) Log.d(TAG, "Starting job.");
+        synchronized (mLock) {
+            SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
+            SharedPreferences.Editor editor = sp.edit();
+            SharedPreferences followUp = this.getSharedPreferences(
+                    SHARED_FOLLOW_UP, Context.MODE_PRIVATE);
+            SharedPreferences.Editor followUpEditor = followUp.edit();
+
+            // Remove from SHARED_FOLLOW_UP storage all widgets that are now ready to be updated.
+            Map<String, Set<String>> remainingWidgets =
+                    processFollowUpFile(followUp, followUpEditor);
+
+            // Check if all widgets were restored or if enough time elapsed to cancel the job.
+            long start = params.getExtras().getLong(START_DATE);
+            long now = System.currentTimeMillis();
+            if (shouldCancelJob(remainingWidgets, start, now)) {
+                cancelJobAndClearRemainingWidgets(remainingWidgets, followUpEditor, sp);
+            }
+
+            editor.apply();
+            followUpEditor.apply();
+        }
+
+        // Ensure all widgets modified from SHARED_FOLLOW_UP storage are now updated.
+        PeopleBackupHelper.updateWidgets(mContext);
+        return false;
+    }
+
+    /**
+     * Iterates through follow-up file entries and checks which shortcuts are now available.
+     * Returns a map of shortcuts that should be checked at a later time.
+     */
+    public Map<String, Set<String>> processFollowUpFile(SharedPreferences followUp,
+            SharedPreferences.Editor followUpEditor) {
+        Map<String, Set<String>> remainingWidgets = new HashMap<>();
+        Map<String, ?> all = followUp.getAll();
+        for (Map.Entry<String, ?> entry : all.entrySet()) {
+            String key = entry.getKey();
+
+            PeopleTileKey peopleTileKey = PeopleTileKey.fromString(key);
+            boolean restored = isReadyForRestore(mIPeopleManager, mPackageManager, peopleTileKey);
+            if (restored) {
+                if (DEBUG) Log.d(TAG, "Removing key from follow-up: " + key);
+                followUpEditor.remove(key);
+                continue;
+            }
+
+            if (DEBUG) Log.d(TAG, "Key should not be restored yet, try later: " + key);
+            try {
+                remainingWidgets.put(entry.getKey(), (Set<String>) entry.getValue());
+            } catch (Exception e) {
+                Log.e(TAG, "Malformed entry value: " + entry.getValue());
+            }
+        }
+        return remainingWidgets;
+    }
+
+    /** Returns whether all shortcuts were restored or if enough time elapsed to cancel the job. */
+    public boolean shouldCancelJob(Map<String, Set<String>> remainingWidgets,
+            long start, long now) {
+        if (remainingWidgets.isEmpty()) {
+            if (DEBUG) Log.d(TAG, "All widget storage was successfully restored.");
+            return true;
+        }
+
+        boolean oneDayHasPassed = (now - start) > CLEAN_UP_STORAGE_AFTER_DURATION;
+        if (oneDayHasPassed) {
+            if (DEBUG) {
+                Log.w(TAG, "One or more widgets were not properly restored, "
+                        + "but cancelling job because it has been a day.");
+            }
+            return true;
+        }
+        if (DEBUG) Log.d(TAG, "There are still non-restored widgets, run job again.");
+        return false;
+    }
+
+    /** Cancels job and removes storage of any shortcut that was not restored. */
+    public void cancelJobAndClearRemainingWidgets(Map<String, Set<String>> remainingWidgets,
+            SharedPreferences.Editor followUpEditor, SharedPreferences sp) {
+        if (DEBUG) Log.d(TAG, "Cancelling follow up job.");
+        removeUnavailableShortcutsFromSharedStorage(remainingWidgets, sp);
+        followUpEditor.clear();
+        mJobScheduler.cancel(JOB_ID);
+    }
+
+    private void removeUnavailableShortcutsFromSharedStorage(Map<String,
+            Set<String>> remainingWidgets, SharedPreferences sp) {
+        for (Map.Entry<String, Set<String>> entry : remainingWidgets.entrySet()) {
+            PeopleTileKey peopleTileKey = PeopleTileKey.fromString(entry.getKey());
+            if (!PeopleTileKey.isValid(peopleTileKey)) {
+                Log.e(TAG, "Malformed peopleTileKey in follow-up file: " + entry.getKey());
+                continue;
+            }
+            Set<String> widgetIds;
+            try {
+                widgetIds = (Set<String>) entry.getValue();
+            } catch (Exception e) {
+                Log.e(TAG, "Malformed widget ids in follow-up file: " + e);
+                continue;
+            }
+            for (String id : widgetIds) {
+                int widgetId;
+                try {
+                    widgetId = Integer.parseInt(id);
+                } catch (NumberFormatException ex) {
+                    Log.e(TAG, "Malformed widget id in follow-up file: " + ex);
+                    continue;
+                }
+
+                String contactUriString = sp.getString(String.valueOf(widgetId), EMPTY_STRING);
+                removeSharedPreferencesStorageForTile(
+                        mContext, peopleTileKey, widgetId, contactUriString);
+            }
+        }
+    }
+
+    @Override
+    public boolean onStopJob(JobParameters params) {
+        return false;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
index 917a060..dcab86b 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
@@ -25,6 +25,7 @@
 
 import android.annotation.Nullable;
 import android.app.Notification;
+import android.app.backup.BackupManager;
 import android.app.people.ConversationChannel;
 import android.app.people.IPeopleManager;
 import android.app.people.PeopleSpaceTile;
@@ -89,7 +90,7 @@
 
     /** Returns stored widgets for the conversation specified. */
     public static Set<String> getStoredWidgetIds(SharedPreferences sp, PeopleTileKey key) {
-        if (!key.isValid()) {
+        if (!PeopleTileKey.isValid(key)) {
             return new HashSet<>();
         }
         return new HashSet<>(sp.getStringSet(key.toString(), new HashSet<>()));
@@ -97,19 +98,16 @@
 
     /** Sets all relevant storage for {@code appWidgetId} association to {@code tile}. */
     public static void setSharedPreferencesStorageForTile(Context context, PeopleTileKey key,
-            int appWidgetId, Uri contactUri) {
-        if (!key.isValid()) {
+            int appWidgetId, Uri contactUri, BackupManager backupManager) {
+        if (!PeopleTileKey.isValid(key)) {
             Log.e(TAG, "Not storing for invalid key");
             return;
         }
         // Write relevant persisted storage.
         SharedPreferences widgetSp = context.getSharedPreferences(String.valueOf(appWidgetId),
                 Context.MODE_PRIVATE);
-        SharedPreferences.Editor widgetEditor = widgetSp.edit();
-        widgetEditor.putString(PeopleSpaceUtils.PACKAGE_NAME, key.getPackageName());
-        widgetEditor.putString(PeopleSpaceUtils.SHORTCUT_ID, key.getShortcutId());
-        widgetEditor.putInt(PeopleSpaceUtils.USER_ID, key.getUserId());
-        widgetEditor.apply();
+        SharedPreferencesHelper.setPeopleTileKey(widgetSp, key);
+
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
         SharedPreferences.Editor editor = sp.edit();
         String contactUriString = contactUri == null ? EMPTY_STRING : contactUri.toString();
@@ -117,14 +115,18 @@
 
         // Don't overwrite existing widgets with the same key.
         addAppWidgetIdForKey(sp, editor, appWidgetId, key.toString());
-        addAppWidgetIdForKey(sp, editor, appWidgetId, contactUriString);
+        if (!TextUtils.isEmpty(contactUriString)) {
+            addAppWidgetIdForKey(sp, editor, appWidgetId, contactUriString);
+        }
         editor.apply();
+        backupManager.dataChanged();
     }
 
     /** Removes stored data when tile is deleted. */
     public static void removeSharedPreferencesStorageForTile(Context context, PeopleTileKey key,
             int widgetId, String contactUriString) {
         // Delete widgetId mapping to key.
+        if (DEBUG) Log.d(TAG, "Removing widget info from sharedPrefs");
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
         SharedPreferences.Editor editor = sp.edit();
         editor.remove(String.valueOf(widgetId));
@@ -230,7 +232,7 @@
      */
     public static PeopleSpaceTile augmentTileFromNotification(Context context, PeopleSpaceTile tile,
             PeopleTileKey key, NotificationEntry notificationEntry, int messagesCount,
-            Optional<Integer> appWidgetId) {
+            Optional<Integer> appWidgetId, BackupManager backupManager) {
         if (notificationEntry == null || notificationEntry.getSbn().getNotification() == null) {
             if (DEBUG) Log.d(TAG, "Tile key: " + key.toString() + ". Notification is null");
             return removeNotificationFields(tile);
@@ -246,7 +248,7 @@
             Uri contactUri = Uri.parse(uriFromNotification);
             // Update storage.
             setSharedPreferencesStorageForTile(context, new PeopleTileKey(tile), appWidgetId.get(),
-                    contactUri);
+                    contactUri, backupManager);
             // Update cached tile in-memory.
             updatedTile.setContactUri(contactUri);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
index 844a8c6..d363614 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
@@ -330,11 +330,8 @@
                     R.layout.people_tile_suppressed_layout);
         }
         Drawable appIcon = mContext.getDrawable(R.drawable.ic_conversation_icon);
-        Bitmap appIconAsBitmap = convertDrawableToBitmap(appIcon);
-        FastBitmapDrawable drawable = new FastBitmapDrawable(appIconAsBitmap);
-        drawable.setIsDisabled(true);
-        Bitmap convertedBitmap = convertDrawableToBitmap(drawable);
-        views.setImageViewBitmap(R.id.icon, convertedBitmap);
+        Bitmap disabledBitmap = convertDrawableToDisabledBitmap(appIcon);
+        views.setImageViewBitmap(R.id.icon, disabledBitmap);
         return views;
     }
 
@@ -504,6 +501,11 @@
     }
 
     private RemoteViews setLaunchIntents(RemoteViews views) {
+        if (!PeopleTileKey.isValid(mKey) || mTile == null) {
+            if (DEBUG) Log.d(TAG, "Skipping launch intent, Null tile or invalid key: " + mKey);
+            return views;
+        }
+
         try {
             Intent activityIntent = new Intent(mContext, LaunchConversationActivity.class);
             activityIntent.addFlags(
@@ -706,7 +708,8 @@
         views.setViewVisibility(R.id.predefined_icon, View.VISIBLE);
         views.setTextViewText(R.id.text_content, statusText);
 
-        if (status.getActivity() == ACTIVITY_BIRTHDAY) {
+        if (status.getActivity() == ACTIVITY_BIRTHDAY
+            || status.getActivity() == ACTIVITY_UPCOMING_BIRTHDAY) {
             setEmojiBackground(views, EMOJI_CAKE);
         }
 
@@ -1067,7 +1070,8 @@
 
         Icon icon = tile.getUserIcon();
         if (icon == null) {
-            return null;
+            Drawable placeholder = context.getDrawable(R.drawable.ic_avatar_with_badge);
+            return convertDrawableToDisabledBitmap(placeholder);
         }
         PeopleStoryIconFactory storyIcon = new PeopleStoryIconFactory(context,
                 context.getPackageManager(),
@@ -1179,4 +1183,11 @@
             mAvatarSize = avatarSize;
         }
     }
+
+    private static Bitmap convertDrawableToDisabledBitmap(Drawable icon) {
+        Bitmap appIconAsBitmap = convertDrawableToBitmap(icon);
+        FastBitmapDrawable drawable = new FastBitmapDrawable(appIconAsBitmap);
+        drawable.setIsDisabled(true);
+        return convertDrawableToBitmap(drawable);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/people/SharedPreferencesHelper.java b/packages/SystemUI/src/com/android/systemui/people/SharedPreferencesHelper.java
new file mode 100644
index 0000000..aef08fb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/people/SharedPreferencesHelper.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.people;
+
+import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
+import static com.android.systemui.people.PeopleSpaceUtils.PACKAGE_NAME;
+import static com.android.systemui.people.PeopleSpaceUtils.SHORTCUT_ID;
+import static com.android.systemui.people.PeopleSpaceUtils.USER_ID;
+
+import android.content.SharedPreferences;
+
+import com.android.systemui.people.widget.PeopleTileKey;
+
+/** Helper class for Conversations widgets SharedPreferences storage. */
+public class SharedPreferencesHelper {
+    /** Clears all storage from {@code sp}. */
+    public static void clear(SharedPreferences sp) {
+        SharedPreferences.Editor editor = sp.edit();
+        editor.clear();
+        editor.apply();
+    }
+
+    /** Sets {@code sp}'s storage to identify a {@link PeopleTileKey}. */
+    public static void setPeopleTileKey(SharedPreferences sp, PeopleTileKey key) {
+        setPeopleTileKey(sp, key.getShortcutId(), key.getUserId(), key.getPackageName());
+    }
+
+    /** Sets {@code sp}'s storage to identify a {@link PeopleTileKey}. */
+    public static void setPeopleTileKey(SharedPreferences sp, String shortcutId, int userId,
+            String packageName) {
+        SharedPreferences.Editor editor = sp.edit();
+        editor.putString(SHORTCUT_ID, shortcutId);
+        editor.putInt(USER_ID, userId);
+        editor.putString(PACKAGE_NAME, packageName);
+        editor.apply();
+    }
+
+    /** Returns a {@link PeopleTileKey} based on storage from {@code sp}. */
+    public static PeopleTileKey getPeopleTileKey(SharedPreferences sp) {
+        String shortcutId = sp.getString(SHORTCUT_ID, null);
+        String packageName = sp.getString(PACKAGE_NAME, null);
+        int userId = sp.getInt(USER_ID, INVALID_USER_ID);
+        return new PeopleTileKey(shortcutId, userId, packageName);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/LaunchConversationActivity.java b/packages/SystemUI/src/com/android/systemui/people/widget/LaunchConversationActivity.java
index b031637..79318d6 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/LaunchConversationActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/LaunchConversationActivity.java
@@ -152,7 +152,7 @@
                 launcherApps.startShortcut(
                         packageName, tileId, null, null, userHandle);
             } catch (Exception e) {
-                Log.e(TAG, "Exception:" + e);
+                Log.e(TAG, "Exception launching shortcut:" + e);
             }
         } else {
             if (DEBUG) Log.d(TAG, "Trying to launch conversation with null shortcutInfo.");
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleBackupHelper.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleBackupHelper.java
new file mode 100644
index 0000000..d8c96dd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleBackupHelper.java
@@ -0,0 +1,508 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.people.widget;
+
+import static com.android.systemui.people.PeopleBackupFollowUpJob.SHARED_FOLLOW_UP;
+import static com.android.systemui.people.PeopleSpaceUtils.DEBUG;
+import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
+import static com.android.systemui.people.PeopleSpaceUtils.USER_ID;
+
+import android.app.backup.BackupDataInputStream;
+import android.app.backup.BackupDataOutput;
+import android.app.backup.SharedPreferencesBackupHelper;
+import android.app.people.IPeopleManager;
+import android.appwidget.AppWidgetManager;
+import android.content.ComponentName;
+import android.content.ContentProvider;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.preference.PreferenceManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.people.PeopleBackupFollowUpJob;
+import com.android.systemui.people.SharedPreferencesHelper;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Helper class to backup and restore Conversations widgets storage.
+ * It is used by SystemUI's BackupHelper agent.
+ * TODO(b/192334798): Lock access to storage using PeopleSpaceWidgetManager's lock.
+ */
+public class PeopleBackupHelper extends SharedPreferencesBackupHelper {
+    private static final String TAG = "PeopleBackupHelper";
+
+    public static final String ADD_USER_ID_TO_URI = "add_user_id_to_uri_";
+    public static final String SHARED_BACKUP = "shared_backup";
+
+    private final Context mContext;
+    private final UserHandle mUserHandle;
+    private final PackageManager mPackageManager;
+    private final IPeopleManager mIPeopleManager;
+    private final AppWidgetManager mAppWidgetManager;
+
+    /**
+     * Types of entries stored in the default SharedPreferences file for Conversation widgets.
+     * Widget ID corresponds to a pair [widgetId, contactURI].
+     * PeopleTileKey corresponds to a pair [PeopleTileKey, {widgetIds}].
+     * Contact URI corresponds to a pair [Contact URI, {widgetIds}].
+     */
+    enum SharedFileEntryType {
+        UNKNOWN,
+        WIDGET_ID,
+        PEOPLE_TILE_KEY,
+        CONTACT_URI
+    }
+
+    /**
+     * Returns the file names that should be backed up and restored by SharedPreferencesBackupHelper
+     * infrastructure.
+     */
+    public static List<String> getFilesToBackup() {
+        return Collections.singletonList(SHARED_BACKUP);
+    }
+
+    public PeopleBackupHelper(Context context, UserHandle userHandle,
+            String[] sharedPreferencesKey) {
+        super(context, sharedPreferencesKey);
+        mContext = context;
+        mUserHandle = userHandle;
+        mPackageManager = context.getPackageManager();
+        mIPeopleManager = IPeopleManager.Stub.asInterface(
+                ServiceManager.getService(Context.PEOPLE_SERVICE));
+        mAppWidgetManager = AppWidgetManager.getInstance(context);
+    }
+
+    @VisibleForTesting
+    public PeopleBackupHelper(Context context, UserHandle userHandle,
+            String[] sharedPreferencesKey, PackageManager packageManager,
+            IPeopleManager peopleManager) {
+        super(context, sharedPreferencesKey);
+        mContext = context;
+        mUserHandle = userHandle;
+        mPackageManager = packageManager;
+        mIPeopleManager = peopleManager;
+        mAppWidgetManager = AppWidgetManager.getInstance(context);
+    }
+
+    /**
+     * Reads values from default storage, backs them up appropriately to a specified backup file,
+     * and calls super's performBackup, which backs up the values of the backup file.
+     */
+    @Override
+    public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
+            ParcelFileDescriptor newState) {
+        if (DEBUG) Log.d(TAG, "Backing up conversation widgets, writing to: " + SHARED_BACKUP);
+        // Open default value for readings values.
+        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+        if (sp.getAll().isEmpty()) {
+            if (DEBUG) Log.d(TAG, "No information to be backed up, finishing.");
+            return;
+        }
+
+        // Open backup file for writing.
+        SharedPreferences backupSp = mContext.getSharedPreferences(
+                SHARED_BACKUP, Context.MODE_PRIVATE);
+        SharedPreferences.Editor backupEditor = backupSp.edit();
+        backupEditor.clear();
+
+        // Fetch Conversations widgets corresponding to this user.
+        List<String> existingWidgets = getExistingWidgetsForUser(mUserHandle.getIdentifier());
+        if (existingWidgets.isEmpty()) {
+            if (DEBUG) Log.d(TAG, "No existing Conversations widgets, returning.");
+            return;
+        }
+
+        // Writes each entry to backup file.
+        sp.getAll().entrySet().forEach(entry -> backupKey(entry, backupEditor, existingWidgets));
+        backupEditor.apply();
+
+        super.performBackup(oldState, data, newState);
+    }
+
+    /**
+     * Restores backed up values to backup file via super's restoreEntity, then transfers them
+     * back to regular storage. Restore operations for each users are done in sequence, so we can
+     * safely use the same backup file names.
+     */
+    @Override
+    public void restoreEntity(BackupDataInputStream data) {
+        if (DEBUG) Log.d(TAG, "Restoring Conversation widgets.");
+        super.restoreEntity(data);
+
+        // Open backup file for reading values.
+        SharedPreferences backupSp = mContext.getSharedPreferences(
+                SHARED_BACKUP, Context.MODE_PRIVATE);
+
+        // Open default file and follow-up file for writing.
+        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+        SharedPreferences.Editor editor = sp.edit();
+        SharedPreferences followUp = mContext.getSharedPreferences(
+                SHARED_FOLLOW_UP, Context.MODE_PRIVATE);
+        SharedPreferences.Editor followUpEditor = followUp.edit();
+
+        // Writes each entry back to default value.
+        boolean shouldScheduleJob = false;
+        for (Map.Entry<String, ?> entry : backupSp.getAll().entrySet()) {
+            boolean restored = restoreKey(entry, editor, followUpEditor, backupSp);
+            if (!restored) {
+                shouldScheduleJob = true;
+            }
+        }
+
+        editor.apply();
+        followUpEditor.apply();
+        SharedPreferencesHelper.clear(backupSp);
+
+        // If any of the widgets is not yet available, schedule a follow-up job to check later.
+        if (shouldScheduleJob) {
+            if (DEBUG) Log.d(TAG, "At least one shortcut is not available, scheduling follow-up.");
+            PeopleBackupFollowUpJob.scheduleJob(mContext);
+        }
+
+        updateWidgets(mContext);
+    }
+
+    /** Backs up an entry from default file to backup file. */
+    public void backupKey(Map.Entry<String, ?> entry, SharedPreferences.Editor backupEditor,
+            List<String> existingWidgets) {
+        String key = entry.getKey();
+        if (TextUtils.isEmpty(key)) {
+            return;
+        }
+
+        SharedFileEntryType entryType = getEntryType(entry);
+        switch(entryType) {
+            case WIDGET_ID:
+                backupWidgetIdKey(key, String.valueOf(entry.getValue()), backupEditor,
+                        existingWidgets);
+                break;
+            case PEOPLE_TILE_KEY:
+                backupPeopleTileKey(key, (Set<String>) entry.getValue(), backupEditor,
+                        existingWidgets);
+                break;
+            case CONTACT_URI:
+                backupContactUriKey(key, (Set<String>) entry.getValue(), backupEditor);
+                break;
+            case UNKNOWN:
+            default:
+                Log.w(TAG, "Key not identified, skipping: " + key);
+        }
+    }
+
+    /**
+     * Tries to restore an entry from backup file to default file.
+     * Returns true if restore is finished, false if it needs to be checked later.
+     */
+    boolean restoreKey(Map.Entry<String, ?> entry, SharedPreferences.Editor editor,
+            SharedPreferences.Editor followUpEditor, SharedPreferences backupSp) {
+        String key = entry.getKey();
+        SharedFileEntryType keyType = getEntryType(entry);
+        int storedUserId = backupSp.getInt(ADD_USER_ID_TO_URI + key, INVALID_USER_ID);
+        switch (keyType) {
+            case WIDGET_ID:
+                restoreWidgetIdKey(key, String.valueOf(entry.getValue()), editor, storedUserId);
+                return true;
+            case PEOPLE_TILE_KEY:
+                return restorePeopleTileKeyAndCorrespondingWidgetFile(
+                        key, (Set<String>) entry.getValue(), editor, followUpEditor);
+            case CONTACT_URI:
+                restoreContactUriKey(key, (Set<String>) entry.getValue(), editor, storedUserId);
+                return true;
+            case UNKNOWN:
+            default:
+                Log.e(TAG, "Key not identified, skipping:" + key);
+                return true;
+        }
+    }
+
+    /**
+     * Backs up a [widgetId, contactURI] pair, if widget id corresponds to current user.
+     * If contact URI has a user id, stores it so it can be re-added on restore.
+     */
+    private void backupWidgetIdKey(String key, String uriString, SharedPreferences.Editor editor,
+            List<String> existingWidgets) {
+        if (!existingWidgets.contains(key)) {
+            if (DEBUG) Log.d(TAG, "Widget: " + key + " does't correspond to this user, skipping.");
+            return;
+        }
+        Uri uri = Uri.parse(uriString);
+        if (ContentProvider.uriHasUserId(uri)) {
+            if (DEBUG) Log.d(TAG, "Contact URI value has user ID, removing from: " + uri);
+            int userId = ContentProvider.getUserIdFromUri(uri);
+            editor.putInt(ADD_USER_ID_TO_URI + key, userId);
+            uri = ContentProvider.getUriWithoutUserId(uri);
+        }
+        if (DEBUG) Log.d(TAG, "Backing up widgetId key: " + key + " . Value: " + uri.toString());
+        editor.putString(key, uri.toString());
+    }
+
+    /** Restores a [widgetId, contactURI] pair, and a potential {@code storedUserId}. */
+    private void restoreWidgetIdKey(String key, String uriString, SharedPreferences.Editor editor,
+            int storedUserId) {
+        Uri uri = Uri.parse(uriString);
+        if (storedUserId != INVALID_USER_ID) {
+            uri = ContentProvider.createContentUriForUser(uri, UserHandle.of(storedUserId));
+            if (DEBUG) Log.d(TAG, "UserId was removed from URI on back up, re-adding as:" + uri);
+
+        }
+        if (DEBUG) Log.d(TAG, "Restoring widgetId key: " + key + " . Value: " + uri.toString());
+        editor.putString(key, uri.toString());
+    }
+
+    /**
+     * Backs up a [PeopleTileKey, {widgetIds}] pair, if PeopleTileKey's user is the same as current
+     * user, stripping out the user id.
+     */
+    private void backupPeopleTileKey(String key, Set<String> widgetIds,
+            SharedPreferences.Editor editor, List<String> existingWidgets) {
+        PeopleTileKey peopleTileKey = PeopleTileKey.fromString(key);
+        if (peopleTileKey.getUserId() != mUserHandle.getIdentifier()) {
+            if (DEBUG) Log.d(TAG, "PeopleTileKey corresponds to different user, skipping backup.");
+            return;
+        }
+
+        Set<String> filteredWidgets = widgetIds.stream()
+                .filter(id -> existingWidgets.contains(id))
+                .collect(Collectors.toSet());
+        if (filteredWidgets.isEmpty()) {
+            return;
+        }
+
+        peopleTileKey.setUserId(INVALID_USER_ID);
+        if (DEBUG) {
+            Log.d(TAG, "Backing up PeopleTileKey key: " + peopleTileKey.toString() + ". Value: "
+                    + filteredWidgets);
+        }
+        editor.putStringSet(peopleTileKey.toString(), filteredWidgets);
+    }
+
+    /**
+     * Restores a [PeopleTileKey, {widgetIds}] pair, restoring the user id. Checks if the
+     * corresponding shortcut exists, and if not, we should schedule a follow up to check later.
+     * Also restores corresponding [widgetId, PeopleTileKey], which is not backed up since the
+     * information can be inferred from this.
+     * Returns true if restore is finished, false if we should check if shortcut is available later.
+     */
+    private boolean restorePeopleTileKeyAndCorrespondingWidgetFile(String key,
+            Set<String> widgetIds, SharedPreferences.Editor editor,
+            SharedPreferences.Editor followUpEditor) {
+        PeopleTileKey peopleTileKey = PeopleTileKey.fromString(key);
+        // Should never happen, as type of key has been checked.
+        if (peopleTileKey == null) {
+            if (DEBUG) Log.d(TAG, "PeopleTileKey key to be restored is null, skipping.");
+            return true;
+        }
+
+        peopleTileKey.setUserId(mUserHandle.getIdentifier());
+        if (!PeopleTileKey.isValid(peopleTileKey)) {
+            if (DEBUG) Log.d(TAG, "PeopleTileKey key to be restored is not valid, skipping.");
+            return true;
+        }
+
+        boolean restored = isReadyForRestore(
+                mIPeopleManager, mPackageManager, peopleTileKey);
+        if (!restored) {
+            if (DEBUG) Log.d(TAG, "Adding key to follow-up storage: " + peopleTileKey.toString());
+            // Follow-up file stores shortcuts that need to be checked later, and possibly wiped
+            // from our storage.
+            followUpEditor.putStringSet(peopleTileKey.toString(), widgetIds);
+        }
+
+        if (DEBUG) {
+            Log.d(TAG, "Restoring PeopleTileKey key: " + peopleTileKey.toString() + " . Value: "
+                    + widgetIds);
+        }
+        editor.putStringSet(peopleTileKey.toString(), widgetIds);
+        restoreWidgetIdFiles(mContext, widgetIds, peopleTileKey);
+        return restored;
+    }
+
+    /**
+     * Backs up a [contactURI, {widgetIds}] pair. If contactURI contains a userId, we back up
+     * this entry in the corresponding user. If it doesn't, we back it up as user 0.
+     * If contact URI has a user id, stores it so it can be re-added on restore.
+     * We do not take existing widgets for this user into consideration.
+     */
+    private void backupContactUriKey(String key, Set<String> widgetIds,
+            SharedPreferences.Editor editor) {
+        Uri uri = Uri.parse(String.valueOf(key));
+        if (ContentProvider.uriHasUserId(uri)) {
+            int userId = ContentProvider.getUserIdFromUri(uri);
+            if (DEBUG) Log.d(TAG, "Contact URI has user Id: " + userId);
+            if (userId == mUserHandle.getIdentifier()) {
+                uri = ContentProvider.getUriWithoutUserId(uri);
+                if (DEBUG) {
+                    Log.d(TAG, "Backing up contactURI key: " + uri.toString() + " . Value: "
+                            + widgetIds);
+                }
+                editor.putInt(ADD_USER_ID_TO_URI + uri.toString(), userId);
+                editor.putStringSet(uri.toString(), widgetIds);
+            } else {
+                if (DEBUG) Log.d(TAG, "ContactURI corresponds to different user, skipping.");
+            }
+        } else if (mUserHandle.isSystem()) {
+            if (DEBUG) {
+                Log.d(TAG, "Backing up contactURI key: " + uri.toString() + " . Value: "
+                        + widgetIds);
+            }
+            editor.putStringSet(uri.toString(), widgetIds);
+        }
+    }
+
+    /** Restores a [contactURI, {widgetIds}] pair, and a potential {@code storedUserId}. */
+    private void restoreContactUriKey(String key, Set<String> widgetIds,
+            SharedPreferences.Editor editor, int storedUserId) {
+        Uri uri = Uri.parse(key);
+        if (storedUserId != INVALID_USER_ID) {
+            uri = ContentProvider.createContentUriForUser(uri, UserHandle.of(storedUserId));
+            if (DEBUG) Log.d(TAG, "UserId was removed from URI on back up, re-adding as:" + uri);
+        }
+        if (DEBUG) {
+            Log.d(TAG, "Restoring contactURI key: " + uri.toString() + " . Value: " + widgetIds);
+        }
+        editor.putStringSet(uri.toString(), widgetIds);
+    }
+
+    /** Restores the widget-specific files that contain PeopleTileKey information. */
+    public static void restoreWidgetIdFiles(Context context, Set<String> widgetIds,
+            PeopleTileKey key) {
+        for (String id : widgetIds) {
+            if (DEBUG) Log.d(TAG, "Restoring widget Id file: " + id + " . Value: " + key);
+            SharedPreferences dest = context.getSharedPreferences(id, Context.MODE_PRIVATE);
+            SharedPreferencesHelper.setPeopleTileKey(dest, key);
+        }
+    }
+
+    private List<String> getExistingWidgetsForUser(int userId) {
+        List<String> existingWidgets = new ArrayList<>();
+        int[] ids = mAppWidgetManager.getAppWidgetIds(
+                new ComponentName(mContext, PeopleSpaceWidgetProvider.class));
+        for (int id : ids) {
+            String idString = String.valueOf(id);
+            SharedPreferences sp = mContext.getSharedPreferences(idString, Context.MODE_PRIVATE);
+            if (sp.getInt(USER_ID, INVALID_USER_ID) == userId) {
+                existingWidgets.add(idString);
+            }
+        }
+        if (DEBUG) Log.d(TAG, "Existing widgets: " + existingWidgets);
+        return existingWidgets;
+    }
+
+    /**
+     * Returns whether {@code key} corresponds to a shortcut that is ready for restore, either
+     * because it is available or because it never will be. If not ready, we schedule a job to check
+     * again later.
+     */
+    public static boolean isReadyForRestore(IPeopleManager peopleManager,
+            PackageManager packageManager, PeopleTileKey key) {
+        if (DEBUG) Log.d(TAG, "Checking if we should schedule a follow up job : " + key);
+        if (!PeopleTileKey.isValid(key)) {
+            if (DEBUG) Log.d(TAG, "Key is invalid, should not follow up.");
+            return true;
+        }
+
+        try {
+            PackageInfo info = packageManager.getPackageInfoAsUser(
+                    key.getPackageName(), 0, key.getUserId());
+        } catch (PackageManager.NameNotFoundException e) {
+            if (DEBUG) Log.d(TAG, "Package is not installed, should follow up.");
+            return false;
+        }
+
+        try {
+            boolean isConversation = peopleManager.isConversation(
+                    key.getPackageName(), key.getUserId(), key.getShortcutId());
+            if (DEBUG) {
+                Log.d(TAG, "Checked if shortcut exists, should follow up: " + !isConversation);
+            }
+            return isConversation;
+        } catch (Exception e) {
+            if (DEBUG) Log.d(TAG, "Error checking if backed up info is a shortcut.");
+            return false;
+        }
+    }
+
+    /** Parses default file {@code entry} to determine the entry's type.*/
+    public static SharedFileEntryType getEntryType(Map.Entry<String, ?> entry) {
+        String key = entry.getKey();
+        if (key == null) {
+            return SharedFileEntryType.UNKNOWN;
+        }
+
+        try {
+            int id = Integer.parseInt(key);
+            try {
+                String contactUri = (String) entry.getValue();
+            } catch (Exception e) {
+                Log.w(TAG, "Malformed value, skipping:" + entry.getValue());
+                return SharedFileEntryType.UNKNOWN;
+            }
+            return SharedFileEntryType.WIDGET_ID;
+        } catch (NumberFormatException ignored) { }
+
+        try {
+            Set<String> widgetIds = (Set<String>) entry.getValue();
+        } catch (Exception e) {
+            Log.w(TAG, "Malformed value, skipping:" + entry.getValue());
+            return SharedFileEntryType.UNKNOWN;
+        }
+
+        PeopleTileKey peopleTileKey = PeopleTileKey.fromString(key);
+        if (peopleTileKey != null) {
+            return SharedFileEntryType.PEOPLE_TILE_KEY;
+        }
+
+        try {
+            Uri uri = Uri.parse(key);
+            return SharedFileEntryType.CONTACT_URI;
+        } catch (Exception e) {
+            return SharedFileEntryType.UNKNOWN;
+        }
+    }
+
+    /** Sends a broadcast to update the existing Conversation widgets. */
+    public static void updateWidgets(Context context) {
+        int[] widgetIds = AppWidgetManager.getInstance(context)
+                .getAppWidgetIds(new ComponentName(context, PeopleSpaceWidgetProvider.class));
+        if (DEBUG) {
+            for (int id : widgetIds) {
+                Log.d(TAG, "Calling update to widget: " + id);
+            }
+        }
+        if (widgetIds != null && widgetIds.length != 0) {
+            Intent intent = new Intent(context, PeopleSpaceWidgetProvider.class);
+            intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
+            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, widgetIds);
+            context.sendBroadcast(intent);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
index 62a0df2..72cddd0 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
@@ -22,6 +22,7 @@
 import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE;
 import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
 import static android.content.Intent.ACTION_BOOT_COMPLETED;
+import static android.content.Intent.ACTION_PACKAGE_ADDED;
 import static android.content.Intent.ACTION_PACKAGE_REMOVED;
 import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_ANYONE;
 
@@ -29,6 +30,7 @@
 import static com.android.systemui.people.NotificationHelper.getHighestPriorityNotification;
 import static com.android.systemui.people.NotificationHelper.shouldFilterOut;
 import static com.android.systemui.people.NotificationHelper.shouldMatchNotificationByUri;
+import static com.android.systemui.people.PeopleBackupFollowUpJob.SHARED_FOLLOW_UP;
 import static com.android.systemui.people.PeopleSpaceUtils.EMPTY_STRING;
 import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
 import static com.android.systemui.people.PeopleSpaceUtils.PACKAGE_NAME;
@@ -38,6 +40,7 @@
 import static com.android.systemui.people.PeopleSpaceUtils.getMessagesCount;
 import static com.android.systemui.people.PeopleSpaceUtils.getNotificationsByUri;
 import static com.android.systemui.people.PeopleSpaceUtils.removeNotificationFields;
+import static com.android.systemui.people.widget.PeopleBackupHelper.getEntryType;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -46,6 +49,8 @@
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.Person;
+import android.app.backup.BackupManager;
+import android.app.job.JobScheduler;
 import android.app.people.ConversationChannel;
 import android.app.people.IPeopleManager;
 import android.app.people.PeopleManager;
@@ -84,8 +89,10 @@
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.people.NotificationHelper;
+import com.android.systemui.people.PeopleBackupFollowUpJob;
 import com.android.systemui.people.PeopleSpaceUtils;
 import com.android.systemui.people.PeopleTileViewHelper;
+import com.android.systemui.people.SharedPreferencesHelper;
 import com.android.systemui.statusbar.NotificationListener;
 import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -93,6 +100,7 @@
 import com.android.wm.shell.bubbles.Bubbles;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -126,6 +134,7 @@
     private Optional<Bubbles> mBubblesOptional;
     private UserManager mUserManager;
     private PeopleSpaceWidgetManager mManager;
+    private BackupManager mBackupManager;
     public UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
     private NotificationManager mNotificationManager;
     private BroadcastDispatcher mBroadcastDispatcher;
@@ -164,6 +173,7 @@
                 ServiceManager.getService(Context.NOTIFICATION_SERVICE));
         mBubblesOptional = bubblesOptional;
         mUserManager = userManager;
+        mBackupManager = new BackupManager(context);
         mNotificationManager = notificationManager;
         mManager = this;
         mBroadcastDispatcher = broadcastDispatcher;
@@ -189,6 +199,7 @@
 
                         null /* executor */, UserHandle.ALL);
                 IntentFilter perAppFilter = new IntentFilter(ACTION_PACKAGE_REMOVED);
+                perAppFilter.addAction(ACTION_PACKAGE_ADDED);
                 perAppFilter.addDataScheme("package");
                 // BroadcastDispatcher doesn't allow data schemes.
                 mContext.registerReceiver(mBaseBroadcastReceiver, perAppFilter);
@@ -224,7 +235,7 @@
             AppWidgetManager appWidgetManager, IPeopleManager iPeopleManager,
             PeopleManager peopleManager, LauncherApps launcherApps,
             NotificationEntryManager notificationEntryManager, PackageManager packageManager,
-            Optional<Bubbles> bubblesOptional, UserManager userManager,
+            Optional<Bubbles> bubblesOptional, UserManager userManager, BackupManager backupManager,
             INotificationManager iNotificationManager, NotificationManager notificationManager,
             @Background Executor executor) {
         mContext = context;
@@ -236,6 +247,7 @@
         mPackageManager = packageManager;
         mBubblesOptional = bubblesOptional;
         mUserManager = userManager;
+        mBackupManager = backupManager;
         mINotificationManager = iNotificationManager;
         mNotificationManager = notificationManager;
         mManager = this;
@@ -257,8 +269,6 @@
                 if (DEBUG) Log.d(TAG, "no widgets to update");
                 return;
             }
-
-            if (DEBUG) Log.d(TAG, "updating " + widgetIds.length + " widgets: " + widgetIds);
             synchronized (mLock) {
                 updateSingleConversationWidgets(widgetIds);
             }
@@ -274,6 +284,7 @@
     public void updateSingleConversationWidgets(int[] appWidgetIds) {
         Map<Integer, PeopleSpaceTile> widgetIdToTile = new HashMap<>();
         for (int appWidgetId : appWidgetIds) {
+            if (DEBUG) Log.d(TAG, "Updating widget: " + appWidgetId);
             PeopleSpaceTile tile = getTileForExistingWidget(appWidgetId);
             if (tile == null) {
                 Log.e(TAG, "Matching conversation not found for shortcut ID");
@@ -293,7 +304,8 @@
     private void updateAppWidgetViews(int appWidgetId, PeopleSpaceTile tile, Bundle options) {
         PeopleTileKey key = getKeyFromStorageByWidgetId(appWidgetId);
         if (DEBUG) Log.d(TAG, "Widget: " + appWidgetId + " for: " + key.toString());
-        if (!key.isValid()) {
+
+        if (!PeopleTileKey.isValid(key)) {
             Log.e(TAG, "Cannot update invalid widget");
             return;
         }
@@ -301,6 +313,7 @@
                 options, key);
 
         // Tell the AppWidgetManager to perform an update on the current app widget.
+        if (DEBUG) Log.d(TAG, "Calling update widget for widgetId: " + appWidgetId);
         mAppWidgetManager.updateAppWidget(appWidgetId, views);
     }
 
@@ -314,6 +327,9 @@
 
     /** Updates tile in app widget options and the current view. */
     public void updateAppWidgetOptionsAndView(int appWidgetId, PeopleSpaceTile tile) {
+        if (tile == null) {
+            if (DEBUG) Log.w(TAG, "Storing null tile");
+        }
         synchronized (mTiles) {
             mTiles.put(appWidgetId, tile);
         }
@@ -368,7 +384,7 @@
     @Nullable
     public PeopleSpaceTile getTileFromPersistentStorage(PeopleTileKey key, int appWidgetId) throws
             PackageManager.NameNotFoundException {
-        if (!key.isValid()) {
+        if (!PeopleTileKey.isValid(key)) {
             Log.e(TAG, "PeopleTileKey invalid: " + key.toString());
             return null;
         }
@@ -430,7 +446,8 @@
         try {
             PeopleTileKey key = new PeopleTileKey(
                     sbn.getShortcutId(), sbn.getUser().getIdentifier(), sbn.getPackageName());
-            if (!key.isValid()) {
+            if (!PeopleTileKey.isValid(key)) {
+                Log.d(TAG, "Sbn doesn't contain valid PeopleTileKey: " + key.toString());
                 return;
             }
             int[] widgetIds = mAppWidgetManager.getAppWidgetIds(
@@ -561,7 +578,7 @@
 
         if (DEBUG) Log.d(TAG, "Augmenting tile from notification, key: " + key.toString());
         return augmentTileFromNotification(mContext, tile, key, highestPriority, messagesCount,
-                appWidgetId);
+                appWidgetId, mBackupManager);
     }
 
     /** Returns an augmented tile for an existing widget. */
@@ -588,7 +605,7 @@
 
     /** Returns stored widgets for the conversation specified. */
     public Set<String> getMatchingKeyWidgetIds(PeopleTileKey key) {
-        if (!key.isValid()) {
+        if (!PeopleTileKey.isValid(key)) {
             return new HashSet<>();
         }
         return new HashSet<>(mSharedPrefs.getStringSet(key.toString(), new HashSet<>()));
@@ -776,7 +793,7 @@
         // PeopleTileKey arguments.
         if (DEBUG) Log.d(TAG, "onAppWidgetOptionsChanged called for widget: " + appWidgetId);
         PeopleTileKey optionsKey = AppWidgetOptionsHelper.getPeopleTileKeyFromBundle(newOptions);
-        if (optionsKey.isValid()) {
+        if (PeopleTileKey.isValid(optionsKey)) {
             if (DEBUG) {
                 Log.d(TAG, "PeopleTileKey was present in Options, shortcutId: "
                         + optionsKey.getShortcutId());
@@ -808,7 +825,7 @@
             existingKeyIfStored = getKeyFromStorageByWidgetId(appWidgetId);
         }
         // Delete previous storage if the widget already existed and is just reconfigured.
-        if (existingKeyIfStored.isValid()) {
+        if (PeopleTileKey.isValid(existingKeyIfStored)) {
             if (DEBUG) Log.d(TAG, "Remove previous storage for widget: " + appWidgetId);
             deleteWidgets(new int[]{appWidgetId});
         } else {
@@ -820,7 +837,7 @@
         synchronized (mLock) {
             if (DEBUG) Log.d(TAG, "Add storage for : " + key.toString());
             PeopleSpaceUtils.setSharedPreferencesStorageForTile(mContext, key, appWidgetId,
-                    tile.getContactUri());
+                    tile.getContactUri(), mBackupManager);
         }
         if (DEBUG) Log.d(TAG, "Ensure listener is registered for widget: " + appWidgetId);
         registerConversationListenerIfNeeded(appWidgetId, key);
@@ -838,7 +855,7 @@
     /** Registers a conversation listener for {@code appWidgetId} if not already registered. */
     public void registerConversationListenerIfNeeded(int widgetId, PeopleTileKey key) {
         // Retrieve storage needed for registration.
-        if (!key.isValid()) {
+        if (!PeopleTileKey.isValid(key)) {
             if (DEBUG) Log.w(TAG, "Could not register listener for widget: " + widgetId);
             return;
         }
@@ -887,7 +904,7 @@
                         widgetSp.getString(SHORTCUT_ID, null),
                         widgetSp.getInt(USER_ID, INVALID_USER_ID),
                         widgetSp.getString(PACKAGE_NAME, null));
-                if (!key.isValid()) {
+                if (!PeopleTileKey.isValid(key)) {
                     if (DEBUG) Log.e(TAG, "Could not delete " + widgetId);
                     return;
                 }
@@ -1053,6 +1070,7 @@
             return;
         }
         for (int appWidgetId : appWidgetIds) {
+            if (DEBUG) Log.d(TAG, "Updating widget from broadcast, widget id: " +  appWidgetId);
             PeopleSpaceTile existingTile = null;
             PeopleSpaceTile updatedTile = null;
             try {
@@ -1060,7 +1078,7 @@
                     existingTile = getTileForExistingWidgetThrowing(appWidgetId);
                     if (existingTile == null) {
                         Log.e(TAG, "Matching conversation not found for shortcut ID");
-                        return;
+                        continue;
                     }
                     updatedTile = getTileWithCurrentState(existingTile, entryPoint);
                     updateAppWidgetOptionsAndView(appWidgetId, updatedTile);
@@ -1068,6 +1086,14 @@
             } catch (PackageManager.NameNotFoundException e) {
                 // Delete data for uninstalled widgets.
                 Log.e(TAG, "Package no longer found for tile: " + e);
+                JobScheduler jobScheduler = mContext.getSystemService(JobScheduler.class);
+                if (jobScheduler != null
+                        && jobScheduler.getPendingJob(PeopleBackupFollowUpJob.JOB_ID) != null) {
+                    if (DEBUG) {
+                        Log.d(TAG, "Device was recently restored, wait before deleting storage.");
+                    }
+                    continue;
+                }
                 synchronized (mLock) {
                     updateAppWidgetOptionsAndView(appWidgetId, updatedTile);
                 }
@@ -1185,4 +1211,139 @@
                 return PeopleSpaceTile.BLOCK_CONVERSATIONS;
         }
     }
+
+    /**
+     * Modifies widgets storage after a restore operation, since widget ids get remapped on restore.
+     * This is guaranteed to run after the PeopleBackupHelper restore operation.
+     */
+    public void remapWidgets(int[] oldWidgetIds, int[] newWidgetIds) {
+        if (DEBUG) {
+            Log.d(TAG, "Remapping widgets, old: " + Arrays.toString(oldWidgetIds) + ". new: "
+                    + Arrays.toString(newWidgetIds));
+        }
+
+        Map<String, String> widgets = new HashMap<>();
+        for (int i = 0; i < oldWidgetIds.length; i++) {
+            widgets.put(String.valueOf(oldWidgetIds[i]), String.valueOf(newWidgetIds[i]));
+        }
+
+        remapWidgetFiles(widgets);
+        remapSharedFile(widgets);
+        remapFollowupFile(widgets);
+
+        int[] widgetIds = mAppWidgetManager.getAppWidgetIds(
+                new ComponentName(mContext, PeopleSpaceWidgetProvider.class));
+        Bundle b = new Bundle();
+        b.putBoolean(AppWidgetManager.OPTION_APPWIDGET_RESTORE_COMPLETED, true);
+        for (int id : widgetIds) {
+            if (DEBUG) Log.d(TAG, "Setting widget as restored, widget id:" + id);
+            mAppWidgetManager.updateAppWidgetOptions(id, b);
+        }
+
+        updateWidgets(widgetIds);
+    }
+
+    /** Remaps widget ids in widget specific files. */
+    public void remapWidgetFiles(Map<String, String> widgets) {
+        if (DEBUG) Log.d(TAG, "Remapping widget files");
+        for (Map.Entry<String, String> entry : widgets.entrySet()) {
+            String from = String.valueOf(entry.getKey());
+            String to = String.valueOf(entry.getValue());
+
+            SharedPreferences src = mContext.getSharedPreferences(from, Context.MODE_PRIVATE);
+            PeopleTileKey key = SharedPreferencesHelper.getPeopleTileKey(src);
+            if (PeopleTileKey.isValid(key)) {
+                if (DEBUG) {
+                    Log.d(TAG, "Moving PeopleTileKey: " + key.toString() + " from file: "
+                            + from + ", to file: " + to);
+                }
+                SharedPreferences dest = mContext.getSharedPreferences(to, Context.MODE_PRIVATE);
+                SharedPreferencesHelper.setPeopleTileKey(dest, key);
+                SharedPreferencesHelper.clear(src);
+            }
+        }
+    }
+
+    /** Remaps widget ids in default shared storage. */
+    public void remapSharedFile(Map<String, String> widgets) {
+        if (DEBUG) Log.d(TAG, "Remapping shared file");
+        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+        SharedPreferences.Editor editor = sp.edit();
+        Map<String, ?> all = sp.getAll();
+        for (Map.Entry<String, ?> entry : all.entrySet()) {
+            String key = entry.getKey();
+            PeopleBackupHelper.SharedFileEntryType keyType = getEntryType(entry);
+            if (DEBUG) Log.d(TAG, "Remapping key:" + key);
+            switch (keyType) {
+                case WIDGET_ID:
+                    String newId = widgets.get(key);
+                    if (TextUtils.isEmpty(newId)) {
+                        Log.w(TAG, "Key is widget id without matching new id, skipping: " + key);
+                        break;
+                    }
+                    if (DEBUG) Log.d(TAG, "Key is widget id: " + key + ", replace with: " + newId);
+                    try {
+                        editor.putString(newId, (String) entry.getValue());
+                    } catch (Exception e) {
+                        Log.e(TAG, "Malformed entry value: " + entry.getValue());
+                    }
+                    editor.remove(key);
+                    break;
+                case PEOPLE_TILE_KEY:
+                case CONTACT_URI:
+                    Set<String> oldWidgetIds;
+                    try {
+                        oldWidgetIds = (Set<String>) entry.getValue();
+                    } catch (Exception e) {
+                        Log.e(TAG, "Malformed entry value: " + entry.getValue());
+                        editor.remove(key);
+                        break;
+                    }
+                    Set<String> newWidgets = getNewWidgets(oldWidgetIds, widgets);
+                    if (DEBUG) {
+                        Log.d(TAG, "Key is PeopleTileKey or contact URI: " + key
+                                + ", replace values with new ids: " + newWidgets);
+                    }
+                    editor.putStringSet(key, newWidgets);
+                    break;
+                case UNKNOWN:
+                    Log.e(TAG, "Key not identified:" + key);
+            }
+        }
+        editor.apply();
+    }
+
+    /** Remaps widget ids in follow-up job file. */
+    public void remapFollowupFile(Map<String, String> widgets) {
+        if (DEBUG) Log.d(TAG, "Remapping follow up file");
+        SharedPreferences followUp = mContext.getSharedPreferences(
+                SHARED_FOLLOW_UP, Context.MODE_PRIVATE);
+        SharedPreferences.Editor followUpEditor = followUp.edit();
+        Map<String, ?> followUpAll = followUp.getAll();
+        for (Map.Entry<String, ?> entry : followUpAll.entrySet()) {
+            String key = entry.getKey();
+            Set<String> oldWidgetIds;
+            try {
+                oldWidgetIds = (Set<String>) entry.getValue();
+            } catch (Exception e) {
+                Log.e(TAG, "Malformed entry value: " + entry.getValue());
+                followUpEditor.remove(key);
+                continue;
+            }
+            Set<String> newWidgets = getNewWidgets(oldWidgetIds, widgets);
+            if (DEBUG) {
+                Log.d(TAG, "Follow up key: " + key + ", replace with new ids: " + newWidgets);
+            }
+            followUpEditor.putStringSet(key, newWidgets);
+        }
+        followUpEditor.apply();
+    }
+
+    private Set<String> getNewWidgets(Set<String> oldWidgets, Map<String, String> widgetsMapping) {
+        return oldWidgets
+                .stream()
+                .map(widgetsMapping::get)
+                .filter(id -> !TextUtils.isEmpty(id))
+                .collect(Collectors.toSet());
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetPinnedReceiver.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetPinnedReceiver.java
index a28da43..c4be1975 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetPinnedReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetPinnedReceiver.java
@@ -75,7 +75,7 @@
         String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
         int userId = intent.getIntExtra(Intent.EXTRA_USER_ID, INVALID_USER_ID);
         PeopleTileKey key = new PeopleTileKey(shortcutId, userId, packageName);
-        if (!key.isValid()) {
+        if (!PeopleTileKey.isValid(key)) {
             if (DEBUG) Log.w(TAG, "Skipping: key is not valid: " + key.toString());
             return;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java
index 3522b76..36939b7 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java
@@ -70,6 +70,13 @@
         mPeopleSpaceWidgetManager.deleteWidgets(appWidgetIds);
     }
 
+    @Override
+    public void onRestored(Context context, int[] oldWidgetIds, int[] newWidgetIds) {
+        super.onRestored(context, oldWidgetIds, newWidgetIds);
+        ensurePeopleSpaceWidgetManagerInitialized();
+        mPeopleSpaceWidgetManager.remapWidgets(oldWidgetIds, newWidgetIds);
+    }
+
     private void ensurePeopleSpaceWidgetManagerInitialized() {
         mPeopleSpaceWidgetManager.init();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleTileKey.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleTileKey.java
index 319df85..6e6ca25 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleTileKey.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleTileKey.java
@@ -25,6 +25,8 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 
 import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /** Class that encapsulates fields identifying a Conversation. */
 public class PeopleTileKey {
@@ -32,6 +34,8 @@
     private int mUserId;
     private String mPackageName;
 
+    private static final Pattern KEY_PATTERN = Pattern.compile("(.+)/(-?\\d+)/(\\p{L}.*)");
+
     public PeopleTileKey(String shortcutId, int userId, String packageName) {
         mShortcutId = shortcutId;
         mUserId = userId;
@@ -66,8 +70,12 @@
         return mPackageName;
     }
 
+    public void setUserId(int userId) {
+        mUserId = userId;
+    }
+
     /** Returns whether PeopleTileKey is valid/well-formed. */
-    public boolean isValid() {
+    private boolean validate() {
         return !TextUtils.isEmpty(mShortcutId) && !TextUtils.isEmpty(mPackageName) && mUserId >= 0;
     }
 
@@ -88,10 +96,31 @@
      */
     @Override
     public String toString() {
-        if (!isValid()) return EMPTY_STRING;
         return mShortcutId + "/" + mUserId + "/" + mPackageName;
     }
 
+    /** Parses {@code key} into a {@link PeopleTileKey}. */
+    public static PeopleTileKey fromString(String key) {
+        if (key == null) {
+            return null;
+        }
+        Matcher m = KEY_PATTERN.matcher(key);
+        if (m.find()) {
+            try {
+                int userId = Integer.parseInt(m.group(2));
+                return new PeopleTileKey(m.group(1), userId, m.group(3));
+            } catch (NumberFormatException e) {
+                return null;
+            }
+        }
+        return null;
+    }
+
+    /** Returns whether {@code key} is a valid {@link PeopleTileKey}. */
+    public static boolean isValid(PeopleTileKey key) {
+        return key != null && key.validate();
+    }
+
     @Override
     public boolean equals(Object other) {
         if (this == other) {
diff --git a/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java b/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java
index 1ed98c0..03d1f15 100644
--- a/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java
+++ b/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java
@@ -93,6 +93,8 @@
         setAlpha(1f);
         setVisibility(View.VISIBLE);
         mWindowManager.addView(this, getLayoutParams(mWindowToken));
+        announceForAccessibility(
+                getContext().getString(R.string.inattentive_sleep_warning_message));
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index 14bf8ab..3f7a0e2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -81,6 +81,7 @@
     private QSExpansionPathInterpolator mQSExpansionPathInterpolator;
     private TouchAnimator mFirstPageAnimator;
     private TouchAnimator mFirstPageDelayedAnimator;
+    private TouchAnimator mTranslationXAnimator;
     private TouchAnimator mTranslationYAnimator;
     private TouchAnimator mNonfirstPageAnimator;
     private TouchAnimator mNonfirstPageDelayedAnimator;
@@ -223,18 +224,25 @@
             View qqsView,
             View qsView,
             View commonParent,
+            int xOffset,
             int yOffset,
             int[] temp,
-            TouchAnimator.Builder animatorBuilder
+            TouchAnimator.Builder animatorBuilderX,
+            TouchAnimator.Builder animatorBuilderY
     ) {
         getRelativePosition(temp, qqsView, commonParent);
-        int qqsPos = temp[1];
+        int qqsPosX = temp[0];
+        int qqsPosY = temp[1];
         getRelativePosition(temp, qsView, commonParent);
-        int qsPos = temp[1];
+        int qsPosX = temp[0];
+        int qsPosY = temp[1];
 
-        int diff = qsPos - qqsPos - yOffset;
-        animatorBuilder.addFloat(qqsView, "translationY", 0, diff);
-        animatorBuilder.addFloat(qsView, "translationY", -diff, 0);
+        int xDiff = qsPosX - qqsPosX - xOffset;
+        animatorBuilderX.addFloat(qqsView, "translationX", 0, xDiff);
+        animatorBuilderX.addFloat(qsView, "translationX", -xDiff, 0);
+        int yDiff = qsPosY - qqsPosY - yOffset;
+        animatorBuilderY.addFloat(qqsView, "translationY", 0, yDiff);
+        animatorBuilderY.addFloat(qsView, "translationY", -yDiff, 0);
         mAllViews.add(qqsView);
         mAllViews.add(qsView);
     }
@@ -243,6 +251,7 @@
         mNeedsAnimatorUpdate = false;
         TouchAnimator.Builder firstPageBuilder = new Builder();
         TouchAnimator.Builder translationYBuilder = new Builder();
+        TouchAnimator.Builder translationXBuilder = new Builder();
 
         Collection<QSTile> tiles = mHost.getTiles();
         int count = 0;
@@ -289,6 +298,7 @@
                     getRelativePosition(loc1, quickTileView, view);
                     getRelativePosition(loc2, tileView, view);
                     int yOffset = loc2[1] - loc1[1];
+                    int xOffset = loc2[0] - loc1[0];
 
                     // Offset the translation animation on the views
                     // (that goes from 0 to getOffsetTranslation)
@@ -299,6 +309,9 @@
                     translationYBuilder.addFloat(tileView, "translationY",
                             -offsetWithQSBHTranslation, 0);
 
+                    translationXBuilder.addFloat(quickTileView, "translationX", 0, xOffset);
+                    translationXBuilder.addFloat(tileView, "translationX", -xOffset, 0);
+
                     if (mQQSTileHeightAnimator == null) {
                         mQQSTileHeightAnimator = new HeightExpansionAnimator(this,
                                 quickTileView.getHeight(), tileView.getHeight());
@@ -312,8 +325,10 @@
                             quickTileView.getIcon(),
                             tileView.getIcon(),
                             view,
+                            xOffset,
                             yOffset,
                             loc1,
+                            translationXBuilder,
                             translationYBuilder
                     );
 
@@ -322,8 +337,10 @@
                             quickTileView.getLabelContainer(),
                             tileView.getLabelContainer(),
                             view,
+                            xOffset,
                             yOffset,
                             loc1,
+                            translationXBuilder,
                             translationYBuilder
                     );
 
@@ -332,8 +349,10 @@
                             quickTileView.getSecondaryIcon(),
                             tileView.getSecondaryIcon(),
                             view,
+                            xOffset,
                             yOffset,
                             loc1,
+                            translationXBuilder,
                             translationYBuilder
                     );
 
@@ -401,7 +420,9 @@
             mAllPagesDelayedAnimator = builder.build();
             mAllViews.add(mSecurityFooter.getView());
             translationYBuilder.setInterpolator(mQSExpansionPathInterpolator.getYInterpolator());
+            translationXBuilder.setInterpolator(mQSExpansionPathInterpolator.getXInterpolator());
             mTranslationYAnimator = translationYBuilder.build();
+            mTranslationXAnimator = translationXBuilder.build();
             if (mQQSTileHeightAnimator != null) {
                 mQQSTileHeightAnimator.setInterpolator(
                         mQSExpansionPathInterpolator.getYInterpolator());
@@ -474,6 +495,7 @@
             mFirstPageAnimator.setPosition(position);
             mFirstPageDelayedAnimator.setPosition(position);
             mTranslationYAnimator.setPosition(position);
+            mTranslationXAnimator.setPosition(position);
             if (mQQSTileHeightAnimator != null) {
                 mQQSTileHeightAnimator.setPosition(position);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index db8efd5..7c7f566 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -98,11 +98,7 @@
     private LinearLayout mHorizontalLinearLayout;
     protected LinearLayout mHorizontalContentContainer;
 
-    // Only used with media
-    private QSTileLayout mHorizontalTileLayout;
-    protected QSTileLayout mRegularTileLayout;
     protected QSTileLayout mTileLayout;
-    private int mLastOrientation = -1;
     private int mMediaTotalBottomMargin;
 
     public QSPanel(Context context, AttributeSet attrs) {
@@ -119,8 +115,7 @@
     }
 
     void initialize() {
-        mRegularTileLayout = createRegularTileLayout();
-        mTileLayout = mRegularTileLayout;
+        mTileLayout = getOrCreateTileLayout();
 
         if (mUsingMediaPlayer) {
             mHorizontalLinearLayout = new RemeasuringLinearLayout(mContext);
@@ -133,7 +128,6 @@
             mHorizontalContentContainer.setClipChildren(true);
             mHorizontalContentContainer.setClipToPadding(false);
 
-            mHorizontalTileLayout = createHorizontalTileLayout();
             LayoutParams lp = new LayoutParams(0, LayoutParams.WRAP_CONTENT, 1);
             int marginSize = (int) mContext.getResources().getDimension(R.dimen.qs_media_padding);
             lp.setMarginStart(0);
@@ -176,17 +170,12 @@
     }
 
     /** */
-    public QSTileLayout createRegularTileLayout() {
-        if (mRegularTileLayout == null) {
-            mRegularTileLayout = (QSTileLayout) LayoutInflater.from(mContext)
+    public QSTileLayout getOrCreateTileLayout() {
+        if (mTileLayout == null) {
+            mTileLayout = (QSTileLayout) LayoutInflater.from(mContext)
                     .inflate(R.layout.qs_paged_tile_layout, this, false);
         }
-        return mRegularTileLayout;
-    }
-
-
-    protected QSTileLayout createHorizontalTileLayout() {
-        return createRegularTileLayout();
+        return mTileLayout;
     }
 
     @Override
@@ -273,18 +262,18 @@
      * @param pageIndicator indicator to use for page scrolling
      */
     public void setFooterPageIndicator(PageIndicator pageIndicator) {
-        if (mRegularTileLayout instanceof PagedTileLayout) {
+        if (mTileLayout instanceof PagedTileLayout) {
             mFooterPageIndicator = pageIndicator;
             updatePageIndicator();
         }
     }
 
     private void updatePageIndicator() {
-        if (mRegularTileLayout instanceof PagedTileLayout) {
+        if (mTileLayout instanceof PagedTileLayout) {
             if (mFooterPageIndicator != null) {
                 mFooterPageIndicator.setVisibility(View.GONE);
 
-                ((PagedTileLayout) mRegularTileLayout).setPageIndicator(mFooterPageIndicator);
+                ((PagedTileLayout) mTileLayout).setPageIndicator(mFooterPageIndicator);
             }
         }
     }
@@ -354,7 +343,7 @@
         return true;
     }
 
-    protected boolean needsDynamicRowsAndColumns() {
+    private boolean needsDynamicRowsAndColumns() {
         return true;
     }
 
@@ -669,39 +658,20 @@
     }
 
     protected void setPageMargin(int pageMargin) {
-        if (mRegularTileLayout instanceof PagedTileLayout) {
-            ((PagedTileLayout) mRegularTileLayout).setPageMargin(pageMargin);
-        }
-        if (mHorizontalTileLayout != mRegularTileLayout
-                && mHorizontalTileLayout instanceof PagedTileLayout) {
-            ((PagedTileLayout) mHorizontalTileLayout).setPageMargin(pageMargin);
+        if (mTileLayout instanceof PagedTileLayout) {
+            ((PagedTileLayout) mTileLayout).setPageMargin(pageMargin);
         }
     }
 
-    void setUsingHorizontalLayout(boolean horizontal, ViewGroup mediaHostView, boolean force,
-            UiEventLogger uiEventLogger) {
+    void setUsingHorizontalLayout(boolean horizontal, ViewGroup mediaHostView, boolean force) {
         if (horizontal != mUsingHorizontalLayout || force) {
             mUsingHorizontalLayout = horizontal;
-            View visibleView = horizontal ? mHorizontalLinearLayout : (View) mRegularTileLayout;
-            View hiddenView = horizontal ? (View) mRegularTileLayout : mHorizontalLinearLayout;
             ViewGroup newParent = horizontal ? mHorizontalContentContainer : this;
-            QSPanel.QSTileLayout newLayout = horizontal
-                    ? mHorizontalTileLayout : mRegularTileLayout;
-            if (hiddenView != null
-                    && (mRegularTileLayout != mHorizontalTileLayout
-                    || hiddenView != mRegularTileLayout)) {
-                // Only hide the view if the horizontal and the regular view are different,
-                // otherwise its reattached.
-                hiddenView.setVisibility(View.GONE);
-            }
-            visibleView.setVisibility(View.VISIBLE);
-            switchAllContentToParent(newParent, newLayout);
+            switchAllContentToParent(newParent, mTileLayout);
             reAttachMediaHost(mediaHostView, horizontal);
-            mTileLayout = newLayout;
-            newLayout.setListening(mListening, uiEventLogger);
             if (needsDynamicRowsAndColumns()) {
-                newLayout.setMinRows(horizontal ? 2 : 1);
-                newLayout.setMaxColumns(horizontal ? 2 : 4);
+                mTileLayout.setMinRows(horizontal ? 2 : 1);
+                mTileLayout.setMaxColumns(horizontal ? 2 : 4);
             }
             updateMargins(mediaHostView);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
index 9810e96..ae0f510 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
@@ -147,14 +147,14 @@
             mBrightnessMirrorController.addCallback(mBrightnessMirrorListener);
         }
 
-        ((PagedTileLayout) mView.createRegularTileLayout())
+        ((PagedTileLayout) mView.getOrCreateTileLayout())
                 .setOnTouchListener(mTileLayoutTouchListener);
     }
 
     @Override
     protected QSTileRevealController createTileRevealController() {
         return mQsTileRevealControllerFactory.create(
-                this, (PagedTileLayout) mView.createRegularTileLayout());
+                this, (PagedTileLayout) mView.getOrCreateTileLayout());
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
index 77591b50..7a09826 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -297,20 +297,12 @@
     }
 
     boolean switchTileLayout(boolean force) {
-        /** Whether or not the QuickQSPanel currently contains a media player. */
+        /* Whether or not the panel currently contains a media player. */
         boolean horizontal = shouldUseHorizontalLayout();
         if (horizontal != mUsingHorizontalLayout || force) {
             mUsingHorizontalLayout = horizontal;
-            for (QSPanelControllerBase.TileRecord record : mRecords) {
-                mView.removeTile(record);
-                record.tile.removeCallback(record.callback);
-            }
-            mView.setUsingHorizontalLayout(mUsingHorizontalLayout, mMediaHost.getHostView(), force,
-                    mUiEventLogger);
+            mView.setUsingHorizontalLayout(mUsingHorizontalLayout, mMediaHost.getHostView(), force);
             updateMediaDisappearParameters();
-
-            setTiles();
-
             return true;
         }
         return false;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 659475d..68962b0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -61,21 +61,10 @@
     }
 
     @Override
-    public TileLayout createRegularTileLayout() {
+    public TileLayout getOrCreateTileLayout() {
         return new QQSSideLabelTileLayout(mContext);
     }
 
-    @Override
-    protected QSTileLayout createHorizontalTileLayout() {
-        TileLayout t = createRegularTileLayout();
-        t.setMaxColumns(2);
-        return t;
-    }
-
-    @Override
-    protected boolean needsDynamicRowsAndColumns() {
-        return false; // QQS always have the same layout
-    }
 
     @Override
     protected boolean displayMediaMarginsOnMedia() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
index 98cd88a..4dc7508 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
@@ -73,6 +73,7 @@
     private final QuickAccessWalletController mController;
 
     private WalletCard mSelectedCard;
+    private boolean mIsWalletUpdating = true;
     @VisibleForTesting Drawable mCardViewDrawable;
 
     @Inject
@@ -110,7 +111,8 @@
         super.handleSetListening(listening);
         if (listening) {
             mController.setupWalletChangeObservers(mCardRetriever, DEFAULT_PAYMENT_APP_CHANGE);
-            if (!mController.getWalletClient().isWalletServiceAvailable()) {
+            if (!mController.getWalletClient().isWalletServiceAvailable()
+                    || !mController.getWalletClient().isWalletFeatureAvailable()) {
                 Log.i(TAG, "QAW service is unavailable, recreating the wallet client.");
                 mController.reCreateWalletClient();
             }
@@ -158,7 +160,8 @@
         state.contentDescription = state.label;
         state.icon = ResourceIcon.get(R.drawable.ic_wallet_lockscreen);
         boolean isDeviceLocked = !mKeyguardStateController.isUnlocked();
-        if (mController.getWalletClient().isWalletServiceAvailable()) {
+        if (mController.getWalletClient().isWalletServiceAvailable()
+                && mController.getWalletClient().isWalletFeatureAvailable()) {
             if (mSelectedCard != null) {
                 if (isDeviceLocked) {
                     state.state = Tile.STATE_INACTIVE;
@@ -172,7 +175,11 @@
                 }
             } else {
                 state.state = Tile.STATE_INACTIVE;
-                state.secondaryLabel = mContext.getString(R.string.wallet_secondary_label_no_card);
+                state.secondaryLabel =
+                        mContext.getString(
+                                mIsWalletUpdating
+                                        ? R.string.wallet_secondary_label_updating
+                                        : R.string.wallet_secondary_label_no_card);
                 state.sideViewCustomDrawable = null;
             }
             state.stateDescription = state.secondaryLabel;
@@ -218,6 +225,7 @@
         @Override
         public void onWalletCardsRetrieved(@NonNull GetWalletCardsResponse response) {
             Log.i(TAG, "Successfully retrieved wallet cards.");
+            mIsWalletUpdating = false;
             List<WalletCard> cards = response.getWalletCards();
             if (cards.isEmpty()) {
                 Log.d(TAG, "No wallet cards exist.");
@@ -240,7 +248,7 @@
 
         @Override
         public void onWalletCardRetrievalError(@NonNull GetWalletCardsError error) {
-            Log.w(TAG, "Error retrieve wallet cards");
+            mIsWalletUpdating = false;
             mCardViewDrawable = null;
             mSelectedCard = null;
             refreshState();
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
index 0a60f6d..a9cecaa 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
@@ -44,6 +44,7 @@
 import androidx.customview.widget.ExploreByTouchHelper;
 import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
 
+import com.android.internal.graphics.ColorUtils;
 import com.android.systemui.R;
 
 import java.util.List;
@@ -95,7 +96,9 @@
         TypedArray t = context.getTheme().obtainStyledAttributes(
                 attrs, R.styleable.CropView, 0, 0);
         mShadePaint = new Paint();
-        mShadePaint.setColor(t.getColor(R.styleable.CropView_scrimColor, Color.TRANSPARENT));
+        int alpha = t.getInteger(R.styleable.CropView_scrimAlpha, 255);
+        int scrimColor = t.getColor(R.styleable.CropView_scrimColor, Color.TRANSPARENT);
+        mShadePaint.setColor(ColorUtils.setAlphaComponent(scrimColor, alpha));
         mContainerBackgroundPaint = new Paint();
         mContainerBackgroundPaint.setColor(t.getColor(R.styleable.CropView_containerBackgroundColor,
                 Color.TRANSPARENT));
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
index 741dddc..35637f6 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
@@ -126,6 +126,8 @@
         mTransitionView = requireViewById(R.id.transition);
         mEnterTransitionView = requireViewById(R.id.enter_transition);
 
+        requireViewById(R.id.cancel).setOnClickListener(v -> finishAndRemoveTask());
+
         mSave.setOnClickListener(this::onClicked);
         mEdit.setOnClickListener(this::onClicked);
         mShare.setOnClickListener(this::onClicked);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java b/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java
index 34b40f7..7873732 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java
@@ -33,6 +33,7 @@
 
 import androidx.annotation.Nullable;
 
+import com.android.internal.graphics.ColorUtils;
 import com.android.systemui.R;
 
 /**
@@ -83,7 +84,9 @@
         TypedArray t = context.getTheme().obtainStyledAttributes(
                 attrs, R.styleable.MagnifierView, 0, 0);
         mShadePaint = new Paint();
-        mShadePaint.setColor(t.getColor(R.styleable.MagnifierView_scrimColor, Color.TRANSPARENT));
+        int alpha = t.getInteger(R.styleable.MagnifierView_scrimAlpha, 255);
+        int scrimColor = t.getColor(R.styleable.MagnifierView_scrimColor, Color.TRANSPARENT);
+        mShadePaint.setColor(ColorUtils.setAlphaComponent(scrimColor, alpha));
         mHandlePaint = new Paint();
         mHandlePaint.setColor(t.getColor(R.styleable.MagnifierView_handleColor, Color.BLACK));
         mHandlePaint.setStrokeWidth(
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 63ecc0b..5a3d3f9 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.screenshot;
 
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
@@ -259,6 +260,7 @@
     private ScreenshotView mScreenshotView;
     private Bitmap mScreenBitmap;
     private SaveImageInBackgroundTask mSaveInBgTask;
+    private boolean mScreenshotTakenInPortrait;
 
     private Animator mScreenshotAnimation;
     private RequestCallback mCurrentRequestCallback;
@@ -488,6 +490,9 @@
      * Takes a screenshot of the current display and shows an animation.
      */
     private void takeScreenshotInternal(Consumer<Uri> finisher, Rect crop) {
+        mScreenshotTakenInPortrait =
+                mContext.getResources().getConfiguration().orientation == ORIENTATION_PORTRAIT;
+
         // copy the input Rect, since SurfaceControl.screenshot can mutate it
         Rect screenRect = new Rect(crop);
         Bitmap screenshot = captureScreenshot(crop);
@@ -661,7 +666,8 @@
                 Bitmap newScreenshot = captureScreenshot(
                         new Rect(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels));
 
-                mScreenshotView.prepareScrollingTransition(response, mScreenBitmap, newScreenshot);
+                mScreenshotView.prepareScrollingTransition(response, mScreenBitmap, newScreenshot,
+                        mScreenshotTakenInPortrait);
                 // delay starting scroll capture to make sure the scrim is up before the app moves
                 mScreenshotView.post(() -> {
                     // Clear the reference to prevent close() in dismissScreenshot
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index 9fe8c84..dc73637 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -162,6 +162,7 @@
     private GestureDetector mSwipeDetector;
     private SwipeDismissHandler mSwipeDismissHandler;
     private InputMonitorCompat mInputMonitor;
+    private boolean mShowScrollablePreview;
 
     private final ArrayList<ScreenshotActionChip> mSmartChips = new ArrayList<>();
     private PendingInteraction mPendingInteraction;
@@ -772,70 +773,99 @@
 
     void startLongScreenshotTransition(Rect destination, Runnable onTransitionEnd,
             ScrollCaptureController.LongScreenshot longScreenshot) {
-        mScrollablePreview.setImageBitmap(longScreenshot.toBitmap());
-        ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
-        float startX = mScrollablePreview.getX();
-        float startY = mScrollablePreview.getY();
-        int[] locInScreen = mScrollablePreview.getLocationOnScreen();
-        destination.offset((int) startX - locInScreen[0], (int) startY - locInScreen[1]);
-        mScrollablePreview.setPivotX(0);
-        mScrollablePreview.setPivotY(0);
-        mScrollablePreview.setAlpha(1f);
-        float currentScale = mScrollablePreview.getWidth() / (float) longScreenshot.getWidth();
-        Matrix matrix = new Matrix();
-        matrix.setScale(currentScale, currentScale);
-        matrix.postTranslate(
-                longScreenshot.getLeft() * currentScale, longScreenshot.getTop() * currentScale);
-        mScrollablePreview.setImageMatrix(matrix);
-        float destinationScale = destination.width() / (float) mScrollablePreview.getWidth();
-        anim.addUpdateListener(animation -> {
-            float t = animation.getAnimatedFraction();
-            mScrollingScrim.setAlpha(1 - t);
-            float currScale = MathUtils.lerp(1, destinationScale, t);
-            mScrollablePreview.setScaleX(currScale);
-            mScrollablePreview.setScaleY(currScale);
-            mScrollablePreview.setX(MathUtils.lerp(startX, destination.left, t));
-            mScrollablePreview.setY(MathUtils.lerp(startY, destination.top, t));
-        });
-        anim.addListener(new AnimatorListenerAdapter() {
+        AnimatorSet animSet = new AnimatorSet();
+
+        ValueAnimator scrimAnim = ValueAnimator.ofFloat(0, 1);
+        scrimAnim.addUpdateListener(animation ->
+                mScrollingScrim.setAlpha(1 - animation.getAnimatedFraction()));
+
+        if (mShowScrollablePreview) {
+            mScrollablePreview.setImageBitmap(longScreenshot.toBitmap());
+            float startX = mScrollablePreview.getX();
+            float startY = mScrollablePreview.getY();
+            int[] locInScreen = mScrollablePreview.getLocationOnScreen();
+            destination.offset((int) startX - locInScreen[0], (int) startY - locInScreen[1]);
+            mScrollablePreview.setPivotX(0);
+            mScrollablePreview.setPivotY(0);
+            mScrollablePreview.setAlpha(1f);
+            float currentScale = mScrollablePreview.getWidth() / (float) longScreenshot.getWidth();
+            Matrix matrix = new Matrix();
+            matrix.setScale(currentScale, currentScale);
+            matrix.postTranslate(
+                    longScreenshot.getLeft() * currentScale,
+                    longScreenshot.getTop() * currentScale);
+            mScrollablePreview.setImageMatrix(matrix);
+            float destinationScale = destination.width() / (float) mScrollablePreview.getWidth();
+
+            ValueAnimator previewAnim = ValueAnimator.ofFloat(0, 1);
+            previewAnim.addUpdateListener(animation -> {
+                float t = animation.getAnimatedFraction();
+                float currScale = MathUtils.lerp(1, destinationScale, t);
+                mScrollablePreview.setScaleX(currScale);
+                mScrollablePreview.setScaleY(currScale);
+                mScrollablePreview.setX(MathUtils.lerp(startX, destination.left, t));
+                mScrollablePreview.setY(MathUtils.lerp(startY, destination.top, t));
+            });
+            ValueAnimator previewFadeAnim = ValueAnimator.ofFloat(1, 0);
+            previewFadeAnim.addUpdateListener(animation ->
+                    mScrollablePreview.setAlpha(1 - animation.getAnimatedFraction()));
+            animSet.play(previewAnim).with(scrimAnim).before(previewFadeAnim);
+            previewAnim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    super.onAnimationEnd(animation);
+                    onTransitionEnd.run();
+                }
+            });
+        } else {
+            // if we switched orientations between the original screenshot and the long screenshot
+            // capture, just fade out the scrim instead of running the preview animation
+            animSet.play(scrimAnim);
+            animSet.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    super.onAnimationEnd(animation);
+                    onTransitionEnd.run();
+                }
+            });
+        }
+        animSet.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
                 super.onAnimationEnd(animation);
-                onTransitionEnd.run();
-                mScrollablePreview.animate().alpha(0).setListener(new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        super.onAnimationEnd(animation);
                         mCallbacks.onDismiss();
                     }
-                });
-            }
         });
-        anim.start();
+        animSet.start();
     }
 
     void prepareScrollingTransition(ScrollCaptureResponse response, Bitmap screenBitmap,
-            Bitmap newBitmap) {
+            Bitmap newBitmap, boolean screenshotTakenInPortrait) {
+        mShowScrollablePreview = (screenshotTakenInPortrait == mOrientationPortrait);
+
         mScrollingScrim.setImageBitmap(newBitmap);
         mScrollingScrim.setVisibility(View.VISIBLE);
-        Rect scrollableArea = scrollableAreaOnScreen(response);
-        float scale = mCornerSizeX
-                / (mOrientationPortrait ? screenBitmap.getWidth() : screenBitmap.getHeight());
-        ConstraintLayout.LayoutParams params =
-                (ConstraintLayout.LayoutParams) mScrollablePreview.getLayoutParams();
 
-        params.width = (int) (scale * scrollableArea.width());
-        params.height = (int) (scale * scrollableArea.height());
-        Matrix matrix = new Matrix();
-        matrix.setScale(scale, scale);
-        matrix.postTranslate(-scrollableArea.left * scale, -scrollableArea.top * scale);
+        if (mShowScrollablePreview) {
+            Rect scrollableArea = scrollableAreaOnScreen(response);
 
-        mScrollablePreview.setTranslationX(scale * scrollableArea.left);
-        mScrollablePreview.setTranslationY(scale * scrollableArea.top);
-        mScrollablePreview.setImageMatrix(matrix);
+            float scale = mCornerSizeX
+                    / (mOrientationPortrait ? screenBitmap.getWidth() : screenBitmap.getHeight());
+            ConstraintLayout.LayoutParams params =
+                    (ConstraintLayout.LayoutParams) mScrollablePreview.getLayoutParams();
 
-        mScrollablePreview.setImageBitmap(screenBitmap);
-        mScrollablePreview.setVisibility(View.VISIBLE);
+            params.width = (int) (scale * scrollableArea.width());
+            params.height = (int) (scale * scrollableArea.height());
+            Matrix matrix = new Matrix();
+            matrix.setScale(scale, scale);
+            matrix.postTranslate(-scrollableArea.left * scale, -scrollableArea.top * scale);
+
+            mScrollablePreview.setTranslationX(scale * scrollableArea.left);
+            mScrollablePreview.setTranslationY(scale * scrollableArea.top);
+            mScrollablePreview.setImageMatrix(matrix);
+            mScrollablePreview.setImageBitmap(screenBitmap);
+            mScrollablePreview.setVisibility(View.VISIBLE);
+        }
         mDismissButton.setVisibility(View.GONE);
         mActionsContainer.setVisibility(View.GONE);
         mBackgroundProtection.setVisibility(View.GONE);
@@ -919,6 +949,8 @@
         mActionsContainer.setVisibility(View.GONE);
         mBackgroundProtection.setAlpha(0f);
         mDismissButton.setVisibility(View.GONE);
+        mScrollingScrim.setVisibility(View.GONE);
+        mScrollablePreview.setVisibility(View.GONE);
         mScreenshotStatic.setTranslationX(0);
         mScreenshotPreview.setTranslationY(0);
         mScreenshotPreview.setContentDescription(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index a2048e2..f6b16b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -21,6 +21,7 @@
 import android.animation.ValueAnimator
 import android.app.WallpaperManager
 import android.os.SystemClock
+import android.os.Trace
 import android.util.IndentingPrintWriter
 import android.util.Log
 import android.util.MathUtils
@@ -198,6 +199,7 @@
         blur = (blur * (1f - brightnessMirrorSpring.ratio)).toInt()
 
         val opaque = scrimsVisible && !blursDisabledForAppLaunch
+        Trace.traceCounter(Trace.TRACE_TAG_APP, "shade_blur_radius", blur)
         blurUtils.applyBlur(blurRoot?.viewRootImpl ?: root.viewRootImpl, blur, opaque)
         try {
             if (root.isAttachedToWindow && root.windowToken != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/charging/ChargingRippleView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/charging/ChargingRippleView.kt
index 3196eba..4a467ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/charging/ChargingRippleView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/charging/ChargingRippleView.kt
@@ -39,9 +39,15 @@
 
     var rippleInProgress: Boolean = false
     var radius: Float = 0.0f
-        set(value) { rippleShader.radius = value }
+        set(value) {
+            rippleShader.radius = value
+            field = value
+        }
     var origin: PointF = PointF()
-        set(value) { rippleShader.origin = value }
+        set(value) {
+            rippleShader.origin = value
+            field = value
+        }
     var duration: Long = 1750
 
     init {
@@ -94,6 +100,11 @@
     }
 
     override fun onDraw(canvas: Canvas?) {
-        canvas?.drawRect(0f, 0f, width.toFloat(), height.toFloat(), ripplePaint)
+        // To reduce overdraw, we mask the effect to a circle whose radius is big enough to cover
+        // the active effect area. Values here should be kept in sync with the
+        // animation implementation in the ripple shader.
+        val maskRadius = (1 - (1 - rippleShader.progress) * (1 - rippleShader.progress) *
+                (1 - rippleShader.progress)) * radius * 1.5f
+        canvas?.drawCircle(origin.x, origin.y, maskRadius, ripplePaint)
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 9ce9aa8..add6fda 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -27,7 +27,6 @@
 import com.android.systemui.R;
 import com.android.systemui.animation.Interpolators;
 import com.android.systemui.statusbar.NotificationShelf;
-import com.android.systemui.statusbar.notification.dagger.SilentHeader;
 import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
@@ -37,9 +36,9 @@
 import java.util.List;
 
 /**
- * The Algorithm of the {@link com.android.systemui.statusbar.notification.stack
- * .NotificationStackScrollLayout} which can be queried for {@link com.android.systemui.statusbar
- * .stack.StackScrollState}
+ * The Algorithm of the
+ * {@link com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout} which can
+ * be queried for {@link StackScrollAlgorithmState}
  */
 public class StackScrollAlgorithm {
 
@@ -96,7 +95,7 @@
 
         // First we reset the view states to their default values.
         resetChildViewStates();
-        initAlgorithmState(mHostView, algorithmState, ambientState);
+        initAlgorithmState(algorithmState, ambientState);
         updatePositionsForState(algorithmState, ambientState);
         updateZValuesForState(algorithmState, ambientState);
         updateHeadsUpStates(algorithmState, ambientState);
@@ -216,19 +215,18 @@
     /**
      * Initialize the algorithm state like updating the visible children.
      */
-    private void initAlgorithmState(ViewGroup hostView, StackScrollAlgorithmState state,
-            AmbientState ambientState) {
+    private void initAlgorithmState(StackScrollAlgorithmState state, AmbientState ambientState) {
         state.scrollY = ambientState.getScrollY();
         state.mCurrentYPosition = -state.scrollY;
         state.mCurrentExpandedYPosition = -state.scrollY;
 
         //now init the visible children and update paddings
-        int childCount = hostView.getChildCount();
+        int childCount = mHostView.getChildCount();
         state.visibleChildren.clear();
         state.visibleChildren.ensureCapacity(childCount);
         int notGoneIndex = 0;
         for (int i = 0; i < childCount; i++) {
-            ExpandableView v = (ExpandableView) hostView.getChildAt(i);
+            ExpandableView v = (ExpandableView) mHostView.getChildAt(i);
             if (v.getVisibility() != View.GONE) {
                 if (v == ambientState.getShelf()) {
                     continue;
@@ -237,7 +235,7 @@
                 if (v instanceof ExpandableNotificationRow) {
                     ExpandableNotificationRow row = (ExpandableNotificationRow) v;
 
-                    // handle the notgoneIndex for the children as well
+                    // handle the notGoneIndex for the children as well
                     List<ExpandableNotificationRow> children = row.getAttachedChildren();
                     if (row.isSummaryWithChildren() && children != null) {
                         for (ExpandableNotificationRow childRow : children) {
@@ -407,29 +405,33 @@
             final boolean noSpaceForFooter = footerEnd > ambientState.getStackEndHeight();
             ((FooterView.FooterViewState) viewState).hideContent =
                     shadeClosed || isShelfShowing || noSpaceForFooter;
-
-        } else if (view != ambientState.getTrackedHeadsUpRow()) {
-            if (ambientState.isExpansionChanging()) {
-                // Show all views. Views below the shelf will later be clipped (essentially hidden)
-                // in NotificationShelf.
-                viewState.hidden = false;
-                viewState.inShelf = algorithmState.firstViewInShelf != null
-                        && i >= algorithmState.visibleChildren.indexOf(
-                                algorithmState.firstViewInShelf);
-            } else if (ambientState.getShelf() != null) {
-                // When pulsing (incoming notification on AOD), innerHeight is 0; clamp all
-                // to shelf start, thereby hiding all notifications (except the first one, which we
-                // later unhide in updatePulsingState)
-                final int stackBottom = !ambientState.isShadeExpanded() || ambientState.isDozing()
-                        ? ambientState.getInnerHeight() : (int) ambientState.getStackHeight();
-                final int shelfStart = stackBottom - ambientState.getShelf().getIntrinsicHeight();
-                viewState.yTranslation = Math.min(viewState.yTranslation, shelfStart);
-                if (viewState.yTranslation >= shelfStart) {
-                    viewState.hidden = !view.isExpandAnimationRunning()
-                            && !view.hasExpandingChild();
-                    viewState.inShelf = true;
-                    // Notifications in the shelf cannot be visible HUNs.
-                    viewState.headsUpIsVisible = false;
+        } else {
+            if (view != ambientState.getTrackedHeadsUpRow()) {
+                if (ambientState.isExpansionChanging()) {
+                    // Show all views. Views below the shelf will later be clipped (essentially
+                    // hidden) in NotificationShelf.
+                    viewState.hidden = false;
+                    viewState.inShelf = algorithmState.firstViewInShelf != null
+                            && i >= algorithmState.visibleChildren.indexOf(
+                                    algorithmState.firstViewInShelf);
+                } else if (ambientState.getShelf() != null) {
+                    // When pulsing (incoming notification on AOD), innerHeight is 0; clamp all
+                    // to shelf start, thereby hiding all notifications (except the first one, which
+                    // we later unhide in updatePulsingState)
+                    final int stackBottom =
+                            !ambientState.isShadeExpanded() || ambientState.isDozing()
+                                    ? ambientState.getInnerHeight()
+                                    : (int) ambientState.getStackHeight();
+                    final int shelfStart =
+                            stackBottom - ambientState.getShelf().getIntrinsicHeight();
+                    viewState.yTranslation = Math.min(viewState.yTranslation, shelfStart);
+                    if (viewState.yTranslation >= shelfStart) {
+                        viewState.hidden = !view.isExpandAnimationRunning()
+                                && !view.hasExpandingChild();
+                        viewState.inShelf = true;
+                        // Notifications in the shelf cannot be visible HUNs.
+                        viewState.headsUpIsVisible = false;
+                    }
                 }
             }
 
@@ -485,7 +487,7 @@
             View previousChild) {
         return sectionProvider.beginsSection(child, previousChild)
                 && visibleIndex > 0
-                && !(previousChild instanceof SilentHeader)
+                && !(previousChild instanceof SectionHeaderView)
                 && !(child instanceof FooterView);
     }
 
@@ -696,7 +698,7 @@
         this.mIsExpanded = isExpanded;
     }
 
-    public class StackScrollAlgorithmState {
+    public static class StackScrollAlgorithmState {
 
         /**
          * The scroll position of the algorithm (absolute scrolling).
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index fa5011e..ad4213d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -234,7 +234,9 @@
 
     private int getClockY(float panelExpansion, float darkAmount) {
         float clockYRegular = getExpandedPreferredClockY();
-        float clockYBouncer = -mKeyguardStatusHeight;
+
+        // Dividing the height creates a smoother transition when the user swipes up to unlock
+        float clockYBouncer = -mKeyguardStatusHeight / 3.0f;
 
         // Move clock up while collapsing the shade
         float shadeExpansion = Interpolators.FAST_OUT_LINEAR_IN.getInterpolation(panelExpansion);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 1a2b989..c123a40 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -121,6 +121,7 @@
 import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.NotificationShadeDepthController;
 import com.android.systemui.statusbar.NotificationShelfController;
 import com.android.systemui.statusbar.PulseExpansionHandler;
@@ -314,6 +315,7 @@
     private final ScrimController mScrimController;
     private final PrivacyDotViewController mPrivacyDotViewController;
     private final QuickAccessWalletController mQuickAccessWalletController;
+    private final NotificationRemoteInputManager mRemoteInputManager;
 
     // Maximum # notifications to show on Keyguard; extras will be collapsed in an overflow card.
     // If there are exactly 1 + mMaxKeyguardNotifications, then still shows all notifications
@@ -372,7 +374,6 @@
     private float mLastOverscroll;
     private boolean mQsExpansionEnabledPolicy = true;
     private boolean mQsExpansionEnabledAmbient = true;
-    private boolean mQsExpansionEnabled = mQsExpansionEnabledPolicy && mQsExpansionEnabledAmbient;
     private ValueAnimator mQsExpansionAnimator;
     private FlingAnimationUtils mFlingAnimationUtils;
     private int mStatusBarMinHeight;
@@ -696,7 +697,8 @@
             QuickAccessWalletController quickAccessWalletController,
             @Main Executor uiExecutor,
             SecureSettings secureSettings,
-            UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
+            UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
+            NotificationRemoteInputManager remoteInputManager) {
         super(view, falsingManager, dozeLog, keyguardStateController,
                 (SysuiStatusBarStateController) statusBarStateController, vibratorHelper,
                 statusBarKeyguardViewManager, latencyTracker, flingAnimationUtilsBuilder.get(),
@@ -789,6 +791,8 @@
         mAuthController = authController;
         mLockIconViewController = lockIconViewController;
         mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
+        mRemoteInputManager = remoteInputManager;
+
         int currentMode = navigationModeController.addListener(
                 mode -> mIsGestureNavigation = QuickStepContract.isGesturalMode(mode));
         mIsGestureNavigation = QuickStepContract.isGesturalMode(currentMode);
@@ -1460,9 +1464,8 @@
     }
 
     private void setQsExpansionEnabled() {
-        mQsExpansionEnabled = mQsExpansionEnabledPolicy && mQsExpansionEnabledAmbient;
         if (mQs == null) return;
-        mQs.setHeaderClickable(mQsExpansionEnabled);
+        mQs.setHeaderClickable(isQsExpansionEnabled());
     }
 
     public void setQsExpansionEnabledPolicy(boolean qsExpansionEnabledPolicy) {
@@ -1531,8 +1534,13 @@
         flingSettings(0 /* vel */, animateAway ? FLING_HIDE : FLING_COLLAPSE);
     }
 
+    private boolean isQsExpansionEnabled() {
+        return mQsExpansionEnabledPolicy && mQsExpansionEnabledAmbient
+                && !mRemoteInputManager.getController().isRemoteInputActive();
+    }
+
     public void expandWithQs() {
-        if (mQsExpansionEnabled) {
+        if (isQsExpansionEnabled()) {
             mQsExpandImmediate = true;
             mNotificationStackScrollLayoutController.setShouldShowShelfOnly(true);
         }
@@ -1797,7 +1805,7 @@
     private boolean handleQsTouch(MotionEvent event) {
         final int action = event.getActionMasked();
         if (action == MotionEvent.ACTION_DOWN && getExpandedFraction() == 1f
-                && mBarState != KEYGUARD && !mQsExpanded && mQsExpansionEnabled) {
+                && mBarState != KEYGUARD && !mQsExpanded && isQsExpansionEnabled()) {
             // Down in the empty area while fully expanded - go to QS.
             mQsTracking = true;
             traceQsJank(true /* startTracing */, false /* wasCancelled */);
@@ -1819,7 +1827,7 @@
         if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
             mConflictingQsExpansionGesture = false;
         }
-        if (action == MotionEvent.ACTION_DOWN && isFullyCollapsed() && mQsExpansionEnabled) {
+        if (action == MotionEvent.ACTION_DOWN && isFullyCollapsed() && isQsExpansionEnabled()) {
             mTwoFingerQsExpandPossible = true;
         }
         if (mTwoFingerQsExpandPossible && isOpenQsEvent(event) && event.getY(event.getActionIndex())
@@ -2657,7 +2665,7 @@
      * @return Whether we should intercept a gesture to open Quick Settings.
      */
     private boolean shouldQuickSettingsIntercept(float x, float y, float yDiff) {
-        if (!mQsExpansionEnabled || mCollapsedOnDown || (mKeyguardShowing
+        if (!isQsExpansionEnabled() || mCollapsedOnDown || (mKeyguardShowing
                 && mKeyguardBypassController.getBypassEnabled())) {
             return false;
         }
@@ -2780,7 +2788,6 @@
     private int calculatePanelHeightShade() {
         int emptyBottomMargin = mNotificationStackScrollLayoutController.getEmptyBottomMargin();
         int maxHeight = mNotificationStackScrollLayoutController.getHeight() - emptyBottomMargin;
-        maxHeight += mNotificationStackScrollLayoutController.getTopPaddingOverflow();
 
         if (mBarState == KEYGUARD) {
             int minKeyguardPanelBottom = mClockPositionAlgorithm.getLockscreenStatusViewHeight()
@@ -3476,7 +3483,7 @@
             mQs = (QS) fragment;
             mQs.setPanelView(mHeightListener);
             mQs.setExpandClickListener(mOnClickListener);
-            mQs.setHeaderClickable(mQsExpansionEnabled);
+            mQs.setHeaderClickable(isQsExpansionEnabled());
             updateQSPulseExpansion();
             mQs.setOverscrolling(mStackScrollerOverscrolling);
             mQs.setTranslateWhileExpanding(mShouldUseSplitNotificationShade);
@@ -3967,7 +3974,7 @@
             if (mQsExpanded) {
                 flingSettings(0 /* vel */, FLING_COLLAPSE, null /* onFinishRunnable */,
                         true /* isClick */);
-            } else if (mQsExpansionEnabled) {
+            } else if (isQsExpansionEnabled()) {
                 mLockscreenGestureLogger.write(MetricsEvent.ACTION_SHADE_QS_TAP, 0, 0);
                 flingSettings(0 /* vel */, FLING_EXPAND, null /* onFinishRunnable */,
                         true /* isClick */);
@@ -3984,7 +3991,7 @@
                 return;
             }
             cancelQsAnimation();
-            if (!mQsExpansionEnabled) {
+            if (!isQsExpansionEnabled()) {
                 amount = 0f;
             }
             float rounded = amount >= 1f ? amount : 0f;
@@ -4012,8 +4019,9 @@
                 setOverScrolling(false);
             }
             setQsExpansion(mQsExpansionHeight);
-            flingSettings(!mQsExpansionEnabled && open ? 0f : velocity,
-                    open && mQsExpansionEnabled ? FLING_EXPAND : FLING_COLLAPSE, () -> {
+            boolean canExpand = isQsExpansionEnabled();
+            flingSettings(!canExpand && open ? 0f : velocity,
+                    open && canExpand ? FLING_EXPAND : FLING_COLLAPSE, () -> {
                         setOverScrolling(false);
                         updateQsState();
                     }, false /* isClick */);
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
index 65f236b..0ecc4e2 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
@@ -25,6 +25,7 @@
 import android.service.quickaccesswallet.GetWalletCardsRequest;
 import android.service.quickaccesswallet.QuickAccessWalletClient;
 import android.service.quickaccesswallet.QuickAccessWalletClientImpl;
+import android.util.Log;
 
 import com.android.systemui.R;
 import com.android.systemui.dagger.SysUISingleton;
@@ -142,6 +143,10 @@
      */
     public void queryWalletCards(
             QuickAccessWalletClient.OnWalletCardsRetrievedCallback cardsRetriever) {
+        if (!mQuickAccessWalletClient.isWalletFeatureAvailable()) {
+            Log.d(TAG, "QuickAccessWallet feature is not available.");
+            return;
+        }
         int cardWidth =
                 mContext.getResources().getDimensionPixelSize(R.dimen.wallet_tile_card_view_width);
         int cardHeight =
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
index 2dcc43c..dc240db 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
@@ -136,7 +136,7 @@
             }
         };
 
-        walletView.getAppButton().setOnClickListener(
+        walletView.setShowWalletAppOnClickListener(
                 v -> {
                     if (mWalletClient.createWalletIntent() == null) {
                         Log.w(TAG, "Unable to create wallet app intent.");
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
index 0c53477..0a09d59 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
@@ -22,6 +22,7 @@
 import android.annotation.Nullable;
 import android.app.PendingIntent;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.graphics.drawable.Drawable;
 import android.text.TextUtils;
 import android.util.AttributeSet;
@@ -54,6 +55,8 @@
     private final TextView mCardLabel;
     // Displays at the bottom of the screen, allow user to enter the default wallet app.
     private final Button mAppButton;
+    // Displays on the top right of the screen, allow user to enter the default wallet app.
+    private final Button mToolbarAppButton;
     // Displays underneath the carousel, allow user to unlock device, verify card, etc.
     private final Button mActionButton;
     private final Interpolator mOutInterpolator;
@@ -61,10 +64,10 @@
     private final ViewGroup mCardCarouselContainer;
     private final TextView mErrorView;
     private final ViewGroup mEmptyStateView;
-    private CharSequence mCenterCardText;
     private boolean mIsDeviceLocked = false;
     private boolean mIsUdfpsEnabled = false;
     private OnClickListener mDeviceLockedActionOnClickListener;
+    private OnClickListener mShowWalletAppOnClickListener;
 
     public WalletView(Context context) {
         this(context, null);
@@ -79,6 +82,7 @@
         mIcon = requireViewById(R.id.icon);
         mCardLabel = requireViewById(R.id.label);
         mAppButton = requireViewById(R.id.wallet_app_button);
+        mToolbarAppButton = requireViewById(R.id.wallet_toolbar_app_button);
         mActionButton = requireViewById(R.id.wallet_action_button);
         mErrorView = requireViewById(R.id.error_view);
         mEmptyStateView = requireViewById(R.id.wallet_empty_state);
@@ -94,6 +98,43 @@
     }
 
     @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        updateViewForOrientation(newConfig.orientation);
+    }
+
+    private void updateViewForOrientation(@Configuration.Orientation int orientation) {
+        if (orientation == Configuration.ORIENTATION_PORTRAIT) {
+            renderViewPortrait();
+        } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
+            renderViewLandscape();
+        }
+        ViewGroup.LayoutParams params = mCardCarouselContainer.getLayoutParams();
+        if (params instanceof MarginLayoutParams) {
+            ((MarginLayoutParams) params).topMargin =
+                    getResources().getDimensionPixelSize(
+                            R.dimen.wallet_card_carousel_container_top_margin);
+        }
+    }
+
+    private void renderViewPortrait() {
+        mAppButton.setVisibility(VISIBLE);
+        mToolbarAppButton.setVisibility(GONE);
+        mCardLabel.setVisibility(VISIBLE);
+        requireViewById(R.id.dynamic_placeholder).setVisibility(VISIBLE);
+
+        mAppButton.setOnClickListener(mShowWalletAppOnClickListener);
+    }
+
+    private void renderViewLandscape() {
+        mToolbarAppButton.setVisibility(VISIBLE);
+        mAppButton.setVisibility(GONE);
+        mCardLabel.setVisibility(GONE);
+        requireViewById(R.id.dynamic_placeholder).setVisibility(GONE);
+
+        mToolbarAppButton.setOnClickListener(mShowWalletAppOnClickListener);
+    }
+
+    @Override
     public boolean onTouchEvent(MotionEvent event) {
         // Forward touch events to card carousel to allow for swiping outside carousel bounds.
         return mCardCarousel.onTouchEvent(event) || super.onTouchEvent(event);
@@ -137,10 +178,12 @@
         mIsDeviceLocked = isDeviceLocked;
         mIsUdfpsEnabled = isUdfpsEnabled;
         mCardCarouselContainer.setVisibility(VISIBLE);
+        mCardCarousel.setVisibility(VISIBLE);
         mErrorView.setVisibility(GONE);
         mEmptyStateView.setVisibility(GONE);
         mIcon.setImageDrawable(getHeaderIcon(mContext, data.get(selectedIndex)));
         mCardLabel.setText(getLabelText(data.get(selectedIndex)));
+        updateViewForOrientation(getResources().getConfiguration().orientation);
         renderActionButton(data.get(selectedIndex), isDeviceLocked, mIsUdfpsEnabled);
         if (shouldAnimate) {
             animateViewsShown(mIcon, mCardLabel, mActionButton);
@@ -190,6 +233,10 @@
         mDeviceLockedActionOnClickListener = onClickListener;
     }
 
+    void setShowWalletAppOnClickListener(OnClickListener onClickListener) {
+        mShowWalletAppOnClickListener = onClickListener;
+    }
+
     void hide() {
         setVisibility(GONE);
     }
@@ -206,10 +253,6 @@
         return mCardCarousel;
     }
 
-    Button getAppButton() {
-        return mAppButton;
-    }
-
     Button getActionButton() {
         return mActionButton;
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleBackupFollowUpJobTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleBackupFollowUpJobTest.java
new file mode 100644
index 0000000..00e012e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleBackupFollowUpJobTest.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.people;
+
+import static com.android.systemui.people.PeopleBackupFollowUpJob.SHARED_FOLLOW_UP;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.job.JobScheduler;
+import android.app.people.IPeopleManager;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.RemoteException;
+import android.preference.PreferenceManager;
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.people.widget.PeopleTileKey;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.time.Duration;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class PeopleBackupFollowUpJobTest extends SysuiTestCase {
+    private static final String SHORTCUT_ID_1 = "101";
+    private static final String PACKAGE_NAME_1 = "package_name";
+    private static final int USER_ID_1 = 0;
+
+    private static final PeopleTileKey PEOPLE_TILE_KEY =
+            new PeopleTileKey(SHORTCUT_ID_1, USER_ID_1, PACKAGE_NAME_1);
+
+    private static final String WIDGET_ID_STRING = "3";
+    private static final String SECOND_WIDGET_ID_STRING = "12";
+    private static final Set<String> WIDGET_IDS = new HashSet<>(
+            Arrays.asList(WIDGET_ID_STRING, SECOND_WIDGET_ID_STRING));
+
+    private static final Uri URI = Uri.parse("fake_uri");
+
+    @Mock
+    private PackageManager mPackageManager;
+    @Mock
+    private PackageInfo mPackageInfo;
+    @Mock
+    private IPeopleManager mIPeopleManager;
+    @Mock
+    private JobScheduler mJobScheduler;
+
+    private final SharedPreferences mSp = PreferenceManager.getDefaultSharedPreferences(mContext);
+    private final SharedPreferences.Editor mEditor = mSp.edit();
+    private final SharedPreferences mFollowUpSp = mContext.getSharedPreferences(
+            SHARED_FOLLOW_UP, Context.MODE_PRIVATE);
+    private final SharedPreferences.Editor mFollowUpEditor = mFollowUpSp.edit();
+    private final SharedPreferences mWidgetIdSp = mContext.getSharedPreferences(
+            WIDGET_ID_STRING, Context.MODE_PRIVATE);
+    private final SharedPreferences mSecondWidgetIdSp = mContext.getSharedPreferences(
+            SECOND_WIDGET_ID_STRING, Context.MODE_PRIVATE);
+
+    private PeopleBackupFollowUpJob mPeopleBackupFollowUpJob;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        when(mPackageManager.getPackageInfoAsUser(any(), anyInt(), anyInt()))
+                .thenReturn(mPackageInfo);
+        when(mIPeopleManager.isConversation(any(), anyInt(), any())).thenReturn(true);
+
+        mPeopleBackupFollowUpJob = new PeopleBackupFollowUpJob();
+        mPeopleBackupFollowUpJob.setManagers(
+                mContext, mPackageManager, mIPeopleManager, mJobScheduler);
+    }
+
+    @After
+    public void tearDown() {
+        mEditor.clear().commit();
+        mFollowUpEditor.clear().commit();
+        mWidgetIdSp.edit().clear().commit();
+        mSecondWidgetIdSp.edit().clear().commit();
+    }
+
+    @Test
+    public void testProcessFollowUpFile_shouldFollowUp() throws RemoteException {
+        when(mIPeopleManager.isConversation(any(), anyInt(), any())).thenReturn(false);
+        mFollowUpEditor.putStringSet(PEOPLE_TILE_KEY.toString(), WIDGET_IDS);
+        mFollowUpEditor.apply();
+
+        Map<String, Set<String>> remainingWidgets =
+                mPeopleBackupFollowUpJob.processFollowUpFile(mFollowUpSp, mFollowUpEditor);
+        mEditor.apply();
+        mFollowUpEditor.apply();
+
+        assertThat(remainingWidgets.size()).isEqualTo(1);
+        assertThat(remainingWidgets.get(PEOPLE_TILE_KEY.toString()))
+                .containsExactly(WIDGET_ID_STRING, SECOND_WIDGET_ID_STRING);
+        assertThat(mFollowUpSp.getStringSet(PEOPLE_TILE_KEY.toString(), new HashSet<>()))
+                .containsExactly(WIDGET_ID_STRING, SECOND_WIDGET_ID_STRING);
+    }
+
+    @Test
+    public void testProcessFollowUpFile_shouldRestore() {
+        mFollowUpEditor.putStringSet(PEOPLE_TILE_KEY.toString(), WIDGET_IDS);
+        mFollowUpEditor.apply();
+
+        Map<String, Set<String>> remainingWidgets =
+                mPeopleBackupFollowUpJob.processFollowUpFile(mFollowUpSp, mFollowUpEditor);
+        mEditor.apply();
+        mFollowUpEditor.apply();
+
+        assertThat(remainingWidgets).isEmpty();
+        assertThat(mFollowUpSp.getStringSet(PEOPLE_TILE_KEY.toString(), new HashSet<>())).isEmpty();
+    }
+
+    @Test
+    public void testShouldCancelJob_noRemainingWidgets_shouldCancel() {
+        assertThat(mPeopleBackupFollowUpJob.shouldCancelJob(
+                new HashMap<>(), 10, Duration.ofMinutes(1).toMillis())).isTrue();
+    }
+
+    @Test
+    public void testShouldCancelJob_noRemainingWidgets_longTimeElapsed_shouldCancel() {
+        assertThat(mPeopleBackupFollowUpJob.shouldCancelJob(
+                new HashMap<>(), 10, Duration.ofHours(25).toMillis())).isTrue();
+    }
+
+    @Test
+    public void testShouldCancelJob_remainingWidgets_shortTimeElapsed_shouldNotCancel() {
+        Map<String, Set<String>> remainingWidgets = new HashMap<>();
+        remainingWidgets.put(PEOPLE_TILE_KEY.toString(), WIDGET_IDS);
+        assertThat(mPeopleBackupFollowUpJob.shouldCancelJob(remainingWidgets, 10, 1000)).isFalse();
+    }
+
+    @Test
+    public void testShouldCancelJob_remainingWidgets_longTimeElapsed_shouldCancel() {
+        Map<String, Set<String>> remainingWidgets = new HashMap<>();
+        remainingWidgets.put(PEOPLE_TILE_KEY.toString(), WIDGET_IDS);
+        assertThat(mPeopleBackupFollowUpJob.shouldCancelJob(
+                remainingWidgets, 10, 1000 * 60 * 60 * 25)).isTrue();
+    }
+
+    @Test
+    public void testCancelJobAndClearRemainingWidgets() {
+        SharedPreferencesHelper.setPeopleTileKey(mWidgetIdSp, PEOPLE_TILE_KEY);
+        SharedPreferencesHelper.setPeopleTileKey(mSecondWidgetIdSp, PEOPLE_TILE_KEY);
+        mEditor.putStringSet(URI.toString(), WIDGET_IDS);
+        mEditor.putString(WIDGET_ID_STRING, URI.toString());
+        mEditor.putString(SECOND_WIDGET_ID_STRING, URI.toString());
+        mEditor.apply();
+        Map<String, Set<String>> remainingWidgets = new HashMap<>();
+        remainingWidgets.put(PEOPLE_TILE_KEY.toString(), WIDGET_IDS);
+
+        mPeopleBackupFollowUpJob.cancelJobAndClearRemainingWidgets(
+                remainingWidgets, mFollowUpEditor, mSp);
+        mEditor.apply();
+        mFollowUpEditor.apply();
+
+        verify(mJobScheduler, times(1)).cancel(anyInt());
+        assertThat(mFollowUpSp.getAll()).isEmpty();
+        assertThat(mWidgetIdSp.getAll()).isEmpty();
+        assertThat(mSecondWidgetIdSp.getAll()).isEmpty();
+        assertThat(mSp.getStringSet(PEOPLE_TILE_KEY.toString(), new HashSet<>())).isEmpty();
+        assertThat(mSp.getStringSet(URI.toString(), new HashSet<>())).isEmpty();
+        assertThat(mSp.getString(WIDGET_ID_STRING, null)).isNull();
+        assertThat(mSp.getString(SECOND_WIDGET_ID_STRING, null)).isNull();
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
index 33c7a57..fba1986 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
@@ -33,6 +33,7 @@
 import android.app.INotificationManager;
 import android.app.Notification;
 import android.app.Person;
+import android.app.backup.BackupManager;
 import android.app.people.IPeopleManager;
 import android.app.people.PeopleSpaceTile;
 import android.appwidget.AppWidgetManager;
@@ -198,6 +199,8 @@
     private NotificationEntryManager mNotificationEntryManager;
     @Mock
     private PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
+    @Mock
+    private BackupManager mBackupManager;
 
     private Bundle mOptions;
 
@@ -252,7 +255,7 @@
         PeopleTileKey key = new PeopleTileKey(tile);
         PeopleSpaceTile actual = PeopleSpaceUtils
                 .augmentTileFromNotification(mContext, tile, key, mNotificationEntry1, 0,
-                        Optional.empty());
+                        Optional.empty(), mBackupManager);
 
         assertThat(actual.getNotificationContent().toString()).isEqualTo(NOTIFICATION_TEXT_2);
         assertThat(actual.getNotificationSender()).isEqualTo(null);
@@ -292,7 +295,7 @@
         PeopleTileKey key = new PeopleTileKey(tile);
         PeopleSpaceTile actual = PeopleSpaceUtils
                 .augmentTileFromNotification(mContext, tile, key, notificationEntry, 0,
-                        Optional.empty());
+                        Optional.empty(), mBackupManager);
 
         assertThat(actual.getNotificationContent().toString()).isEqualTo(NOTIFICATION_TEXT_2);
         assertThat(actual.getNotificationSender().toString()).isEqualTo("name");
@@ -325,7 +328,7 @@
         PeopleTileKey key = new PeopleTileKey(tile);
         PeopleSpaceTile actual = PeopleSpaceUtils
                 .augmentTileFromNotification(mContext, tile, key, notificationEntry, 0,
-                        Optional.empty());
+                        Optional.empty(), mBackupManager);
 
         assertThat(actual.getNotificationContent().toString()).isEqualTo(NOTIFICATION_TEXT_1);
         assertThat(actual.getNotificationDataUri()).isEqualTo(URI);
@@ -358,7 +361,7 @@
         PeopleTileKey key = new PeopleTileKey(tile);
         PeopleSpaceTile actual = PeopleSpaceUtils
                 .augmentTileFromNotification(mContext, tile, key, notificationEntry, 0,
-                        Optional.empty());
+                        Optional.empty(), mBackupManager);
 
         assertThat(actual.getNotificationContent().toString()).isEqualTo(NOTIFICATION_TEXT_1);
         assertThat(actual.getNotificationDataUri()).isNull();
@@ -376,7 +379,7 @@
         PeopleTileKey key = new PeopleTileKey(tile);
         PeopleSpaceTile actual = PeopleSpaceUtils
                 .augmentTileFromNotification(mContext, tile, key, mNotificationEntry3, 0,
-                        Optional.empty());
+                        Optional.empty(), mBackupManager);
 
         assertThat(actual.getNotificationContent()).isEqualTo(null);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/SharedPreferencesHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/SharedPreferencesHelperTest.java
new file mode 100644
index 0000000..7cd5e22
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/SharedPreferencesHelperTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.people;
+
+import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
+import static com.android.systemui.people.PeopleSpaceUtils.PACKAGE_NAME;
+import static com.android.systemui.people.PeopleSpaceUtils.SHORTCUT_ID;
+import static com.android.systemui.people.PeopleSpaceUtils.USER_ID;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.people.widget.PeopleTileKey;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class SharedPreferencesHelperTest extends SysuiTestCase {
+    private static final String SHORTCUT_ID_1 = "101";
+    private static final String PACKAGE_NAME_1 = "package_name";
+    private static final int USER_ID_1 = 0;
+
+    private static final PeopleTileKey PEOPLE_TILE_KEY =
+            new PeopleTileKey(SHORTCUT_ID_1, USER_ID_1, PACKAGE_NAME_1);
+
+    private static final int WIDGET_ID = 1;
+
+    private void setStorageForTile(PeopleTileKey peopleTileKey, int widgetId) {
+        SharedPreferences widgetSp = mContext.getSharedPreferences(
+                String.valueOf(widgetId),
+                Context.MODE_PRIVATE);
+        SharedPreferences.Editor widgetEditor = widgetSp.edit();
+        widgetEditor.putString(PeopleSpaceUtils.PACKAGE_NAME, peopleTileKey.getPackageName());
+        widgetEditor.putString(PeopleSpaceUtils.SHORTCUT_ID, peopleTileKey.getShortcutId());
+        widgetEditor.putInt(PeopleSpaceUtils.USER_ID, peopleTileKey.getUserId());
+        widgetEditor.apply();
+    }
+
+    @Test
+    public void testGetPeopleTileKey() {
+        setStorageForTile(PEOPLE_TILE_KEY, WIDGET_ID);
+
+        SharedPreferences sp = mContext.getSharedPreferences(
+                String.valueOf(WIDGET_ID),
+                Context.MODE_PRIVATE);
+        PeopleTileKey actual = SharedPreferencesHelper.getPeopleTileKey(sp);
+
+        assertThat(actual.getPackageName()).isEqualTo(PACKAGE_NAME_1);
+        assertThat(actual.getShortcutId()).isEqualTo(SHORTCUT_ID_1);
+        assertThat(actual.getUserId()).isEqualTo(USER_ID_1);
+    }
+
+    @Test
+    public void testSetPeopleTileKey() {
+        SharedPreferences sp = mContext.getSharedPreferences(
+                String.valueOf(WIDGET_ID),
+                Context.MODE_PRIVATE);
+        SharedPreferencesHelper.setPeopleTileKey(sp, PEOPLE_TILE_KEY);
+
+        assertThat(sp.getString(SHORTCUT_ID, null)).isEqualTo(SHORTCUT_ID_1);
+        assertThat(sp.getString(PACKAGE_NAME, null)).isEqualTo(PACKAGE_NAME_1);
+        assertThat(sp.getInt(USER_ID, INVALID_USER_ID)).isEqualTo(USER_ID_1);
+    }
+
+    @Test
+    public void testClear() {
+        setStorageForTile(PEOPLE_TILE_KEY, WIDGET_ID);
+
+        SharedPreferences sp = mContext.getSharedPreferences(
+                String.valueOf(WIDGET_ID),
+                Context.MODE_PRIVATE);
+        SharedPreferencesHelper.clear(sp);
+
+        assertThat(sp.getString(SHORTCUT_ID, null)).isEqualTo(null);
+        assertThat(sp.getString(PACKAGE_NAME, null)).isEqualTo(null);
+        assertThat(sp.getInt(USER_ID, INVALID_USER_ID)).isEqualTo(INVALID_USER_ID);
+
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/LaunchConversationActivityTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/LaunchConversationActivityTest.java
index f6264ff..d8ba164 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/LaunchConversationActivityTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/LaunchConversationActivityTest.java
@@ -49,7 +49,6 @@
 import com.android.wm.shell.bubbles.Bubble;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -92,20 +91,23 @@
     private NotificationListenerService.Ranking mRanking;
     @Mock
     private UserManager mUserManager;
-
+    @Mock
     private CommandQueue mCommandQueue;
 
     @Captor
     private ArgumentCaptor<NotificationVisibility> mNotificationVisibilityCaptor;
+    @Captor
+    private ArgumentCaptor<CommandQueue.Callbacks> mCallbacksCaptor;
 
     private Intent mIntent;
 
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mCommandQueue = new CommandQueue(mContext);
         mActivity = new LaunchConversationActivity(mNotificationEntryManager,
                 Optional.of(mBubblesManager), mUserManager, mCommandQueue);
+        verify(mCommandQueue, times(1)).addCallback(mCallbacksCaptor.capture());
+
         mActivity.setIsForTesting(true, mIStatusBarService);
         mIntent = new Intent();
         mIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_TILE_ID, "tile ID");
@@ -169,7 +171,7 @@
         mActivity.onCreate(new Bundle());
 
         assertThat(mActivity.isFinishing()).isTrue();
-        mCommandQueue.appTransitionFinished(DEFAULT_DISPLAY);
+        mCallbacksCaptor.getValue().appTransitionFinished(DEFAULT_DISPLAY);
 
         verify(mIStatusBarService, times(1)).onNotificationClear(any(),
                 anyInt(), any(), anyInt(), anyInt(), mNotificationVisibilityCaptor.capture());
@@ -183,17 +185,20 @@
 
     @Test
     public void testBubbleEntryOpensBubbleAndDoesNotClearNotification() throws Exception {
+        when(mBubblesManager.getBubbleWithShortcutId(any())).thenReturn(null);
         mIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_NOTIFICATION_KEY,
                 NOTIF_KEY_CAN_BUBBLE);
         mActivity.setIntent(mIntent);
         mActivity.onCreate(new Bundle());
 
         assertThat(mActivity.isFinishing()).isTrue();
-        mCommandQueue.appTransitionFinished(DEFAULT_DISPLAY);
+        mCallbacksCaptor.getValue().appTransitionFinished(DEFAULT_DISPLAY);
 
         // Don't clear the notification for bubbles.
         verify(mIStatusBarService, never()).onNotificationClear(any(),
                 anyInt(), any(), anyInt(), anyInt(), any());
+        // Select the bubble.
+        verify(mBubblesManager, times(1)).getBubbleWithShortcutId(any());
         verify(mBubblesManager, times(1)).expandStackAndSelectBubble(eq(mNotifEntryCanBubble));
     }
 
@@ -214,7 +219,7 @@
         verify(mBubblesManager, never()).expandStackAndSelectBubble(any(NotificationEntry.class));
     }
 
-    @Ignore
+
     @Test
     public void testBubbleWithNoNotifOpensBubble() throws Exception {
         Bubble bubble = mock(Bubble.class);
@@ -226,7 +231,7 @@
         mActivity.onCreate(new Bundle());
 
         assertThat(mActivity.isFinishing()).isTrue();
-        mCommandQueue.appTransitionFinished(DEFAULT_DISPLAY);
+        mCallbacksCaptor.getValue().appTransitionFinished(DEFAULT_DISPLAY);
 
         verify(mBubblesManager, times(1)).expandStackAndSelectBubble(eq(bubble));
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleBackupHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleBackupHelperTest.java
new file mode 100644
index 0000000..5d526e1
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleBackupHelperTest.java
@@ -0,0 +1,537 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.people.widget;
+
+import static com.android.systemui.people.PeopleBackupFollowUpJob.SHARED_FOLLOW_UP;
+import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
+import static com.android.systemui.people.widget.PeopleBackupHelper.ADD_USER_ID_TO_URI;
+import static com.android.systemui.people.widget.PeopleBackupHelper.SHARED_BACKUP;
+import static com.android.systemui.people.widget.PeopleBackupHelper.SharedFileEntryType;
+import static com.android.systemui.people.widget.PeopleBackupHelper.getEntryType;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.when;
+
+import android.app.people.IPeopleManager;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.preference.PreferenceManager;
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.people.SharedPreferencesHelper;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class PeopleBackupHelperTest extends SysuiTestCase {
+    private static final String SHORTCUT_ID_1 = "101";
+    private static final String PACKAGE_NAME_1 = "package_name";
+    private static final int USER_ID_0 = 0;
+    private static final int USER_ID_10 = 10;
+
+    private static final PeopleTileKey PEOPLE_TILE_KEY =
+            new PeopleTileKey(SHORTCUT_ID_1, USER_ID_0, PACKAGE_NAME_1);
+    private static final PeopleTileKey OTHER_PEOPLE_TILE_KEY =
+            new PeopleTileKey(SHORTCUT_ID_1, USER_ID_10, PACKAGE_NAME_1);
+    private static final PeopleTileKey INVALID_USER_ID_PEOPLE_TILE_KEY =
+            new PeopleTileKey(SHORTCUT_ID_1, INVALID_USER_ID, PACKAGE_NAME_1);
+
+    private static final String WIDGET_ID_STRING = "3";
+    private static final String SECOND_WIDGET_ID_STRING = "12";
+    private static final String OTHER_WIDGET_ID_STRING = "7";
+    private static final Set<String> WIDGET_IDS = new HashSet<>(
+            Arrays.asList(WIDGET_ID_STRING, SECOND_WIDGET_ID_STRING));
+
+    private static final String URI_STRING = "content://mms";
+    private static final String URI_WITH_USER_ID_0 = "content://0@mms";
+    private static final String URI_WITH_USER_ID_10 = "content://10@mms";
+
+    private final SharedPreferences mBackupSp = mContext.getSharedPreferences(
+            SHARED_BACKUP, Context.MODE_PRIVATE);
+    private final SharedPreferences.Editor mBackupEditor = mBackupSp.edit();
+    private final SharedPreferences mSp = PreferenceManager.getDefaultSharedPreferences(mContext);
+    private final SharedPreferences.Editor mEditor = mSp.edit();
+    private final SharedPreferences mFollowUpSp = mContext.getSharedPreferences(
+            SHARED_FOLLOW_UP, Context.MODE_PRIVATE);
+    private final SharedPreferences.Editor mFollowUpEditor = mFollowUpSp.edit();
+    private final SharedPreferences mWidgetIdSp = mContext.getSharedPreferences(
+            WIDGET_ID_STRING, Context.MODE_PRIVATE);
+    private final SharedPreferences mSecondWidgetIdSp = mContext.getSharedPreferences(
+            SECOND_WIDGET_ID_STRING, Context.MODE_PRIVATE);
+
+    @Mock
+    private PackageManager mPackageManager;
+    @Mock
+    private PackageInfo mPackageInfo;
+    @Mock
+    private IPeopleManager mIPeopleManager;
+
+    private PeopleBackupHelper mHelper;
+    private PeopleBackupHelper mOtherHelper;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mHelper = new PeopleBackupHelper(mContext,
+                UserHandle.of(0), new String[]{SHARED_BACKUP}, mPackageManager, mIPeopleManager);
+        mOtherHelper = new PeopleBackupHelper(mContext,
+                UserHandle.of(10), new String[]{SHARED_BACKUP}, mPackageManager, mIPeopleManager);
+
+        when(mPackageManager.getPackageInfoAsUser(any(), anyInt(), anyInt()))
+                .thenReturn(mPackageInfo);
+        when(mIPeopleManager.isConversation(any(), anyInt(), any())).thenReturn(true);
+    }
+
+    @After
+    public void tearDown() {
+        mBackupEditor.clear().commit();
+        mEditor.clear().commit();
+        mFollowUpEditor.clear().commit();
+        mWidgetIdSp.edit().clear().commit();
+        mSecondWidgetIdSp.edit().clear().commit();
+    }
+
+    @Test
+    public void testGetKeyType_widgetId() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(WIDGET_ID_STRING, "contact");
+        assertThat(getEntryType(entry)).isEqualTo(SharedFileEntryType.WIDGET_ID);
+    }
+
+    @Test
+    public void testGetKeyType_widgetId_twoDigits() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(
+                SECOND_WIDGET_ID_STRING, URI_STRING);
+        assertThat(getEntryType(entry)).isEqualTo(SharedFileEntryType.WIDGET_ID);
+    }
+
+    @Test
+    public void testGetKeyType_peopleTileKey_valid() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(
+                "shortcut_id/12/com.android.systemui", WIDGET_IDS);
+        assertThat(getEntryType(entry)).isEqualTo(SharedFileEntryType.PEOPLE_TILE_KEY);
+    }
+
+    @Test
+    public void testGetKeyType_peopleTileKey_validWithSlashes() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(
+                "shortcut_id/with/slashes/12/com.android.systemui2", WIDGET_IDS);
+        assertThat(getEntryType(entry)).isEqualTo(SharedFileEntryType.PEOPLE_TILE_KEY);
+    }
+
+    @Test
+    public void testGetKeyType_peopleTileKey_negativeNumber() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(
+                "shortcut_id/with/slashes/-1/com.android.systemui2", WIDGET_IDS);
+        assertThat(getEntryType(entry)).isEqualTo(SharedFileEntryType.PEOPLE_TILE_KEY);
+    }
+
+    @Test
+    public void testGetKeyType_contactUri() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(
+                "shortcut_id/1f/com.android.systemui2", WIDGET_IDS);
+        assertThat(getEntryType(entry)).isEqualTo(SharedFileEntryType.CONTACT_URI);
+    }
+
+    @Test
+    public void testGetKeyType_contactUri_valid() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(
+                "http://content.fake", WIDGET_IDS);
+        assertThat(getEntryType(entry)).isEqualTo(SharedFileEntryType.CONTACT_URI);
+    }
+
+    @Test
+    public void testGetKeyType_contactUri_invalidPackageName() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(
+                "shortcut_id/with/slashes/12/2r/com.android.systemui2", WIDGET_IDS);
+        assertThat(getEntryType(entry)).isEqualTo(SharedFileEntryType.CONTACT_URI);
+    }
+
+    @Test
+    public void testGetKeyType_unknown_unexpectedValueForPeopleTileKey() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(
+                "shortcut_id/12/com.android.systemui", URI_STRING);
+        assertThat(getEntryType(entry)).isEqualTo(SharedFileEntryType.UNKNOWN);
+    }
+
+    @Test
+    public void testGetKeyType_unknown_unexpectedValueForContactUri() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(
+                URI_STRING, "12");
+        assertThat(getEntryType(entry)).isEqualTo(SharedFileEntryType.UNKNOWN);
+    }
+
+    @Test
+    public void testGetKeyType_unknown() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(
+                null, WIDGET_IDS);
+        assertThat(getEntryType(entry)).isEqualTo(SharedFileEntryType.UNKNOWN);
+    }
+
+    @Test
+    public void testBackupKey_widgetIdKey_containsWidget_noUserIdInUri() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(WIDGET_ID_STRING, URI_STRING);
+
+        mHelper.backupKey(entry, mBackupEditor, Collections.singletonList(WIDGET_ID_STRING));
+        mBackupEditor.apply();
+
+        assertThat(mBackupSp.getString(WIDGET_ID_STRING, null)).isEqualTo(URI_STRING);
+    }
+
+    @Test
+    public void testBackupKey_widgetIdKey_doesNotContainWidget_noUserIdInUri() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(WIDGET_ID_STRING, URI_STRING);
+
+        mHelper.backupKey(entry, mBackupEditor, Collections.singletonList(OTHER_WIDGET_ID_STRING));
+        mBackupEditor.apply();
+
+        assertThat(mBackupSp.getString(WIDGET_ID_STRING, null)).isNull();
+    }
+
+    @Test
+    public void testBackupKey_widgetIdKey_containsOneWidget_differentUserIdInUri() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(WIDGET_ID_STRING,
+                URI_WITH_USER_ID_10);
+
+        mHelper.backupKey(entry, mBackupEditor, Collections.singletonList(WIDGET_ID_STRING));
+        mBackupEditor.apply();
+
+        assertThat(mBackupSp.getString(WIDGET_ID_STRING, null)).isEqualTo(URI_STRING);
+        assertThat(mBackupSp.getInt(ADD_USER_ID_TO_URI + WIDGET_ID_STRING, INVALID_USER_ID))
+                .isEqualTo(USER_ID_10);
+    }
+
+    @Test
+    public void testBackupKey_widgetIdKey_containsWidget_SameUserIdInUri() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(
+                WIDGET_ID_STRING, URI_WITH_USER_ID_10);
+
+        mOtherHelper.backupKey(entry, mBackupEditor, Collections.singletonList(WIDGET_ID_STRING));
+        mBackupEditor.apply();
+
+        assertThat(mBackupSp.getString(WIDGET_ID_STRING, null)).isEqualTo(URI_STRING);
+        assertThat(mBackupSp.getInt(ADD_USER_ID_TO_URI + WIDGET_ID_STRING, INVALID_USER_ID))
+                .isEqualTo(USER_ID_10);
+    }
+
+    @Test
+    public void testBackupKey_contactUriKey_ignoresExistingWidgets() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(URI_STRING, WIDGET_IDS);
+
+        mHelper.backupKey(entry, mBackupEditor, Collections.singletonList(WIDGET_ID_STRING));
+        mBackupEditor.apply();
+
+        assertThat(mBackupSp.getStringSet(URI_STRING, new HashSet<>()))
+                .containsExactly(WIDGET_ID_STRING, SECOND_WIDGET_ID_STRING);
+    }
+
+    @Test
+    public void testBackupKey_contactUriKey_ignoresExistingWidgets_otherWidget() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(URI_STRING, WIDGET_IDS);
+
+        mHelper.backupKey(entry, mBackupEditor, Collections.singletonList(WIDGET_ID_STRING));
+        mBackupEditor.apply();
+
+        assertThat(mBackupSp.getStringSet(URI_STRING, new HashSet<>()))
+                .containsExactly(WIDGET_ID_STRING, SECOND_WIDGET_ID_STRING);
+    }
+
+    @Test
+    public void testBackupKey_contactUriKey_noUserId_otherUser_doesntBackup() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(URI_STRING, WIDGET_IDS);
+
+        mOtherHelper.backupKey(entry, mBackupEditor, Collections.singletonList(WIDGET_ID_STRING));
+        mBackupEditor.apply();
+
+        assertThat(mBackupSp.getStringSet(URI_STRING, new HashSet<>())).isEmpty();
+    }
+
+    @Test
+    public void testBackupKey_contactUriKey_sameUserId() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(URI_WITH_USER_ID_10, WIDGET_IDS);
+
+        mOtherHelper.backupKey(entry, mBackupEditor, Collections.singletonList(WIDGET_ID_STRING));
+        mBackupEditor.apply();
+
+        assertThat(mBackupSp.getStringSet(URI_STRING, new HashSet<>()))
+                .containsExactly(WIDGET_ID_STRING, SECOND_WIDGET_ID_STRING);
+        assertThat(mBackupSp.getInt(ADD_USER_ID_TO_URI + URI_STRING, INVALID_USER_ID))
+                .isEqualTo(USER_ID_10);
+    }
+
+    @Test
+    public void testBackupKey_contactUriKey_differentUserId_runningAsUser0() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(URI_WITH_USER_ID_10, WIDGET_IDS);
+
+        mHelper.backupKey(entry, mBackupEditor, Collections.singletonList(WIDGET_ID_STRING));
+        mBackupEditor.apply();
+
+        assertThat(mBackupSp.getStringSet(URI_STRING, new HashSet<>())).isEmpty();
+        assertThat(mBackupSp.getInt(ADD_USER_ID_TO_URI + URI_STRING, INVALID_USER_ID))
+                .isEqualTo(INVALID_USER_ID);
+    }
+
+    @Test
+    public void testBackupKey_contactUriKey_differentUserId_runningAsUser10() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(URI_WITH_USER_ID_0, WIDGET_IDS);
+
+        mOtherHelper.backupKey(entry, mBackupEditor, Collections.singletonList(WIDGET_ID_STRING));
+        mBackupEditor.apply();
+
+        assertThat(mBackupSp.getStringSet(URI_STRING, new HashSet<>())).isEmpty();
+        assertThat(mBackupSp.getInt(ADD_USER_ID_TO_URI + URI_STRING, INVALID_USER_ID))
+                .isEqualTo(INVALID_USER_ID);
+    }
+
+    @Test
+    public void testBackupKey_peopleTileKey_containsWidget() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(
+                PEOPLE_TILE_KEY.toString(), WIDGET_IDS);
+
+        mHelper.backupKey(entry, mBackupEditor, Collections.singletonList(WIDGET_ID_STRING));
+        mBackupEditor.apply();
+
+        assertThat(mBackupSp.getStringSet(
+                INVALID_USER_ID_PEOPLE_TILE_KEY.toString(), new HashSet<>()))
+                .containsExactly(WIDGET_ID_STRING);
+    }
+
+    @Test
+    public void testBackupKey_peopleTileKey_containsBothWidgets() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(
+                PEOPLE_TILE_KEY.toString(), WIDGET_IDS);
+
+        mHelper.backupKey(entry, mBackupEditor,
+                Arrays.asList(WIDGET_ID_STRING, SECOND_WIDGET_ID_STRING));
+        mBackupEditor.apply();
+
+        assertThat(
+                mBackupSp.getStringSet(INVALID_USER_ID_PEOPLE_TILE_KEY.toString(), new HashSet<>()))
+                .containsExactly(WIDGET_ID_STRING, SECOND_WIDGET_ID_STRING);
+    }
+
+    @Test
+    public void testBackupKey_peopleTileKey_doesNotContainWidget() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(
+                PEOPLE_TILE_KEY.toString(), WIDGET_IDS);
+
+        mHelper.backupKey(entry, mBackupEditor, Collections.singletonList(OTHER_WIDGET_ID_STRING));
+        mBackupEditor.apply();
+
+        assertThat(mBackupSp.getStringSet(
+                INVALID_USER_ID_PEOPLE_TILE_KEY.toString(), new HashSet<>())).isEmpty();
+    }
+
+    @Test
+    public void testBackupKey_peopleTileKey_differentUserId() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(
+                OTHER_PEOPLE_TILE_KEY.toString(), WIDGET_IDS);
+
+        mHelper.backupKey(entry, mBackupEditor, Collections.singletonList(WIDGET_ID_STRING));
+        mBackupEditor.apply();
+
+        assertThat(mBackupSp.getStringSet(
+                INVALID_USER_ID_PEOPLE_TILE_KEY.toString(), new HashSet<>())).isEmpty();
+    }
+
+    @Test
+    public void testRestoreKey_widgetIdKey_noUserIdInUri() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(WIDGET_ID_STRING, URI_STRING);
+
+        boolean restored = mHelper.restoreKey(entry, mEditor, mFollowUpEditor, mBackupSp);
+        mEditor.apply();
+        mFollowUpEditor.apply();
+
+        assertThat(restored).isTrue();
+        assertThat(mSp.getString(WIDGET_ID_STRING, null)).isEqualTo(URI_STRING);
+        assertThat(mFollowUpSp.getAll()).isEmpty();
+    }
+
+    @Test
+    public void testRestoreKey_widgetIdKey_sameUserInUri() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(WIDGET_ID_STRING, URI_STRING);
+        mBackupEditor.putInt(ADD_USER_ID_TO_URI + WIDGET_ID_STRING, USER_ID_0);
+        mBackupEditor.apply();
+
+        boolean restored = mHelper.restoreKey(entry, mEditor, mFollowUpEditor, mBackupSp);
+        mEditor.apply();
+        mFollowUpEditor.apply();
+
+        assertThat(restored).isTrue();
+        assertThat(mSp.getString(WIDGET_ID_STRING, null)).isEqualTo(URI_WITH_USER_ID_0);
+        assertThat(mFollowUpSp.getAll()).isEmpty();
+    }
+
+    @Test
+    public void testRestoreKey_widgetIdKey_differentUserInUri() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(WIDGET_ID_STRING, URI_STRING);
+        mBackupEditor.putInt(ADD_USER_ID_TO_URI + WIDGET_ID_STRING, USER_ID_10);
+        mBackupEditor.apply();
+
+        boolean restored = mHelper.restoreKey(entry, mEditor, mFollowUpEditor, mBackupSp);
+        mEditor.apply();
+        mFollowUpEditor.apply();
+
+        assertThat(restored).isTrue();
+        assertThat(mSp.getString(WIDGET_ID_STRING, null)).isEqualTo(URI_WITH_USER_ID_10);
+        assertThat(mFollowUpSp.getAll()).isEmpty();
+    }
+
+    @Test
+    public void testRestoreKey_widgetIdKey_nonSystemUser_differentUser() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(WIDGET_ID_STRING, URI_STRING);
+        mBackupEditor.putInt(ADD_USER_ID_TO_URI + WIDGET_ID_STRING, USER_ID_0);
+        mBackupEditor.apply();
+
+        boolean restored = mOtherHelper.restoreKey(entry, mEditor, mFollowUpEditor, mBackupSp);
+        mEditor.apply();
+        mFollowUpEditor.apply();
+
+        assertThat(restored).isTrue();
+        assertThat(mSp.getString(WIDGET_ID_STRING, null)).isEqualTo(URI_WITH_USER_ID_0);
+        assertThat(mFollowUpSp.getAll()).isEmpty();
+    }
+
+    @Test
+    public void testRestoreKey_contactUriKey_noUserIdInUri() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(URI_STRING, WIDGET_IDS);
+
+        boolean restored = mHelper.restoreKey(entry, mEditor, mFollowUpEditor, mBackupSp);
+        mEditor.apply();
+        mFollowUpEditor.apply();
+
+        assertThat(restored).isTrue();
+        assertThat(mSp.getStringSet(URI_STRING, new HashSet<>()))
+                .containsExactly(WIDGET_ID_STRING, SECOND_WIDGET_ID_STRING);
+        assertThat(mFollowUpSp.getAll()).isEmpty();
+    }
+
+    @Test
+    public void testRestoreKey_contactUriKey_sameUserInUri() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(URI_STRING, WIDGET_IDS);
+        mBackupEditor.putInt(ADD_USER_ID_TO_URI + URI_STRING, USER_ID_0);
+        mBackupEditor.apply();
+
+        boolean restored = mHelper.restoreKey(entry, mEditor, mFollowUpEditor, mBackupSp);
+        mEditor.apply();
+        mFollowUpEditor.apply();
+
+        assertThat(restored).isTrue();
+        assertThat(mSp.getStringSet(URI_WITH_USER_ID_0, new HashSet<>()))
+                .containsExactly(WIDGET_ID_STRING, SECOND_WIDGET_ID_STRING);
+        assertThat(mSp.getStringSet(URI_STRING, new HashSet<>())).isEmpty();
+        assertThat(mFollowUpSp.getAll()).isEmpty();
+    }
+
+    @Test
+    public void testRestoreKey_contactUriKey_differentUserInUri() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(URI_STRING, WIDGET_IDS);
+        mBackupEditor.putInt(ADD_USER_ID_TO_URI + URI_STRING, USER_ID_10);
+        mBackupEditor.apply();
+
+        boolean restored = mHelper.restoreKey(entry, mEditor, mFollowUpEditor, mBackupSp);
+        mEditor.apply();
+        mFollowUpEditor.apply();
+
+        assertThat(restored).isTrue();
+        assertThat(mSp.getStringSet(URI_WITH_USER_ID_10, new HashSet<>()))
+                .containsExactly(WIDGET_ID_STRING, SECOND_WIDGET_ID_STRING);
+        assertThat(mSp.getStringSet(URI_STRING, new HashSet<>())).isEmpty();
+        assertThat(mFollowUpSp.getAll()).isEmpty();
+    }
+
+    @Test
+    public void testRestoreKey_contactUriKey_nonSystemUser_differentUser() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(URI_STRING, WIDGET_IDS);
+        mBackupEditor.putInt(ADD_USER_ID_TO_URI + URI_STRING, USER_ID_0);
+        mBackupEditor.apply();
+
+        boolean restored = mOtherHelper.restoreKey(entry, mEditor, mFollowUpEditor, mBackupSp);
+        mEditor.apply();
+        mFollowUpEditor.apply();
+
+        assertThat(restored).isTrue();
+        assertThat(mSp.getStringSet(URI_WITH_USER_ID_0, new HashSet<>()))
+                .containsExactly(WIDGET_ID_STRING, SECOND_WIDGET_ID_STRING);
+        assertThat(mSp.getStringSet(URI_STRING, new HashSet<>())).isEmpty();
+        assertThat(mFollowUpSp.getAll()).isEmpty();
+    }
+
+    @Test
+    public void testRestoreKey_peopleTileKey_shouldNotFollowUp() {
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(
+                INVALID_USER_ID_PEOPLE_TILE_KEY.toString(), WIDGET_IDS);
+
+        boolean restored = mHelper.restoreKey(entry, mEditor, mFollowUpEditor, mBackupSp);
+        mEditor.apply();
+        mFollowUpEditor.apply();
+
+        assertThat(restored).isTrue();
+        assertThat(mSp.getStringSet(PEOPLE_TILE_KEY.toString(), new HashSet<>()))
+                .containsExactly(WIDGET_ID_STRING, SECOND_WIDGET_ID_STRING);
+        assertThat(SharedPreferencesHelper.getPeopleTileKey(mWidgetIdSp))
+                .isEqualTo(PEOPLE_TILE_KEY);
+        assertThat(SharedPreferencesHelper.getPeopleTileKey(mSecondWidgetIdSp))
+                .isEqualTo(PEOPLE_TILE_KEY);
+        assertThat(mFollowUpSp.getAll()).isEmpty();
+    }
+
+    @Test
+    public void testRestoreKey_peopleTileKey_shortcutNotYetRestored_shouldFollowUpBoth()
+            throws RemoteException {
+        when(mIPeopleManager.isConversation(any(), anyInt(), any())).thenReturn(false);
+
+        Map.Entry<String, ?> entry = new AbstractMap.SimpleEntry<>(
+                INVALID_USER_ID_PEOPLE_TILE_KEY.toString(), WIDGET_IDS);
+
+        boolean restored = mHelper.restoreKey(entry, mEditor, mFollowUpEditor, mBackupSp);
+        mEditor.apply();
+        mFollowUpEditor.apply();
+
+        assertThat(restored).isFalse();
+        assertThat(mSp.getStringSet(PEOPLE_TILE_KEY.toString(), new HashSet<>()))
+                .containsExactly(WIDGET_ID_STRING, SECOND_WIDGET_ID_STRING);
+        assertThat(SharedPreferencesHelper.getPeopleTileKey(mWidgetIdSp))
+                .isEqualTo(PEOPLE_TILE_KEY);
+        assertThat(SharedPreferencesHelper.getPeopleTileKey(mSecondWidgetIdSp))
+                .isEqualTo(PEOPLE_TILE_KEY);
+
+        assertThat(mFollowUpSp.getStringSet(PEOPLE_TILE_KEY.toString(), new HashSet<>()))
+                .containsExactly(WIDGET_ID_STRING, SECOND_WIDGET_ID_STRING);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
index c48f26b..ddad758 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
@@ -73,6 +73,7 @@
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.Person;
+import android.app.backup.BackupManager;
 import android.app.people.ConversationChannel;
 import android.app.people.ConversationStatus;
 import android.app.people.IPeopleManager;
@@ -102,7 +103,9 @@
 
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.people.PeopleBackupFollowUpJob;
 import com.android.systemui.people.PeopleSpaceUtils;
+import com.android.systemui.people.SharedPreferencesHelper;
 import com.android.systemui.statusbar.NotificationListener;
 import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
 import com.android.systemui.statusbar.SbnBuilder;
@@ -151,6 +154,11 @@
     private static final int WIDGET_ID_WITH_KEY_IN_OPTIONS = 4;
     private static final int WIDGET_ID_WITH_SAME_URI = 5;
     private static final int WIDGET_ID_WITH_DIFFERENT_URI = 6;
+    private static final int WIDGET_ID_8 = 8;
+    private static final int WIDGET_ID_9 = 9;
+    private static final int WIDGET_ID_11 = 11;
+    private static final int WIDGET_ID_14 = 14;
+    private static final int WIDGET_ID_15 = 15;
     private static final String SHORTCUT_ID = "101";
     private static final String OTHER_SHORTCUT_ID = "102";
     private static final String NOTIFICATION_KEY = "0|com.android.systemui.tests|0|null|0";
@@ -195,6 +203,14 @@
             | SUPPRESSED_EFFECT_NOTIFICATION_LIST;
     private static final long SBN_POST_TIME = 567L;
 
+    private static final Map<String, String> WIDGETS_MAPPING = Map.of(
+            String.valueOf(WIDGET_ID_8), String.valueOf(WIDGET_ID_WITH_SHORTCUT),
+            String.valueOf(WIDGET_ID_9), String.valueOf(WIDGET_ID_WITHOUT_SHORTCUT),
+            String.valueOf(WIDGET_ID_11), String.valueOf(WIDGET_ID_WITH_KEY_IN_OPTIONS),
+            String.valueOf(WIDGET_ID_14), String.valueOf(WIDGET_ID_WITH_SAME_URI),
+            String.valueOf(WIDGET_ID_15), String.valueOf(WIDGET_ID_WITH_DIFFERENT_URI)
+    );
+
     private ShortcutInfo mShortcutInfo;
     private NotificationEntry mNotificationEntry;
 
@@ -228,6 +244,8 @@
     private NotificationManager.Policy mNotificationPolicy;
     @Mock
     private Bubbles mBubbles;
+    @Mock
+    private BackupManager mBackupManager;
 
     @Captor
     private ArgumentCaptor<NotificationHandler> mListenerCaptor;
@@ -246,8 +264,8 @@
         mDependency.injectTestDependency(NotificationEntryManager.class, mNotificationEntryManager);
         mManager = new PeopleSpaceWidgetManager(mContext, mAppWidgetManager, mIPeopleManager,
                 mPeopleManager, mLauncherApps, mNotificationEntryManager, mPackageManager,
-                Optional.of(mBubbles), mUserManager, mINotificationManager, mNotificationManager,
-                mFakeExecutor);
+                Optional.of(mBubbles), mUserManager, mBackupManager, mINotificationManager,
+                mNotificationManager, mFakeExecutor);
         mManager.attach(mListenerService);
 
         verify(mListenerService).addNotificationHandler(mListenerCaptor.capture());
@@ -1410,6 +1428,89 @@
         assertThat(tile.getNotificationPolicyState()).isEqualTo(expected | SHOW_CONVERSATIONS);
     }
 
+    @Test
+    public void testRemapWidgetFiles() {
+        setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_8, URI);
+        setStorageForTile(OTHER_SHORTCUT_ID, TEST_PACKAGE_B, WIDGET_ID_11, URI);
+
+        mManager.remapWidgetFiles(WIDGETS_MAPPING);
+
+        SharedPreferences sp1 = mContext.getSharedPreferences(
+                String.valueOf(WIDGET_ID_WITH_SHORTCUT), Context.MODE_PRIVATE);
+        PeopleTileKey key1 = SharedPreferencesHelper.getPeopleTileKey(sp1);
+        assertThat(key1.getShortcutId()).isEqualTo(SHORTCUT_ID);
+        assertThat(key1.getPackageName()).isEqualTo(TEST_PACKAGE_A);
+
+        SharedPreferences sp4 = mContext.getSharedPreferences(
+                String.valueOf(WIDGET_ID_WITH_KEY_IN_OPTIONS), Context.MODE_PRIVATE);
+        PeopleTileKey key4 = SharedPreferencesHelper.getPeopleTileKey(sp4);
+        assertThat(key4.getShortcutId()).isEqualTo(OTHER_SHORTCUT_ID);
+        assertThat(key4.getPackageName()).isEqualTo(TEST_PACKAGE_B);
+
+        SharedPreferences sp8 = mContext.getSharedPreferences(
+                String.valueOf(WIDGET_ID_8), Context.MODE_PRIVATE);
+        PeopleTileKey key8 = SharedPreferencesHelper.getPeopleTileKey(sp8);
+        assertThat(key8.getShortcutId()).isNull();
+        assertThat(key8.getPackageName()).isNull();
+
+        SharedPreferences sp11 = mContext.getSharedPreferences(
+                String.valueOf(WIDGET_ID_11), Context.MODE_PRIVATE);
+        PeopleTileKey key11 = SharedPreferencesHelper.getPeopleTileKey(sp11);
+        assertThat(key11.getShortcutId()).isNull();
+        assertThat(key11.getPackageName()).isNull();
+    }
+
+    @Test
+    public void testRemapSharedFile() {
+        setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_8, URI);
+        setStorageForTile(OTHER_SHORTCUT_ID, TEST_PACKAGE_B, WIDGET_ID_11, URI);
+
+        mManager.remapSharedFile(WIDGETS_MAPPING);
+
+        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+
+        assertThat(sp.getString(String.valueOf(WIDGET_ID_8), null)).isNull();
+        assertThat(sp.getString(String.valueOf(WIDGET_ID_11), null)).isNull();
+        assertThat(sp.getString(String.valueOf(WIDGET_ID_WITH_SHORTCUT), null))
+                .isEqualTo(URI.toString());
+        assertThat(sp.getString(String.valueOf(WIDGET_ID_WITH_KEY_IN_OPTIONS), null))
+                .isEqualTo(URI.toString());
+
+        assertThat(sp.getStringSet(URI.toString(), new HashSet<>())).containsExactly(
+                String.valueOf(WIDGET_ID_WITH_SHORTCUT),
+                String.valueOf(WIDGET_ID_WITH_KEY_IN_OPTIONS));
+
+        PeopleTileKey key8 = new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A);
+        assertThat(sp.getStringSet(key8.toString(), new HashSet<>())).containsExactly(
+                String.valueOf(WIDGET_ID_WITH_SHORTCUT));
+
+        PeopleTileKey key11 = new PeopleTileKey(OTHER_SHORTCUT_ID, 0, TEST_PACKAGE_B);
+        assertThat(sp.getStringSet(key11.toString(), new HashSet<>())).containsExactly(
+                String.valueOf(WIDGET_ID_WITH_KEY_IN_OPTIONS));
+    }
+
+    @Test
+    public void testRemapFollowupFile() {
+        PeopleTileKey key8 = new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A);
+        PeopleTileKey key11 = new PeopleTileKey(OTHER_SHORTCUT_ID, 0, TEST_PACKAGE_B);
+        Set<String> set8 = new HashSet<>(Collections.singleton(String.valueOf(WIDGET_ID_8)));
+        Set<String> set11 = new HashSet<>(Collections.singleton(String.valueOf(WIDGET_ID_11)));
+
+        SharedPreferences followUp = mContext.getSharedPreferences(
+                PeopleBackupFollowUpJob.SHARED_FOLLOW_UP, Context.MODE_PRIVATE);
+        SharedPreferences.Editor followUpEditor = followUp.edit();
+        followUpEditor.putStringSet(key8.toString(), set8);
+        followUpEditor.putStringSet(key11.toString(), set11);
+        followUpEditor.apply();
+
+        mManager.remapFollowupFile(WIDGETS_MAPPING);
+
+        assertThat(followUp.getStringSet(key8.toString(), new HashSet<>())).containsExactly(
+                String.valueOf(WIDGET_ID_WITH_SHORTCUT));
+        assertThat(followUp.getStringSet(key11.toString(), new HashSet<>())).containsExactly(
+                String.valueOf(WIDGET_ID_WITH_KEY_IN_OPTIONS));
+    }
+
     private void setFinalField(String fieldName, int value) {
         try {
             Field field = NotificationManager.Policy.class.getDeclaredField(fieldName);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
index 1f066d8..65e5f97 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
@@ -127,7 +127,7 @@
         when(mQSPanel.getDumpableTag()).thenReturn("QSPanel");
         when(mQSPanel.openPanelEvent()).thenReturn(QSEvent.QS_PANEL_EXPANDED);
         when(mQSPanel.closePanelEvent()).thenReturn(QSEvent.QS_PANEL_COLLAPSED);
-        when(mQSPanel.createRegularTileLayout()).thenReturn(mPagedTileLayout);
+        when(mQSPanel.getOrCreateTileLayout()).thenReturn(mPagedTileLayout);
         when(mQSPanel.getTileLayout()).thenReturn(mPagedTileLayout);
         when(mQSTile.getTileSpec()).thenReturn("dnd");
         when(mQSTileHost.getTiles()).thenReturn(Collections.singleton(mQSTile));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java
index 53eae8c..bf6c981 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java
@@ -107,7 +107,7 @@
 
         when(mQSPanel.isAttachedToWindow()).thenReturn(true);
         when(mQSPanel.getDumpableTag()).thenReturn("QSPanel");
-        when(mQSPanel.createRegularTileLayout()).thenReturn(mPagedTileLayout);
+        when(mQSPanel.getOrCreateTileLayout()).thenReturn(mPagedTileLayout);
         when(mQSPanel.getTileLayout()).thenReturn(mPagedTileLayout);
         when(mQSTileHost.getTiles()).thenReturn(Collections.singleton(mQSTile));
         when(mQSTileHost.createTileView(any(), eq(mQSTile), anyBoolean())).thenReturn(mQSTileView);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
index a50cbe5..b1e67f5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
@@ -175,6 +175,15 @@
     }
 
     @Test
+    public void testWalletFeatureUnavailable_recreateWalletClient() {
+        when(mQuickAccessWalletClient.isWalletFeatureAvailable()).thenReturn(false);
+
+        mTile.handleSetListening(true);
+
+        verify(mController, times(1)).reCreateWalletClient();
+    }
+
+    @Test
     public void testIsAvailable_qawFeatureAvailable() {
         when(mPackageManager.hasSystemFeature(FEATURE_NFC_HOST_CARD_EMULATION)).thenReturn(true);
         when(mPackageManager.hasSystemFeature("org.chromium.arc")).thenReturn(false);
@@ -267,6 +276,41 @@
     }
 
     @Test
+    public void testHandleUpdateState_walletIsUpdating() {
+        when(mKeyguardStateController.isUnlocked()).thenReturn(true);
+        QSTile.State state = new QSTile.State();
+        GetWalletCardsResponse response =
+                new GetWalletCardsResponse(
+                        Collections.singletonList(createWalletCard(mContext)), 0);
+
+        mTile.handleSetListening(true);
+
+        verify(mController).queryWalletCards(mCallbackCaptor.capture());
+
+        // Wallet cards fetching on its way; wallet updating.
+        mTile.handleUpdateState(state, null);
+
+        assertEquals(Tile.STATE_INACTIVE, state.state);
+        assertEquals(
+                mContext.getString(R.string.wallet_secondary_label_updating), state.secondaryLabel);
+        assertNotNull(state.stateDescription);
+        assertNull(state.sideViewCustomDrawable);
+
+        // Wallet cards fetching completed.
+        mCallbackCaptor.getValue().onWalletCardsRetrieved(response);
+        mTestableLooper.processAllMessages();
+
+        mTile.handleUpdateState(state, null);
+
+        assertEquals(Tile.STATE_ACTIVE, state.state);
+        assertEquals(
+                "•••• 1234",
+                state.secondaryLabel);
+        assertNotNull(state.stateDescription);
+        assertNotNull(state.sideViewCustomDrawable);
+    }
+
+    @Test
     public void testHandleUpdateState_hasCard_deviceLocked_tileInactive() {
         when(mKeyguardStateController.isUnlocked()).thenReturn(false);
         QSTile.State state = new QSTile.State();
@@ -315,7 +359,7 @@
     }
 
     @Test
-    public void testHandleUpdateState_qawFeatureUnavailable_tileUnavailable() {
+    public void testHandleUpdateState_qawServiceUnavailable_tileUnavailable() {
         when(mQuickAccessWalletClient.isWalletServiceAvailable()).thenReturn(false);
         QSTile.State state = new QSTile.State();
 
@@ -327,6 +371,18 @@
     }
 
     @Test
+    public void testHandleUpdateState_qawFeatureUnavailable_tileUnavailable() {
+        when(mQuickAccessWalletClient.isWalletFeatureAvailable()).thenReturn(false);
+        QSTile.State state = new QSTile.State();
+
+        mTile.handleUpdateState(state, null);
+
+        assertEquals(Tile.STATE_UNAVAILABLE, state.state);
+        assertNull(state.stateDescription);
+        assertNull(state.sideViewCustomDrawable);
+    }
+
+    @Test
     public void testHandleSetListening_queryCards() {
         mTile.handleSetListening(true);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
index 226c466..690b841 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
@@ -323,7 +323,8 @@
         // WHEN the clock position algorithm is run
         positionClock();
         // THEN the notif padding is zero.
-        assertThat(mClockPosition.stackScrollerPadding).isEqualTo(0);
+        assertThat(mClockPosition.stackScrollerPadding).isEqualTo(
+                (int) (mKeyguardStatusHeight * .667f));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index 2693b94..a6fc02d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -100,9 +100,11 @@
 import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.NotificationShadeDepthController;
 import com.android.systemui.statusbar.NotificationShelfController;
 import com.android.systemui.statusbar.PulseExpansionHandler;
+import com.android.systemui.statusbar.RemoteInputController;
 import com.android.systemui.statusbar.StatusBarStateControllerImpl;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.VibratorHelper;
@@ -289,6 +291,10 @@
     private FragmentHostManager mFragmentHostManager;
     @Mock
     private QuickAccessWalletController mQuickAccessWalletController;
+    @Mock
+    private NotificationRemoteInputManager mNotificationRemoteInputManager;
+    @Mock
+    private RemoteInputController mRemoteInputController;
 
     private SysuiStatusBarStateController mStatusBarStateController;
     private NotificationPanelViewController mNotificationPanelViewController;
@@ -384,6 +390,8 @@
                 .thenReturn(mKeyguardStatusView);
         when(mLayoutInflater.inflate(eq(R.layout.keyguard_bottom_area), any(), anyBoolean()))
                 .thenReturn(mKeyguardBottomArea);
+        when(mNotificationRemoteInputManager.getController()).thenReturn(mRemoteInputController);
+        when(mRemoteInputController.isRemoteInputActive()).thenReturn(false);
 
         reset(mView);
 
@@ -427,7 +435,8 @@
                 mQuickAccessWalletController,
                 new FakeExecutor(new FakeSystemClock()),
                 mSecureSettings,
-                mUnlockedScreenOffAnimationController);
+                mUnlockedScreenOffAnimationController,
+                mNotificationRemoteInputManager);
         mNotificationPanelViewController.initDependencies(
                 mStatusBar,
                 mNotificationShelfController);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java
index 23abce0..ce0098e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java
@@ -21,7 +21,9 @@
 import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -61,12 +63,10 @@
     private ArgumentCaptor<GetWalletCardsRequest> mRequestCaptor;
 
     private QuickAccessWalletController mController;
-    private TestableLooper mTestableLooper;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mTestableLooper = TestableLooper.get(this);
         when(mQuickAccessWalletClient.isWalletServiceAvailable()).thenReturn(true);
         when(mQuickAccessWalletClient.isWalletFeatureAvailable()).thenReturn(true);
         when(mQuickAccessWalletClient.isWalletFeatureAvailableWhenDeviceLocked()).thenReturn(true);
@@ -143,4 +143,13 @@
                 mContext.getResources().getDimensionPixelSize(R.dimen.wallet_tile_card_view_height),
                 request.getCardHeightPx());
     }
+
+    @Test
+    public void queryWalletCards_walletFeatureNotAvailable_noQuery() {
+        when(mQuickAccessWalletClient.isWalletFeatureAvailable()).thenReturn(false);
+
+        mController.queryWalletCards(mCardsRetriever);
+
+        verify(mQuickAccessWalletClient, never()).getWalletCards(any(), any(), any());
+    }
 }
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 906edb3..9ff1b10 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -455,7 +455,7 @@
 
             }, FgThread.getExecutor()).whenComplete(uncheckExceptions((association, err) -> {
                 if (err == null) {
-                    addAssociation(association);
+                    addAssociation(association, userId);
                 } else {
                     Slog.e(LOG_TAG, "Failed to discover device(s)", err);
                     callback.onFailure("No devices found: " + err.getMessage());
@@ -646,7 +646,7 @@
                 } else {
                     return association;
                 }
-            }));
+            }), userId);
 
             restartBleScan();
         }
@@ -664,7 +664,8 @@
                     android.Manifest.permission.ASSOCIATE_COMPANION_DEVICES, "createAssociation");
 
             addAssociation(new Association(
-                    userId, macAddress, packageName, null, false, System.currentTimeMillis()));
+                    userId, macAddress, packageName, null, false,
+                    System.currentTimeMillis()), userId);
         }
 
         private void checkCanCallNotificationApi(String callingPackage) throws RemoteException {
@@ -738,9 +739,9 @@
         return Binder.getCallingUid() == Process.SYSTEM_UID;
     }
 
-    void addAssociation(Association association) {
+    void addAssociation(Association association, int userId) {
         updateSpecialAccessPermissionForAssociatedPackage(association);
-        recordAssociation(association);
+        recordAssociation(association, userId);
     }
 
     void removeAssociation(int userId, String pkg, String deviceMacAddress) {
@@ -752,7 +753,7 @@
                 onAssociationPreRemove(association);
             }
             return notMatch;
-        }));
+        }), userId);
         restartBleScan();
     }
 
@@ -944,13 +945,9 @@
         }, getContext(), packageName, userId).recycleOnUse());
     }
 
-    private void recordAssociation(Association association) {
+    private void recordAssociation(Association association, int userId) {
         Slog.i(LOG_TAG, "recordAssociation(" + association + ")");
-        updateAssociations(associations -> CollectionUtils.add(associations, association));
-    }
-
-    private void updateAssociations(Function<Set<Association>, Set<Association>> update) {
-        updateAssociations(update, getCallingUserId());
+        updateAssociations(associations -> CollectionUtils.add(associations, association), userId);
     }
 
     private void updateAssociations(Function<Set<Association>, Set<Association>> update,
@@ -1515,7 +1512,7 @@
                         String pkg = getNextArgRequired();
                         String address = getNextArgRequired();
                         addAssociation(new Association(userId, address, pkg, null, false,
-                                System.currentTimeMillis()));
+                                System.currentTimeMillis()), userId);
                     }
                     break;
 
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index 8561042..8e53101 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -517,7 +517,7 @@
         boolean shouldPinCamera = mConfiguredToPinCamera
                 && DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT,
                         "pin_camera",
-                        SystemProperties.getBoolean("pinner.pin_camera", false));
+                        SystemProperties.getBoolean("pinner.pin_camera", true));
         if (shouldPinCamera) {
             pinKeys.add(KEY_CAMERA);
         } else if (DEBUG) {
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 2a634eb..a6a8cf01 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -453,7 +453,7 @@
         if (!checkAccess || hasAccountAccess(account, packageName,
                 UserHandle.getUserHandleForUid(uid))) {
             cancelNotification(getCredentialPermissionNotificationId(account,
-                    AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE, uid), packageName,
+                    AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE, uid),
                     UserHandle.getUserHandleForUid(uid));
         }
     }
@@ -3136,8 +3136,8 @@
         String authTokenType = intent.getStringExtra(
                 GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE);
         final String titleAndSubtitle =
-                mContext.getString(R.string.permission_request_notification_with_subtitle,
-                account.name);
+                mContext.getString(R.string.permission_request_notification_for_app_with_subtitle,
+                getApplicationLabel(packageName), account.name);
         final int index = titleAndSubtitle.indexOf('\n');
         String title = titleAndSubtitle;
         String subtitle = "";
@@ -3160,7 +3160,16 @@
                             null, user))
                     .build();
         installNotification(getCredentialPermissionNotificationId(
-                account, authTokenType, uid), n, packageName, user.getIdentifier());
+                account, authTokenType, uid), n, "android", user.getIdentifier());
+    }
+
+    private String getApplicationLabel(String packageName) {
+        try {
+            return mPackageManager.getApplicationLabel(
+                    mPackageManager.getApplicationInfo(packageName, 0)).toString();
+        } catch (PackageManager.NameNotFoundException e) {
+            return packageName;
+        }
     }
 
     private Intent newGrantCredentialsPermissionIntent(Account account, String packageName,
@@ -3196,7 +3205,7 @@
             nId = accounts.credentialsPermissionNotificationIds.get(key);
             if (nId == null) {
                 String tag = TAG + ":" + SystemMessage.NOTE_ACCOUNT_CREDENTIAL_PERMISSION
-                        + ":" + account.hashCode() + ":" + authTokenType.hashCode();
+                        + ":" + account.hashCode() + ":" + authTokenType.hashCode() + ":" + uid;
                 int id = SystemMessage.NOTE_ACCOUNT_CREDENTIAL_PERMISSION;
                 nId = new NotificationId(tag, id);
                 accounts.credentialsPermissionNotificationIds.put(key, nId);
@@ -4147,7 +4156,7 @@
 
             private void handleAuthenticatorResponse(boolean accessGranted) throws RemoteException {
                 cancelNotification(getCredentialPermissionNotificationId(account,
-                        AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE, uid), packageName,
+                        AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE, uid),
                         UserHandle.getUserHandleForUid(uid));
                 if (callback != null) {
                     Bundle result = new Bundle();
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 58a1ead..875ef37 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -36,6 +36,7 @@
 import static android.os.PowerExemptionManager.REASON_DEVICE_DEMO_MODE;
 import static android.os.PowerExemptionManager.REASON_DEVICE_OWNER;
 import static android.os.PowerExemptionManager.REASON_FGS_BINDING;
+import static android.os.PowerExemptionManager.REASON_CURRENT_INPUT_METHOD;
 import static android.os.PowerExemptionManager.REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION;
 import static android.os.PowerExemptionManager.REASON_INSTR_BACKGROUND_FGS_PERMISSION;
 import static android.os.PowerExemptionManager.REASON_OPT_OUT_REQUESTED;
@@ -6162,6 +6163,20 @@
                 ret = REASON_OP_ACTIVATE_PLATFORM_VPN;
             }
         }
+
+        if (ret == REASON_DENIED) {
+            final String inputMethod =
+                    Settings.Secure.getStringForUser(mAm.mContext.getContentResolver(),
+                            Settings.Secure.DEFAULT_INPUT_METHOD,
+                            UserHandle.getUserId(callingUid));
+            if (inputMethod != null) {
+                final ComponentName cn = ComponentName.unflattenFromString(inputMethod);
+                if (cn != null && cn.getPackageName().equals(callingPackage)) {
+                    ret = REASON_CURRENT_INPUT_METHOD;
+                }
+            }
+        }
+
         if (ret == REASON_DENIED) {
             if (mAm.mConstants.mFgsAllowOptOut
                     && targetService != null
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index a6b50f3..7c82502 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5684,6 +5684,16 @@
         if (pid == MY_PID) {
             return PackageManager.PERMISSION_GRANTED;
         }
+        try {
+            if (uid != 0) { // bypass the root
+                final String[] packageNames = getPackageManager().getPackagesForUid(uid);
+                if (ArrayUtils.isEmpty(packageNames)) {
+                    // The uid is not existed or not visible to the caller.
+                    return PackageManager.PERMISSION_DENIED;
+                }
+            }
+        } catch (RemoteException e) {
+        }
         return mUgmInternal.checkUriPermission(new GrantUri(userId, uri, modeFlags), uid, modeFlags)
                 ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED;
     }
@@ -7619,6 +7629,7 @@
         t.traceEnd();
 
         t.traceBegin("ActivityManagerStartApps");
+        mBatteryStatsService.onSystemReady();
         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
                 Integer.toString(currentUserId), currentUserId);
         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 7d9d789..9f41c8b 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -126,7 +126,7 @@
         Watchdog.Monitor {
     static final String TAG = "BatteryStatsService";
     static final boolean DBG = false;
-    private static final boolean BATTERY_USAGE_STORE_ENABLED = false;
+    private static final boolean BATTERY_USAGE_STORE_ENABLED = true;
 
     private static IBatteryStats sService;
 
@@ -398,6 +398,16 @@
         registerStatsCallbacks();
     }
 
+    /**
+     * Notifies BatteryStatsService that the system server is ready.
+     */
+    public void onSystemReady() {
+        mStats.onSystemReady();
+        if (BATTERY_USAGE_STORE_ENABLED) {
+            mBatteryUsageStatsStore.onSystemReady();
+        }
+    }
+
     private final class LocalService extends BatteryStatsInternal {
         @Override
         public String[] getWifiIfaces() {
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index b325ea3..5c9d385 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -27,6 +27,7 @@
 import android.provider.Settings;
 import android.widget.WidgetFlags;
 
+import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.ArrayList;
@@ -159,12 +160,9 @@
                 DeviceConfig.NAMESPACE_WIDGET, WidgetFlags.MAGNIFIER_ASPECT_RATIO,
                 WidgetFlags.KEY_MAGNIFIER_ASPECT_RATIO, float.class,
                 WidgetFlags.MAGNIFIER_ASPECT_RATIO_DEFAULT));
-        sDeviceConfigEntries.add(new DeviceConfigEntry<>(
-                DeviceConfig.NAMESPACE_WIDGET, WidgetFlags.ANALOG_CLOCK_SECONDS_HAND_FPS,
-                WidgetFlags.KEY_ANALOG_CLOCK_SECONDS_HAND_FPS, int.class,
-                WidgetFlags.ANALOG_CLOCK_SECONDS_HAND_FPS_DEFAULT));
         // add other device configs here...
     }
+    private static volatile boolean sDeviceConfigContextEntriesLoaded = false;
 
     private final Bundle mCoreSettings = new Bundle();
 
@@ -172,11 +170,29 @@
 
     public CoreSettingsObserver(ActivityManagerService activityManagerService) {
         super(activityManagerService.mHandler);
+
+        if (!sDeviceConfigContextEntriesLoaded) {
+            synchronized (sDeviceConfigEntries) {
+                if (!sDeviceConfigContextEntriesLoaded) {
+                    loadDeviceConfigContextEntries(activityManagerService.mContext);
+                    sDeviceConfigContextEntriesLoaded = true;
+                }
+            }
+        }
+
         mActivityManagerService = activityManagerService;
         beginObserveCoreSettings();
         sendCoreSettings();
     }
 
+    private static void loadDeviceConfigContextEntries(Context context) {
+        sDeviceConfigEntries.add(new DeviceConfigEntry<>(
+                DeviceConfig.NAMESPACE_WIDGET, WidgetFlags.ANALOG_CLOCK_SECONDS_HAND_FPS,
+                WidgetFlags.KEY_ANALOG_CLOCK_SECONDS_HAND_FPS, int.class,
+                context.getResources()
+                        .getInteger(R.integer.config_defaultAnalogClockSecondsHandFps)));
+    }
+
     public Bundle getCoreSettingsLocked() {
         return (Bundle) mCoreSettings.clone();
     }
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 7c5d09c..fd9a536 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -4691,10 +4691,10 @@
                         final ApplicationInfo ai = AppGlobals.getPackageManager()
                                 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
                         if (ai != null) {
-                            app.getThread().scheduleApplicationInfoChanged(ai);
                             if (ai.packageName.equals(app.info.packageName)) {
                                 app.info = ai;
                             }
+                            app.getThread().scheduleApplicationInfoChanged(ai);
                             targetProcesses.add(app.getWindowProcessController());
                         }
                     } catch (RemoteException e) {
@@ -4705,8 +4705,7 @@
             });
         }
 
-        mService.mActivityTaskManager.updateAssetConfiguration(
-                updateFrameworkRes ? null : targetProcesses);
+        mService.mActivityTaskManager.updateAssetConfiguration(targetProcesses, updateFrameworkRes);
     }
 
     @GuardedBy("mService")
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 122880c..e001b05 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -4523,10 +4523,15 @@
         int callingUid = Binder.getCallingUid();
 
         // Allow any attribution tag for resolvable uids
-        int pkgUid = resolveUid(packageName);
-        if (pkgUid != Process.INVALID_UID) {
+        int pkgUid;
+        if (Objects.equals(packageName, "com.android.shell")) {
             // Special case for the shell which is a package but should be able
             // to bypass app attribution tag restrictions.
+            pkgUid = Process.SHELL_UID;
+        } else {
+            pkgUid = resolveUid(packageName);
+        }
+        if (pkgUid != Process.INVALID_UID) {
             if (pkgUid != UserHandle.getAppId(uid)) {
                 String otherUidMessage = DEBUG ? " but it is really " + pkgUid : " but it is not";
                 throw new SecurityException("Specified package " + packageName + " under uid "
@@ -6993,7 +6998,6 @@
                 return Process.ROOT_UID;
             case "shell":
             case "dumpstate":
-            case "com.android.shell":
                 return Process.SHELL_UID;
             case "media":
                 return Process.MEDIA_UID;
diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java
index f1f5251..bfb42f8 100644
--- a/services/core/java/com/android/server/biometrics/AuthSession.java
+++ b/services/core/java/com/android/server/biometrics/AuthSession.java
@@ -366,10 +366,9 @@
         // sending the final error callback to the application.
         for (BiometricSensor sensor : mPreAuthInfo.eligibleSensors) {
             try {
-                if (filter.apply(sensor)) {
-                    if (DEBUG) {
-                        Slog.v(TAG, "Canceling sensor: " + sensor.id);
-                    }
+                final boolean shouldCancel = filter.apply(sensor);
+                Slog.d(TAG, "sensorId: " + sensor.id + ", shouldCancel: " + shouldCancel);
+                if (shouldCancel) {
                     sensor.goToStateCancelling(mToken, mOpPackageName);
                 }
             } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index e8e25f1..fed320d 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -1369,11 +1369,11 @@
     /**
      * handleAuthenticate() (above) which is called from BiometricPrompt determines which
      * modality/modalities to start authenticating with. authenticateInternal() should only be
-     * used for:
-     * 1) Preparing <Biometric>Services for authentication when BiometricPrompt#authenticate is,
-     * invoked, shortly after which BiometricPrompt is shown and authentication starts
-     * 2) Preparing <Biometric>Services for authentication when BiometricPrompt is already shown
-     * and the user has pressed "try again"
+     * used for preparing <Biometric>Services for authentication when BiometricPrompt#authenticate
+     * is invoked, shortly after which BiometricPrompt is shown and authentication starts.
+     *
+     * Note that this path is NOT invoked when the BiometricPrompt "Try again" button is pressed.
+     * In that case, see {@link #handleOnTryAgainPressed()}.
      */
     private void authenticateInternal(IBinder token, long operationId, int userId,
             IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo,
diff --git a/services/core/java/com/android/server/biometrics/PreAuthInfo.java b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
index c4bd18b..cd0ff10 100644
--- a/services/core/java/com/android/server/biometrics/PreAuthInfo.java
+++ b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
@@ -408,22 +408,22 @@
     public String toString() {
         StringBuilder string = new StringBuilder(
                 "BiometricRequested: " + mBiometricRequested
-                        + "\nStrengthRequested: " + mBiometricStrengthRequested
-                        + "\nCredentialRequested: " + credentialRequested);
-        string.append("\nEligible:{");
+                        + ", StrengthRequested: " + mBiometricStrengthRequested
+                        + ", CredentialRequested: " + credentialRequested);
+        string.append(", Eligible:{");
         for (BiometricSensor sensor: eligibleSensors) {
             string.append(sensor.id).append(" ");
         }
         string.append("}");
 
-        string.append("\nIneligible:{");
+        string.append(", Ineligible:{");
         for (Pair<BiometricSensor, Integer> ineligible : ineligibleSensors) {
             string.append(ineligible.first).append(":").append(ineligible.second).append(" ");
         }
         string.append("}");
 
-        string.append("\nCredentialAvailable: ").append(credentialAvailable);
-        string.append("\n");
+        string.append(", CredentialAvailable: ").append(credentialAvailable);
+        string.append(", ");
         return string.toString();
     }
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
index b52cb70..adda10e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
@@ -579,6 +579,9 @@
         final boolean isCorrectClient = isAuthenticationOrDetectionOperation(mCurrentOperation);
         final boolean tokenMatches = mCurrentOperation.mClientMonitor.getToken() == token;
 
+        Slog.d(getTag(), "cancelAuthenticationOrDetection, isCorrectClient: " + isCorrectClient
+                + ", tokenMatches: " + tokenMatches);
+
         if (isCorrectClient && tokenMatches) {
             Slog.d(getTag(), "Cancelling: " + mCurrentOperation);
             cancelInternal(mCurrentOperation);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 54abc63..012e47e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -498,6 +498,8 @@
 
             Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
 
+            Slog.d(TAG, "cancelAuthenticationFromService, sensorId: " + sensorId);
+
             final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
                 Slog.w(TAG, "Null provider for cancelAuthenticationFromService");
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUtils.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUtils.java
index d69151d..0062d31 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUtils.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUtils.java
@@ -18,9 +18,11 @@
 
 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD;
 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_IMAGER_DIRTY;
+import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_IMMOBILE;
 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_INSUFFICIENT;
 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_PARTIAL;
 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_START;
+import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_TOO_BRIGHT;
 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_TOO_FAST;
 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_TOO_SLOW;
 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR;
@@ -188,6 +190,8 @@
             case FINGERPRINT_ACQUIRED_TOO_FAST:
             case FINGERPRINT_ACQUIRED_VENDOR:
             case FINGERPRINT_ACQUIRED_START:
+            case FINGERPRINT_ACQUIRED_TOO_BRIGHT:
+            case FINGERPRINT_ACQUIRED_IMMOBILE:
                 return true;
 
             default:
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlConversionUtils.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlConversionUtils.java
index 0ae2e38..341aaa6 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlConversionUtils.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/AidlConversionUtils.java
@@ -78,7 +78,7 @@
             return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_UNKNOWN;
         } else if (aidlAcquiredInfo == AcquiredInfo.TOO_BRIGHT) {
             // No framework constant available
-            return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_UNKNOWN;
+            return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_TOO_BRIGHT;
         } else if (aidlAcquiredInfo == AcquiredInfo.IMMOBILE) {
             return BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_IMMOBILE;
         } else if (aidlAcquiredInfo == AcquiredInfo.RETRYING_CAPTURE) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
index 102aecc..7daea88 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
@@ -632,6 +632,7 @@
 
     @Override
     public void cancelAuthentication(int sensorId, @NonNull IBinder token) {
+        Slog.d(TAG, "cancelAuthentication, sensorId: " + sensorId);
         mHandler.post(() -> mScheduler.cancelAuthenticationOrDetection(token));
     }
 
diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java
index 1401fa9..06ff691 100644
--- a/services/core/java/com/android/server/pm/AppsFilter.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -17,8 +17,6 @@
 package com.android.server.pm;
 
 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
-import static android.os.UserHandle.USER_ALL;
-import static android.os.UserHandle.USER_NULL;
 import static android.provider.DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE;
 
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
@@ -687,7 +685,7 @@
                 synchronized (mCacheLock) {
                     if (mShouldFilterCache != null) {
                         updateShouldFilterCacheForPackage(mShouldFilterCache, null, newPkgSetting,
-                                settings, users, USER_ALL, settings.size());
+                                settings, users, settings.size());
                         if (additionalChangedPackages != null) {
                             for (int index = 0; index < additionalChangedPackages.size(); index++) {
                                 String changedPackage = additionalChangedPackages.valueAt(index);
@@ -700,8 +698,7 @@
                                 }
 
                                 updateShouldFilterCacheForPackage(mShouldFilterCache, null,
-                                        changedPkgSetting, settings, users, USER_ALL,
-                                        settings.size());
+                                        changedPkgSetting, settings, users, settings.size());
                             }
                         }
                     } // else, rebuild entire cache when system is ready
@@ -833,57 +830,24 @@
             }
         }
     }
-    private void updateEntireShouldFilterCache() {
-        updateEntireShouldFilterCache(USER_ALL);
-    }
 
-    private void updateEntireShouldFilterCache(int subjectUserId) {
+    private void updateEntireShouldFilterCache() {
         mStateProvider.runWithState((settings, users) -> {
-            int userId = USER_NULL;
-            for (int u = 0; u < users.length; u++) {
-                if (subjectUserId == users[u].id) {
-                    userId = subjectUserId;
-                    break;
-                }
-            }
-            if (userId == USER_NULL) {
-                Slog.e(TAG, "We encountered a new user that isn't a member of known users, "
-                        + "updating the whole cache");
-                userId = USER_ALL;
-            }
             WatchedSparseBooleanMatrix cache =
-                    updateEntireShouldFilterCacheInner(settings, users, userId);
+                    updateEntireShouldFilterCacheInner(settings, users);
             synchronized (mCacheLock) {
-                if (userId != USER_ALL) {
-                    // if we're only updating a single user id, we need to copy over the prior
-                    // cached values for the other users.
-                    int[] uids = mShouldFilterCache.keys();
-                    for (int i = 0; i < uids.length; i++) {
-                        int uid1 = uids[i];
-                        if (UserHandle.getUserId(uid1) == userId) {
-                            continue;
-                        }
-                        for (int j = 0; j < uids.length; j++) {
-                            int uid2 = uids[j];
-                            if (UserHandle.getUserId(uid2) == userId) {
-                                continue;
-                            }
-                            cache.put(uid1, uid2, mShouldFilterCache.get(uid1, uid2));
-                        }
-                    }
-                }
                 mShouldFilterCache = cache;
             }
         });
     }
 
     private WatchedSparseBooleanMatrix updateEntireShouldFilterCacheInner(
-            ArrayMap<String, PackageSetting> settings, UserInfo[] users, int subjectUserId) {
+            ArrayMap<String, PackageSetting> settings, UserInfo[] users) {
         WatchedSparseBooleanMatrix cache =
                 new WatchedSparseBooleanMatrix(users.length * settings.size());
         for (int i = settings.size() - 1; i >= 0; i--) {
             updateShouldFilterCacheForPackage(cache,
-                    null /*skipPackage*/, settings.valueAt(i), settings, users, subjectUserId, i);
+                    null /*skipPackage*/, settings.valueAt(i), settings, users, i);
         }
         return cache;
     }
@@ -904,8 +868,8 @@
                     packagesCache.put(settings.keyAt(i), pkg);
                 }
             });
-            WatchedSparseBooleanMatrix cache = updateEntireShouldFilterCacheInner(
-                    settingsCopy, usersRef[0], USER_ALL);
+            WatchedSparseBooleanMatrix cache =
+                    updateEntireShouldFilterCacheInner(settingsCopy, usersRef[0]);
             boolean[] changed = new boolean[1];
             // We have a cache, let's make sure the world hasn't changed out from under us.
             mStateProvider.runWithState((settings, users) -> {
@@ -935,10 +899,10 @@
         });
     }
 
-    public void onUserCreated(int newUserId) {
+    public void onUsersChanged() {
         synchronized (mCacheLock) {
             if (mShouldFilterCache != null) {
-                updateEntireShouldFilterCache(newUserId);
+                updateEntireShouldFilterCache();
                 onChanged();
             }
         }
@@ -949,7 +913,7 @@
             if (mShouldFilterCache != null) {
                 mStateProvider.runWithState((settings, users) -> {
                     updateShouldFilterCacheForPackage(mShouldFilterCache, null /* skipPackage */,
-                            settings.get(packageName), settings, users, USER_ALL,
+                            settings.get(packageName), settings, users,
                             settings.size() /*maxIndex*/);
                 });
             }
@@ -958,7 +922,7 @@
 
     private void updateShouldFilterCacheForPackage(WatchedSparseBooleanMatrix cache,
             @Nullable String skipPackageName, PackageSetting subjectSetting, ArrayMap<String,
-            PackageSetting> allSettings, UserInfo[] allUsers, int subjectUserId, int maxIndex) {
+            PackageSetting> allSettings, UserInfo[] allUsers, int maxIndex) {
         for (int i = Math.min(maxIndex, allSettings.size() - 1); i >= 0; i--) {
             PackageSetting otherSetting = allSettings.valueAt(i);
             if (subjectSetting.appId == otherSetting.appId) {
@@ -968,34 +932,25 @@
             if (subjectSetting.name == skipPackageName || otherSetting.name == skipPackageName) {
                 continue;
             }
-            if (subjectUserId == USER_ALL) {
-                for (int su = 0; su < allUsers.length; su++) {
-                    updateShouldFilterCacheForUser(cache, subjectSetting, allUsers, otherSetting,
-                            allUsers[su].id);
+            final int userCount = allUsers.length;
+            final int appxUidCount = userCount * allSettings.size();
+            for (int su = 0; su < userCount; su++) {
+                int subjectUser = allUsers[su].id;
+                for (int ou = 0; ou < userCount; ou++) {
+                    int otherUser = allUsers[ou].id;
+                    int subjectUid = UserHandle.getUid(subjectUser, subjectSetting.appId);
+                    int otherUid = UserHandle.getUid(otherUser, otherSetting.appId);
+                    cache.put(subjectUid, otherUid,
+                            shouldFilterApplicationInternal(
+                                    subjectUid, subjectSetting, otherSetting, otherUser));
+                    cache.put(otherUid, subjectUid,
+                            shouldFilterApplicationInternal(
+                                    otherUid, otherSetting, subjectSetting, subjectUser));
                 }
-            } else {
-                updateShouldFilterCacheForUser(cache, subjectSetting, allUsers, otherSetting,
-                        subjectUserId);
             }
         }
     }
 
-    private void updateShouldFilterCacheForUser(WatchedSparseBooleanMatrix cache,
-            PackageSetting subjectSetting, UserInfo[] allUsers, PackageSetting otherSetting,
-            int subjectUserId) {
-        for (int ou = 0; ou < allUsers.length; ou++) {
-            int otherUser = allUsers[ou].id;
-            int subjectUid = UserHandle.getUid(subjectUserId, subjectSetting.appId);
-            int otherUid = UserHandle.getUid(otherUser, otherSetting.appId);
-            cache.put(subjectUid, otherUid,
-                    shouldFilterApplicationInternal(
-                            subjectUid, subjectSetting, otherSetting, otherUser));
-            cache.put(otherUid, subjectUid,
-                    shouldFilterApplicationInternal(
-                            otherUid, otherSetting, subjectSetting, subjectUserId));
-        }
-    }
-
     private static boolean isSystemSigned(@NonNull PackageParser.SigningDetails sysSigningDetails,
             PackageSetting pkgSetting) {
         return pkgSetting.isSystem()
@@ -1190,7 +1145,7 @@
                             continue;
                         }
                         updateShouldFilterCacheForPackage(mShouldFilterCache, setting.name,
-                                siblingSetting, settings, users, USER_ALL, settings.size());
+                                siblingSetting, settings, users, settings.size());
                     }
                 }
 
@@ -1207,7 +1162,7 @@
                             }
 
                             updateShouldFilterCacheForPackage(mShouldFilterCache, null,
-                                    changedPkgSetting, settings, users, USER_ALL, settings.size());
+                                    changedPkgSetting, settings, users, settings.size());
                         }
                     }
                 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 889785d..9325c6b 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -20111,7 +20111,28 @@
 
             notifyPackageChangeObserversOnUpdate(reconciledPkg);
         }
-        NativeLibraryHelper.waitForNativeBinariesExtraction(incrementalStorages);
+        waitForNativeBinariesExtraction(incrementalStorages);
+    }
+
+    static void waitForNativeBinariesExtraction(
+            ArraySet<IncrementalStorage> incrementalStorages) {
+        if (incrementalStorages.isEmpty()) {
+            return;
+        }
+        try {
+            // Native library extraction may take very long time: each page could potentially
+            // wait for either 10s or 100ms (adb vs non-adb data loader), and that easily adds
+            // up to a full watchdog timeout of 1 min, killing the system after that. It doesn't
+            // make much sense as blocking here doesn't lock up the framework, but only blocks
+            // the installation session and the following ones.
+            Watchdog.getInstance().pauseWatchingCurrentThread("native_lib_extract");
+            for (int i = 0; i < incrementalStorages.size(); ++i) {
+                IncrementalStorage storage = incrementalStorages.valueAtUnchecked(i);
+                storage.waitForNativeBinariesExtraction();
+            }
+        } finally {
+            Watchdog.getInstance().resumeWatchingCurrentThread("native_lib_extract");
+        }
     }
 
     private int[] getInstalledUsers(PackageSetting ps, int userId) {
@@ -26504,7 +26525,7 @@
         synchronized (mLock) {
             scheduleWritePackageRestrictionsLocked(userId);
             scheduleWritePackageListLocked(userId);
-            mAppsFilter.onUserCreated(userId);
+            mAppsFilter.onUsersChanged();
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING
index 878eb92..9182d81 100644
--- a/services/core/java/com/android/server/pm/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/TEST_MAPPING
@@ -162,9 +162,6 @@
           "include-filter": "com.android.server.pm.parsing.SystemPartitionParseTest"
         }
       ]
-    },
-    {
-      "name": "CtsPackageManagerBootTestCases"
     }
   ],
   "imports": [
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java
index a389f40..7689f5f 100644
--- a/services/core/java/com/android/server/policy/AppOpsPolicy.java
+++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java
@@ -81,6 +81,12 @@
     private final VoiceInteractionManagerInternal mVoiceInteractionManagerInternal;
 
     /**
+     * Whether this device allows only the HotwordDetectionService to use OP_RECORD_AUDIO_HOTWORD
+     * which doesn't incur the privacy indicator.
+     */
+    private final boolean mIsHotwordDetectionServiceRequired;
+
+    /**
      * The locking policy around the location tags is a bit special. Since we want to
      * avoid grabbing the lock on every op note we are taking the approach where the
      * read and write are being done via a thread-safe data structure such that the
@@ -114,6 +120,8 @@
         mRoleManager = mContext.getSystemService(RoleManager.class);
         mVoiceInteractionManagerInternal = LocalServices.getService(
                 VoiceInteractionManagerInternal.class);
+        mIsHotwordDetectionServiceRequired = isHotwordDetectionServiceRequired(
+                mContext.getPackageManager());
 
         final LocationManagerInternal locationManagerInternal = LocalServices.getService(
                 LocationManagerInternal.class);
@@ -174,6 +182,12 @@
         initializeActivityRecognizersTags();
     }
 
+    private static boolean isHotwordDetectionServiceRequired(PackageManager pm) {
+        // The HotwordDetectionService APIs aren't ready yet for Auto or TV.
+        return !(pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
+                || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK));
+    }
+
     @Override
     public int checkOperation(int code, int uid, String packageName,
             @Nullable String attributionTag, boolean raw,
@@ -257,6 +271,7 @@
 
     private int resolveDatasourceOp(int code, int uid, @NonNull String packageName,
             @Nullable String attributionTag) {
+        code = resolveRecordAudioOp(code, uid);
         if (attributionTag == null) {
             return code;
         }
@@ -359,6 +374,24 @@
         return code;
     }
 
+    private int resolveRecordAudioOp(int code, int uid) {
+        if (code == AppOpsManager.OP_RECORD_AUDIO_HOTWORD) {
+            if (!mIsHotwordDetectionServiceRequired) {
+                return code;
+            }
+            // Only the HotwordDetectionService can use the HOTWORD op which doesn't incur the
+            // privacy indicator. Downgrade to standard RECORD_AUDIO for other processes.
+            final HotwordDetectionServiceIdentity hotwordDetectionServiceIdentity =
+                    mVoiceInteractionManagerInternal.getHotwordDetectionServiceIdentity();
+            if (hotwordDetectionServiceIdentity != null
+                    && uid == hotwordDetectionServiceIdentity.getIsolatedUid()) {
+                return code;
+            }
+            return AppOpsManager.OP_RECORD_AUDIO;
+        }
+        return code;
+    }
+
     private int resolveUid(int code, int uid) {
         // The HotwordDetectionService is an isolated service, which ordinarily cannot hold
         // permissions. So we allow it to assume the owning package identity for certain
diff --git a/services/core/java/com/android/server/rotationresolver/RotationResolverManagerPerUserService.java b/services/core/java/com/android/server/rotationresolver/RotationResolverManagerPerUserService.java
index ccf096e..165a1d6 100644
--- a/services/core/java/com/android/server/rotationresolver/RotationResolverManagerPerUserService.java
+++ b/services/core/java/com/android/server/rotationresolver/RotationResolverManagerPerUserService.java
@@ -109,7 +109,7 @@
         ensureRemoteServiceInitiated();
 
         // Cancel the previous on-going request.
-        if (mCurrentRequest != null) {
+        if (mCurrentRequest != null && !mCurrentRequest.mIsFulfilled) {
             cancelLocked();
         }
 
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index cd0ce2b..dda8961 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -117,6 +117,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
 import android.os.StatFs;
 import android.os.SynchronousResultReceiver;
 import android.os.SystemClock;
@@ -132,6 +133,18 @@
 import android.os.storage.VolumeInfo;
 import android.provider.DeviceConfig;
 import android.provider.Settings;
+import android.security.metrics.IKeystoreMetrics;
+import android.security.metrics.KeyCreationWithAuthInfo;
+import android.security.metrics.KeyCreationWithGeneralInfo;
+import android.security.metrics.KeyCreationWithPurposeAndModesInfo;
+import android.security.metrics.KeyOperationWithGeneralInfo;
+import android.security.metrics.KeyOperationWithPurposeAndModesInfo;
+import android.security.metrics.Keystore2AtomWithOverflow;
+import android.security.metrics.KeystoreAtom;
+import android.security.metrics.KeystoreAtomPayload;
+import android.security.metrics.RkpErrorStats;
+import android.security.metrics.RkpPoolStats;
+import android.security.metrics.StorageStats;
 import android.stats.storage.StorageEnums;
 import android.telephony.ModemActivityInfo;
 import android.telephony.SubscriptionInfo;
@@ -373,6 +386,10 @@
 
     private SelectedProcessCpuThreadReader mSurfaceFlingerProcessCpuThreadReader;
 
+    // Only access via getIKeystoreMetricsService
+    @GuardedBy("mKeystoreLock")
+    private IKeystoreMetrics mIKeystoreMetrics;
+
     // Puller locks
     private final Object mDataBytesTransferLock = new Object();
     private final Object mBluetoothBytesTransferLock = new Object();
@@ -428,6 +445,7 @@
     private final Object mAttributedAppOpsLock = new Object();
     private final Object mSettingsStatsLock = new Object();
     private final Object mInstalledIncrementalPackagesLock = new Object();
+    private final Object mKeystoreLock = new Object();
 
     public StatsPullAtomService(Context context) {
         super(context);
@@ -435,6 +453,7 @@
     }
 
     private native void initializeNativePullers();
+
     /**
      * Use of this StatsPullAtomCallbackImpl means we avoid one class per tagId, which we would
      * get if we used lambdas.
@@ -703,6 +722,16 @@
                         synchronized (mInstalledIncrementalPackagesLock) {
                             return pullInstalledIncrementalPackagesLocked(atomTag, data);
                         }
+                    case FrameworkStatsLog.KEYSTORE2_STORAGE_STATS:
+                    case FrameworkStatsLog.RKP_POOL_STATS:
+                    case FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_GENERAL_INFO:
+                    case FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_AUTH_INFO:
+                    case FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_PURPOSE_AND_MODES_INFO:
+                    case FrameworkStatsLog.KEYSTORE2_ATOM_WITH_OVERFLOW:
+                    case FrameworkStatsLog.KEYSTORE2_KEY_OPERATION_WITH_PURPOSE_AND_MODES_INFO:
+                    case FrameworkStatsLog.KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO:
+                    case FrameworkStatsLog.RKP_ERROR_STATS:
+                        return pullKeystoreAtoms(atomTag, data);
                     default:
                         throw new UnsupportedOperationException("Unknown tagId=" + atomTag);
                 }
@@ -795,6 +824,8 @@
 
         mSurfaceFlingerProcessCpuThreadReader =
                 new SelectedProcessCpuThreadReader("/system/bin/surfaceflinger");
+
+        getIKeystoreMetricsService();
     }
 
     void registerEventListeners() {
@@ -887,6 +918,15 @@
         registerBatteryCycleCount();
         registerSettingsStats();
         registerInstalledIncrementalPackages();
+        registerKeystoreStorageStats();
+        registerRkpPoolStats();
+        registerKeystoreKeyCreationWithGeneralInfo();
+        registerKeystoreKeyCreationWithAuthInfo();
+        registerKeystoreKeyCreationWithPurposeModesInfo();
+        registerKeystoreAtomWithOverflow();
+        registerKeystoreKeyOperationWithPurposeAndModesInfo();
+        registerKeystoreKeyOperationWithGeneralInfo();
+        registerRkpErrorStats();
     }
 
     private void initAndRegisterNetworkStatsPullers() {
@@ -971,6 +1011,28 @@
         }
     }
 
+    private IKeystoreMetrics getIKeystoreMetricsService() {
+        synchronized (mKeystoreLock) {
+            if (mIKeystoreMetrics == null) {
+                mIKeystoreMetrics = IKeystoreMetrics.Stub.asInterface(
+                        ServiceManager.getService("android.security.metrics"));
+                if (mIKeystoreMetrics != null) {
+                    try {
+                        mIKeystoreMetrics.asBinder().linkToDeath(() -> {
+                            synchronized (mKeystoreLock) {
+                                mIKeystoreMetrics = null;
+                            }
+                        }, /* flags */ 0);
+                    } catch (RemoteException e) {
+                        Slog.e(TAG, "linkToDeath with IKeystoreMetrics failed", e);
+                        mIKeystoreMetrics = null;
+                    }
+                }
+            }
+            return mIKeystoreMetrics;
+        }
+    }
+
     private IStoraged getIStoragedService() {
         synchronized (mStoragedLock) {
             if (mStorageService == null) {
@@ -4005,6 +4067,253 @@
         return StatsManager.PULL_SUCCESS;
     }
 
+    private void registerKeystoreStorageStats() {
+        mStatsManager.setPullAtomCallback(
+                FrameworkStatsLog.KEYSTORE2_STORAGE_STATS,
+                null, // use default PullAtomMetadata values,
+                DIRECT_EXECUTOR,
+                mStatsCallbackImpl);
+    }
+
+    private void registerRkpPoolStats() {
+        mStatsManager.setPullAtomCallback(
+                FrameworkStatsLog.RKP_POOL_STATS,
+                null, // use default PullAtomMetadata values,
+                DIRECT_EXECUTOR,
+                mStatsCallbackImpl);
+    }
+
+    private void registerKeystoreKeyCreationWithGeneralInfo() {
+        mStatsManager.setPullAtomCallback(
+                FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_GENERAL_INFO,
+                null, // use default PullAtomMetadata values,
+                DIRECT_EXECUTOR,
+                mStatsCallbackImpl);
+    }
+
+    private void registerKeystoreKeyCreationWithAuthInfo() {
+        mStatsManager.setPullAtomCallback(
+                FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_AUTH_INFO,
+                null, // use default PullAtomMetadata values,
+                DIRECT_EXECUTOR,
+                mStatsCallbackImpl);
+    }
+
+    private void registerKeystoreKeyCreationWithPurposeModesInfo() {
+        mStatsManager.setPullAtomCallback(
+                FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_PURPOSE_AND_MODES_INFO,
+                null, // use default PullAtomMetadata values,
+                DIRECT_EXECUTOR,
+                mStatsCallbackImpl);
+    }
+
+    private void registerKeystoreAtomWithOverflow() {
+        mStatsManager.setPullAtomCallback(
+                FrameworkStatsLog.KEYSTORE2_ATOM_WITH_OVERFLOW,
+                null, // use default PullAtomMetadata values,
+                DIRECT_EXECUTOR,
+                mStatsCallbackImpl);
+    }
+
+    private void registerKeystoreKeyOperationWithPurposeAndModesInfo() {
+        mStatsManager.setPullAtomCallback(
+                FrameworkStatsLog.KEYSTORE2_KEY_OPERATION_WITH_PURPOSE_AND_MODES_INFO,
+                null, // use default PullAtomMetadata values,
+                DIRECT_EXECUTOR,
+                mStatsCallbackImpl);
+    }
+
+    private void registerKeystoreKeyOperationWithGeneralInfo() {
+        mStatsManager.setPullAtomCallback(
+                FrameworkStatsLog.KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO,
+                null, // use default PullAtomMetadata values,
+                DIRECT_EXECUTOR,
+                mStatsCallbackImpl);
+    }
+
+    private void registerRkpErrorStats() {
+        mStatsManager.setPullAtomCallback(
+                FrameworkStatsLog.RKP_ERROR_STATS,
+                null, // use default PullAtomMetadata values,
+                DIRECT_EXECUTOR,
+                mStatsCallbackImpl);
+    }
+
+    int parseKeystoreStorageStats(KeystoreAtom[] atoms, List<StatsEvent> pulledData) {
+        for (KeystoreAtom atomWrapper : atoms) {
+            if (atomWrapper.payload.getTag() != KeystoreAtomPayload.storageStats) {
+                return StatsManager.PULL_SKIP;
+            }
+            StorageStats atom = atomWrapper.payload.getStorageStats();
+            pulledData.add(FrameworkStatsLog.buildStatsEvent(
+                    FrameworkStatsLog.KEYSTORE2_STORAGE_STATS, atom.storage_type,
+                    atom.size, atom.unused_size));
+        }
+        return StatsManager.PULL_SUCCESS;
+    }
+
+    int parseRkpPoolStats(KeystoreAtom[] atoms, List<StatsEvent> pulledData) {
+        for (KeystoreAtom atomWrapper : atoms) {
+            if (atomWrapper.payload.getTag() != KeystoreAtomPayload.rkpPoolStats) {
+                return StatsManager.PULL_SKIP;
+            }
+            RkpPoolStats atom = atomWrapper.payload.getRkpPoolStats();
+            pulledData.add(FrameworkStatsLog.buildStatsEvent(
+                    FrameworkStatsLog.RKP_POOL_STATS, atom.pool_status, atom.count_of_keys));
+        }
+        return StatsManager.PULL_SUCCESS;
+    }
+
+    int parseKeystoreKeyCreationWithGeneralInfo(KeystoreAtom[] atoms, List<StatsEvent> pulledData) {
+        for (KeystoreAtom atomWrapper : atoms) {
+            if (atomWrapper.payload.getTag()
+                    != KeystoreAtomPayload.keyCreationWithGeneralInfo) {
+                return StatsManager.PULL_SKIP;
+            }
+            KeyCreationWithGeneralInfo atom = atomWrapper.payload.getKeyCreationWithGeneralInfo();
+            pulledData.add(FrameworkStatsLog.buildStatsEvent(
+                    FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_GENERAL_INFO, atom.algorithm,
+                    atom.key_size, atom.ec_curve, atom.key_origin, atom.error_code,
+                    atom.attestation_requested, atomWrapper.count));
+        }
+        return StatsManager.PULL_SUCCESS;
+    }
+
+    int parseKeystoreKeyCreationWithAuthInfo(KeystoreAtom[] atoms, List<StatsEvent> pulledData) {
+        for (KeystoreAtom atomWrapper : atoms) {
+            if (atomWrapper.payload.getTag() != KeystoreAtomPayload.keyCreationWithAuthInfo) {
+                return StatsManager.PULL_SKIP;
+            }
+            KeyCreationWithAuthInfo atom = atomWrapper.payload.getKeyCreationWithAuthInfo();
+            pulledData.add(FrameworkStatsLog.buildStatsEvent(
+                    FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_AUTH_INFO, atom.user_auth_type,
+                    atom.log10_auth_key_timeout_seconds, atom.security_level, atomWrapper.count));
+        }
+        return StatsManager.PULL_SUCCESS;
+    }
+
+
+    int parseKeystoreKeyCreationWithPurposeModesInfo(KeystoreAtom[] atoms,
+            List<StatsEvent> pulledData) {
+        for (KeystoreAtom atomWrapper : atoms) {
+            if (atomWrapper.payload.getTag()
+                    != KeystoreAtomPayload.keyCreationWithPurposeAndModesInfo) {
+                return StatsManager.PULL_SKIP;
+            }
+            KeyCreationWithPurposeAndModesInfo atom =
+                    atomWrapper.payload.getKeyCreationWithPurposeAndModesInfo();
+            pulledData.add(FrameworkStatsLog.buildStatsEvent(
+                    FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_PURPOSE_AND_MODES_INFO,
+                    atom.algorithm, atom.purpose_bitmap,
+                    atom.padding_mode_bitmap, atom.digest_bitmap, atom.block_mode_bitmap,
+                    atomWrapper.count));
+        }
+        return StatsManager.PULL_SUCCESS;
+    }
+
+    int parseKeystoreAtomWithOverflow(KeystoreAtom[] atoms, List<StatsEvent> pulledData) {
+        for (KeystoreAtom atomWrapper : atoms) {
+            if (atomWrapper.payload.getTag()
+                    != KeystoreAtomPayload.keystore2AtomWithOverflow) {
+                return StatsManager.PULL_SKIP;
+            }
+            Keystore2AtomWithOverflow atom = atomWrapper.payload.getKeystore2AtomWithOverflow();
+            pulledData.add(FrameworkStatsLog.buildStatsEvent(
+                    FrameworkStatsLog.KEYSTORE2_ATOM_WITH_OVERFLOW, atom.atom_id,
+                    atomWrapper.count));
+        }
+        return StatsManager.PULL_SUCCESS;
+    }
+
+    int parseKeystoreKeyOperationWithPurposeModesInfo(KeystoreAtom[] atoms,
+            List<StatsEvent> pulledData) {
+        for (KeystoreAtom atomWrapper : atoms) {
+            if (atomWrapper.payload.getTag()
+                    != KeystoreAtomPayload.keyOperationWithPurposeAndModesInfo) {
+                return StatsManager.PULL_SKIP;
+            }
+            KeyOperationWithPurposeAndModesInfo atom =
+                    atomWrapper.payload.getKeyOperationWithPurposeAndModesInfo();
+            pulledData.add(FrameworkStatsLog.buildStatsEvent(
+                    FrameworkStatsLog.KEYSTORE2_KEY_OPERATION_WITH_PURPOSE_AND_MODES_INFO,
+                    atom.purpose, atom.padding_mode_bitmap, atom.digest_bitmap,
+                    atom.block_mode_bitmap, atomWrapper.count));
+        }
+        return StatsManager.PULL_SUCCESS;
+    }
+
+    int parseKeystoreKeyOperationWithGeneralInfo(KeystoreAtom[] atoms,
+            List<StatsEvent> pulledData) {
+        for (KeystoreAtom atomWrapper : atoms) {
+            if (atomWrapper.payload.getTag()
+                    != KeystoreAtomPayload.keyOperationWithGeneralInfo) {
+                return StatsManager.PULL_SKIP;
+            }
+            KeyOperationWithGeneralInfo atom = atomWrapper.payload.getKeyOperationWithGeneralInfo();
+            pulledData.add(FrameworkStatsLog.buildStatsEvent(
+                    FrameworkStatsLog.KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO, atom.outcome,
+                    atom.error_code, atom.key_upgraded, atom.security_level, atomWrapper.count));
+        }
+        return StatsManager.PULL_SUCCESS;
+    }
+
+    int parseRkpErrorStats(KeystoreAtom[] atoms,
+            List<StatsEvent> pulledData) {
+        for (KeystoreAtom atomWrapper : atoms) {
+            if (atomWrapper.payload.getTag() != KeystoreAtomPayload.rkpErrorStats) {
+                return StatsManager.PULL_SKIP;
+            }
+            RkpErrorStats atom = atomWrapper.payload.getRkpErrorStats();
+            pulledData.add(FrameworkStatsLog.buildStatsEvent(
+                    FrameworkStatsLog.RKP_ERROR_STATS, atom.rkpError, atomWrapper.count));
+        }
+        return StatsManager.PULL_SUCCESS;
+    }
+
+    int pullKeystoreAtoms(int atomTag, List<StatsEvent> pulledData) {
+        IKeystoreMetrics keystoreMetricsService = getIKeystoreMetricsService();
+        if (keystoreMetricsService == null) {
+            Slog.w(TAG, "Keystore service is null");
+            return StatsManager.PULL_SKIP;
+        }
+        final long callingToken = Binder.clearCallingIdentity();
+        try {
+            KeystoreAtom[] atoms = keystoreMetricsService.pullMetrics(atomTag);
+            switch (atomTag) {
+                case FrameworkStatsLog.KEYSTORE2_STORAGE_STATS:
+                    return parseKeystoreStorageStats(atoms, pulledData);
+                case FrameworkStatsLog.RKP_POOL_STATS:
+                    return parseRkpPoolStats(atoms, pulledData);
+                case FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_GENERAL_INFO:
+                    return parseKeystoreKeyCreationWithGeneralInfo(atoms, pulledData);
+                case FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_AUTH_INFO:
+                    return parseKeystoreKeyCreationWithAuthInfo(atoms, pulledData);
+                case FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_PURPOSE_AND_MODES_INFO:
+                    return parseKeystoreKeyCreationWithPurposeModesInfo(atoms, pulledData);
+                case FrameworkStatsLog.KEYSTORE2_ATOM_WITH_OVERFLOW:
+                    return parseKeystoreAtomWithOverflow(atoms, pulledData);
+                case FrameworkStatsLog.KEYSTORE2_KEY_OPERATION_WITH_PURPOSE_AND_MODES_INFO:
+                    return parseKeystoreKeyOperationWithPurposeModesInfo(atoms, pulledData);
+                case FrameworkStatsLog.KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO:
+                    return parseKeystoreKeyOperationWithGeneralInfo(atoms, pulledData);
+                case FrameworkStatsLog.RKP_ERROR_STATS:
+                    return parseRkpErrorStats(atoms, pulledData);
+                default:
+                    Slog.w(TAG, "Unsupported keystore atom: " + atomTag);
+                    return StatsManager.PULL_SKIP;
+            }
+        } catch (RemoteException e) {
+            // Should not happen.
+            Slog.e(TAG, "Disconnected from keystore service. Cannot pull.", e);
+            return StatsManager.PULL_SKIP;
+        } catch (ServiceSpecificException e) {
+            Slog.e(TAG, "pulling keystore metrics failed", e);
+            return StatsManager.PULL_SKIP;
+        } finally {
+            Binder.restoreCallingIdentity(callingToken);
+        }
+    }
+
     // Thermal event received from vendor thermal management subsystem
     private static final class ThermalEventListener extends IThermalEventListener.Stub {
         @Override
diff --git a/services/core/java/com/android/server/timedetector/ServerFlags.java b/services/core/java/com/android/server/timedetector/ServerFlags.java
index 7145f5e..fe977f8 100644
--- a/services/core/java/com/android/server/timedetector/ServerFlags.java
+++ b/services/core/java/com/android/server/timedetector/ServerFlags.java
@@ -50,10 +50,6 @@
     /**
      * An annotation used to indicate when a {@link DeviceConfig#NAMESPACE_SYSTEM_TIME} key is
      * required.
-     *
-     * <p>Note that the com.android.geotz module deployment of the Offline LocationTimeZoneProvider
-     * also shares the {@link DeviceConfig#NAMESPACE_SYSTEM_TIME}, and uses the
-     * prefix "geotz_" on all of its key strings.
      */
     @StringDef(prefix = "KEY_", value = {
             KEY_LOCATION_TIME_ZONE_DETECTION_FEATURE_SUPPORTED,
diff --git a/services/core/java/com/android/server/vibrator/DeviceVibrationEffectAdapter.java b/services/core/java/com/android/server/vibrator/DeviceVibrationEffectAdapter.java
index e8ce4f3..24da261 100644
--- a/services/core/java/com/android/server/vibrator/DeviceVibrationEffectAdapter.java
+++ b/services/core/java/com/android/server/vibrator/DeviceVibrationEffectAdapter.java
@@ -16,7 +16,6 @@
 
 package com.android.server.vibrator;
 
-import android.content.Context;
 import android.os.VibrationEffect;
 import android.os.VibratorInfo;
 
@@ -29,14 +28,13 @@
 
     private final List<VibrationEffectAdapters.SegmentsAdapter<VibratorInfo>> mSegmentAdapters;
 
-    DeviceVibrationEffectAdapter(Context context) {
+    DeviceVibrationEffectAdapter(VibrationSettings settings) {
         mSegmentAdapters = Arrays.asList(
                 // TODO(b/167947076): add filter that removes unsupported primitives
                 // TODO(b/167947076): add filter that replaces unsupported prebaked with fallback
-                new RampToStepAdapter(context.getResources().getInteger(
-                        com.android.internal.R.integer.config_vibrationWaveformRampStepDuration)),
-                new StepToRampAdapter(context.getResources().getInteger(
-                        com.android.internal.R.integer.config_vibrationWaveformRampDownDuration)),
+                new RampToStepAdapter(settings.getRampStepDuration()),
+                new StepToRampAdapter(),
+                new RampDownAdapter(settings.getRampDownDuration(), settings.getRampStepDuration()),
                 new ClippingAmplitudeAndFrequencyAdapter()
         );
     }
diff --git a/services/core/java/com/android/server/vibrator/RampDownAdapter.java b/services/core/java/com/android/server/vibrator/RampDownAdapter.java
new file mode 100644
index 0000000..d5cd344
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/RampDownAdapter.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vibrator;
+
+import android.os.VibratorInfo;
+import android.os.vibrator.RampSegment;
+import android.os.vibrator.StepSegment;
+import android.os.vibrator.VibrationEffectSegment;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Adapter that applies the ramp down duration config to bring down the vibrator amplitude smoothly.
+ *
+ * <p>This prevents the device from ringing when it cannot handle abrupt changes between ON and OFF
+ * states. This will not change other types of abrupt amplitude changes in the original effect. The
+ * effect overall duration is preserved by this transformation.
+ *
+ * <p>Waveforms with ON/OFF segments are handled gracefully by the ramp down changes. Each OFF
+ * segment preceded by an ON segment will be shortened, and a ramp or step down will be added to the
+ * transition between ON and OFF. The ramps/steps can be shorter than the configured duration in
+ * order to preserve the waveform  timings, but they will still soften the ringing effect.
+ *
+ * <p>If the segment preceding an OFF segment a {@link RampSegment} then a new ramp segment will be
+ * added to bring the amplitude down. If it is a {@link StepSegment} then a sequence of steps will
+ * be used to bring the amplitude down to zero. This ensures that the transition from the last
+ * amplitude to zero will be handled by the same vibrate method.
+ */
+final class RampDownAdapter implements VibrationEffectAdapters.SegmentsAdapter<VibratorInfo> {
+    private final int mRampDownDuration;
+    private final int mStepDuration;
+
+    RampDownAdapter(int rampDownDuration, int stepDuration) {
+        mRampDownDuration = rampDownDuration;
+        mStepDuration = stepDuration;
+    }
+
+    @Override
+    public int apply(List<VibrationEffectSegment> segments, int repeatIndex,
+            VibratorInfo info) {
+        if (mRampDownDuration <= 0) {
+            // Nothing to do, no ramp down duration configured.
+            return repeatIndex;
+        }
+        repeatIndex = addRampDownToZeroAmplitudeSegments(segments, repeatIndex);
+        repeatIndex = addRampDownToLoop(segments, repeatIndex);
+        return repeatIndex;
+    }
+
+    /**
+     * This will add ramp or steps down to zero as follows:
+     *
+     * <ol>
+     *     <li>Remove the OFF segment that follows a segment of non-zero amplitude;
+     *     <li>Add a single {@link RampSegment} or a list of {@link StepSegment} starting at the
+     *         previous segment's amplitude and frequency, with min between the configured ramp down
+     *         duration or the removed segment's duration;
+     *     <li>Add a zero amplitude segment following the steps, if necessary, to fill the remaining
+     *         duration;
+     * </ol>
+     */
+    private int addRampDownToZeroAmplitudeSegments(List<VibrationEffectSegment> segments,
+            int repeatIndex) {
+        int newRepeatIndex = repeatIndex;
+        int newSegmentCount = segments.size();
+        for (int i = 1; i < newSegmentCount; i++) {
+            VibrationEffectSegment previousSegment = segments.get(i - 1);
+            if (!isOffSegment(segments.get(i))
+                    || !endsWithNonZeroAmplitude(previousSegment)) {
+                continue;
+            }
+
+            List<VibrationEffectSegment> replacementSegments = null;
+            long offDuration = segments.get(i).getDuration();
+
+            if (previousSegment instanceof StepSegment) {
+                float previousAmplitude = ((StepSegment) previousSegment).getAmplitude();
+                float previousFrequency = ((StepSegment) previousSegment).getFrequency();
+
+                replacementSegments =
+                        createStepsDown(previousAmplitude, previousFrequency, offDuration);
+            } else if (previousSegment instanceof RampSegment) {
+                float previousAmplitude = ((RampSegment) previousSegment).getEndAmplitude();
+                float previousFrequency = ((RampSegment) previousSegment).getEndFrequency();
+
+                if (offDuration <= mRampDownDuration) {
+                    // Replace the zero amplitude segment with a ramp down of same duration, to
+                    // preserve waveform timings and still soften the transition to zero.
+                    replacementSegments = Arrays.asList(
+                            createRampDown(previousAmplitude, previousFrequency, offDuration));
+                } else {
+                    // Replace the zero amplitude segment with a ramp down of configured duration
+                    // followed by a shorter off segment.
+                    replacementSegments = Arrays.asList(
+                            createRampDown(previousAmplitude, previousFrequency, mRampDownDuration),
+                            createRampDown(0, previousFrequency, offDuration - mRampDownDuration));
+                }
+            }
+
+            if (replacementSegments != null) {
+                int segmentsAdded = replacementSegments.size() - 1;
+
+                segments.remove(i);
+                segments.addAll(i, replacementSegments);
+                if (repeatIndex > i) {
+                    newRepeatIndex += segmentsAdded;
+                }
+                i += segmentsAdded;
+                newSegmentCount += segmentsAdded;
+            }
+        }
+        return newRepeatIndex;
+    }
+
+    /**
+     * This will ramps down to zero at the repeating index of the given effect, if set, only if
+     * the last segment ends at a non-zero amplitude and the repeating segment has zero amplitude.
+     * The update is described as:
+     *
+     * <ol>
+     *     <li>Add a ramp or sequence of steps down to zero following the last segment, with the min
+     *         between the removed segment duration and the configured ramp down duration;
+     *     <li>Skip the zero-amplitude segment by incrementing the repeat index, splitting it if
+     *         necessary to skip the correct amount;
+     * </ol>
+     */
+    private int addRampDownToLoop(List<VibrationEffectSegment> segments, int repeatIndex) {
+        if (repeatIndex < 0) {
+            // Nothing to do, no ramp down duration configured or effect is not repeating.
+            return repeatIndex;
+        }
+
+        int segmentCount = segments.size();
+        if (!endsWithNonZeroAmplitude(segments.get(segmentCount - 1))
+                || !isOffSegment(segments.get(repeatIndex))) {
+            // Nothing to do, not going back from a positive amplitude to a off segment.
+            return repeatIndex;
+        }
+
+        VibrationEffectSegment lastSegment = segments.get(segmentCount - 1);
+        VibrationEffectSegment offSegment = segments.get(repeatIndex);
+        long offDuration = offSegment.getDuration();
+
+        if (offDuration > mRampDownDuration) {
+            // Split the zero amplitude segment and start repeating from the second half, to
+            // preserve waveform timings. This will update the waveform as follows:
+            //  R              R+1
+            //  |   ____        |  ____
+            // _|__/       => __|_/    \
+            segments.set(repeatIndex, updateDuration(offSegment, offDuration - mRampDownDuration));
+            segments.add(repeatIndex, updateDuration(offSegment, mRampDownDuration));
+        }
+
+        // Skip the zero amplitude segment and append ramp/steps down at the end.
+        repeatIndex++;
+        if (lastSegment instanceof StepSegment) {
+            float previousAmplitude = ((StepSegment) lastSegment).getAmplitude();
+            float previousFrequency = ((StepSegment) lastSegment).getFrequency();
+            segments.addAll(createStepsDown(previousAmplitude, previousFrequency,
+                    Math.min(offDuration, mRampDownDuration)));
+        } else if (lastSegment instanceof RampSegment) {
+            float previousAmplitude = ((RampSegment) lastSegment).getEndAmplitude();
+            float previousFrequency = ((RampSegment) lastSegment).getEndFrequency();
+            segments.add(createRampDown(previousAmplitude, previousFrequency,
+                    Math.min(offDuration, mRampDownDuration)));
+        }
+
+        return repeatIndex;
+    }
+
+    private List<VibrationEffectSegment> createStepsDown(float amplitude, float frequency,
+            long duration) {
+        // Step down for at most the configured ramp duration.
+        int stepCount = (int) Math.min(duration, mRampDownDuration) / mStepDuration;
+        float amplitudeStep = amplitude / stepCount;
+        List<VibrationEffectSegment> steps = new ArrayList<>();
+        for (int i = 1; i < stepCount; i++) {
+            steps.add(new StepSegment(amplitude - i * amplitudeStep, frequency, mStepDuration));
+        }
+        int remainingDuration = (int) duration - mStepDuration * (stepCount - 1);
+        steps.add(new StepSegment(0, frequency, remainingDuration));
+        return steps;
+    }
+
+    private static RampSegment createRampDown(float amplitude, float frequency, long duration) {
+        return new RampSegment(amplitude, /* endAmplitude= */ 0, frequency, frequency,
+                (int) duration);
+    }
+
+    private static VibrationEffectSegment updateDuration(VibrationEffectSegment segment,
+            long newDuration) {
+        if (segment instanceof RampSegment) {
+            RampSegment ramp = (RampSegment) segment;
+            return new RampSegment(ramp.getStartAmplitude(), ramp.getEndAmplitude(),
+                    ramp.getStartFrequency(), ramp.getEndFrequency(), (int) newDuration);
+        } else if (segment instanceof StepSegment) {
+            StepSegment step = (StepSegment) segment;
+            return new StepSegment(step.getAmplitude(), step.getFrequency(), (int) newDuration);
+        }
+        return segment;
+    }
+
+    /** Returns true if the segment is a ramp or a step that starts and ends at zero amplitude. */
+    private static boolean isOffSegment(VibrationEffectSegment segment) {
+        if (segment instanceof StepSegment) {
+            StepSegment ramp = (StepSegment) segment;
+            return ramp.getAmplitude() == 0;
+        } else if (segment instanceof RampSegment) {
+            RampSegment ramp = (RampSegment) segment;
+            return ramp.getStartAmplitude() == 0 && ramp.getEndAmplitude() == 0;
+        }
+        return false;
+    }
+
+    /** Returns true if the segment is a ramp or a step that ends at a non-zero amplitude. */
+    private static boolean endsWithNonZeroAmplitude(VibrationEffectSegment segment) {
+        if (segment instanceof StepSegment) {
+            return ((StepSegment) segment).getAmplitude() != 0;
+        } else if (segment instanceof RampSegment) {
+            return ((RampSegment) segment).getEndAmplitude() != 0;
+        }
+        return false;
+    }
+}
diff --git a/services/core/java/com/android/server/vibrator/StepToRampAdapter.java b/services/core/java/com/android/server/vibrator/StepToRampAdapter.java
index 1d8c64b..6f5adac 100644
--- a/services/core/java/com/android/server/vibrator/StepToRampAdapter.java
+++ b/services/core/java/com/android/server/vibrator/StepToRampAdapter.java
@@ -31,25 +31,9 @@
  * <p>Each replaced {@link StepSegment} will be represented by a {@link RampSegment} with same
  * start and end amplitudes/frequencies, which can then be converted to PWLE compositions. This
  * adapter leaves the segments unchanged if the device doesn't have the PWLE composition capability.
- *
- * <p>This adapter also applies the ramp down duration config on devices with PWLE support. This
- * prevents the device from ringing when it cannot handle abrupt changes between ON and OFF states.
- * This will not change other types of abrupt amplitude changes in the original effect.
- *
- * <p>The effect overall duration is preserved by this transformation. Waveforms with ON/OFF
- * segments are handled gracefully by the ramp down changes. Each OFF segment preceded by an ON
- * segment will be shortened, and a ramp down will be added to the transition between ON and OFF.
- * The ramps can be shorter than the configured duration in order to preserve the waveform timings,
- * but they will still soften the ringing effect.
  */
 final class StepToRampAdapter implements VibrationEffectAdapters.SegmentsAdapter<VibratorInfo> {
 
-    private final int mRampDownDuration;
-
-    StepToRampAdapter(int rampDownDuration) {
-        mRampDownDuration = rampDownDuration;
-    }
-
     @Override
     public int apply(List<VibrationEffectSegment> segments, int repeatIndex,
             VibratorInfo info) {
@@ -58,28 +42,17 @@
             return repeatIndex;
         }
         convertStepsToRamps(segments);
-        int newRepeatIndex = addRampDownToZeroAmplitudeSegments(segments, repeatIndex);
-        newRepeatIndex = addRampDownToLoop(segments, newRepeatIndex);
-        newRepeatIndex = splitLongRampSegments(info, segments, newRepeatIndex);
-        return newRepeatIndex;
+        repeatIndex = splitLongRampSegments(info, segments, repeatIndex);
+        return repeatIndex;
     }
 
     private void convertStepsToRamps(List<VibrationEffectSegment> segments) {
         int segmentCount = segments.size();
-        if (mRampDownDuration > 0) {
-            // Convert all steps to ramps if the device requires ramp down.
-            for (int i = 0; i < segmentCount; i++) {
-                if (isStep(segments.get(i))) {
-                    segments.set(i, apply((StepSegment) segments.get(i)));
-                }
-            }
-            return;
-        }
         // Convert steps that require frequency control to ramps.
         for (int i = 0; i < segmentCount; i++) {
             VibrationEffectSegment segment = segments.get(i);
             if (isStep(segment) && ((StepSegment) segment).getFrequency() != 0) {
-                segments.set(i, apply((StepSegment) segment));
+                segments.set(i, convertStepToRamp((StepSegment) segment));
             }
         }
         // Convert steps that are next to ramps to also become ramps, so they can be composed
@@ -87,132 +60,16 @@
         for (int i = 0; i < segmentCount; i++) {
             if (segments.get(i) instanceof RampSegment) {
                 for (int j = i - 1; j >= 0 && isStep(segments.get(j)); j--) {
-                    segments.set(j, apply((StepSegment) segments.get(j)));
+                    segments.set(j, convertStepToRamp((StepSegment) segments.get(j)));
                 }
                 for (int j = i + 1; j < segmentCount && isStep(segments.get(j)); j++) {
-                    segments.set(j, apply((StepSegment) segments.get(j)));
+                    segments.set(j, convertStepToRamp((StepSegment) segments.get(j)));
                 }
             }
         }
     }
 
     /**
-     * This will add a ramp to zero as follows:
-     *
-     * <ol>
-     *     <li>Remove the {@link VibrationEffectSegment} that starts and ends at zero amplitude
-     *         and follows a segment that ends at non-zero amplitude;
-     *     <li>Add a ramp down to zero starting at the previous segment end amplitude and frequency,
-     *         with min between the removed segment duration and the configured ramp down duration;
-     *     <li>Add a zero amplitude segment following the ramp with the remaining duration, if
-     *         necessary;
-     * </ol>
-     */
-    private int addRampDownToZeroAmplitudeSegments(List<VibrationEffectSegment> segments,
-            int repeatIndex) {
-        if (mRampDownDuration <= 0) {
-            // Nothing to do, no ramp down duration configured.
-            return repeatIndex;
-        }
-        int newRepeatIndex = repeatIndex;
-        int newSegmentCount = segments.size();
-        for (int i = 1; i < newSegmentCount; i++) {
-            if (!isOffRampSegment(segments.get(i))
-                    || !endsWithNonZeroAmplitude(segments.get(i - 1))) {
-                continue;
-            }
-
-            // We know the previous segment is a ramp that ends at non-zero amplitude.
-            float previousAmplitude = ((RampSegment) segments.get(i - 1)).getEndAmplitude();
-            float previousFrequency = ((RampSegment) segments.get(i - 1)).getEndFrequency();
-            RampSegment ramp = (RampSegment) segments.get(i);
-
-            if (ramp.getDuration() <= mRampDownDuration) {
-                // Replace the zero amplitude segment with a ramp down of same duration, to
-                // preserve waveform timings and still soften the transition to zero.
-                segments.set(i, createRampDown(previousAmplitude, previousFrequency,
-                        ramp.getDuration()));
-            } else {
-                // Make the zero amplitude segment shorter, to preserve waveform timings, and add a
-                // ramp down to zero segment right before it.
-                segments.set(i, updateDuration(ramp, ramp.getDuration() - mRampDownDuration));
-                segments.add(i, createRampDown(previousAmplitude, previousFrequency,
-                        mRampDownDuration));
-                if (repeatIndex > i) {
-                    newRepeatIndex++;
-                }
-                i++;
-                newSegmentCount++;
-            }
-        }
-        return newRepeatIndex;
-    }
-
-    /**
-     * This will add a ramp to zero at the repeating index of the given effect, if set, only if
-     * the last segment ends at a non-zero amplitude and the repeating segment starts and ends at
-     * zero amplitude. The update is described as:
-     *
-     * <ol>
-     *     <li>Add a ramp down to zero following the last segment, with the min between the
-     *         removed segment duration and the configured ramp down duration;
-     *     <li>Skip the zero-amplitude segment by incrementing the repeat index, splitting it if
-     *         necessary to skip the correct amount;
-     * </ol>
-     */
-    private int addRampDownToLoop(List<VibrationEffectSegment> segments, int repeatIndex) {
-        if (repeatIndex < 0) {
-            // Non-repeating compositions should remain unchanged so duration will be preserved.
-            return repeatIndex;
-        }
-
-        int segmentCount = segments.size();
-        if (mRampDownDuration <= 0 || !endsWithNonZeroAmplitude(segments.get(segmentCount - 1))) {
-            // Nothing to do, no ramp down duration configured or composition already ends at zero.
-            return repeatIndex;
-        }
-
-        // We know the last segment is a ramp that ends at non-zero amplitude.
-        RampSegment lastRamp = (RampSegment) segments.get(segmentCount - 1);
-        float previousAmplitude = lastRamp.getEndAmplitude();
-        float previousFrequency = lastRamp.getEndFrequency();
-
-        if (isOffRampSegment(segments.get(repeatIndex))) {
-            // Repeating from a non-zero to a zero amplitude segment, we know the next segment is a
-            // ramp with zero amplitudes.
-            RampSegment nextRamp = (RampSegment) segments.get(repeatIndex);
-
-            if (nextRamp.getDuration() <= mRampDownDuration) {
-                // Skip the zero amplitude segment and append a ramp down of same duration to the
-                // end of the composition, to preserve waveform timings and still soften the
-                // transition to zero.
-                // This will update the waveform as follows:
-                //  R               R+1
-                //  |  ____          | ____
-                // _|_/       =>   __|/    \
-                segments.add(createRampDown(previousAmplitude, previousFrequency,
-                        nextRamp.getDuration()));
-                repeatIndex++;
-            } else {
-                // Append a ramp down to the end of the composition, split the zero amplitude
-                // segment and start repeating from the second half, to preserve waveform timings.
-                // This will update the waveform as follows:
-                //  R              R+1
-                //  |   ____        |  ____
-                // _|__/       => __|_/    \
-                segments.add(createRampDown(previousAmplitude, previousFrequency,
-                        mRampDownDuration));
-                segments.set(repeatIndex, updateDuration(nextRamp,
-                        nextRamp.getDuration() - mRampDownDuration));
-                segments.add(repeatIndex, updateDuration(nextRamp, mRampDownDuration));
-                repeatIndex++;
-            }
-        }
-
-        return repeatIndex;
-    }
-
-    /**
      * Split {@link RampSegment} entries that have duration longer than {@link
      * VibratorInfo#getPwlePrimitiveDurationMax()}.
      */
@@ -247,7 +104,7 @@
         return repeatIndex;
     }
 
-    private static RampSegment apply(StepSegment segment) {
+    private static RampSegment convertStepToRamp(StepSegment segment) {
         return new RampSegment(segment.getAmplitude(), segment.getAmplitude(),
                 segment.getFrequency(), segment.getFrequency(), (int) segment.getDuration());
     }
@@ -276,36 +133,10 @@
         return ramps;
     }
 
-    private static RampSegment createRampDown(float amplitude, float frequency, long duration) {
-        return new RampSegment(amplitude, /* endAmplitude= */ 0, frequency, frequency,
-                (int) duration);
-    }
-
-    private static RampSegment updateDuration(RampSegment ramp, long newDuration) {
-        return new RampSegment(ramp.getStartAmplitude(), ramp.getEndAmplitude(),
-                ramp.getStartFrequency(), ramp.getEndFrequency(), (int) newDuration);
-    }
-
     private static boolean isStep(VibrationEffectSegment segment) {
         return segment instanceof StepSegment;
     }
 
-    /** Returns true if the segment is a ramp that starts and ends at zero amplitude. */
-    private static boolean isOffRampSegment(VibrationEffectSegment segment) {
-        if (segment instanceof RampSegment) {
-            RampSegment ramp = (RampSegment) segment;
-            return ramp.getStartAmplitude() == 0 && ramp.getEndAmplitude() == 0;
-        }
-        return false;
-    }
-
-    private static boolean endsWithNonZeroAmplitude(VibrationEffectSegment segment) {
-        if (segment instanceof RampSegment) {
-            return ((RampSegment) segment).getEndAmplitude() != 0;
-        }
-        return false;
-    }
-
     private static float interpolateAmplitude(RampSegment ramp, long duration) {
         return interpolate(ramp.getStartAmplitude(), ramp.getEndAmplitude(), duration,
                 ramp.getDuration());
diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java
index 885f0e4..c0a1d92 100644
--- a/services/core/java/com/android/server/vibrator/VibrationSettings.java
+++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java
@@ -67,11 +67,13 @@
     @VisibleForTesting
     final UserObserver mUserReceiver;
 
-
     @GuardedBy("mLock")
     private final List<OnVibratorSettingsChanged> mListeners = new ArrayList<>();
     private final SparseArray<VibrationEffect> mFallbackEffects;
 
+    private final int mRampStepDuration;
+    private final int mRampDownDuration;
+
     @GuardedBy("mLock")
     @Nullable
     private Vibrator mVibrator;
@@ -102,6 +104,12 @@
         mUidObserver = new UidObserver();
         mUserReceiver = new UserObserver();
 
+        // TODO(b/191150049): move these to vibrator static config file
+        mRampStepDuration = context.getResources().getInteger(
+                com.android.internal.R.integer.config_vibrationWaveformRampStepDuration);
+        mRampDownDuration = context.getResources().getInteger(
+                com.android.internal.R.integer.config_vibrationWaveformRampDownDuration);
+
         VibrationEffect clickEffect = createEffectFromResource(
                 com.android.internal.R.array.config_virtualKeyVibePattern);
         VibrationEffect doubleClickEffect = VibrationEffect.createWaveform(
@@ -193,6 +201,23 @@
     }
 
     /**
+     * The duration, in milliseconds, that should be applied to convert vibration effect's
+     * {@link android.os.vibrator.RampSegment} to a {@link android.os.vibrator.StepSegment} on
+     * devices without PWLE support.
+     */
+    public int getRampStepDuration() {
+        return mRampStepDuration;
+    }
+
+    /**
+     * The duration, in milliseconds, that should be applied to the ramp to turn off the vibrator
+     * when a vibration is cancelled or finished at non-zero amplitude.
+     */
+    public int getRampDownDuration() {
+        return mRampDownDuration;
+    }
+
+    /**
      * Return default vibration intensity for given usage.
      *
      * @param usageHint one of VibrationAttributes.USAGE_*
@@ -354,6 +379,8 @@
                 + ", mZenMode=" + Settings.Global.zenModeToString(mZenMode)
                 + ", mProcStatesCache=" + mUidObserver.mProcStatesCache
                 + ", mHapticChannelMaxVibrationAmplitude=" + getHapticChannelMaxVibrationAmplitude()
+                + ", mRampStepDuration=" + mRampStepDuration
+                + ", mRampDownDuration=" + mRampDownDuration
                 + ", mHapticFeedbackIntensity="
                 + intensityToString(getCurrentIntensity(VibrationAttributes.USAGE_TOUCH))
                 + ", mHapticFeedbackDefaultIntensity="
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index 79706ea..644e451 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -176,7 +176,7 @@
         mVibrationSettings = new VibrationSettings(mContext, mHandler);
         mVibrationScaler = new VibrationScaler(mContext, mVibrationSettings);
         mInputDeviceDelegate = new InputDeviceDelegate(mContext, mHandler);
-        mDeviceVibrationEffectAdapter = new DeviceVibrationEffectAdapter(mContext);
+        mDeviceVibrationEffectAdapter = new DeviceVibrationEffectAdapter(mVibrationSettings);
 
         VibrationCompleteListener listener = new VibrationCompleteListener(this);
         mNativeWrapper = injector.getNativeWrapper();
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 0ad8782..dd54529 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -5015,6 +5015,7 @@
         mAppStopped = true;
         // Reset the last saved PiP snap fraction on app stop.
         mDisplayContent.mPinnedTaskController.onActivityHidden(mActivityComponent);
+        mDisplayContent.mUnknownAppVisibilityController.appRemovedOrHidden(this);
         destroySurfaces();
         // Remove any starting window that was added for this app if they are still around.
         removeStartingWindow();
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 2bf78e9..680937b 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -2633,10 +2633,11 @@
                 }
                 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
                         STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
-                if (ainfo.applicationInfo.uid != callingUid) {
-                    throw new SecurityException(
-                            "Can't add task for another application: target uid="
-                                    + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
+                if (ainfo == null || ainfo.applicationInfo.uid != callingUid) {
+                    Slog.e(TAG, "Can't add task for another application: target uid="
+                            + (ainfo == null ? Process.INVALID_UID : ainfo.applicationInfo.uid)
+                            + ", calling uid=" + callingUid);
+                    return INVALID_TASK_ID;
                 }
 
                 final Task rootTask = r.getRootTask();
@@ -4158,21 +4159,21 @@
 
     /**
      * Update the asset configuration and increase the assets sequence number.
-     * @param processes the processes that needs to update the asset configuration, if none
-     *                  updates the global configuration for all processes.
+     * @param processes the processes that needs to update the asset configuration
      */
-    public void updateAssetConfiguration(List<WindowProcessController> processes) {
+    public void updateAssetConfiguration(List<WindowProcessController> processes,
+            boolean updateFrameworkRes) {
         synchronized (mGlobalLock) {
             final int assetSeq = increaseAssetConfigurationSeq();
 
-            // Update the global configuration if the no target processes
-            if (processes == null) {
+            if (updateFrameworkRes) {
                 Configuration newConfig = new Configuration();
                 newConfig.assetsSeq = assetSeq;
                 updateConfiguration(newConfig);
-                return;
             }
 
+            // Always update the override of every process so the asset sequence of the process is
+            // always greater than or equal to the global configuration.
             for (int i = processes.size() - 1; i >= 0; i--) {
                 final WindowProcessController wpc = processes.get(i);
                 wpc.updateAssetConfiguration(assetSeq);
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 4acadb2..3dea686 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -412,7 +412,13 @@
                 return TRANSIT_OLD_TASK_CLOSE;
             }
             if (isActivityClosing) {
-                return TRANSIT_OLD_ACTIVITY_CLOSE;
+                for (int i = closingApps.size() - 1; i >= 0; i--) {
+                    if (closingApps.valueAt(i).visibleIgnoringKeyguard) {
+                        return TRANSIT_OLD_ACTIVITY_CLOSE;
+                    }
+                }
+                // Skip close activity transition since no closing app can be visible
+                return WindowManager.TRANSIT_OLD_UNSET;
             }
         }
         if (appTransition.containsTransitRequest(TRANSIT_RELAUNCH)
diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java
index b24ab93..baa27e3 100644
--- a/services/core/java/com/android/server/wm/DisplayArea.java
+++ b/services/core/java/com/android/server/wm/DisplayArea.java
@@ -551,7 +551,13 @@
             }
             final WindowManagerPolicy policy = mWmService.mPolicy;
             if (policy.isKeyguardHostWindow(w.mAttrs)) {
-                if (mWmService.mKeyguardGoingAway) {
+                // Ignore the orientation of keyguard if it is going away or is not showing while
+                // the device is fully awake. In other words, use the orientation of keyguard if
+                // its window is visible while the device is going to sleep or is sleeping.
+                if (!mWmService.mAtmService.isKeyguardLocked()
+                        && mDisplayContent.getDisplayPolicy().isAwake()
+                        // Device is not going to sleep.
+                        && policy.okToAnimate(true /* ignoreScreenOn */)) {
                     return false;
                 }
                 // Consider unoccluding only when all unknown visibilities have been
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 3dbc517..62d8ace 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1564,12 +1564,6 @@
                 // window was transferred ({@link #mSkipAppTransitionAnimation}).
                 return false;
             }
-            if ((mAppTransition.getTransitFlags()
-                    & WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION) != 0) {
-                // The transition may be finished before keyguard hidden. In order to avoid the
-                // intermediate orientation change, it is more stable to freeze the display.
-                return false;
-            }
             if (r.isState(RESUMED) && !r.getRootTask().mInResumeTopActivity) {
                 // If the activity is executing or has done the lifecycle callback, use normal
                 // rotation animation so the display info can be updated immediately (see
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index f8238c1..3208ae3 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -72,7 +72,6 @@
     private boolean mAodShowing;
     private boolean mKeyguardGoingAway;
     private boolean mDismissalRequested;
-    private int mBeforeUnoccludeTransit;
     private final SparseArray<KeyguardDisplayState> mDisplayStates = new SparseArray<>();
     private final ActivityTaskManagerService mService;
     private RootWindowContainer mRootWindowContainer;
@@ -191,14 +190,11 @@
             // Irrelevant to AOD.
             dismissMultiWindowModeForTaskIfNeeded(null /* currentTaskControllsingOcclusion */,
                     false /* turningScreenOn */);
-            setKeyguardGoingAway(false);
+            mKeyguardGoingAway = false;
             if (keyguardShowing) {
                 mDismissalRequested = false;
             }
         }
-        // TODO(b/113840485): Check usage for non-default display
-        mWindowManager.setKeyguardOrAodShowingOnDefaultDisplay(
-                isKeyguardOrAodShowing(DEFAULT_DISPLAY));
 
         // Update the sleep token first such that ensureActivitiesVisible has correct sleep token
         // state when evaluating visibilities.
@@ -219,8 +215,8 @@
         }
         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "keyguardGoingAway");
         mService.deferWindowLayout();
+        mKeyguardGoingAway = true;
         try {
-            setKeyguardGoingAway(true);
             EventLogTags.writeWmSetKeyguardShown(
                     1 /* keyguardShowing */,
                     mAodShowing ? 1 : 0,
@@ -258,11 +254,6 @@
         mWindowManager.dismissKeyguard(callback, message);
     }
 
-    private void setKeyguardGoingAway(boolean keyguardGoingAway) {
-        mKeyguardGoingAway = keyguardGoingAway;
-        mWindowManager.setKeyguardGoingAway(keyguardGoingAway);
-    }
-
     private void failCallback(IKeyguardDismissCallback callback) {
         try {
             callback.onDismissError();
diff --git a/services/core/java/com/android/server/wm/SplashScreenExceptionList.java b/services/core/java/com/android/server/wm/SplashScreenExceptionList.java
new file mode 100644
index 0000000..e815a0e
--- /dev/null
+++ b/services/core/java/com/android/server/wm/SplashScreenExceptionList.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.provider.DeviceConfig.NAMESPACE_WINDOW_MANAGER;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.pm.ApplicationInfo;
+import android.os.Build;
+import android.provider.DeviceConfig;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.concurrent.Executor;
+import java.util.function.Supplier;
+
+/**
+ * Handles filtering the list of package that don't use the system splash screen.
+ * The list is backed by a {@link DeviceConfig} property.
+ * <p>
+ * An application can manually opt-out of the exception list by setting the &lt;meta-data
+ * {@value OPT_OUT_METADATA_FLAG}="true"/&gt; in the <code>&lt;application&gt;</code> section of the
+ * manifest.
+ */
+class SplashScreenExceptionList {
+
+    private static final boolean DEBUG = Build.isDebuggable();
+    private static final String LOG_TAG = "SplashScreenExceptionList";
+    private static final String KEY_SPLASH_SCREEN_EXCEPTION_LIST = "splash_screen_exception_list";
+    private static final String NAMESPACE = NAMESPACE_WINDOW_MANAGER;
+    private static final String OPT_OUT_METADATA_FLAG = "android.splashscreen.exception_opt_out";
+
+    @GuardedBy("mLock")
+    private final HashSet<String> mDeviceConfigExcludedPackages = new HashSet<>();
+    private final Object mLock = new Object();
+
+    @VisibleForTesting
+    final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener;
+
+    SplashScreenExceptionList(@NonNull Executor executor) {
+        updateDeviceConfig(DeviceConfig.getString(NAMESPACE, KEY_SPLASH_SCREEN_EXCEPTION_LIST, ""));
+        mOnPropertiesChangedListener = properties -> updateDeviceConfig(
+                properties.getString(KEY_SPLASH_SCREEN_EXCEPTION_LIST, ""));
+        DeviceConfig.addOnPropertiesChangedListener(NAMESPACE, executor,
+                mOnPropertiesChangedListener);
+    }
+
+    private void updateDeviceConfig(String values) {
+        parseDeviceConfigPackageList(values);
+    }
+
+    /**
+     * Returns true if the packageName is in the list and the target sdk is before S.
+     *
+     * @param packageName  The package name of the application to check
+     * @param targetSdk    The target sdk of the application
+     * @param infoSupplier A {@link Supplier} that returns an {@link ApplicationInfo} used to
+     *                     check if the application wants to opt-out of the exception list in the
+     *                     manifest metadata. Evaluated only if the application is in the exception
+     *                     list.
+     */
+    @SuppressWarnings("AndroidFrameworkCompatChange") // Target sdk check
+    public boolean isException(@NonNull String packageName, int targetSdk,
+            @Nullable Supplier<ApplicationInfo> infoSupplier) {
+        if (targetSdk >= Build.VERSION_CODES.S) {
+            return false;
+        }
+
+        synchronized (mLock) {
+            if (DEBUG) {
+                Slog.v(LOG_TAG, String.format(Locale.US,
+                        "SplashScreen checking exception for package %s (target sdk:%d) -> %s",
+                        packageName, targetSdk,
+                        mDeviceConfigExcludedPackages.contains(packageName)));
+            }
+            if (!mDeviceConfigExcludedPackages.contains(packageName)) {
+                return false;
+            }
+        }
+        return !isOptedOut(infoSupplier);
+    }
+
+    /**
+     * An application can manually opt-out of the exception list by setting the meta-data
+     * {@value OPT_OUT_METADATA_FLAG} = true in the <code>application</code> section of the manifest
+     */
+    private static boolean isOptedOut(@Nullable Supplier<ApplicationInfo> infoProvider) {
+        if (infoProvider == null) {
+            return false;
+        }
+        ApplicationInfo info = infoProvider.get();
+        return info != null && info.metaData != null && info.metaData.getBoolean(
+                OPT_OUT_METADATA_FLAG, false);
+    }
+
+    private void parseDeviceConfigPackageList(String rawList) {
+        synchronized (mLock) {
+            mDeviceConfigExcludedPackages.clear();
+            String[] packages = rawList.split(",");
+            for (String packageName : packages) {
+                String packageNameTrimmed = packageName.trim();
+                if (!packageNameTrimmed.isEmpty()) {
+                    mDeviceConfigExcludedPackages.add(packageNameTrimmed);
+                }
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/wm/StartingSurfaceController.java b/services/core/java/com/android/server/wm/StartingSurfaceController.java
index 39ff940..da25747 100644
--- a/services/core/java/com/android/server/wm/StartingSurfaceController.java
+++ b/services/core/java/com/android/server/wm/StartingSurfaceController.java
@@ -26,6 +26,9 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.pm.ApplicationInfo;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.os.SystemProperties;
@@ -34,6 +37,8 @@
 
 import com.android.server.policy.WindowManagerPolicy.StartingSurface;
 
+import java.util.function.Supplier;
+
 /**
  * Managing to create and release a starting window surface.
  */
@@ -44,9 +49,11 @@
     static final boolean DEBUG_ENABLE_SHELL_DRAWER =
             SystemProperties.getBoolean("persist.debug.shell_starting_surface", true);
     private final WindowManagerService mService;
+    private final SplashScreenExceptionList mSplashScreenExceptionsList;
 
     public StartingSurfaceController(WindowManagerService wm) {
         mService = wm;
+        mSplashScreenExceptionsList = new SplashScreenExceptionList(wm.mContext.getMainExecutor());
     }
 
     StartingSurface createSplashScreenStartingSurface(ActivityRecord activity, String packageName,
@@ -68,6 +75,14 @@
         return null;
     }
 
+    /**
+     * @see SplashScreenExceptionList#isException(String, int, Supplier)
+     */
+    boolean isExceptionApp(@NonNull String packageName, int targetSdk,
+            @Nullable Supplier<ApplicationInfo> infoProvider) {
+        return mSplashScreenExceptionsList.isException(packageName, targetSdk, infoProvider);
+    }
+
     int makeStartingWindowTypeParameter(boolean newTask, boolean taskSwitch,
             boolean processRunning, boolean allowTaskSnapshot, boolean activityCreated,
             boolean useEmpty) {
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index 0000f95..e743710 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -644,7 +644,7 @@
 
     /** Called when the device is going to sleep (e.g. screen off, AOD without screen off). */
     void snapshotForSleeping(int displayId) {
-        if (shouldDisableSnapshots()) {
+        if (shouldDisableSnapshots() || !mService.mDisplayEnabled) {
             return;
         }
         final DisplayContent displayContent = mService.mRoot.getDisplayContent(displayId);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 147260b..1075806 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -483,10 +483,7 @@
     private final DisplayAreaPolicy.Provider mDisplayAreaPolicyProvider;
 
     final private KeyguardDisableHandler mKeyguardDisableHandler;
-    // TODO: eventually unify all keyguard state in a common place instead of having it spread over
-    // AM's KeyguardController and the policy's KeyguardServiceDelegate.
-    boolean mKeyguardGoingAway;
-    boolean mKeyguardOrAodShowingOnDefaultDisplay;
+
     // VR Vr2d Display Id.
     int mVr2dDisplayId = INVALID_DISPLAY;
     boolean mVrModeEnabled = false;
@@ -3072,17 +3069,6 @@
         mAtmInternal.notifyKeyguardFlagsChanged(callback, displayId);
     }
 
-    public void setKeyguardGoingAway(boolean keyguardGoingAway) {
-        synchronized (mGlobalLock) {
-            mKeyguardGoingAway = keyguardGoingAway;
-        }
-    }
-
-    public void setKeyguardOrAodShowingOnDefaultDisplay(boolean showing) {
-        synchronized (mGlobalLock) {
-            mKeyguardOrAodShowingOnDefaultDisplay = showing;
-        }
-    }
 
     // -------------------------------------------------------------
     // Misc IWindowSession methods
diff --git a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/BootTest.kt b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/BootTest.kt
new file mode 100644
index 0000000..7fb4907
--- /dev/null
+++ b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/BootTest.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm.test
+
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test
+import com.google.common.truth.Truth
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TemporaryFolder
+import org.junit.runner.RunWith
+
+@RunWith(DeviceJUnit4ClassRunner::class)
+class BootTest : BaseHostJUnit4Test() {
+    companion object {
+        private const val TEST_PKG_NAME = "com.android.server.pm.test.test_app"
+        private const val TEST_APK_NAME = "PackageManagerTestAppStub.apk"
+    }
+
+    @Rule
+    @JvmField
+    val tempFolder = TemporaryFolder()
+
+    @Before
+    fun installApk() {
+        val testApkFile = HostUtils.copyResourceToHostFile(TEST_APK_NAME, tempFolder.newFile())
+        device.installPackage(testApkFile, true)
+    }
+
+    @After
+    fun removeApk() {
+        device.uninstallPackage(TEST_PKG_NAME)
+    }
+
+    @Test
+    fun testUninstallPackageWithKeepDataAndReboot() {
+        Truth.assertThat(isPackageInstalled(TEST_PKG_NAME)).isTrue()
+        uninstallPackageWithKeepData(TEST_PKG_NAME)
+        Truth.assertThat(isPackageInstalled(TEST_PKG_NAME)).isFalse()
+        device.rebootUntilOnline()
+        waitForBootCompleted()
+    }
+
+    private fun uninstallPackageWithKeepData(packageName: String) {
+        device.executeShellCommand("pm uninstall -k $packageName")
+    }
+
+    private fun waitForBootCompleted() {
+        for (i in 0 until 45) {
+            if (isBootCompleted()) {
+                return
+            }
+            Thread.sleep(1000)
+        }
+        throw AssertionError("System failed to become ready!")
+    }
+
+    private fun isBootCompleted(): Boolean {
+        return "1" == device.executeShellCommand("getprop sys.boot_completed").trim()
+    }
+}
\ No newline at end of file
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index eab1afb..583797e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -1910,17 +1910,6 @@
         assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
     }
 
-    @Test
-    public void hasScheduleExactAlarmBinderCallChangeDisabled() throws RemoteException {
-        mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false);
-
-        mockExactAlarmPermissionGrant(false, true, MODE_DEFAULT);
-        assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
-
-        mockExactAlarmPermissionGrant(true, false, MODE_ERRORED);
-        assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
-    }
-
     private void mockChangeEnabled(long changeId, boolean enabled) {
         doReturn(enabled).when(() -> CompatChanges.isChangeEnabled(eq(changeId), anyString(),
                 any(UserHandle.class)));
@@ -1941,6 +1930,53 @@
     }
 
     @Test
+    public void canScheduleExactAlarmsBinderCallChangeDisabled() throws RemoteException {
+        mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false);
+
+        mockExactAlarmPermissionGrant(false, true, MODE_DEFAULT);
+        assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
+
+        mockExactAlarmPermissionGrant(true, false, MODE_ERRORED);
+        assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
+    }
+
+    @Test
+    public void canScheduleExactAlarmsBinderCall() throws RemoteException {
+        mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
+
+        // No permission, no exemption.
+        mockExactAlarmPermissionGrant(true, true, MODE_DEFAULT);
+        assertFalse(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
+
+        // No permission, no exemption.
+        mockExactAlarmPermissionGrant(true, false, MODE_ERRORED);
+        assertFalse(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
+
+        // Permission, no exemption.
+        mockExactAlarmPermissionGrant(true, false, MODE_DEFAULT);
+        assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
+
+        // Permission, no exemption.
+        mockExactAlarmPermissionGrant(true, true, MODE_ALLOWED);
+        assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
+
+        // No permission, exemption.
+        mockExactAlarmPermissionGrant(true, false, MODE_ERRORED);
+        when(mDeviceIdleInternal.isAppOnWhitelist(TEST_CALLING_UID)).thenReturn(true);
+        assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
+
+        // No permission, exemption.
+        mockExactAlarmPermissionGrant(true, false, MODE_ERRORED);
+        when(mDeviceIdleInternal.isAppOnWhitelist(TEST_CALLING_UID)).thenReturn(false);
+        doReturn(true).when(() -> UserHandle.isCore(TEST_CALLING_UID));
+        assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
+
+        // Both permission and exemption.
+        mockExactAlarmPermissionGrant(true, false, MODE_ALLOWED);
+        assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
+    }
+
+    @Test
     public void noPermissionCheckWhenChangeDisabled() throws RemoteException {
         mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false);
 
@@ -2086,14 +2122,17 @@
 
         final PendingIntent alarmPi = getNewMockPendingIntent();
         final AlarmManager.AlarmClockInfo alarmClock = mock(AlarmManager.AlarmClockInfo.class);
-        try {
-            mBinder.set(TEST_CALLING_PACKAGE, RTC_WAKEUP, 1234, WINDOW_EXACT, 0, 0,
+        mBinder.set(TEST_CALLING_PACKAGE, RTC_WAKEUP, 1234, WINDOW_EXACT, 0, 0,
                     alarmPi, null, null, null, alarmClock);
-            fail("alarm clock binder call succeeded without permission");
-        } catch (SecurityException se) {
-            // Expected.
-        }
-        verify(mDeviceIdleInternal, never()).isAppOnWhitelist(anyInt());
+
+        // Correct permission checks are invoked.
+        verify(mService).hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID);
+        verify(mDeviceIdleInternal).isAppOnWhitelist(UserHandle.getAppId(TEST_CALLING_UID));
+
+        verify(mService).setImpl(eq(RTC_WAKEUP), eq(1234L), eq(WINDOW_EXACT), eq(0L),
+                eq(alarmPi), isNull(), isNull(), eq(FLAG_STANDALONE | FLAG_WAKE_FROM_IDLE),
+                isNull(), eq(alarmClock), eq(TEST_CALLING_UID), eq(TEST_CALLING_PACKAGE),
+                isNull(), eq(EXACT_ALLOW_REASON_ALLOW_LIST));
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
index dc745cd..67dd055 100644
--- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
@@ -83,17 +83,9 @@
     private static final int DUMMY_OVERLAY_APPID = 10756;
     private static final int SYSTEM_USER = 0;
     private static final int SECONDARY_USER = 10;
-    private static final int ADDED_USER = 11;
     private static final int[] USER_ARRAY = {SYSTEM_USER, SECONDARY_USER};
-    private static final int[] USER_ARRAY_WITH_ADDED = {SYSTEM_USER, SECONDARY_USER, ADDED_USER};
-    private static final UserInfo[] USER_INFO_LIST = toUserInfos(USER_ARRAY);
-    private static final UserInfo[] USER_INFO_LIST_WITH_ADDED = toUserInfos(USER_ARRAY_WITH_ADDED);
-
-    private static UserInfo[] toUserInfos(int[] userIds) {
-        return Arrays.stream(userIds)
-                .mapToObj(id -> new UserInfo(id, Integer.toString(id), 0))
-                .toArray(UserInfo[]::new);
-    }
+    private static final UserInfo[] USER_INFO_LIST = Arrays.stream(USER_ARRAY).mapToObj(
+            id -> new UserInfo(id, Integer.toString(id), 0)).toArray(UserInfo[]::new);
 
     @Mock
     AppsFilter.FeatureConfig mFeatureConfigMock;
@@ -327,47 +319,6 @@
     }
 
     @Test
-    public void testOnUserCreated_FilterMatches() throws Exception {
-        final AppsFilter appsFilter =
-                new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
-                        mMockExecutor);
-        simulateAddBasicAndroid(appsFilter);
-
-        appsFilter.onSystemReady();
-
-        PackageSetting target = simulateAddPackage(appsFilter,
-                pkgWithProvider("com.some.package", "com.some.authority"), DUMMY_TARGET_APPID);
-        PackageSetting calling = simulateAddPackage(appsFilter,
-                pkgQueriesProvider("com.some.other.package", "com.some.authority"),
-                DUMMY_CALLING_APPID);
-
-        for (int subjectUserId : USER_ARRAY) {
-            for (int otherUserId : USER_ARRAY) {
-                assertFalse(appsFilter.shouldFilterApplication(
-                        UserHandle.getUid(DUMMY_CALLING_APPID, subjectUserId), calling, target,
-                        otherUserId));
-            }
-        }
-
-        // adds new user
-        doAnswer(invocation -> {
-            ((AppsFilter.StateProvider.CurrentStateCallback) invocation.getArgument(0))
-                    .currentState(mExisting, USER_INFO_LIST_WITH_ADDED);
-            return new Object();
-        }).when(mStateProvider)
-                .runWithState(any(AppsFilter.StateProvider.CurrentStateCallback.class));
-        appsFilter.onUserCreated(ADDED_USER);
-
-        for (int subjectUserId : USER_ARRAY_WITH_ADDED) {
-            for (int otherUserId : USER_ARRAY_WITH_ADDED) {
-                assertFalse(appsFilter.shouldFilterApplication(
-                        UserHandle.getUid(DUMMY_CALLING_APPID, subjectUserId), calling, target,
-                        otherUserId));
-            }
-        }
-    }
-
-    @Test
     public void testQueriesDifferentProvider_Filters() throws Exception {
         final AppsFilter appsFilter =
                 new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null,
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/DeviceVibrationEffectAdapterTest.java b/services/tests/servicestests/src/com/android/server/vibrator/DeviceVibrationEffectAdapterTest.java
index 14cab02..b934ecb 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/DeviceVibrationEffectAdapterTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/DeviceVibrationEffectAdapterTest.java
@@ -20,8 +20,10 @@
 import static org.junit.Assert.assertTrue;
 
 import android.hardware.vibrator.IVibrator;
+import android.os.Handler;
 import android.os.VibrationEffect;
 import android.os.VibratorInfo;
+import android.os.test.TestLooper;
 import android.os.vibrator.PrebakedSegment;
 import android.os.vibrator.PrimitiveSegment;
 import android.os.vibrator.RampSegment;
@@ -62,7 +64,9 @@
 
     @Before
     public void setUp() throws Exception {
-        mAdapter = new DeviceVibrationEffectAdapter(InstrumentationRegistry.getContext());
+        VibrationSettings vibrationSettings = new VibrationSettings(
+                InstrumentationRegistry.getContext(), new Handler(new TestLooper().getLooper()));
+        mAdapter = new DeviceVibrationEffectAdapter(vibrationSettings);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/RampDownAdapterTest.java b/services/tests/servicestests/src/com/android/server/vibrator/RampDownAdapterTest.java
new file mode 100644
index 0000000..b90df21
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/vibrator/RampDownAdapterTest.java
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vibrator;
+
+import static org.junit.Assert.assertEquals;
+
+import android.os.VibrationEffect;
+import android.os.VibratorInfo;
+import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.PrimitiveSegment;
+import android.os.vibrator.RampSegment;
+import android.os.vibrator.StepSegment;
+import android.os.vibrator.VibrationEffectSegment;
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Tests for {@link RampDownAdapter}.
+ *
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:RampDownAdapterTest
+ */
+@Presubmit
+public class RampDownAdapterTest {
+    private static final int TEST_RAMP_DOWN_DURATION = 20;
+    private static final int TEST_STEP_DURATION = 5;
+    private static final VibratorInfo TEST_VIBRATOR_INFO = new VibratorInfo.Builder(0).build();
+
+    private RampDownAdapter mAdapter;
+
+    @Before
+    public void setUp() throws Exception {
+        mAdapter = new RampDownAdapter(TEST_RAMP_DOWN_DURATION, TEST_STEP_DURATION);
+    }
+
+    @Test
+    public void testPrebakedAndPrimitiveSegments_keepsListUnchanged() {
+        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+                new PrebakedSegment(
+                        VibrationEffect.EFFECT_CLICK, false, VibrationEffect.EFFECT_STRENGTH_LIGHT),
+                new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_TICK, 1, 10)));
+        List<VibrationEffectSegment> originalSegments = new ArrayList<>(segments);
+
+        assertEquals(-1, mAdapter.apply(segments, -1, TEST_VIBRATOR_INFO));
+        assertEquals(1, mAdapter.apply(segments, 1, TEST_VIBRATOR_INFO));
+
+        assertEquals(originalSegments, segments);
+    }
+
+    @Test
+    public void testRampAndStepSegments_withNoOffSegment_keepsListUnchanged() {
+        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+                new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 100),
+                new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.2f,
+                        /* startFrequency= */ 10, /* endFrequency= */ -5, /* duration= */ 20)));
+        List<VibrationEffectSegment> originalSegments = new ArrayList<>(segments);
+
+        assertEquals(-1, mAdapter.apply(segments, -1, TEST_VIBRATOR_INFO));
+        assertEquals(0, mAdapter.apply(segments, 0, TEST_VIBRATOR_INFO));
+
+        assertEquals(originalSegments, segments);
+    }
+
+    @Test
+    public void testRampAndStepSegments_withNoRampDownDuration_keepsOriginalSteps() {
+        mAdapter = new RampDownAdapter(/* rampDownDuration= */ 0, TEST_STEP_DURATION);
+
+        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+                new StepSegment(/* amplitude= */ 1, /* frequency= */ 0, /* duration= */ 10),
+                new StepSegment(/* amplitude= */ 0, /* frequency= */ 0, /* duration= */ 100),
+                new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.2f,
+                        /* startFrequency= */ 10, /* endFrequency= */ -5, /* duration= */ 20),
+                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude= */ 0,
+                        /* startFrequency= */ 0, /* endFrequency= */ 0, /* duration= */ 50)));
+        List<VibrationEffectSegment> originalSegments = new ArrayList<>(segments);
+
+        assertEquals(-1, mAdapter.apply(segments, -1, TEST_VIBRATOR_INFO));
+        assertEquals(2, mAdapter.apply(segments, 2, TEST_VIBRATOR_INFO));
+        assertEquals(originalSegments, segments);
+    }
+
+    @Test
+    public void testStepSegments_withShortZeroSegment_replaceWithStepsDown() {
+        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+                new StepSegment(/* amplitude= */ 1, /* frequency= */ 0, /* duration= */ 10),
+                new StepSegment(/* amplitude= */ 0, /* frequency= */ 0, /* duration= */ 10),
+                new StepSegment(/* amplitude= */ 0.8f, /* frequency= */ 0, /* duration= */ 100)));
+        List<VibrationEffectSegment> expectedSegments = Arrays.asList(
+                new StepSegment(/* amplitude= */ 1, /* frequency= */ 0, /* duration= */ 10),
+                new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 5),
+                new StepSegment(/* amplitude= */ 0, /* frequency= */ 0, /* duration= */ 5),
+                new StepSegment(/* amplitude= */ 0.8f, /* frequency= */ 0, /* duration= */ 100));
+
+        assertEquals(1, mAdapter.apply(segments, 1, TEST_VIBRATOR_INFO));
+
+        assertEquals(expectedSegments, segments);
+    }
+
+    @Test
+    public void testStepSegments_withLongZeroSegment_replaceWithStepsDown() {
+        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+                new StepSegment(/* amplitude= */ 1, /* frequency= */ 0, /* duration= */ 10),
+                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude= */ 0,
+                        /* startFrequency= */ 0, /* endFrequency= */ 0, /* duration= */ 50),
+                new StepSegment(/* amplitude= */ 0.8f, /* frequency= */ 0, /* duration= */ 100)));
+        List<VibrationEffectSegment> expectedSegments = Arrays.asList(
+                new StepSegment(/* amplitude= */ 1, /* frequency= */ 0, /* duration= */ 10),
+                new StepSegment(/* amplitude= */ 0.75f, /* frequency= */ 0, /* duration= */ 5),
+                new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 5),
+                new StepSegment(/* amplitude= */ 0.25f, /* frequency= */ 0, /* duration= */ 5),
+                new StepSegment(/* amplitude= */ 0, /* frequency= */ 0, /* duration= */ 35),
+                new StepSegment(/* amplitude= */ 0.8f, /* frequency= */ 0, /* duration= */ 100));
+
+        // Repeat index fixed after intermediate steps added
+        assertEquals(5, mAdapter.apply(segments, 2, TEST_VIBRATOR_INFO));
+
+        assertEquals(expectedSegments, segments);
+    }
+
+    @Test
+    public void testStepSegments_withRepeatToNonZeroSegment_keepsOriginalSteps() {
+        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+                new StepSegment(/* amplitude= */ 0.8f, /* frequency= */ 0, /* duration= */ 10),
+                new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 100)));
+        List<VibrationEffectSegment> originalSegments = new ArrayList<>(segments);
+
+        assertEquals(0, mAdapter.apply(segments, 0, TEST_VIBRATOR_INFO));
+
+        assertEquals(originalSegments, segments);
+    }
+
+    @Test
+    public void testStepSegments_withRepeatToShortZeroSegment_skipAndAppendRampDown() {
+        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude= */ 0,
+                        /* startFrequency= */ 0, /* endFrequency= */ 0, /* duration= */ 10),
+                new StepSegment(/* amplitude= */ 1, /* frequency= */ 0, /* duration= */ 30)));
+        List<VibrationEffectSegment> expectedSegments = Arrays.asList(
+                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude= */ 0,
+                        /* startFrequency= */ 0, /* endFrequency= */ 0, /* duration= */ 10),
+                new StepSegment(/* amplitude= */ 1, /* frequency= */ 0, /* duration= */ 30),
+                new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 5),
+                new StepSegment(/* amplitude= */ 0, /* frequency= */ 0, /* duration= */ 5));
+
+        // Shift repeat index to the right to use append instead of zero segment.
+        assertEquals(1, mAdapter.apply(segments, 0, TEST_VIBRATOR_INFO));
+
+        assertEquals(expectedSegments, segments);
+    }
+
+    @Test
+    public void testStepSegments_withRepeatToLongZeroSegment_splitAndAppendRampDown() {
+        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+                new StepSegment(/* amplitude= */ 0, /* frequency= */ 0, /* duration= */ 120),
+                new StepSegment(/* amplitude= */ 1, /* frequency= */ 0, /* duration= */ 30)));
+        List<VibrationEffectSegment> expectedSegments = Arrays.asList(
+                // Split long zero segment to skip part of it.
+                new StepSegment(/* amplitude= */ 0, /* frequency= */ 0, /* duration= */ 20),
+                new StepSegment(/* amplitude= */ 0, /* frequency= */ 0, /* duration= */ 100),
+                new StepSegment(/* amplitude= */ 1, /* frequency= */ 0, /* duration= */ 30),
+                new StepSegment(/* amplitude= */ 0.75f, /* frequency= */ 0, /* duration= */ 5),
+                new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 5),
+                new StepSegment(/* amplitude= */ 0.25f, /* frequency= */ 0, /* duration= */ 5),
+                new StepSegment(/* amplitude= */ 0, /* frequency= */ 0, /* duration= */ 5));
+
+        // Shift repeat index to the right to use append with part of the zero segment.
+        assertEquals(1, mAdapter.apply(segments, 0, TEST_VIBRATOR_INFO));
+
+        assertEquals(expectedSegments, segments);
+    }
+
+    @Test
+    public void testRampSegments_withShortZeroSegment_replaceWithRampDown() {
+        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+                new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude*/ 0.5f,
+                        /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 10),
+                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude= */ 0,
+                        /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 20),
+                new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
+                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 30)));
+        List<VibrationEffectSegment> expectedSegments = Arrays.asList(
+                new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude*/ 0.5f,
+                        /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 10),
+                new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude= */ 0,
+                        /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 20),
+                new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
+                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 30));
+
+        assertEquals(2, mAdapter.apply(segments, 2, TEST_VIBRATOR_INFO));
+
+        assertEquals(expectedSegments, segments);
+    }
+
+    @Test
+    public void testRampSegments_withLongZeroSegment_splitAndAddRampDown() {
+        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+                new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude*/ 0.5f,
+                        /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 10),
+                new StepSegment(/* amplitude= */ 0, /* frequency= */ 0, /* duration= */ 150),
+                new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
+                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 30)));
+        List<VibrationEffectSegment> expectedSegments = Arrays.asList(
+                new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude*/ 0.5f,
+                        /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 10),
+                new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude= */ 0,
+                        /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 20),
+                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude= */ 0,
+                        /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 130),
+                new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
+                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 30));
+
+        // Repeat index fixed after intermediate steps added
+        assertEquals(3, mAdapter.apply(segments, 2, TEST_VIBRATOR_INFO));
+
+        assertEquals(expectedSegments, segments);
+    }
+
+    @Test
+    public void testRampSegments_withRepeatToNonZeroSegment_keepsOriginalSteps() {
+        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+                new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude*/ 0.5f,
+                        /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 10),
+                new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
+                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 30)));
+        List<VibrationEffectSegment> originalSegments = new ArrayList<>(segments);
+
+        assertEquals(0, mAdapter.apply(segments, 0, TEST_VIBRATOR_INFO));
+
+        assertEquals(originalSegments, segments);
+    }
+
+    @Test
+    public void testRampSegments_withRepeatToShortZeroSegment_skipAndAppendRampDown() {
+        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+                new StepSegment(/* amplitude= */ 0, /* frequency= */ 1, /* duration= */ 20),
+                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude*/ 1,
+                        /* startFrequency= */ 0, /* endFrequency= */ 1, /* duration= */ 20)));
+        List<VibrationEffectSegment> expectedSegments = Arrays.asList(
+                new StepSegment(/* amplitude= */ 0, /* frequency= */ 1, /* duration= */ 20),
+                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude= */ 1,
+                        /* startFrequency= */ 0, /* endFrequency= */ 1, /* duration= */ 20),
+                new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 0,
+                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 20));
+
+        // Shift repeat index to the right to use append instead of zero segment.
+        assertEquals(1, mAdapter.apply(segments, 0, TEST_VIBRATOR_INFO));
+
+        assertEquals(expectedSegments, segments);
+    }
+
+    @Test
+    public void testRampSegments_withRepeatToLongZeroSegment_splitAndAppendRampDown() {
+        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
+                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude*/ 0,
+                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 70),
+                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude= */ 1,
+                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 30)));
+        List<VibrationEffectSegment> expectedSegments = Arrays.asList(
+                // Split long zero segment to skip part of it.
+                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude*/ 0,
+                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 20),
+                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude*/ 0,
+                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 50),
+                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude= */ 1,
+                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 30),
+                new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 0,
+                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 20));
+
+        // Shift repeat index to the right to use append with part of the zero segment.
+        assertEquals(1, mAdapter.apply(segments, 0, TEST_VIBRATOR_INFO));
+
+        assertEquals(expectedSegments, segments);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/StepToRampAdapterTest.java b/services/tests/servicestests/src/com/android/server/vibrator/StepToRampAdapterTest.java
index 32988ef..128cd2f 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/StepToRampAdapterTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/StepToRampAdapterTest.java
@@ -48,7 +48,7 @@
 
     @Before
     public void setUp() throws Exception {
-        mAdapter = new StepToRampAdapter(/* rampDownDuration= */ 0);
+        mAdapter = new StepToRampAdapter();
     }
 
     @Test
@@ -101,8 +101,6 @@
 
     @Test
     public void testStepAndRampSegments_withoutPwleCapability_keepsListUnchanged() {
-        mAdapter = new StepToRampAdapter(50);
-
         List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
                 new StepSegment(/* amplitude= */ 0, /* frequency= */ 1, /* duration= */ 10),
                 new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.2f,
@@ -182,160 +180,6 @@
         assertEquals(expectedSegments, segments);
     }
 
-    @Test
-    public void testStepSegments_withRampDownEndingAtNonZero_noRampDownAdded() {
-        int rampDownDuration = 50;
-        mAdapter = new StepToRampAdapter(rampDownDuration);
-
-        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
-                new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 10),
-                new StepSegment(/* amplitude= */ 0.8f, /* frequency= */ 1, /* duration= */ 100)));
-        List<VibrationEffectSegment> expectedSegments = Arrays.asList(
-                new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude*/ 0.5f,
-                        /* startFrequency= */ 0, /* endFrequency= */ 0, /* duration= */ 10),
-                new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.8f,
-                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 100));
-
-        VibratorInfo vibratorInfo = createVibratorInfo(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
-        assertEquals(-1, mAdapter.apply(segments, -1, vibratorInfo));
-
-        assertEquals(expectedSegments, segments);
-    }
-
-    @Test
-    public void testStepSegments_withRampDownAndShortZeroSegment_replaceWithRampDown() {
-        mAdapter = new StepToRampAdapter(50);
-
-        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
-                new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ -1, /* duration= */ 10),
-                new StepSegment(/* amplitude= */ 0, /* frequency= */ 0, /* duration= */ 20),
-                new StepSegment(/* amplitude= */ 1, /* frequency= */ 1, /* duration= */ 30)));
-        List<VibrationEffectSegment> expectedSegments = Arrays.asList(
-                new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude*/ 0.5f,
-                        /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 10),
-                new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude= */ 0,
-                        /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 20),
-                new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
-                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 30));
-
-        VibratorInfo vibratorInfo = createVibratorInfo(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
-        assertEquals(2, mAdapter.apply(segments, 2, vibratorInfo));
-
-        assertEquals(expectedSegments, segments);
-    }
-
-    @Test
-    public void testStepSegments_withRampDownAndLongZeroSegment_splitAndAddRampDown() {
-        mAdapter = new StepToRampAdapter(50);
-
-        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
-                new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ -1, /* duration= */ 10),
-                new StepSegment(/* amplitude= */ 0, /* frequency= */ 1, /* duration= */ 150),
-                new StepSegment(/* amplitude= */ 1, /* frequency= */ 1, /* duration= */ 30)));
-        List<VibrationEffectSegment> expectedSegments = Arrays.asList(
-                new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude*/ 0.5f,
-                        /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 10),
-                new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude= */ 0,
-                        /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 50),
-                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude= */ 0,
-                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 100),
-                new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
-                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 30));
-
-        VibratorInfo vibratorInfo = createVibratorInfo(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
-        // Repeat index fixed after intermediate steps added
-        assertEquals(3, mAdapter.apply(segments, 2, vibratorInfo));
-
-        assertEquals(expectedSegments, segments);
-    }
-
-    @Test
-    public void testStepSegments_withRampDownAndNoZeroSegment_noRampDownAdded() {
-        mAdapter = new StepToRampAdapter(50);
-
-        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
-                new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ -1, /* duration= */ 10),
-                new StepSegment(/* amplitude= */ 1, /* frequency= */ 1, /* duration= */ 30),
-                new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_TICK, 1, 10)));
-        List<VibrationEffectSegment> expectedSegments = Arrays.asList(
-                new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude*/ 0.5f,
-                        /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 10),
-                new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
-                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 30),
-                new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_TICK, 1, 10));
-
-        VibratorInfo vibratorInfo = createVibratorInfo(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
-        assertEquals(-1, mAdapter.apply(segments, -1, vibratorInfo));
-
-        assertEquals(expectedSegments, segments);
-    }
-
-    @Test
-    public void testStepSegments_withRampDownAndRepeatToNonZeroSegment_noRampDownAdded() {
-        mAdapter = new StepToRampAdapter(50);
-
-        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
-                new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ -1, /* duration= */ 10),
-                new StepSegment(/* amplitude= */ 1, /* frequency= */ 1, /* duration= */ 30)));
-        List<VibrationEffectSegment> expectedSegments = Arrays.asList(
-                new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude*/ 0.5f,
-                        /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 10),
-                new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
-                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 30));
-
-        VibratorInfo vibratorInfo = createVibratorInfo(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
-        assertEquals(0, mAdapter.apply(segments, 0, vibratorInfo));
-
-        assertEquals(expectedSegments, segments);
-    }
-
-    @Test
-    public void testStepSegments_withRampDownAndRepeatToShortZeroSegment_skipAndAppendRampDown() {
-        mAdapter = new StepToRampAdapter(50);
-
-        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
-                new StepSegment(/* amplitude= */ 0, /* frequency= */ 1, /* duration= */ 20),
-                new StepSegment(/* amplitude= */ 1, /* frequency= */ 1, /* duration= */ 30)));
-        List<VibrationEffectSegment> expectedSegments = Arrays.asList(
-                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude*/ 0,
-                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 20),
-                new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
-                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 30),
-                new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 0,
-                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 20));
-
-        VibratorInfo vibratorInfo = createVibratorInfo(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
-        // Shift repeat index to the right to use append instead of zero segment.
-        assertEquals(1, mAdapter.apply(segments, 0, vibratorInfo));
-
-        assertEquals(expectedSegments, segments);
-    }
-
-    @Test
-    public void testStepSegments_withRampDownAndRepeatToLongZeroSegment_splitAndAppendRampDown() {
-        mAdapter = new StepToRampAdapter(50);
-
-        List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList(
-                new StepSegment(/* amplitude= */ 0, /* frequency= */ 1, /* duration= */ 120),
-                new StepSegment(/* amplitude= */ 1, /* frequency= */ 1, /* duration= */ 30)));
-        List<VibrationEffectSegment> expectedSegments = Arrays.asList(
-                // Split long zero segment to skip part of it.
-                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude*/ 0,
-                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 50),
-                new RampSegment(/* startAmplitude= */ 0, /* endAmplitude*/ 0,
-                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 70),
-                new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 1,
-                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 30),
-                new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 0,
-                        /* startFrequency= */ 1, /* endFrequency= */ 1, /* duration= */ 50));
-
-        VibratorInfo vibratorInfo = createVibratorInfo(IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
-        // Shift repeat index to the right to use append with part of the zero segment.
-        assertEquals(1, mAdapter.apply(segments, 0, vibratorInfo));
-
-        assertEquals(expectedSegments, segments);
-    }
-
     private static VibratorInfo createVibratorInfo(int... capabilities) {
         return new VibratorInfo.Builder(0)
                 .setCapabilities(IntStream.of(capabilities).reduce((a, b) -> a | b).orElse(0))
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
index b8fdb55..6d25e8c 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
@@ -36,6 +36,7 @@
 import android.hardware.vibrator.IVibrator;
 import android.hardware.vibrator.IVibratorManager;
 import android.os.CombinedVibration;
+import android.os.Handler;
 import android.os.IBinder;
 import android.os.PowerManager;
 import android.os.Process;
@@ -108,7 +109,9 @@
         mTestLooper = new TestLooper();
 
         Context context = InstrumentationRegistry.getContext();
-        mEffectAdapter = new DeviceVibrationEffectAdapter(context);
+        VibrationSettings vibrationSettings = new VibrationSettings(context,
+                new Handler(mTestLooper.getLooper()));
+        mEffectAdapter = new DeviceVibrationEffectAdapter(vibrationSettings);
         mWakeLock = context.getSystemService(
                 PowerManager.class).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*vibrator*");
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index 57cf865..c555612 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -78,6 +78,24 @@
     }
 
     @Test
+    public void testSkipOccludedActivityCloseTransition() {
+        final ActivityRecord behind = createActivityRecord(mDisplayContent,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final ActivityRecord topOpening = createActivityRecord(behind.getTask());
+        topOpening.setOccludesParent(true);
+        topOpening.setVisible(true);
+
+        mDisplayContent.prepareAppTransition(TRANSIT_OPEN);
+        mDisplayContent.prepareAppTransition(TRANSIT_CLOSE);
+        mDisplayContent.mClosingApps.add(behind);
+
+        assertEquals(WindowManager.TRANSIT_OLD_UNSET,
+                AppTransitionController.getTransitCompatType(mDisplayContent.mAppTransition,
+                        mDisplayContent.mOpeningApps, mDisplayContent.mClosingApps,
+                        null, null, false));
+    }
+
+    @Test
     @FlakyTest(bugId = 131005232)
     public void testTranslucentOpen() {
         final ActivityRecord behind = createActivityRecord(mDisplayContent,
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 5bc4c82..d498d46 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -100,7 +100,6 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doCallRealMethod;
 
-import android.annotation.SuppressLint;
 import android.app.ActivityTaskManager;
 import android.app.WindowConfiguration;
 import android.app.servertransaction.FixedRotationAdjustmentsItem;
@@ -792,15 +791,9 @@
     }
 
     @Test
-    @SuppressLint("InlinedApi")
     public void testOrientationDefinedByKeyguard() {
-        final DisplayContent dc = createNewDisplay();
-
-        // When display content is created its configuration is not yet initialized, which could
-        // cause unnecessary configuration propagation, so initialize it here.
-        final Configuration config = new Configuration();
-        dc.computeScreenConfiguration(config);
-        dc.onRequestedOverrideConfigurationChanged(config);
+        final DisplayContent dc = mDisplayContent;
+        dc.getDisplayPolicy().setAwake(true);
 
         // Create a window that requests landscape orientation. It will define device orientation
         // by default.
@@ -815,10 +808,12 @@
                 SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
 
         keyguard.mAttrs.screenOrientation = SCREEN_ORIENTATION_PORTRAIT;
+        mAtm.mKeyguardController.setKeyguardShown(true /* keyguardShowing */,
+                false /* aodShowing */);
         assertEquals("Visible keyguard must influence device orientation",
                 SCREEN_ORIENTATION_PORTRAIT, dc.getOrientation());
 
-        mWm.setKeyguardGoingAway(true);
+        mAtm.mKeyguardController.keyguardGoingAway(0 /* flags */);
         assertEquals("Keyguard that is going away must not influence device orientation",
                 SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/SplashScreenExceptionListTest.java b/services/tests/wmtests/src/com/android/server/wm/SplashScreenExceptionListTest.java
new file mode 100644
index 0000000..3714d99
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/SplashScreenExceptionListTest.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.os.Build.VERSION_CODES;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.content.pm.ApplicationInfo;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.os.Looper;
+import android.platform.test.annotations.Presubmit;
+import android.provider.DeviceConfig;
+
+import androidx.test.filters.MediumTest;
+
+import junit.framework.Assert;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test for the splash screen exception list
+ * atest WmTests:SplashScreenExceptionListTest
+ */
+@MediumTest
+@Presubmit
+public class SplashScreenExceptionListTest {
+
+    // Constant copied on purpose so it's not refactored by accident.
+    // If the key needs to be modified, the server side key also needs to be changed.
+    private static final String KEY_SPLASH_SCREEN_EXCEPTION_LIST = "splash_screen_exception_list";
+
+    private DeviceConfig.Properties mInitialWindowManagerProperties;
+    private final HandlerExecutor mExecutor = new HandlerExecutor(
+            new Handler(Looper.getMainLooper()));
+    private final SplashScreenExceptionList mList = new SplashScreenExceptionList(mExecutor);
+
+    @Before
+    public void setUp() throws Exception {
+        mInitialWindowManagerProperties = DeviceConfig.getProperties(
+                DeviceConfig.NAMESPACE_WINDOW_MANAGER);
+        clearConstrainDisplayApisFlags();
+    }
+
+    private void clearConstrainDisplayApisFlags() {
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                KEY_SPLASH_SCREEN_EXCEPTION_LIST,
+                null, /* makeDefault= */ false);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        DeviceConfig.setProperties(mInitialWindowManagerProperties);
+        DeviceConfig.removeOnPropertiesChangedListener(mList.mOnPropertiesChangedListener);
+    }
+
+    @Test
+    public void packageFromDeviceConfigIgnored() {
+        setExceptionListAndWaitForCallback("com.test.nosplashscreen1,com.test.nosplashscreen2");
+
+        assertIsException("com.test.nosplashscreen1", null);
+        assertIsException("com.test.nosplashscreen2", null);
+
+        assertIsNotException("com.test.nosplashscreen1", VERSION_CODES.S, null);
+        assertIsNotException("com.test.nosplashscreen2", VERSION_CODES.S, null);
+        assertIsNotException("com.test.splashscreen", VERSION_CODES.S, null);
+        assertIsNotException("com.test.splashscreen", VERSION_CODES.R, null);
+    }
+
+    private void setExceptionListAndWaitForCallback(String commaSeparatedList) {
+        CountDownLatch latch = new CountDownLatch(1);
+        DeviceConfig.OnPropertiesChangedListener onPropertiesChangedListener = (p) -> {
+            if (commaSeparatedList.equals(p.getString(KEY_SPLASH_SCREEN_EXCEPTION_LIST, null))) {
+                latch.countDown();
+            }
+        };
+        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                mExecutor, onPropertiesChangedListener);
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                KEY_SPLASH_SCREEN_EXCEPTION_LIST, commaSeparatedList, false);
+        try {
+            assertTrue("Timed out waiting for DeviceConfig to be updated.",
+                    latch.await(1, TimeUnit.SECONDS));
+        } catch (InterruptedException e) {
+            Assert.fail(e.getMessage());
+        } finally {
+            DeviceConfig.removeOnPropertiesChangedListener(onPropertiesChangedListener);
+        }
+    }
+
+    @Test
+    public void metaDataOptOut() {
+        String packageName = "com.test.nosplashscreen_opt_out";
+        setExceptionListAndWaitForCallback(packageName);
+
+        Bundle metaData = new Bundle();
+        ApplicationInfo activityInfo = new ApplicationInfo();
+        activityInfo.metaData = metaData;
+
+        // No Exceptions
+        metaData.putBoolean("android.splashscreen.exception_opt_out", true);
+        assertIsNotException(packageName, VERSION_CODES.R, activityInfo);
+        assertIsNotException(packageName, VERSION_CODES.S, activityInfo);
+
+        // Exception Pre S
+        metaData.putBoolean("android.splashscreen.exception_opt_out", false);
+        assertIsException(packageName, activityInfo);
+        assertIsNotException(packageName, VERSION_CODES.S, activityInfo);
+
+        // Edge Cases
+        activityInfo.metaData = null;
+        assertIsException(packageName, activityInfo);
+        assertIsException(packageName, null);
+    }
+
+    private void assertIsNotException(String packageName, int targetSdk,
+            ApplicationInfo activityInfo) {
+        assertFalse(String.format("%s (sdk=%d) should have not been considered as an exception",
+                packageName, targetSdk),
+                mList.isException(packageName, targetSdk, () -> activityInfo));
+    }
+
+    private void assertIsException(String packageName,
+            ApplicationInfo activityInfo) {
+        assertTrue(String.format("%s (sdk=%d) should have been considered as an exception",
+                packageName, VERSION_CODES.R),
+                mList.isException(packageName, VERSION_CODES.R, () -> activityInfo));
+    }
+}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index beaca68..fc10fb1 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -79,7 +79,7 @@
 final class HotwordDetectionConnection {
     private static final String TAG = "HotwordDetectionConnection";
     // TODO (b/177502877): Set the Debug flag to false before shipping.
-    private static final boolean DEBUG = true;
+    static final boolean DEBUG = true;
 
     // TODO: These constants need to be refined.
     private static final long VALIDATION_TIMEOUT_MILLIS = 3000;
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionBinderProxy.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionBinderProxy.java
new file mode 100644
index 0000000..dd9fee3
--- /dev/null
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionBinderProxy.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.voiceinteraction;
+
+import android.hardware.soundtrigger.SoundTrigger;
+import android.os.RemoteException;
+
+import com.android.internal.app.IHotwordRecognitionStatusCallback;
+import com.android.internal.app.IVoiceInteractionSoundTriggerSession;
+
+/**
+ * A remote object that simply proxies calls to a real {@link IVoiceInteractionSoundTriggerSession}
+ * implementation. This design pattern allows us to add decorators to the core implementation
+ * (simply wrapping a binder object does not work).
+ */
+final class SoundTriggerSessionBinderProxy extends IVoiceInteractionSoundTriggerSession.Stub {
+
+    private final IVoiceInteractionSoundTriggerSession mDelegate;
+
+    SoundTriggerSessionBinderProxy(IVoiceInteractionSoundTriggerSession delegate) {
+        mDelegate = delegate;
+    }
+
+    @Override
+    public SoundTrigger.ModuleProperties getDspModuleProperties() throws RemoteException {
+        return mDelegate.getDspModuleProperties();
+    }
+
+    @Override
+    public int startRecognition(int i, String s,
+            IHotwordRecognitionStatusCallback iHotwordRecognitionStatusCallback,
+            SoundTrigger.RecognitionConfig recognitionConfig, boolean b) throws RemoteException {
+        return mDelegate.startRecognition(i, s, iHotwordRecognitionStatusCallback,
+                recognitionConfig, b);
+    }
+
+    @Override
+    public int stopRecognition(int i,
+            IHotwordRecognitionStatusCallback iHotwordRecognitionStatusCallback)
+            throws RemoteException {
+        return mDelegate.stopRecognition(i, iHotwordRecognitionStatusCallback);
+    }
+
+    @Override
+    public int setParameter(int i, int i1, int i2) throws RemoteException {
+        return mDelegate.setParameter(i, i1, i2);
+    }
+
+    @Override
+    public int getParameter(int i, int i1) throws RemoteException {
+        return mDelegate.getParameter(i, i1);
+    }
+
+    @Override
+    public SoundTrigger.ModelParamRange queryParameter(int i, int i1) throws RemoteException {
+        return mDelegate.queryParameter(i, i1);
+    }
+}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java
new file mode 100644
index 0000000..bb7ca16
--- /dev/null
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.voiceinteraction;
+
+import static android.Manifest.permission.CAPTURE_AUDIO_HOTWORD;
+import static android.Manifest.permission.RECORD_AUDIO;
+
+import static com.android.server.voiceinteraction.HotwordDetectionConnection.DEBUG;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.content.PermissionChecker;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.media.permission.Identity;
+import android.media.permission.PermissionUtil;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import com.android.internal.app.IHotwordRecognitionStatusCallback;
+import com.android.internal.app.IVoiceInteractionSoundTriggerSession;
+
+/**
+ * Decorates {@link IVoiceInteractionSoundTriggerSession} with permission checks for {@link
+ * android.Manifest.permission#RECORD_AUDIO} and
+ * {@link android.Manifest.permission#CAPTURE_AUDIO_HOTWORD}.
+ * <p>
+ * Does not implement {@link #asBinder()} as it's intended to be wrapped by an
+ * {@link IVoiceInteractionSoundTriggerSession.Stub} object.
+ */
+final class SoundTriggerSessionPermissionsDecorator implements
+        IVoiceInteractionSoundTriggerSession {
+    static final String TAG = "SoundTriggerSessionPermissionsDecorator";
+
+    private final IVoiceInteractionSoundTriggerSession mDelegate;
+    private final Context mContext;
+    private final Identity mOriginatorIdentity;
+
+    SoundTriggerSessionPermissionsDecorator(IVoiceInteractionSoundTriggerSession delegate,
+            Context context, Identity originatorIdentity) {
+        mDelegate = delegate;
+        mContext = context;
+        mOriginatorIdentity = originatorIdentity;
+    }
+
+    @Override
+    public SoundTrigger.ModuleProperties getDspModuleProperties() throws RemoteException {
+        // No permission needed.
+        return mDelegate.getDspModuleProperties();
+    }
+
+    @Override
+    public int startRecognition(int i, String s,
+            IHotwordRecognitionStatusCallback iHotwordRecognitionStatusCallback,
+            SoundTrigger.RecognitionConfig recognitionConfig, boolean b) throws RemoteException {
+        if (DEBUG) {
+            Slog.d(TAG, "startRecognition");
+        }
+        enforcePermissions();
+        return mDelegate.startRecognition(i, s, iHotwordRecognitionStatusCallback,
+                recognitionConfig, b);
+    }
+
+    @Override
+    public int stopRecognition(int i,
+            IHotwordRecognitionStatusCallback iHotwordRecognitionStatusCallback)
+            throws RemoteException {
+        enforcePermissions();
+        return mDelegate.stopRecognition(i, iHotwordRecognitionStatusCallback);
+    }
+
+    @Override
+    public int setParameter(int i, int i1, int i2) throws RemoteException {
+        enforcePermissions();
+        return mDelegate.setParameter(i, i1, i2);
+    }
+
+    @Override
+    public int getParameter(int i, int i1) throws RemoteException {
+        enforcePermissions();
+        return mDelegate.getParameter(i, i1);
+    }
+
+    @Override
+    public SoundTrigger.ModelParamRange queryParameter(int i, int i1) throws RemoteException {
+        enforcePermissions();
+        return mDelegate.queryParameter(i, i1);
+    }
+
+    @Override
+    public IBinder asBinder() {
+        throw new UnsupportedOperationException(
+                "This object isn't intended to be used as a Binder.");
+    }
+
+    // TODO: Share this code with SoundTriggerMiddlewarePermission.
+    private void enforcePermissions() {
+        enforcePermissionForPreflight(mContext, mOriginatorIdentity, RECORD_AUDIO);
+        enforcePermissionForPreflight(mContext, mOriginatorIdentity, CAPTURE_AUDIO_HOTWORD);
+    }
+
+    /**
+     * Throws a {@link SecurityException} if originator permanently doesn't have the given
+     * permission, or a {@link ServiceSpecificException} with a {@link
+     * #TEMPORARY_PERMISSION_DENIED} if caller originator doesn't have the given permission.
+     *
+     * @param context    A {@link Context}, used for permission checks.
+     * @param identity   The identity to check.
+     * @param permission The identifier of the permission we want to check.
+     */
+    private static void enforcePermissionForPreflight(@NonNull Context context,
+            @NonNull Identity identity, @NonNull String permission) {
+        final int status = PermissionUtil.checkPermissionForPreflight(context, identity,
+                permission);
+        switch (status) {
+            case PermissionChecker.PERMISSION_GRANTED:
+                return;
+            case PermissionChecker.PERMISSION_HARD_DENIED:
+                throw new SecurityException(
+                        TextUtils.formatSimple("Failed to obtain permission %s for identity %s",
+                                permission, toString(identity)));
+            case PermissionChecker.PERMISSION_SOFT_DENIED:
+                throw new ServiceSpecificException(TEMPORARY_PERMISSION_DENIED,
+                        TextUtils.formatSimple("Failed to obtain permission %s for identity %s",
+                                permission, toString(identity)));
+            default:
+                throw new RuntimeException("Unexpected permission check result.");
+        }
+    }
+
+    private static String toString(Identity identity) {
+        return "{uid=" + identity.uid
+                + " pid=" + identity.pid
+                + " packageName=" + identity.packageName
+                + " attributionTag=" + identity.attributionTag
+                + "}";
+    }
+
+    // Temporary hack for using the same status code as SoundTrigger, so we don't change behavior.
+    // TODO: Reuse SoundTrigger code so we don't need to do this.
+    private static final int TEMPORARY_PERMISSION_DENIED = 3;
+}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 162acba..91d17f7 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -23,6 +23,7 @@
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
+import android.app.ActivityThread;
 import android.app.AppGlobals;
 import android.app.role.OnRoleHoldersChangedListener;
 import android.app.role.RoleManager;
@@ -50,6 +51,7 @@
 import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
 import android.media.AudioFormat;
 import android.media.permission.Identity;
+import android.media.permission.IdentityContext;
 import android.media.permission.PermissionUtil;
 import android.media.permission.SafeCloseable;
 import android.os.Binder;
@@ -59,6 +61,7 @@
 import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
 import android.os.PersistableBundle;
+import android.os.Process;
 import android.os.RemoteCallback;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
@@ -104,11 +107,8 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
 import java.util.ArrayList;
-import java.util.LinkedList;
 import java.util.List;
-import java.util.ListIterator;
 import java.util.Locale;
 import java.util.Objects;
 import java.util.concurrent.Executor;
@@ -288,7 +288,6 @@
         private boolean mTemporarilyDisabled;
 
         private final boolean mEnableService;
-        private final List<WeakReference<SoundTriggerSession>> mSessions = new LinkedList<>();
 
         VoiceInteractionManagerServiceStub() {
             mEnableService = shouldEnableService(mContext);
@@ -299,15 +298,49 @@
         public @NonNull IVoiceInteractionSoundTriggerSession createSoundTriggerSessionAsOriginator(
                 @NonNull Identity originatorIdentity, IBinder client) {
             Objects.requireNonNull(originatorIdentity);
-            try (SafeCloseable ignored = PermissionUtil.establishIdentityDirect(
-                    originatorIdentity)) {
-                SoundTriggerSession session = new SoundTriggerSession(
-                        mSoundTriggerInternal.attach(client));
-                synchronized (mSessions) {
-                    mSessions.add(new WeakReference<>(session));
-                }
-                return session;
+            boolean forHotwordDetectionService;
+            synchronized (VoiceInteractionManagerServiceStub.this) {
+                enforceIsCurrentVoiceInteractionService();
+                forHotwordDetectionService =
+                        mImpl != null && mImpl.mHotwordDetectionConnection != null;
             }
+            IVoiceInteractionSoundTriggerSession session;
+            if (forHotwordDetectionService) {
+                // Use our own identity and handle the permission checks ourselves. This allows
+                // properly checking/noting against the voice interactor or hotword detection
+                // service as needed.
+                if (HotwordDetectionConnection.DEBUG) {
+                    Slog.d(TAG, "Creating a SoundTriggerSession for a HotwordDetectionService");
+                }
+                originatorIdentity.uid = Binder.getCallingUid();
+                originatorIdentity.pid = Binder.getCallingPid();
+                session = new SoundTriggerSessionPermissionsDecorator(
+                        createSoundTriggerSessionForSelfIdentity(client),
+                        mContext,
+                        originatorIdentity);
+            } else {
+                if (HotwordDetectionConnection.DEBUG) {
+                    Slog.d(TAG, "Creating a SoundTriggerSession");
+                }
+                try (SafeCloseable ignored = PermissionUtil.establishIdentityDirect(
+                        originatorIdentity)) {
+                    session = new SoundTriggerSession(mSoundTriggerInternal.attach(client));
+                }
+            }
+            return new SoundTriggerSessionBinderProxy(session);
+        }
+
+        private IVoiceInteractionSoundTriggerSession createSoundTriggerSessionForSelfIdentity(
+                IBinder client) {
+            Identity identity = new Identity();
+            identity.uid = Process.myUid();
+            identity.pid = Process.myPid();
+            identity.packageName = ActivityThread.currentOpPackageName();
+            return Binder.withCleanCallingIdentity(() -> {
+                try (SafeCloseable ignored = IdentityContext.create(identity)) {
+                    return new SoundTriggerSession(mSoundTriggerInternal.attach(client));
+                }
+            });
         }
 
         // TODO: VI Make sure the caller is the current user or profile
@@ -1334,7 +1367,11 @@
             return null;
         }
 
-        class SoundTriggerSession extends IVoiceInteractionSoundTriggerSession.Stub {
+        /**
+         * Implementation of SoundTriggerSession. Does not implement {@link #asBinder()} as it's
+         * intended to be wrapped by an {@link IVoiceInteractionSoundTriggerSession.Stub} object.
+         */
+        private class SoundTriggerSession implements IVoiceInteractionSoundTriggerSession {
             final SoundTriggerInternal.Session mSession;
             private IHotwordRecognitionStatusCallback mSessionExternalCallback;
             private IRecognitionStatusCallback mSessionInternalCallback;
@@ -1481,6 +1518,12 @@
                 }
             }
 
+            @Override
+            public IBinder asBinder() {
+                throw new UnsupportedOperationException(
+                        "This object isn't intended to be used as a Binder.");
+            }
+
             private int unloadKeyphraseModel(int keyphraseId) {
                 final long caller = Binder.clearCallingIdentity();
                 try {
@@ -1709,22 +1752,6 @@
             }
 
             mSoundTriggerInternal.dump(fd, pw, args);
-
-            // Dump all sessions.
-            synchronized (mSessions) {
-                ListIterator<WeakReference<SoundTriggerSession>> iter =
-                        mSessions.listIterator();
-                while (iter.hasNext()) {
-                    SoundTriggerSession session = iter.next().get();
-                    if (session != null) {
-                        session.dump(fd, args);
-                    } else {
-                        // Session is obsolete, now is a good chance to remove it from the list.
-                        iter.remove();
-                    }
-                }
-            }
-
         }
 
         @Override
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 7f1ea8f..e03e74c7 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -4370,7 +4370,7 @@
                     new String[] {});
             defaults.putBoolean(KEY_ENABLE_PRESENCE_CAPABILITY_EXCHANGE_BOOL, false);
             defaults.putBoolean(KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL, false);
-            defaults.putBoolean(KEY_ENABLE_PRESENCE_GROUP_SUBSCRIBE_BOOL, true);
+            defaults.putBoolean(KEY_ENABLE_PRESENCE_GROUP_SUBSCRIBE_BOOL, false);
             defaults.putInt(KEY_NON_RCS_CAPABILITIES_CACHE_EXPIRATION_SEC_INT, 30 * 24 * 60 * 60);
             defaults.putBoolean(KEY_RCS_REQUEST_FORBIDDEN_BY_SIP_489_BOOL, false);
             defaults.putLong(KEY_RCS_REQUEST_RETRY_INTERVAL_MILLIS_LONG, 20 * 60 * 1000);
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 5fb60d7..6a80766 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -506,6 +506,8 @@
     }
 
     /**
+     * Require {@link android.Manifest.permission#ACCESS_FINE_LOCATION}, otherwise return null.
+     *
      * @return The cell information.
      */
     @Nullable
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 6da61b7..d745dc2 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -758,6 +758,11 @@
      * In GSM/UMTS, long format can be up to 16 characters long.
      * In CDMA, returns the ERI text, if set. Otherwise, returns the ONS.
      *
+     * Require at least {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. Otherwise return null if the
+     * caller does not hold neither {@link android.Manifest.permission#ACCESS_FINE_LOCATION} nor
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
+     *
      * @return long name of operator, null if unregistered or unknown
      */
     public String getOperatorAlphaLong() {
@@ -766,6 +771,12 @@
 
     /**
      * Get current registered voice network operator name in long alphanumeric format.
+     *
+     * Require at least {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. Otherwise return null if the
+     * caller does not hold neither {@link android.Manifest.permission#ACCESS_FINE_LOCATION} nor
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
+     *
      * @return long name of operator
      * @hide
      */
@@ -780,6 +791,11 @@
      *
      * In GSM/UMTS, short format can be up to 8 characters long.
      *
+     * Require at least {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. Otherwise return null if the
+     * caller does not hold neither {@link android.Manifest.permission#ACCESS_FINE_LOCATION} nor
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
+     *
      * @return short name of operator, null if unregistered or unknown
      */
     public String getOperatorAlphaShort() {
@@ -788,6 +804,12 @@
 
     /**
      * Get current registered voice network operator name in short alphanumeric format.
+     *
+     * Require at least {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. Otherwise return null if the
+     * caller does not have neither {@link android.Manifest.permission#ACCESS_FINE_LOCATION} nor
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
+     *
      * @return short name of operator, null if unregistered or unknown
      * @hide
      */
@@ -799,6 +821,12 @@
 
     /**
      * Get current registered data network operator name in short alphanumeric format.
+     *
+     * Require at least {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. Otherwise return null if the
+     * caller does not have neither {@link android.Manifest.permission#ACCESS_FINE_LOCATION} nor
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
+     *
      * @return short name of operator, null if unregistered or unknown
      * @hide
      */
@@ -812,6 +840,11 @@
      * Get current registered operator name in long alphanumeric format if
      * available or short otherwise.
      *
+     * Require at least {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. Otherwise return null if the
+     * caller does not hold neither {@link android.Manifest.permission#ACCESS_FINE_LOCATION} nor
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
+     *
      * @see #getOperatorAlphaLong
      * @see #getOperatorAlphaShort
      *
@@ -832,6 +865,11 @@
      * In GSM/UMTS, numeric format is 3 digit country code plus 2 or 3 digit
      * network code.
      *
+     * Require at least {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. Otherwise return null if the
+     * caller does not hold neither {@link android.Manifest.permission#ACCESS_FINE_LOCATION} nor
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
+     *
      * @return numeric format of operator, null if unregistered or unknown
      */
     /*
@@ -844,6 +882,12 @@
 
     /**
      * Get current registered voice network operator numeric id.
+     *
+     * Require at least {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. Otherwise return null if the
+     * caller does not hold neither {@link android.Manifest.permission#ACCESS_FINE_LOCATION} nor
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
+     *
      * @return numeric format of operator, null if unregistered or unknown
      * @hide
      */
@@ -854,6 +898,12 @@
 
     /**
      * Get current registered data network operator numeric id.
+     *
+     * Require at least {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. Otherwise return null if the
+     * caller does not hold neither {@link android.Manifest.permission#ACCESS_FINE_LOCATION} nor
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
+     *
      * @return numeric format of operator, null if unregistered or unknown
      * @hide
      */
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 64aa2994..e0ab0a3 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -15104,8 +15104,8 @@
 
     /**
      * Indicates that the thermal mitigation request could not power off the radio due to the device
-     * either being in an active voice call, device pending an emergency call, or any other state
-     * that would dissallow powering off of radio.
+     * either being in an active emergency voice call, device pending an emergency call, or any
+     * other state that would disallow powering off of radio.
      *
      * @hide
      */
diff --git a/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java b/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java
index 039ba51..0c5205c 100644
--- a/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java
+++ b/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java
@@ -118,7 +118,8 @@
                     Manifest.permission.LOG_COMPAT_CHANGE,
                     Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG,
                     Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD,
-                    Manifest.permission.READ_COMPAT_CHANGE_CONFIG);
+                    Manifest.permission.READ_COMPAT_CHANGE_CONFIG,
+                    Manifest.permission.INTERACT_ACROSS_USERS_FULL);
         }
     }
 }