[automerger skipped] Merge "RESTRICT AUTOMERGE Revive runLimit check logic" into pi-dev am: d7f6ede261 -s ours am: 8d016ab4ff
am: 5181402566

Change-Id: Ia6d2cbc42f1a682eae9c98cf8f05c10239f2ef12
diff --git a/api/test-current.txt b/api/test-current.txt
index 87295fa..d3bea18 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2344,6 +2344,7 @@
     field public static final String LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST = "location_ignore_settings_package_whitelist";
     field public static final String LOW_POWER_MODE = "low_power";
     field public static final String LOW_POWER_MODE_STICKY = "low_power_sticky";
+    field public static final String NOTIFICATION_BUBBLES = "notification_bubbles";
     field public static final String OVERLAY_DISPLAY_DEVICES = "overlay_display_devices";
     field public static final String USE_OPEN_WIFI_PACKAGE = "use_open_wifi_package";
   }
@@ -2367,7 +2368,7 @@
     field public static final String LOCATION_ACCESS_CHECK_DELAY_MILLIS = "location_access_check_delay_millis";
     field public static final String LOCATION_ACCESS_CHECK_INTERVAL_MILLIS = "location_access_check_interval_millis";
     field public static final String NOTIFICATION_BADGING = "notification_badging";
-    field public static final String NOTIFICATION_BUBBLES = "notification_bubbles";
+    field @Deprecated public static final String NOTIFICATION_BUBBLES = "notification_bubbles";
     field @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static final String SYNC_PARENT_SOUNDS = "sync_parent_sounds";
     field public static final String USER_SETUP_COMPLETE = "user_setup_complete";
     field public static final String VOICE_INTERACTION_SERVICE = "voice_interaction_service";
diff --git a/cmds/incidentd/src/WorkDirectory.cpp b/cmds/incidentd/src/WorkDirectory.cpp
index 0570c3a..8dcb865 100644
--- a/cmds/incidentd/src/WorkDirectory.cpp
+++ b/cmds/incidentd/src/WorkDirectory.cpp
@@ -664,7 +664,7 @@
             nanosleep(&spec, nullptr);
         }
         clock_gettime(CLOCK_REALTIME, &spec);
-        timestampNs = (spec.tv_sec) * 1000 + spec.tv_nsec;
+        timestampNs = int64_t(spec.tv_sec) * 1000 + spec.tv_nsec;
     } while (file_exists_locked(timestampNs));
     return timestampNs;
 }
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index e7cce06..1fd9caf 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -5924,7 +5924,8 @@
     optional bool is_ongoing = 10;
 
     // Whether the bubble is produced by an app running in foreground.
-    optional bool is_foreground = 11;
+    // This is deprecated and the value should be ignored.
+    optional bool is_foreground = 11 [deprecated = true];
 }
 
 /**
diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp
index 68082c2..42132ee 100644
--- a/cmds/statsd/src/main.cpp
+++ b/cmds/statsd/src/main.cpp
@@ -78,7 +78,7 @@
     ps->giveThreadPoolName();
     IPCThreadState::self()->disableBackgroundScheduling(true);
 
-    ::android::hardware::configureRpcThreadpool(1 /*threads*/, false /*willJoin*/);
+    ::android::hardware::configureRpcThreadpool(4 /*threads*/, false /*willJoin*/);
 
     std::shared_ptr<LogEventQueue> eventQueue =
             std::make_shared<LogEventQueue>(2000 /*buffer limit. Buffer is NOT pre-allocated*/);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index f5b0b59..5bc0647 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -146,6 +146,7 @@
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -943,6 +944,10 @@
     /** @hide */
     boolean mEnterAnimationComplete;
 
+    /** Track last dispatched multi-window and PiP mode to client, internal debug purpose **/
+    private Boolean mLastDispatchedIsInMultiWindowMode;
+    private Boolean mLastDispatchedIsInPictureInPictureMode;
+
     private static native String getDlWarning();
 
     /** Return the intent that started this activity. */
@@ -3656,6 +3661,22 @@
         return false;
     }
 
+    private static final class RequestFinishCallback extends IRequestFinishCallback.Stub {
+        private final WeakReference<Activity> mActivityRef;
+
+        RequestFinishCallback(WeakReference<Activity> activityRef) {
+            mActivityRef = activityRef;
+        }
+
+        @Override
+        public void requestFinish() {
+            Activity activity = mActivityRef.get();
+            if (activity != null) {
+                activity.mHandler.post(activity::finishAfterTransition);
+            }
+        }
+    }
+
     /**
      * Called when the activity has detected the user's press of the back
      * key.  The default implementation simply finishes the current activity,
@@ -3681,11 +3702,7 @@
             // while at the root of the task. This call allows ActivityTaskManager
             // to intercept or defer finishing.
             ActivityTaskManager.getService().onBackPressedOnTaskRoot(mToken,
-                    new IRequestFinishCallback.Stub() {
-                        public void requestFinish() {
-                            mHandler.post(() -> finishAfterTransition());
-                        }
-                    });
+                    new RequestFinishCallback(new WeakReference<>(this)));
         } catch (RemoteException e) {
             finishAfterTransition();
         }
@@ -6986,6 +7003,10 @@
                 writer.print(mResumed); writer.print(" mStopped=");
                 writer.print(mStopped); writer.print(" mFinished=");
                 writer.println(mFinished);
+        writer.print(innerPrefix); writer.print("mLastDispatchedIsInMultiWindowMode=");
+                writer.print(mLastDispatchedIsInMultiWindowMode);
+                writer.print(" mLastDispatchedIsInPictureInPictureMode=");
+                writer.println(mLastDispatchedIsInPictureInPictureMode);
         writer.print(innerPrefix); writer.print("mChangingConfigurations=");
                 writer.println(mChangingConfigurations);
         writer.print(innerPrefix); writer.print("mCurrentConfig=");
@@ -8065,6 +8086,7 @@
         if (mWindow != null) {
             mWindow.onMultiWindowModeChanged();
         }
+        mLastDispatchedIsInMultiWindowMode = isInMultiWindowMode;
         onMultiWindowModeChanged(isInMultiWindowMode, newConfig);
     }
 
@@ -8077,6 +8099,7 @@
         if (mWindow != null) {
             mWindow.onPictureInPictureModeChanged(isInPictureInPictureMode);
         }
+        mLastDispatchedIsInPictureInPictureMode = isInPictureInPictureMode;
         onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig);
     }
 
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 3bf659b..2b4ff01 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -120,7 +120,10 @@
 
         mActivityTaskManager = ActivityTaskManager.getService();
         mSurfaceView = new SurfaceView(context);
-        mSurfaceView.setAlpha(0f);
+        // Since ActivityView#getAlpha has been overridden, we should use parent class's alpha
+        // as master to synchronize surface view's alpha value.
+        mSurfaceView.setAlpha(super.getAlpha());
+        mSurfaceView.setUseAlpha();
         mSurfaceCallback = new SurfaceCallback();
         mSurfaceView.getHolder().addCallback(mSurfaceCallback);
         addView(mSurfaceView);
@@ -347,9 +350,20 @@
         mSurfaceView.layout(0 /* left */, 0 /* top */, r - l /* right */, b - t /* bottom */);
     }
 
+    /**
+     * Sets the alpha value when the content of {@link SurfaceView} needs to show or hide.
+     * <p>Note: The surface view may ignore the alpha value in some cases. Refer to
+     * {@link SurfaceView#setAlpha} for more details.
+     *
+     * @param alpha The opacity of the view.
+     */
     @Override
     public void setAlpha(float alpha) {
-        mSurfaceView.setAlpha(alpha);
+        super.setAlpha(alpha);
+
+        if (mSurfaceView != null) {
+            mSurfaceView.setAlpha(alpha);
+        }
     }
 
     @Override
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index fb72e65..7787535 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -834,9 +834,12 @@
     public static final int OP_ACCESS_ACCESSIBILITY = 88;
     /** @hide Read the device identifiers (IMEI / MEID, IMSI, SIM / Build serial) */
     public static final int OP_READ_DEVICE_IDENTIFIERS = 89;
+    /** @hide Read location metadata from media */
+    public static final int OP_ACCESS_MEDIA_LOCATION = 90;
+
     /** @hide */
     @UnsupportedAppUsage
-    public static final int _NUM_OP = 90;
+    public static final int _NUM_OP = 91;
 
     /** Access to coarse location information. */
     public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -1107,6 +1110,9 @@
     @TestApi
     @SystemApi
     public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage";
+    /** @hide Read location metadata from media */
+    public static final String OPSTR_ACCESS_MEDIA_LOCATION = "android:access_media_location";
+
     /** @hide Interact with accessibility. */
     @SystemApi
     public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility";
@@ -1134,6 +1140,7 @@
             // Storage
             OP_READ_EXTERNAL_STORAGE,
             OP_WRITE_EXTERNAL_STORAGE,
+            OP_ACCESS_MEDIA_LOCATION,
             // Location
             OP_COARSE_LOCATION,
             OP_FINE_LOCATION,
@@ -1273,6 +1280,7 @@
             OP_LEGACY_STORAGE,                  // LEGACY_STORAGE
             OP_ACCESS_ACCESSIBILITY,            // ACCESS_ACCESSIBILITY
             OP_READ_DEVICE_IDENTIFIERS,         // READ_DEVICE_IDENTIFIERS
+            OP_ACCESS_MEDIA_LOCATION,           // ACCESS_MEDIA_LOCATION
     };
 
     /**
@@ -1369,6 +1377,7 @@
             OPSTR_LEGACY_STORAGE,
             OPSTR_ACCESS_ACCESSIBILITY,
             OPSTR_READ_DEVICE_IDENTIFIERS,
+            OPSTR_ACCESS_MEDIA_LOCATION,
     };
 
     /**
@@ -1466,6 +1475,7 @@
             "LEGACY_STORAGE",
             "ACCESS_ACCESSIBILITY",
             "READ_DEVICE_IDENTIFIERS",
+            "ACCESS_MEDIA_LOCATION",
     };
 
     /**
@@ -1564,6 +1574,7 @@
             null, // no permission for OP_LEGACY_STORAGE
             null, // no permission for OP_ACCESS_ACCESSIBILITY
             null, // no direct permission for OP_READ_DEVICE_IDENTIFIERS
+            Manifest.permission.ACCESS_MEDIA_LOCATION,
     };
 
     /**
@@ -1662,6 +1673,7 @@
             null, // LEGACY_STORAGE
             null, // ACCESS_ACCESSIBILITY
             null, // READ_DEVICE_IDENTIFIERS
+            null, // ACCESS_MEDIA_LOCATION
     };
 
     /**
@@ -1759,6 +1771,7 @@
             false, // LEGACY_STORAGE
             false, // ACCESS_ACCESSIBILITY
             false, // READ_DEVICE_IDENTIFIERS
+            false, // ACCESS_MEDIA_LOCATION
     };
 
     /**
@@ -1855,6 +1868,7 @@
             AppOpsManager.MODE_DEFAULT, // LEGACY_STORAGE
             AppOpsManager.MODE_ALLOWED, // ACCESS_ACCESSIBILITY
             AppOpsManager.MODE_ERRORED, // READ_DEVICE_IDENTIFIERS
+            AppOpsManager.MODE_ALLOWED, // ALLOW_MEDIA_LOCATION
     };
 
     /**
@@ -1955,6 +1969,7 @@
             false, // LEGACY_STORAGE
             false, // ACCESS_ACCESSIBILITY
             false, // READ_DEVICE_IDENTIFIERS
+            false, // ACCESS_MEDIA_LOCATION
     };
 
     /**
@@ -2587,7 +2602,7 @@
          * @return The proxy UID.
          */
         public int getProxyUid() {
-            return (int) findFirstNonNegativeForFlagsInStates(mDurations,
+            return (int) findFirstNonNegativeForFlagsInStates(mProxyUids,
                     MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
         }
 
@@ -2609,7 +2624,7 @@
          * @return The proxy UID.
          */
         public int getProxyUid(@UidState int uidState, @OpFlags int flags) {
-            return (int) findFirstNonNegativeForFlagsInStates(mDurations,
+            return (int) findFirstNonNegativeForFlagsInStates(mProxyUids,
                     uidState, uidState, flags);
         }
 
@@ -4169,8 +4184,8 @@
      * end UID states.
      *
      * @param counts The data array.
-     * @param beginUidState The beginning UID state (exclusive).
-     * @param endUidState The end UID state.
+     * @param beginUidState The beginning UID state (inclusive).
+     * @param endUidState The end UID state (inclusive).
      * @param flags The UID flags.
      * @return The sum.
      */
@@ -4199,13 +4214,13 @@
      * end UID states.
      *
      * @param counts The data array.
+     * @param beginUidState The beginning UID state (inclusive).
+     * @param endUidState The end UID state (inclusive).
      * @param flags The UID flags.
-     * @param beginUidState The beginning UID state (exclusive).
-     * @param endUidState The end UID state.
      * @return The non-negative value or -1.
      */
     private static long findFirstNonNegativeForFlagsInStates(@Nullable LongSparseLongArray counts,
-            @OpFlags int flags, @UidState int beginUidState, @UidState int endUidState) {
+            @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags) {
         if (counts == null) {
             return -1;
         }
@@ -4231,14 +4246,14 @@
      * end UID states.
      *
      * @param counts The data array.
+     * @param beginUidState The beginning UID state (inclusive).
+     * @param endUidState The end UID state (inclusive).
      * @param flags The UID flags.
-     * @param beginUidState The beginning UID state (exclusive).
-     * @param endUidState The end UID state.
      * @return The non-negative value or -1.
      */
     private static @Nullable String findFirstNonNullForFlagsInStates(
-            @Nullable LongSparseArray<String> counts, @OpFlags int flags,
-            @UidState int beginUidState, @UidState int endUidState) {
+            @Nullable LongSparseArray<String> counts, @UidState int beginUidState,
+            @UidState int endUidState, @OpFlags int flags) {
         if (counts == null) {
             return null;
         }
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index e57738f..9f51db8 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -108,6 +108,8 @@
     ParceledListSlice getNotificationChannelsBypassingDnd(String pkg, int userId);
     boolean isPackagePaused(String pkg);
 
+    void silenceNotificationSound();
+
     // TODO: Remove this when callers have been migrated to the equivalent
     // INotificationListener method.
     @UnsupportedAppUsage
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index 650147b..6fd43a6 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -178,6 +178,13 @@
      */
     void onSingleTaskDisplayDrawn(int displayId);
 
+    /*
+     * Called when the last task is removed from a display which can only contain one task.
+     *
+     * @param displayId the id of the display from which the window is removed.
+     */
+    void onSingleTaskDisplayEmpty(int displayId);
+
     /**
      * Called when a task is reparented to a stack on a different display.
      *
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index ceadd85..a4c98e8 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -8539,24 +8539,34 @@
          * If set and the app creating the bubble is in the foreground, the bubble will be posted
          * in its expanded state, with the contents of {@link #getIntent()} in a floating window.
          *
-         * <p>If the app creating the bubble is not in the foreground this flag has no effect.</p>
+         * <p>This flag has no effect if the app posting the bubble is not in the foreground.
+         * The app is considered foreground if it is visible and on the screen, note that
+         * a foreground service does not qualify.
+         * </p>
          *
          * <p>Generally this flag should only be set if the user has performed an action to request
          * or create a bubble.</p>
+         *
+         * @hide
          */
-        private static final int FLAG_AUTO_EXPAND_BUBBLE = 0x00000001;
+        public static final int FLAG_AUTO_EXPAND_BUBBLE = 0x00000001;
 
         /**
          * If set and the app posting the bubble is in the foreground, the bubble will
          * be posted <b>without</b> the associated notification in the notification shade.
          *
-         * <p>If the app posting the bubble is not in the foreground this flag has no effect.</p>
+         * <p>This flag has no effect if the app posting the bubble is not in the foreground.
+         * The app is considered foreground if it is visible and on the screen, note that
+         * a foreground service does not qualify.
+         * </p>
          *
          * <p>Generally this flag should only be set if the user has performed an action to request
          * or create a bubble, or if the user has seen the content in the notification and the
          * notification is no longer relevant.</p>
+         *
+         * @hide
          */
-        private static final int FLAG_SUPPRESS_NOTIFICATION = 0x00000002;
+        public static final int FLAG_SUPPRESS_NOTIFICATION = 0x00000002;
 
         private BubbleMetadata(PendingIntent expandIntent, PendingIntent deleteIntent,
                 Icon icon, int height, @DimenRes int heightResId) {
@@ -8672,11 +8682,21 @@
             out.writeInt(mDesiredHeightResId);
         }
 
-        private void setFlags(int flags) {
+        /**
+         * @hide
+         */
+        public void setFlags(int flags) {
             mFlags = flags;
         }
 
         /**
+         * @hide
+         */
+        public int getFlags() {
+            return mFlags;
+        }
+
+        /**
          * Builder to construct a {@link BubbleMetadata} object.
          */
         public static final class Builder {
@@ -8792,6 +8812,8 @@
              * {@link #getIntent()} in a floating window).
              *
              * <p>This flag has no effect if the app posting the bubble is not in the foreground.
+             * The app is considered foreground if it is visible and on the screen, note that
+             * a foreground service does not qualify.
              * </p>
              *
              * <p>Generally, this flag should only be set if the user has performed an action to
@@ -8810,6 +8832,8 @@
              * the notification shade.
              *
              * <p>This flag has no effect if the app posting the bubble is not in the foreground.
+             * The app is considered foreground if it is visible and on the screen, note that
+             * a foreground service does not qualify.
              * </p>
              *
              * <p>Generally, this flag should only be set if the user has performed an action to
@@ -10484,12 +10508,7 @@
         final StandardTemplateParams fillTextsFrom(Builder b) {
             Bundle extras = b.mN.extras;
             this.title = b.processLegacyText(extras.getCharSequence(EXTRA_TITLE));
-
-            CharSequence text = extras.getCharSequence(EXTRA_BIG_TEXT);
-            if (TextUtils.isEmpty(text)) {
-                text = extras.getCharSequence(EXTRA_TEXT);
-            }
-            this.text = b.processLegacyText(text);
+            this.text = b.processLegacyText(extras.getCharSequence(EXTRA_TEXT));
             this.summaryText = extras.getCharSequence(EXTRA_SUB_TEXT);
             return this;
         }
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index dd39376..b13a34f 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1095,6 +1095,25 @@
     }
 
     /**
+     * Silences the current notification sound, if ones currently playing.
+     * <p>
+     * It is intended to handle use-cases such as silencing a ringing call
+     * when the user presses the volume button during ringing.
+     * <p>
+     * If this method is called prior to when the notification begins playing, the sound will not be
+     * silenced.  As such it is not intended as a means to avoid playing of a sound.
+     * @hide
+     */
+    public void silenceNotificationSound() {
+        INotificationManager service = getService();
+        try {
+            service.silenceNotificationSound();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Returns whether notifications from this package are temporarily hidden. This
      * could be done because the package was marked as distracting to the user via
      * {@code PackageManager#setDistractingPackageRestrictions(String[], int)} or because the
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index d32b6b5..fe4b0d5 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -1162,7 +1162,8 @@
             @Override
             public AppPredictionManager createService(ContextImpl ctx)
                     throws ServiceNotFoundException {
-                return new AppPredictionManager(ctx);
+                IBinder b = ServiceManager.getService(Context.APP_PREDICTION_SERVICE);
+                return b == null ? null : new AppPredictionManager(ctx);
             }
         });
 
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
index b63feb5..b4b7df9 100644
--- a/core/java/android/app/TaskStackListener.java
+++ b/core/java/android/app/TaskStackListener.java
@@ -180,6 +180,10 @@
     }
 
     @Override
+    public void onSingleTaskDisplayEmpty(int displayId) throws RemoteException {
+    }
+
+    @Override
     public void onTaskDisplayChanged(int taskId, int newDisplayId) throws RemoteException {
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index fb78789..cfb363a08 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -118,6 +118,8 @@
      */
     public static final int PAN_OPERATION_SUCCESS = 1004;
 
+    private final Context mContext;
+
     private BluetoothAdapter mAdapter;
     private final BluetoothProfileConnector<IBluetoothPan> mProfileConnector =
             new BluetoothProfileConnector(this, BluetoothProfile.PAN,
@@ -136,6 +138,7 @@
     @UnsupportedAppUsage
     /*package*/ BluetoothPan(Context context, ServiceListener listener) {
         mAdapter = BluetoothAdapter.getDefaultAdapter();
+        mContext = context;
         mProfileConnector.connect(context, listener);
     }
 
@@ -287,11 +290,12 @@
 
     @UnsupportedAppUsage
     public void setBluetoothTethering(boolean value) {
-        if (DBG) log("setBluetoothTethering(" + value + ")");
+        String pkgName = mContext.getOpPackageName();
+        if (DBG) log("setBluetoothTethering(" + value + "), calling package:" + pkgName);
         final IBluetoothPan service = getService();
         if (service != null && isEnabled()) {
             try {
-                service.setBluetoothTethering(value);
+                service.setBluetoothTethering(value, pkgName);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
             }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 658c9b4..414cc39 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4111,6 +4111,9 @@
     /**
      * Official published name of the app prediction service.
      *
+     * <p><b>NOTE: </b> this service is optional; callers of
+     * {@code Context.getSystemServiceName(APP_PREDICTION_SERVICE)} should check for {@code null}.
+     *
      * @hide
      * @see #getSystemService(String)
      */
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index a7eecd7..abcf77b 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -44,6 +44,7 @@
 import android.content.pm.PermissionInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.content.pm.permission.SplitPermissionInfoParcelable;
 import android.content.pm.SuspendDialogInfo;
 import android.content.pm.UserInfo;
 import android.content.pm.VerifierDeviceIdentity;
@@ -772,4 +773,6 @@
     void setRuntimePermissionsVersion(int version, int userId);
 
     void notifyPackagesReplacedReceived(in String[] packages);
+
+    List<SplitPermissionInfoParcelable> getSplitPermissions();
 }
diff --git a/core/java/android/content/pm/PackageList.java b/core/java/android/content/pm/PackageList.java
index f781758..e3eb2c5 100644
--- a/core/java/android/content/pm/PackageList.java
+++ b/core/java/android/content/pm/PackageList.java
@@ -52,6 +52,13 @@
     }
 
     @Override
+    public void onPackageChanged(String packageName, int uid) {
+        if (mWrappedObserver != null) {
+            mWrappedObserver.onPackageChanged(packageName, uid);
+        }
+    }
+
+    @Override
     public void onPackageRemoved(String packageName, int uid) {
         if (mWrappedObserver != null) {
             mWrappedObserver.onPackageRemoved(packageName, uid);
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index b377678..535a8bc 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -57,6 +57,7 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageParserCacheHelper.ReadHelper;
 import android.content.pm.PackageParserCacheHelper.WriteHelper;
+import android.content.pm.permission.SplitPermissionInfoParcelable;
 import android.content.pm.split.DefaultSplitAssetLoader;
 import android.content.pm.split.SplitAssetDependencyLoader;
 import android.content.pm.split.SplitAssetLoader;
@@ -104,6 +105,7 @@
 import com.android.internal.os.ClassLoaderFactory;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.XmlUtils;
+import com.android.server.SystemConfig;
 
 import libcore.io.IoUtils;
 import libcore.util.EmptyArray;
@@ -2482,11 +2484,10 @@
             Slog.i(TAG, newPermsMsg.toString());
         }
 
-
-        final int NS = PermissionManager.SPLIT_PERMISSIONS.size();
-        for (int is=0; is<NS; is++) {
-            final PermissionManager.SplitPermissionInfo spi =
-                    PermissionManager.SPLIT_PERMISSIONS.get(is);
+        List<SplitPermissionInfoParcelable> splitPermissions = getSplitPermissions();
+        final int listSize = splitPermissions.size();
+        for (int is = 0; is < listSize; is++) {
+            final SplitPermissionInfoParcelable spi = splitPermissions.get(is);
             if (pkg.applicationInfo.targetSdkVersion >= spi.getTargetSdk()
                     || !pkg.requestedPermissions.contains(spi.getSplitPermission())) {
                 continue;
@@ -2540,6 +2541,23 @@
         return pkg;
     }
 
+    private List<SplitPermissionInfoParcelable> getSplitPermissions() {
+        // PackageManager runs this code during initialization prior to registering with
+        // ServiceManager, so we can't use the PackageManager API.  Instead, just read from
+        // SystemConfig directly when in any SystemProcess and only use PackageManager when not in
+        // one.
+        if (ActivityThread.isSystem()) {
+            return PermissionManager.splitPermissionInfoListToParcelableList(
+                    SystemConfig.getInstance().getSplitPermissions());
+        } else {
+            try {
+                return ActivityThread.getPackageManager().getSplitPermissions();
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+
     private boolean checkOverlayRequiredSystemProperty(String propName, String propValue) {
 
         if (TextUtils.isEmpty(propName) || TextUtils.isEmpty(propValue)) {
diff --git a/core/java/android/content/pm/permission/SplitPermissionInfoParcelable.aidl b/core/java/android/content/pm/permission/SplitPermissionInfoParcelable.aidl
new file mode 100644
index 0000000..d84454c
--- /dev/null
+++ b/core/java/android/content/pm/permission/SplitPermissionInfoParcelable.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ package android.content.pm.permission;
+
+ parcelable SplitPermissionInfoParcelable;
\ No newline at end of file
diff --git a/core/java/android/content/pm/permission/SplitPermissionInfoParcelable.java b/core/java/android/content/pm/permission/SplitPermissionInfoParcelable.java
new file mode 100644
index 0000000..6537fbc
--- /dev/null
+++ b/core/java/android/content/pm/permission/SplitPermissionInfoParcelable.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm.permission;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Parcelable version of {@link android.permission.PermissionManager.SplitPermissionInfo}
+ * @hide
+ */
+public class SplitPermissionInfoParcelable implements Parcelable {
+
+    /**
+     * The permission that is split.
+     */
+    @NonNull
+    private final String mSplitPermission;
+
+    /**
+     * The permissions that are added.
+     */
+    @NonNull
+    private final List<String> mNewPermissions;
+
+    /**
+     * The target API level when the permission was split.
+     */
+    @IntRange(from = 0)
+    private final int mTargetSdk;
+
+    private void onConstructed() {
+        Preconditions.checkCollectionElementsNotNull(mNewPermissions, "newPermissions");
+    }
+
+
+
+    // Code below generated by codegen v1.0.0.
+    //
+    // DO NOT MODIFY!
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/SplitPermissionInfoParcelable.java
+    //
+    // CHECKSTYLE:OFF Generated code
+
+    /**
+     * Creates a new SplitPermissionInfoParcelable.
+     *
+     * @param splitPermission
+     *   The permission that is split.
+     * @param newPermissions
+     *   The permissions that are added.
+     * @param targetSdk
+     *   The target API level when the permission was split.
+     */
+    public SplitPermissionInfoParcelable(
+            @NonNull String splitPermission,
+            @NonNull List<String> newPermissions,
+            @IntRange(from = 0) int targetSdk) {
+        this.mSplitPermission = splitPermission;
+        Preconditions.checkNotNull(mSplitPermission);
+        this.mNewPermissions = newPermissions;
+        Preconditions.checkNotNull(mNewPermissions);
+        this.mTargetSdk = targetSdk;
+        Preconditions.checkArgumentNonnegative(mTargetSdk);
+
+        onConstructed();
+    }
+
+    /**
+     * The permission that is split.
+     */
+    public @NonNull String getSplitPermission() {
+        return mSplitPermission;
+    }
+
+    /**
+     * The permissions that are added.
+     */
+    public @NonNull List<String> getNewPermissions() {
+        return mNewPermissions;
+    }
+
+    /**
+     * The target API level when the permission was split.
+     */
+    public @IntRange(from = 0) int getTargetSdk() {
+        return mTargetSdk;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        // You can override field equality logic by defining either of the methods like:
+        // boolean fieldNameEquals(SplitPermissionInfoParcelable other) { ... }
+        // boolean fieldNameEquals(FieldType otherValue) { ... }
+
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        @SuppressWarnings("unchecked")
+        SplitPermissionInfoParcelable that = (SplitPermissionInfoParcelable) o;
+        //noinspection PointlessBooleanExpression
+        return true
+                && Objects.equals(mSplitPermission, that.mSplitPermission)
+                && Objects.equals(mNewPermissions, that.mNewPermissions)
+                && mTargetSdk == that.mTargetSdk;
+    }
+
+    @Override
+    public int hashCode() {
+        // You can override field hashCode logic by defining methods like:
+        // int fieldNameHashCode() { ... }
+
+        int _hash = 1;
+        _hash = 31 * _hash + Objects.hashCode(mSplitPermission);
+        _hash = 31 * _hash + Objects.hashCode(mNewPermissions);
+        _hash = 31 * _hash + mTargetSdk;
+        return _hash;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        // You can override field parcelling by defining methods like:
+        // void parcelFieldName(Parcel dest, int flags) { ... }
+
+        dest.writeString(mSplitPermission);
+        dest.writeStringList(mNewPermissions);
+        dest.writeInt(mTargetSdk);
+    }
+
+    @Override
+    public int describeContents() { return 0; }
+
+    public static final @NonNull Parcelable.Creator<SplitPermissionInfoParcelable> CREATOR
+            = new Parcelable.Creator<SplitPermissionInfoParcelable>() {
+        @Override
+        public SplitPermissionInfoParcelable[] newArray(int size) {
+            return new SplitPermissionInfoParcelable[size];
+        }
+
+        @Override
+        @SuppressWarnings({"unchecked", "RedundantCast"})
+        public SplitPermissionInfoParcelable createFromParcel(Parcel in) {
+            // You can override field unparcelling by defining methods like:
+            // static FieldType unparcelFieldName(Parcel in) { ... }
+
+            String splitPermission = in.readString();
+            List<String> newPermissions = new java.util.ArrayList<>();
+            in.readStringList(newPermissions);
+            int targetSdk = in.readInt();
+            return new SplitPermissionInfoParcelable(
+                    splitPermission,
+                    newPermissions,
+                    targetSdk);
+        }
+    };
+}
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 5ac13d8..a0170da 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -206,10 +206,16 @@
                     continue;
                 }
 
-                if (filterTags == null || Arrays.binarySearch(filterTags,
-                        CameraMetadataNative.getTag(keyName, vendorId)) >= 0) {
+
+                if (filterTags != null && Arrays.binarySearch(filterTags,
+                        CameraMetadataNative.getTag(keyName, vendorId)) < 0) {
+                    // ignore vendor keys not in filterTags
+                    continue;
+                }
+                if (instance == null || instance.getProtected(k) != null)  {
                     keyList.add(k);
                 }
+
             }
         }
 
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index cc8c182..f422289 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -1026,34 +1026,35 @@
         // callback is valid
         executor = checkExecutor(executor, callback);
 
-        // Make sure that there all requests have at least 1 surface; all surfaces are non-null;
-        // the surface isn't a physical stream surface for reprocessing request
-        for (CaptureRequest request : requestList) {
-            if (request.getTargets().isEmpty()) {
-                throw new IllegalArgumentException(
-                        "Each request must have at least one Surface target");
-            }
+        synchronized(mInterfaceLock) {
+            checkIfCameraClosedOrInError();
 
-            for (Surface surface : request.getTargets()) {
-                if (surface == null) {
-                    throw new IllegalArgumentException("Null Surface targets are not allowed");
+            // Make sure that there all requests have at least 1 surface; all surfaces are non-null;
+            // the surface isn't a physical stream surface for reprocessing request
+            for (CaptureRequest request : requestList) {
+                if (request.getTargets().isEmpty()) {
+                    throw new IllegalArgumentException(
+                            "Each request must have at least one Surface target");
                 }
 
-                for (int i = 0; i < mConfiguredOutputs.size(); i++) {
-                    OutputConfiguration configuration = mConfiguredOutputs.valueAt(i);
-                    if (configuration.isForPhysicalCamera()
-                            && configuration.getSurfaces().contains(surface)) {
-                        if (request.isReprocess()) {
-                            throw new IllegalArgumentException(
-                                    "Reprocess request on physical stream is not allowed");
+                for (Surface surface : request.getTargets()) {
+                    if (surface == null) {
+                        throw new IllegalArgumentException("Null Surface targets are not allowed");
+                    }
+
+                    for (int i = 0; i < mConfiguredOutputs.size(); i++) {
+                        OutputConfiguration configuration = mConfiguredOutputs.valueAt(i);
+                        if (configuration.isForPhysicalCamera()
+                                && configuration.getSurfaces().contains(surface)) {
+                            if (request.isReprocess()) {
+                                throw new IllegalArgumentException(
+                                        "Reprocess request on physical stream is not allowed");
+                            }
                         }
                     }
                 }
             }
-        }
 
-        synchronized(mInterfaceLock) {
-            checkIfCameraClosedOrInError();
             if (repeating) {
                 stopRepeating();
             }
@@ -2337,20 +2338,33 @@
             final CaptureCallbackHolder holder =
                     CameraDeviceImpl.this.mCaptureCallbackMap.get(requestId);
 
+            if (holder == null) {
+                Log.e(TAG, String.format("Receive capture error on unknown request ID %d",
+                        requestId));
+                return;
+            }
+
             final CaptureRequest request = holder.getRequest(subsequenceId);
 
             Runnable failureDispatch = null;
             if (errorCode == ERROR_CAMERA_BUFFER) {
                 // Because 1 stream id could map to multiple surfaces, we need to specify both
                 // streamId and surfaceId.
-                List<Surface> surfaces =
-                        mConfiguredOutputs.get(resultExtras.getErrorStreamId()).getSurfaces();
-                for (Surface surface : surfaces) {
+                OutputConfiguration config = mConfiguredOutputs.get(
+                        resultExtras.getErrorStreamId());
+                if (config == null) {
+                    Log.v(TAG, String.format(
+                            "Stream %d has been removed. Skipping buffer lost callback",
+                            resultExtras.getErrorStreamId()));
+                    return;
+                }
+                for (Surface surface : config.getSurfaces()) {
                     if (!request.containsTarget(surface)) {
                         continue;
                     }
                     if (DEBUG) {
-                        Log.v(TAG, String.format("Lost output buffer reported for frame %d, target %s",
+                        Log.v(TAG, String.format(
+                                "Lost output buffer reported for frame %d, target %s",
                                 frameNumber, surface));
                     }
                     failureDispatch = new Runnable() {
diff --git a/core/java/android/hardware/radio/TunerAdapter.java b/core/java/android/hardware/radio/TunerAdapter.java
index be2846f..aa5480a 100644
--- a/core/java/android/hardware/radio/TunerAdapter.java
+++ b/core/java/android/hardware/radio/TunerAdapter.java
@@ -271,6 +271,8 @@
             mCallback.setProgramListObserver(list, () -> {
                 try {
                     mTuner.stopProgramListUpdates();
+                } catch (IllegalStateException ex) {
+                    // it's fine to not stop updates if tuner is already closed
                 } catch (RemoteException ex) {
                     Log.e(TAG, "Couldn't stop program list updates", ex);
                 }
diff --git a/core/java/android/hardware/radio/TunerCallbackAdapter.java b/core/java/android/hardware/radio/TunerCallbackAdapter.java
index 0fb93e5..beff0f7 100644
--- a/core/java/android/hardware/radio/TunerCallbackAdapter.java
+++ b/core/java/android/hardware/radio/TunerCallbackAdapter.java
@@ -211,10 +211,12 @@
 
     @Override
     public void onProgramListUpdated(ProgramList.Chunk chunk) {
-        synchronized (mLock) {
-            if (mProgramList == null) return;
-            mProgramList.apply(Objects.requireNonNull(chunk));
-        }
+        mHandler.post(() -> {
+            synchronized (mLock) {
+                if (mProgramList == null) return;
+                mProgramList.apply(Objects.requireNonNull(chunk));
+            }
+        });
     }
 
     @Override
diff --git a/core/java/android/inputmethodservice/SoftInputWindow.java b/core/java/android/inputmethodservice/SoftInputWindow.java
index 0513fee..356b344 100644
--- a/core/java/android/inputmethodservice/SoftInputWindow.java
+++ b/core/java/android/inputmethodservice/SoftInputWindow.java
@@ -21,6 +21,7 @@
 import android.annotation.IntDef;
 import android.app.Dialog;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.graphics.Rect;
 import android.os.Debug;
 import android.os.IBinder;
@@ -50,6 +51,7 @@
     final int mWindowType;
     final int mGravity;
     final boolean mTakesFocus;
+    final boolean mAutomotiveHideNavBarForKeyboard;
     private final Rect mBounds = new Rect();
 
     @Retention(SOURCE)
@@ -134,6 +136,8 @@
         mWindowType = windowType;
         mGravity = gravity;
         mTakesFocus = takesFocus;
+        mAutomotiveHideNavBarForKeyboard = context.getResources().getBoolean(
+                com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard);
         initDockWindow();
     }
 
@@ -247,6 +251,11 @@
             windowModFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
         }
 
+        if (isAutomotive() && mAutomotiveHideNavBarForKeyboard) {
+            windowSetFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
+            windowModFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
+        }
+
         getWindow().setFlags(windowSetFlags, windowModFlags);
     }
 
@@ -338,6 +347,10 @@
         mWindowState = newState;
     }
 
+    private boolean isAutomotive() {
+        return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+    }
+
     private static String stateToString(@SoftInputWindowState int state) {
         switch (state) {
             case SoftInputWindowState.TOKEN_PENDING:
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 00d522b..ecd16dd 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -266,8 +266,11 @@
      *   - Fixed bug in min learned capacity updating process.
      * New in version 34:
      *   - Deprecated STATS_SINCE_UNPLUGGED and STATS_CURRENT.
+     * New in version 35:
+     *   - Fixed bug that was not reporting high cellular tx power correctly
+     *   - Added out of service and emergency service modes to data connection types
      */
-    static final int CHECKIN_VERSION = 34;
+    static final int CHECKIN_VERSION = 35;
 
     /**
      * Old version, we hit 9 and ran out of room, need to remove.
@@ -2371,18 +2374,21 @@
      */
     public abstract int getMobileRadioActiveUnknownCount(int which);
 
-    public static final int DATA_CONNECTION_NONE = 0;
-    public static final int DATA_CONNECTION_OTHER = TelephonyManager.MAX_NETWORK_TYPE + 1;
+    public static final int DATA_CONNECTION_OUT_OF_SERVICE = 0;
+    public static final int DATA_CONNECTION_EMERGENCY_SERVICE =
+            TelephonyManager.MAX_NETWORK_TYPE + 1;
+    public static final int DATA_CONNECTION_OTHER = DATA_CONNECTION_EMERGENCY_SERVICE + 1;
+
 
     static final String[] DATA_CONNECTION_NAMES = {
-        "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A",
+        "oos", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A",
         "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte",
         "ehrpd", "hspap", "gsm", "td_scdma", "iwlan", "lte_ca", "nr",
-        "other"
+        "emngcy", "other"
     };
 
     @UnsupportedAppUsage
-    public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1;
+    public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER + 1;
 
     /**
      * Returns the time in microseconds that the phone has been running with
@@ -6564,6 +6570,10 @@
                 }
                 oldState = rec.states;
                 oldState2 = rec.states2;
+                // Clear High Tx Power Flag for volta positioning
+                if ((rec.states2 & HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG) != 0) {
+                    rec.states2 &= ~HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG;
+                }
             }
 
             return item.toString();
@@ -7865,9 +7875,9 @@
         // Phone data connection (DATA_CONNECTION_TIME_DATA and DATA_CONNECTION_COUNT_DATA)
         for (int i = 0; i < NUM_DATA_CONNECTION_TYPES; ++i) {
             // Map OTHER to TelephonyManager.NETWORK_TYPE_UNKNOWN and mark NONE as a boolean.
-            boolean isNone = (i == DATA_CONNECTION_NONE);
+            boolean isNone = (i == DATA_CONNECTION_OUT_OF_SERVICE);
             int telephonyNetworkType = i;
-            if (i == DATA_CONNECTION_OTHER) {
+            if (i == DATA_CONNECTION_OTHER || i == DATA_CONNECTION_EMERGENCY_SERVICE) {
                 telephonyNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
             }
             final long pdcToken = proto.start(SystemProto.DATA_CONNECTION);
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index ce1942c..7a70e93 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -67,6 +67,8 @@
     private static final String PROPERTY_GFX_DRIVER_PRERELEASE = "ro.gfx.driver.1";
     private static final String PROPERTY_GFX_DRIVER_BUILD_TIME = "ro.gfx.driver_build_time";
     private static final String METADATA_DRIVER_BUILD_TIME = "com.android.gamedriver.build_time";
+    private static final String METADATA_DEVELOPER_DRIVER_ENABLE =
+            "com.android.graphics.developerdriver.enable";
     private static final String ANGLE_RULES_FILE = "a4a_rules.json";
     private static final String ANGLE_TEMP_RULES = "debug.angle.rules";
     private static final String ACTION_ANGLE_FOR_ANDROID = "android.app.action.ANGLE_FOR_ANDROID";
@@ -691,7 +693,8 @@
     /**
      * Return the driver package name to use. Return null for system driver.
      */
-    private static String chooseDriverInternal(Context context, Bundle coreSettings) {
+    private static String chooseDriverInternal(
+            Context context, Bundle coreSettings, PackageManager pm, String packageName) {
         final String gameDriver = SystemProperties.get(PROPERTY_GFX_DRIVER);
         final boolean hasGameDriver = gameDriver != null && !gameDriver.isEmpty();
 
@@ -706,12 +709,24 @@
         // To minimize risk of driver updates crippling the device beyond user repair, never use an
         // updated driver for privileged or non-updated system apps. Presumably pre-installed apps
         // were tested thoroughly with the pre-installed driver.
-        final ApplicationInfo ai = context.getApplicationInfo();
+        ApplicationInfo ai;
+        try {
+            // Get the ApplicationInfo from PackageManager so that metadata fields present.
+            ai = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
+        } catch (PackageManager.NameNotFoundException e) {
+            // Unlikely to fail for applications, but in case of failure, fall back to use the
+            // ApplicationInfo from context directly.
+            ai = context.getApplicationInfo();
+        }
         if (ai.isPrivilegedApp() || (ai.isSystemApp() && !ai.isUpdatedSystemApp())) {
             if (DEBUG) Log.v(TAG, "Ignoring driver package for privileged/non-updated system app.");
             return null;
         }
 
+        final boolean enablePrereleaseDriver =
+                (ai.metaData != null && ai.metaData.getBoolean(METADATA_DEVELOPER_DRIVER_ENABLE))
+                || getCanLoadSystemLibraries() == 1;
+
         // Priority for Game Driver settings global on confliction (Higher priority comes first):
         // 1. GAME_DRIVER_ALL_APPS
         // 2. GAME_DRIVER_OPT_OUT_APPS
@@ -728,7 +743,7 @@
                 return hasGameDriver ? gameDriver : null;
             case GAME_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER:
                 if (DEBUG) Log.v(TAG, "All apps opt in to use prerelease driver.");
-                return hasPrereleaseDriver ? prereleaseDriver : null;
+                return hasPrereleaseDriver && enablePrereleaseDriver ? prereleaseDriver : null;
             case GAME_DRIVER_GLOBAL_OPT_IN_DEFAULT:
             default:
                 break;
@@ -745,7 +760,7 @@
                     null, coreSettings, Settings.Global.GAME_DRIVER_PRERELEASE_OPT_IN_APPS)
                         .contains(appPackageName)) {
             if (DEBUG) Log.v(TAG, "App opts in for prerelease Game Driver.");
-            return hasPrereleaseDriver ? prereleaseDriver : null;
+            return hasPrereleaseDriver && enablePrereleaseDriver ? prereleaseDriver : null;
         }
 
         // Early return here since the rest logic is only for Game Driver.
@@ -783,7 +798,8 @@
      */
     private static boolean chooseDriver(
             Context context, Bundle coreSettings, PackageManager pm, String packageName) {
-        final String driverPackageName = chooseDriverInternal(context, coreSettings);
+        final String driverPackageName = chooseDriverInternal(context, coreSettings, pm,
+                packageName);
         if (driverPackageName == null) {
             return false;
         }
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index 182a2ff..2934c5d 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -25,14 +25,15 @@
 import android.annotation.TestApi;
 import android.content.Context;
 import android.content.pm.IPackageManager;
+import android.content.pm.permission.SplitPermissionInfoParcelable;
 import android.os.RemoteException;
+import android.util.Log;
 
 import com.android.internal.annotations.Immutable;
-import com.android.server.SystemConfig;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
-import java.util.Objects;
 
 /**
  * System level service for accessing the permission capabilities of the platform.
@@ -43,18 +44,14 @@
 @SystemApi
 @SystemService(Context.PERMISSION_SERVICE)
 public final class PermissionManager {
-    /**
-     * {@link android.content.pm.PackageParser} needs access without having a {@link Context}.
-     *
-     * @hide
-     */
-    public static final ArrayList<SplitPermissionInfo> SPLIT_PERMISSIONS =
-            SystemConfig.getInstance().getSplitPermissions();
+    private static final String TAG = PermissionManager.class.getName();
 
     private final @NonNull Context mContext;
 
     private final IPackageManager mPackageManager;
 
+    private List<SplitPermissionInfo> mSplitPermissionInfos;
+
     /**
      * Creates a new instance.
      *
@@ -122,7 +119,48 @@
      * @return All permissions that are split.
      */
     public @NonNull List<SplitPermissionInfo> getSplitPermissions() {
-        return SPLIT_PERMISSIONS;
+        if (mSplitPermissionInfos != null) {
+            return mSplitPermissionInfos;
+        }
+
+        List<SplitPermissionInfoParcelable> parcelableList;
+        try {
+            parcelableList = mPackageManager.getSplitPermissions();
+        } catch (RemoteException e) {
+            Log.w(TAG, "Error getting split permissions", e);
+            return Collections.emptyList();
+        }
+
+        mSplitPermissionInfos = splitPermissionInfoListToNonParcelableList(parcelableList);
+
+        return mSplitPermissionInfos;
+    }
+
+    private List<SplitPermissionInfo> splitPermissionInfoListToNonParcelableList(
+            List<SplitPermissionInfoParcelable> parcelableList) {
+        final int size = parcelableList.size();
+        List<SplitPermissionInfo> list = new ArrayList<>(size);
+        for (int i = 0; i < size; i++) {
+            list.add(new SplitPermissionInfo(parcelableList.get(i)));
+        }
+        return list;
+    }
+
+    /**
+     * Converts a {@link List} of {@link SplitPermissionInfo} into a List of
+     * {@link SplitPermissionInfoParcelable} and returns it.
+     * @hide
+     */
+    public static List<SplitPermissionInfoParcelable> splitPermissionInfoListToParcelableList(
+            List<SplitPermissionInfo> splitPermissionsList) {
+        final int size = splitPermissionsList.size();
+        List<SplitPermissionInfoParcelable> outList = new ArrayList<>(size);
+        for (int i = 0; i < size; i++) {
+            SplitPermissionInfo info = splitPermissionsList.get(i);
+            outList.add(new SplitPermissionInfoParcelable(
+                    info.getSplitPermission(), info.getNewPermissions(), info.getTargetSdk()));
+        }
+        return outList;
     }
 
     /**
@@ -131,44 +169,40 @@
      */
     @Immutable
     public static final class SplitPermissionInfo {
-        private final @NonNull String mSplitPerm;
-        private final @NonNull List<String> mNewPerms;
-        private final int mTargetSdk;
+        private @NonNull final SplitPermissionInfoParcelable mSplitPermissionInfoParcelable;
 
         @Override
         public boolean equals(Object o) {
             if (this == o) return true;
             if (o == null || getClass() != o.getClass()) return false;
             SplitPermissionInfo that = (SplitPermissionInfo) o;
-            return mTargetSdk == that.mTargetSdk
-                    && mSplitPerm.equals(that.mSplitPerm)
-                    && mNewPerms.equals(that.mNewPerms);
+            return mSplitPermissionInfoParcelable.equals(that.mSplitPermissionInfoParcelable);
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(mSplitPerm, mNewPerms, mTargetSdk);
+            return mSplitPermissionInfoParcelable.hashCode();
         }
 
         /**
          * Get the permission that is split.
          */
         public @NonNull String getSplitPermission() {
-            return mSplitPerm;
+            return mSplitPermissionInfoParcelable.getSplitPermission();
         }
 
         /**
          * Get the permissions that are added.
          */
         public @NonNull List<String> getNewPermissions() {
-            return mNewPerms;
+            return mSplitPermissionInfoParcelable.getNewPermissions();
         }
 
         /**
          * Get the target API level when the permission was split.
          */
         public int getTargetSdk() {
-            return mTargetSdk;
+            return mSplitPermissionInfoParcelable.getTargetSdk();
         }
 
         /**
@@ -182,9 +216,11 @@
          */
         public SplitPermissionInfo(@NonNull String splitPerm, @NonNull List<String> newPerms,
                 int targetSdk) {
-            mSplitPerm = splitPerm;
-            mNewPerms = newPerms;
-            mTargetSdk = targetSdk;
+            this(new SplitPermissionInfoParcelable(splitPerm, newPerms, targetSdk));
+        }
+
+        private SplitPermissionInfo(@NonNull SplitPermissionInfoParcelable parcelable) {
+            mSplitPermissionInfoParcelable = parcelable;
         }
     }
 }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 209a364..27033ab 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8362,6 +8362,19 @@
                 BOOLEAN_VALIDATOR;
 
         /**
+         * Whether or not a user should re enroll their face.
+         *
+         * Face unlock re enroll.
+         *  0 = No re enrollment.
+         *  1 = Re enrollment is suggested.
+         *  2 = Re enrollment is required after a set time period.
+         *  3 = Re enrollment is required immediately.
+         *
+         * @hide
+         */
+        public static final String FACE_UNLOCK_RE_ENROLL = "face_unlock_re_enroll";
+
+        /**
          * Whether or not debugging is enabled.
          * @hide
          */
@@ -8697,10 +8710,16 @@
          * Whether the notification bubbles are globally enabled
          * The value is boolean (1 or 0).
          * @hide
+         * @deprecated use {@link Global#NOTIFICATION_BUBBLES} instead.
          */
         @TestApi
+        @Deprecated
         public static final String NOTIFICATION_BUBBLES = "notification_bubbles";
 
+        /**
+         * @deprecated use {@link Global#NOTIFICATION_BUBBLES_VALIDATOR} instead.
+         */
+        @Deprecated
         private static final Validator NOTIFICATION_BUBBLES_VALIDATOR = BOOLEAN_VALIDATOR;
 
         /**
@@ -9011,8 +9030,6 @@
             DOZE_PICK_UP_GESTURE,
             DOZE_DOUBLE_TAP_GESTURE,
             DOZE_TAP_SCREEN_GESTURE,
-            DOZE_WAKE_LOCK_SCREEN_GESTURE,
-            DOZE_WAKE_DISPLAY_GESTURE,
             NFC_PAYMENT_DEFAULT_COMPONENT,
             AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
             FACE_UNLOCK_KEYGUARD_ENABLED,
@@ -9020,12 +9037,8 @@
             FACE_UNLOCK_DISMISSES_KEYGUARD,
             FACE_UNLOCK_APP_ENABLED,
             FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
-            ASSIST_GESTURE_ENABLED,
-            ASSIST_GESTURE_SILENCE_ALERTS_ENABLED,
-            ASSIST_GESTURE_WAKE_ENABLED,
             VR_DISPLAY_MODE,
             NOTIFICATION_BADGING,
-            NOTIFICATION_BUBBLES,
             NOTIFICATION_DISMISS_RTL,
             QS_AUTO_ADDED_TILES,
             SCREENSAVER_ENABLED,
@@ -9056,12 +9069,9 @@
             TRUST_AGENTS_EXTEND_UNLOCK,
             UI_NIGHT_MODE,
             LOCK_SCREEN_WHEN_TRUST_LOST,
-            SKIP_GESTURE,
             SKIP_DIRECTION,
-            SILENCE_GESTURE,
             THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
             NAVIGATION_MODE,
-            AWARE_ENABLED,
             SKIP_GESTURE_COUNT,
             SKIP_TOUCH_COUNT,
             SILENCE_ALARMS_GESTURE_COUNT,
@@ -9394,6 +9404,16 @@
         public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/global");
 
         /**
+         * Whether the notification bubbles are globally enabled
+         * The value is boolean (1 or 0).
+         * @hide
+         */
+        @TestApi
+        public static final String NOTIFICATION_BUBBLES = "notification_bubbles";
+
+        private static final Validator NOTIFICATION_BUBBLES_VALIDATOR = BOOLEAN_VALIDATOR;
+
+        /**
          * Whether users are allowed to add more users or guest from lockscreen.
          * <p>
          * Type: int
@@ -13852,6 +13872,7 @@
             ZEN_DURATION,
             CHARGING_VIBRATION_ENABLED,
             AWARE_ALLOWED,
+            NOTIFICATION_BUBBLES,
         };
 
         /**
@@ -13918,6 +13939,7 @@
             VALIDATORS.put(AWARE_ALLOWED, AWARE_ALLOWED_VALIDATOR);
             VALIDATORS.put(POWER_BUTTON_LONG_PRESS, POWER_BUTTON_LONG_PRESS_VALIDATOR);
             VALIDATORS.put(POWER_BUTTON_VERY_LONG_PRESS, POWER_BUTTON_VERY_LONG_PRESS_VALIDATOR);
+            VALIDATORS.put(NOTIFICATION_BUBBLES, NOTIFICATION_BUBBLES_VALIDATOR);
         }
 
         /**
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index cb7d41b..93bcdbf 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -1639,7 +1639,7 @@
         @UnsupportedAppUsage
         public String name;              // required for automatic
         @UnsupportedAppUsage
-        public int zenMode;
+        public int zenMode;             // ie: Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
         @UnsupportedAppUsage
         public Uri conditionId;          // required for automatic
         public Condition condition;      // optional
diff --git a/core/java/android/service/textclassifier/TextClassifierService.java b/core/java/android/service/textclassifier/TextClassifierService.java
index 30c4e90..bb39be2 100644
--- a/core/java/android/service/textclassifier/TextClassifierService.java
+++ b/core/java/android/service/textclassifier/TextClassifierService.java
@@ -51,7 +51,6 @@
 
 import com.android.internal.util.Preconditions;
 
-import java.lang.ref.WeakReference;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
@@ -431,23 +430,18 @@
      * Forwards the callback result to a wrapped binder callback.
      */
     private static final class ProxyCallback<T extends Parcelable> implements Callback<T> {
-        private WeakReference<ITextClassifierCallback> mTextClassifierCallback;
+        private ITextClassifierCallback mTextClassifierCallback;
 
         private ProxyCallback(ITextClassifierCallback textClassifierCallback) {
-            mTextClassifierCallback =
-                    new WeakReference<>(Preconditions.checkNotNull(textClassifierCallback));
+            mTextClassifierCallback = Preconditions.checkNotNull(textClassifierCallback);
         }
 
         @Override
         public void onSuccess(T result) {
-            ITextClassifierCallback callback = mTextClassifierCallback.get();
-            if (callback == null) {
-                return;
-            }
             try {
                 Bundle bundle = new Bundle(1);
                 bundle.putParcelable(KEY_RESULT, result);
-                callback.onSuccess(bundle);
+                mTextClassifierCallback.onSuccess(bundle);
             } catch (RemoteException e) {
                 Slog.d(LOG_TAG, "Error calling callback");
             }
@@ -455,12 +449,8 @@
 
         @Override
         public void onFailure(CharSequence error) {
-            ITextClassifierCallback callback = mTextClassifierCallback.get();
-            if (callback == null) {
-                return;
-            }
             try {
-                callback.onFailure();
+                mTextClassifierCallback.onFailure();
             } catch (RemoteException e) {
                 Slog.d(LOG_TAG, "Error calling callback");
             }
diff --git a/core/java/android/view/GestureExclusionTracker.java b/core/java/android/view/GestureExclusionTracker.java
index 6fcdd71..fffb323e 100644
--- a/core/java/android/view/GestureExclusionTracker.java
+++ b/core/java/android/view/GestureExclusionTracker.java
@@ -44,7 +44,7 @@
         while (i.hasNext()) {
             final GestureExclusionViewInfo info = i.next();
             final View v = info.getView();
-            if (v == null || !v.isAttachedToWindow()) {
+            if (v == null || !v.isAttachedToWindow() || !v.isAggregatedVisible()) {
                 mGestureExclusionViewsChanged = true;
                 i.remove();
                 continue;
@@ -122,7 +122,8 @@
 
         public int update() {
             final View excludedView = getView();
-            if (excludedView == null || !excludedView.isAttachedToWindow()) return GONE;
+            if (excludedView == null || !excludedView.isAttachedToWindow()
+                    || !excludedView.isAggregatedVisible()) return GONE;
             final List<Rect> localRects = excludedView.getSystemGestureExclusionRects();
             final List<Rect> newRects = new ArrayList<>(localRects.size());
             for (Rect src : localRects) {
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 3c045f4..2313b13 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -84,7 +84,6 @@
     private static native long nativeCopyFromSurfaceControl(long nativeObject);
     private static native void nativeWriteToParcel(long nativeObject, Parcel out);
     private static native void nativeRelease(long nativeObject);
-    private static native void nativeDestroy(long nativeObject);
     private static native void nativeDisconnect(long nativeObject);
 
     private static native ScreenshotGraphicBuffer nativeScreenshot(IBinder displayToken,
@@ -930,19 +929,6 @@
     }
 
     /**
-     * Release the local resources like {@link #release} but also
-     * remove the Surface from the screen.
-     * @hide
-     */
-    public void remove() {
-        if (mNativeObject != 0) {
-            nativeDestroy(mNativeObject);
-            mNativeObject = 0;
-        }
-        mCloseGuard.close();
-    }
-
-    /**
      * Disconnect any client still connected to the surface.
      * @hide
      */
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 254d04e..d11548d 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -23,7 +23,6 @@
 import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.CompatibilityInfo.Translator;
-import android.content.res.Configuration;
 import android.graphics.BlendMode;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -100,10 +99,10 @@
 public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallback {
     private static final String TAG = "SurfaceView";
     private static final boolean DEBUG = false;
+    private static final boolean DEBUG_POSITION = false;
 
     @UnsupportedAppUsage
-    final ArrayList<SurfaceHolder.Callback> mCallbacks
-            = new ArrayList<SurfaceHolder.Callback>();
+    final ArrayList<SurfaceHolder.Callback> mCallbacks = new ArrayList<>();
 
     final int[] mLocation = new int[2];
 
@@ -126,8 +125,8 @@
     // we need to preserve the old one until the new one has drawn.
     SurfaceControl mDeferredDestroySurfaceControl;
     SurfaceControl mBackgroundControl;
+    final Object mSurfaceControlLock = new Object();
     final Rect mTmpRect = new Rect();
-    final Configuration mConfiguration = new Configuration();
 
     Paint mRoundedViewportPaint;
 
@@ -137,25 +136,16 @@
     boolean mIsCreating = false;
     private volatile boolean mRtHandlingPositionUpdates = false;
 
-    private final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener
-            = new ViewTreeObserver.OnScrollChangedListener() {
-                    @Override
-                    public void onScrollChanged() {
-                        updateSurface();
-                    }
-            };
+    private final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener =
+            this::updateSurface;
 
     @UnsupportedAppUsage
-    private final ViewTreeObserver.OnPreDrawListener mDrawListener =
-            new ViewTreeObserver.OnPreDrawListener() {
-                @Override
-                public boolean onPreDraw() {
-                    // reposition ourselves where the surface is
-                    mHaveFrame = getWidth() > 0 && getHeight() > 0;
-                    updateSurface();
-                    return true;
-                }
-            };
+    private final ViewTreeObserver.OnPreDrawListener mDrawListener = () -> {
+        // reposition ourselves where the surface is
+        mHaveFrame = getWidth() > 0 && getHeight() > 0;
+        updateSurface();
+        return true;
+    };
 
     boolean mRequestedVisible = false;
     boolean mWindowVisibility = false;
@@ -173,6 +163,9 @@
     @UnsupportedAppUsage
     int mRequestedFormat = PixelFormat.RGB_565;
 
+    boolean mUseAlpha = false;
+    float mSurfaceAlpha = 1f;
+
     @UnsupportedAppUsage
     boolean mHaveFrame = false;
     boolean mSurfaceCreated = false;
@@ -190,7 +183,6 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     final Rect mSurfaceFrame = new Rect();
     int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1;
-    private Translator mTranslator;
 
     private boolean mGlobalListenersAdded;
     private boolean mAttachedToWindow;
@@ -200,6 +192,7 @@
     private int mPendingReportDraws;
 
     private SurfaceControl.Transaction mRtTransaction = new SurfaceControl.Transaction();
+    private SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction();
 
     public SurfaceView(Context context) {
         this(context, null);
@@ -288,6 +281,152 @@
         updateSurface();
     }
 
+    /**
+     * Make alpha value of this view reflect onto the surface. This can only be called from at most
+     * one SurfaceView within a view tree.
+     *
+     * <p class="note"><strong>Note:</strong> Alpha value of the view is ignored and the underlying
+     * surface is rendered opaque by default.</p>
+     *
+     * @hide
+     */
+    public void setUseAlpha() {
+        if (!mUseAlpha) {
+            mUseAlpha = true;
+            updateSurfaceAlpha();
+        }
+    }
+
+    @Override
+    public void setAlpha(float alpha) {
+        // Sets the opacity of the view to a value, where 0 means the view is completely transparent
+        // and 1 means the view is completely opaque.
+        //
+        // Note: Alpha value of this view is ignored by default. To enable alpha blending, you need
+        // to call setUseAlpha() as well.
+        // This view doesn't support translucent opacity if the view is located z-below, since the
+        // logic to punch a hole in the view hierarchy cannot handle such case. See also
+        // #clearSurfaceViewPort(Canvas)
+        if (DEBUG) {
+            Log.d(TAG, System.identityHashCode(this)
+                    + " setAlpha: mUseAlpha = " + mUseAlpha + " alpha=" + alpha);
+        }
+        super.setAlpha(alpha);
+        updateSurfaceAlpha();
+    }
+
+    private float getFixedAlpha() {
+        // Compute alpha value to be set on the underlying surface.
+        final float alpha = getAlpha();
+        return mUseAlpha && (mSubLayer > 0 || alpha == 0f) ? alpha : 1f;
+    }
+
+    private void updateSurfaceAlpha() {
+        if (!mUseAlpha) {
+            if (DEBUG) {
+                Log.d(TAG, System.identityHashCode(this)
+                        + " updateSurfaceAlpha: setUseAlpha() is not called, ignored.");
+            }
+            return;
+        }
+        final float viewAlpha = getAlpha();
+        if (mSubLayer < 0 && 0f < viewAlpha && viewAlpha < 1f) {
+            Log.w(TAG, System.identityHashCode(this)
+                    + " updateSurfaceAlpha:"
+                    + " translucent color is not supported for a surface placed z-below.");
+        }
+        if (!mHaveFrame) {
+            if (DEBUG) {
+                Log.d(TAG, System.identityHashCode(this)
+                        + " updateSurfaceAlpha: has no surface.");
+            }
+            return;
+        }
+        final ViewRootImpl viewRoot = getViewRootImpl();
+        if (viewRoot == null) {
+            if (DEBUG) {
+                Log.d(TAG, System.identityHashCode(this)
+                        + " updateSurfaceAlpha: ViewRootImpl not available.");
+            }
+            return;
+        }
+        if (mSurfaceControl == null) {
+            if (DEBUG) {
+                Log.d(TAG, System.identityHashCode(this)
+                        + "updateSurfaceAlpha:"
+                        + " surface is not yet created, or already released.");
+            }
+            return;
+        }
+        final Surface parent = viewRoot.mSurface;
+        if (parent == null || !parent.isValid()) {
+            if (DEBUG) {
+                Log.d(TAG, System.identityHashCode(this)
+                        + " updateSurfaceAlpha: ViewRootImpl has no valid surface");
+            }
+            return;
+        }
+        final float alpha = getFixedAlpha();
+        if (alpha != mSurfaceAlpha) {
+            if (isHardwareAccelerated()) {
+                /*
+                 * Schedule a callback that reflects an alpha value onto the underlying surfaces.
+                 * This gets called on a RenderThread worker thread, so members accessed here must
+                 * be protected by a lock.
+                 */
+                viewRoot.registerRtFrameCallback(frame -> {
+                    try {
+                        final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+                        synchronized (mSurfaceControlLock) {
+                            if (!parent.isValid()) {
+                                if (DEBUG) {
+                                    Log.d(TAG, System.identityHashCode(this)
+                                            + " updateSurfaceAlpha RT:"
+                                            + " ViewRootImpl has no valid surface");
+                                }
+                                return;
+                            }
+                            if (mSurfaceControl == null) {
+                                if (DEBUG) {
+                                    Log.d(TAG, System.identityHashCode(this)
+                                            + "updateSurfaceAlpha RT:"
+                                            + " mSurfaceControl has already released");
+                                }
+                                return;
+                            }
+                            if (DEBUG) {
+                                Log.d(TAG, System.identityHashCode(this)
+                                        + " updateSurfaceAlpha RT: set alpha=" + alpha);
+                            }
+                            t.setAlpha(mSurfaceControl, alpha);
+                            t.deferTransactionUntilSurface(mSurfaceControl, parent, frame);
+                        }
+                        // It's possible that mSurfaceControl is released in the UI thread before
+                        // the transaction completes. If that happens, an exception is thrown, which
+                        // must be caught immediately.
+                        t.apply();
+                    } catch (Exception e) {
+                        Log.e(TAG, System.identityHashCode(this)
+                                + "updateSurfaceAlpha RT: Exception during surface transaction", e);
+                    }
+                });
+                damageInParent();
+            } else {
+                if (DEBUG) {
+                    Log.d(TAG, System.identityHashCode(this)
+                            + " updateSurfaceAlpha: set alpha=" + alpha);
+                }
+                SurfaceControl.openTransaction();
+                try {
+                    mSurfaceControl.setAlpha(alpha);
+                } finally {
+                    SurfaceControl.closeTransaction();
+                }
+            }
+            mSurfaceAlpha = alpha;
+        }
+    }
+
     private void performDrawFinished() {
         if (mPendingReportDraws > 0) {
             mDrawFinished = true;
@@ -337,11 +476,7 @@
         mRequestedVisible = false;
 
         updateSurface();
-        if (mSurfaceControl != null) {
-            mSurfaceControl.remove();
-        }
-        mSurfaceControl = null;
-
+        releaseSurfaces();
         mHaveFrame = false;
 
         super.onDetachedFromWindow();
@@ -510,15 +645,6 @@
         }
     }
 
-    private Rect getParentSurfaceInsets() {
-        final ViewRootImpl root = getViewRootImpl();
-        if (root == null) {
-            return null;
-        } else {
-            return root.mWindowAttributes.surfaceInsets;
-        }
-    }
-
     private void updateBackgroundVisibilityInTransaction(SurfaceControl viewRoot) {
         if (mBackgroundControl == null) {
             return;
@@ -532,29 +658,40 @@
     }
 
     private void releaseSurfaces() {
-        if (mSurfaceControl != null) {
-            mSurfaceControl.remove();
-            mSurfaceControl = null;
+        synchronized (mSurfaceControlLock) {
+            if (mSurfaceControl != null) {
+                mTmpTransaction.remove(mSurfaceControl);
+                mSurfaceControl = null;
+            }
+            if (mBackgroundControl != null) {
+                mTmpTransaction.remove(mBackgroundControl);
+                mBackgroundControl = null;
+            }
+            mTmpTransaction.apply();
         }
-        if (mBackgroundControl != null) {
-            mBackgroundControl.remove();
-            mBackgroundControl = null;
-        }
+        mSurfaceAlpha = 1f;
     }
 
     /** @hide */
     protected void updateSurface() {
         if (!mHaveFrame) {
+            if (DEBUG) {
+                Log.d(TAG, System.identityHashCode(this) + " updateSurface: has no frame");
+            }
             return;
         }
         ViewRootImpl viewRoot = getViewRootImpl();
         if (viewRoot == null || viewRoot.mSurface == null || !viewRoot.mSurface.isValid()) {
+            if (DEBUG) {
+                Log.d(TAG, System.identityHashCode(this)
+                        + " updateSurface: no valid surface");
+            }
             return;
         }
 
-        mTranslator = viewRoot.mTranslator;
-        if (mTranslator != null) {
-            mSurface.setCompatibilityTranslator(mTranslator);
+        final Translator translator = viewRoot.mTranslator;
+        if (translator != null) {
+            mSurface.setCompatibilityTranslator(translator);
         }
 
         int myWidth = mRequestedWidth;
@@ -562,20 +699,25 @@
         int myHeight = mRequestedHeight;
         if (myHeight <= 0) myHeight = getHeight();
 
+        final float alpha = getFixedAlpha();
         final boolean formatChanged = mFormat != mRequestedFormat;
         final boolean visibleChanged = mVisible != mRequestedVisible;
+        final boolean alphaChanged = mSurfaceAlpha != alpha;
         final boolean creating = (mSurfaceControl == null || formatChanged || visibleChanged)
                 && mRequestedVisible;
         final boolean sizeChanged = mSurfaceWidth != myWidth || mSurfaceHeight != myHeight;
         final boolean windowVisibleChanged = mWindowVisibility != mLastWindowVisibility;
         boolean redrawNeeded = false;
 
-        if (creating || formatChanged || sizeChanged || visibleChanged || windowVisibleChanged) {
+        if (creating || formatChanged || sizeChanged || visibleChanged || (mUseAlpha
+                && alphaChanged) || windowVisibleChanged) {
             getLocationInWindow(mLocation);
 
             if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
                     + "Changes: creating=" + creating
                     + " format=" + formatChanged + " size=" + sizeChanged
+                    + " visible=" + visibleChanged + " alpha=" + alphaChanged
+                    + " mUseAlpha=" + mUseAlpha
                     + " visible=" + visibleChanged
                     + " left=" + (mWindowSpaceLeft != mLocation[0])
                     + " top=" + (mWindowSpaceTop != mLocation[1]));
@@ -593,11 +735,11 @@
                 mScreenRect.top = mWindowSpaceTop;
                 mScreenRect.right = mWindowSpaceLeft + getWidth();
                 mScreenRect.bottom = mWindowSpaceTop + getHeight();
-                if (mTranslator != null) {
-                    mTranslator.translateRectInAppWindowToScreen(mScreenRect);
+                if (translator != null) {
+                    translator.translateRectInAppWindowToScreen(mScreenRect);
                 }
 
-                final Rect surfaceInsets = getParentSurfaceInsets();
+                final Rect surfaceInsets = viewRoot.mWindowAttributes.surfaceInsets;
                 mScreenRect.offset(surfaceInsets.left, surfaceInsets.top);
 
                 if (creating) {
@@ -646,6 +788,10 @@
                             mSurfaceControl.hide();
                         }
                         updateBackgroundVisibilityInTransaction(viewRoot.getSurfaceControl());
+                        if (mUseAlpha) {
+                            mSurfaceControl.setAlpha(alpha);
+                            mSurfaceAlpha = alpha;
+                        }
 
                         // While creating the surface, we will set it's initial
                         // geometry. Outside of that though, we should generally
@@ -680,11 +826,11 @@
 
                     mSurfaceFrame.left = 0;
                     mSurfaceFrame.top = 0;
-                    if (mTranslator == null) {
+                    if (translator == null) {
                         mSurfaceFrame.right = mSurfaceWidth;
                         mSurfaceFrame.bottom = mSurfaceHeight;
                     } else {
-                        float appInvertedScale = mTranslator.applicationInvertedScale;
+                        float appInvertedScale = translator.applicationInvertedScale;
                         mSurfaceFrame.right = (int) (mSurfaceWidth * appInvertedScale + 0.5f);
                         mSurfaceFrame.bottom = (int) (mSurfaceHeight * appInvertedScale + 0.5f);
                     }
@@ -702,7 +848,7 @@
                 try {
                     redrawNeeded |= visible && !mDrawFinished;
 
-                    SurfaceHolder.Callback callbacks[] = null;
+                    SurfaceHolder.Callback[] callbacks = null;
 
                     final boolean surfaceChanged = creating;
                     if (mSurfaceCreated && (surfaceChanged || (!visible && visibleChanged))) {
@@ -788,7 +934,6 @@
                     mIsCreating = false;
                     if (mSurfaceControl != null && !mSurfaceCreated) {
                         mSurface.release();
-
                         releaseSurfaces();
                     }
                 }
@@ -818,8 +963,8 @@
                 mScreenRect.set(mWindowSpaceLeft, mWindowSpaceTop,
                         mWindowSpaceLeft + mLocation[0], mWindowSpaceTop + mLocation[1]);
 
-                if (mTranslator != null) {
-                    mTranslator.translateRectInAppWindowToScreen(mScreenRect);
+                if (translator != null) {
+                    translator.translateRectInAppWindowToScreen(mScreenRect);
                 }
 
                 if (mSurfaceControl == null) {
@@ -828,10 +973,13 @@
 
                 if (!isHardwareAccelerated() || !mRtHandlingPositionUpdates) {
                     try {
-                        if (DEBUG) Log.d(TAG, String.format("%d updateSurfacePosition UI, " +
-                                "postion = [%d, %d, %d, %d]", System.identityHashCode(this),
-                                mScreenRect.left, mScreenRect.top,
-                                mScreenRect.right, mScreenRect.bottom));
+                        if (DEBUG_POSITION) {
+                            Log.d(TAG, String.format("%d updateSurfacePosition UI, "
+                                            + "position = [%d, %d, %d, %d]",
+                                    System.identityHashCode(this),
+                                    mScreenRect.left, mScreenRect.top,
+                                    mScreenRect.right, mScreenRect.bottom));
+                        }
                         setParentSpaceRectangle(mScreenRect, -1);
                     } catch (Exception ex) {
                         Log.e(TAG, "Exception configuring surface", ex);
@@ -848,13 +996,11 @@
         }
 
         if (mDeferredDestroySurfaceControl != null) {
-            mDeferredDestroySurfaceControl.remove();
+            mTmpTransaction.remove(mDeferredDestroySurfaceControl).apply();
             mDeferredDestroySurfaceControl = null;
         }
 
-        runOnUiThread(() -> {
-            performDrawFinished();
-        });
+        runOnUiThread(this::performDrawFinished);
     }
 
     /**
@@ -884,7 +1030,6 @@
         if (mViewVisibility) {
             mRtTransaction.show(surface);
         }
-
     }
 
     private void setParentSpaceRectangle(Rect position, long frameNumber) {
@@ -925,10 +1070,10 @@
                 return;
             }
             try {
-                if (DEBUG) {
+                if (DEBUG_POSITION) {
                     Log.d(TAG, String.format(
                             "%d updateSurfacePosition RenderWorker, frameNr = %d, "
-                                    + "postion = [%d, %d, %d, %d]",
+                                    + "position = [%d, %d, %d, %d]",
                             System.identityHashCode(this), frameNumber,
                             left, top, right, bottom));
                 }
@@ -964,7 +1109,7 @@
     };
 
     private SurfaceHolder.Callback[] getSurfaceCallbacks() {
-        SurfaceHolder.Callback callbacks[];
+        SurfaceHolder.Callback[] callbacks;
         synchronized (mCallbacks) {
             callbacks = new SurfaceHolder.Callback[mCallbacks.size()];
             mCallbacks.toArray(callbacks);
@@ -1034,7 +1179,7 @@
             synchronized (mCallbacks) {
                 // This is a linear search, but in practice we'll
                 // have only a couple callbacks, so it doesn't matter.
-                if (mCallbacks.contains(callback) == false) {
+                if (!mCallbacks.contains(callback)) {
                     mCallbacks.add(callback);
                 }
             }
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 3d3d5dc..f18aa81 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -17,6 +17,7 @@
 package android.view;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.HardwareRenderer;
@@ -35,6 +36,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 
 /**
  * Threaded renderer that proxies the rendering to a render thread. Most calls
@@ -300,7 +302,8 @@
     private boolean mEnabled;
     private boolean mRequested = true;
 
-    private FrameDrawingCallback mNextRtFrameCallback;
+    @Nullable
+    private ArrayList<FrameDrawingCallback> mNextRtFrameCallbacks;
 
     ThreadedRenderer(Context context, boolean translucent, String name) {
         super();
@@ -441,8 +444,11 @@
      *
      * @param callback The callback to register.
      */
-    void registerRtFrameCallback(FrameDrawingCallback callback) {
-        mNextRtFrameCallback = callback;
+    void registerRtFrameCallback(@NonNull FrameDrawingCallback callback) {
+        if (mNextRtFrameCallbacks == null) {
+            mNextRtFrameCallbacks = new ArrayList<>();
+        }
+        mNextRtFrameCallbacks.add(callback);
     }
 
     /**
@@ -583,10 +589,14 @@
         // Consume and set the frame callback after we dispatch draw to the view above, but before
         // onPostDraw below which may reset the callback for the next frame.  This ensures that
         // updates to the frame callback during scroll handling will also apply in this frame.
-        final FrameDrawingCallback callback = mNextRtFrameCallback;
-        mNextRtFrameCallback = null;
-        if (callback != null) {
-            setFrameCallback(callback);
+        if (mNextRtFrameCallbacks != null) {
+            final ArrayList<FrameDrawingCallback> frameCallbacks = mNextRtFrameCallbacks;
+            mNextRtFrameCallbacks = null;
+            setFrameCallback(frame -> {
+                for (int i = 0; i < frameCallbacks.size(); ++i) {
+                    frameCallbacks.get(i).onFrameDraw(frame);
+                }
+            });
         }
 
         if (mRootNodeNeedsUpdate || !mRootNode.hasDisplayList()) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 4e86e60..c6536bb 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -14344,6 +14344,14 @@
     }
 
     /**
+     * @return true if this view and all ancestors are visible as of the last
+     * {@link #onVisibilityAggregated(boolean)} call.
+     */
+    boolean isAggregatedVisible() {
+        return (mPrivateFlags3 & PFLAG3_AGGREGATED_VISIBLE) != 0;
+    }
+
+    /**
      * Internal dispatching method for {@link #onVisibilityAggregated}. Overridden by
      * ViewGroup. Intended to only be called when {@link #isAttachedToWindow()},
      * {@link #getWindowVisibility()} is {@link #VISIBLE} and this view's parent {@link #isShown()}.
@@ -14371,7 +14379,7 @@
     @CallSuper
     public void onVisibilityAggregated(boolean isVisible) {
         // Update our internal visibility tracking so we can detect changes
-        boolean oldVisible = (mPrivateFlags3 & PFLAG3_AGGREGATED_VISIBLE) != 0;
+        boolean oldVisible = isAggregatedVisible();
         mPrivateFlags3 = isVisible ? (mPrivateFlags3 | PFLAG3_AGGREGATED_VISIBLE)
                 : (mPrivateFlags3 & ~PFLAG3_AGGREGATED_VISIBLE);
         if (isVisible && mAttachInfo != null) {
@@ -14423,6 +14431,9 @@
         }
 
         notifyAppearedOrDisappearedForContentCaptureIfNeeded(isVisible);
+        if (!getSystemGestureExclusionRects().isEmpty() && isVisible != oldVisible) {
+            postUpdateSystemGestureExclusionRects();
+        }
     }
 
     /**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 440df89..57a01a3 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1129,7 +1129,7 @@
      *
      * @param callback The callback to register.
      */
-    public void registerRtFrameCallback(FrameDrawingCallback callback) {
+    public void registerRtFrameCallback(@NonNull FrameDrawingCallback callback) {
         if (mAttachInfo.mThreadedRenderer != null) {
             mAttachInfo.mThreadedRenderer.registerRtFrameCallback(frame -> {
                 try {
@@ -1637,7 +1637,7 @@
         mSurfaceSession = null;
 
         if (mBoundsSurfaceControl != null) {
-            mBoundsSurfaceControl.remove();
+            mTransaction.remove(mBoundsSurfaceControl).apply();
             mBoundsSurface.release();
             mBoundsSurfaceControl = null;
         }
diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java
index c50a3aa..9a5f4c9 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -1074,7 +1074,7 @@
      * be called manually if you are forcing the drawing on a View or a hierarchy of Views
      * that are not attached to a Window or in the GONE state.
      *
-     * @return True if the current draw should be canceled and resceduled, false otherwise.
+     * @return True if the current draw should be canceled and rescheduled, false otherwise.
      */
     @SuppressWarnings("unchecked")
     public final boolean dispatchOnPreDraw() {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 2e5a750..36fea58 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1473,6 +1473,9 @@
          * <p>When this flag is enabled for a window, it automatically sets
          * the system UI visibility flags {@link View#SYSTEM_UI_FLAG_LAYOUT_STABLE} and
          * {@link View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}.</p>
+         *
+         * <p>Note: For devices that support
+         * {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE} this flag may be ignored.
          */
         public static final int FLAG_TRANSLUCENT_STATUS = 0x04000000;
 
@@ -1492,6 +1495,10 @@
          * <p>When this flag is enabled for a window, it automatically sets
          * the system UI visibility flags {@link View#SYSTEM_UI_FLAG_LAYOUT_STABLE} and
          * {@link View#SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION}.</p>
+         *
+         * <p>Note: For devices that support
+         * {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE} this flag can be disabled
+         * by the car manufacturers.
          */
         public static final int FLAG_TRANSLUCENT_NAVIGATION = 0x08000000;
 
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index d302c2b..032af1c 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -707,9 +707,10 @@
                         if (mBindSequence != bindSequence) {
                             return;
                         }
-                        if (matrixValues == null) {
-                            // That this app is unbound from the parent ActivityView. In this case,
-                            // calling updateCursorAnchorInfo() isn't safe.  Only clear the matrix.
+                        if (matrixValues == null || mActivityViewToScreenMatrix == null) {
+                            // Either InputBoundResult#mActivityViewToScreenMatrixValues is null
+                            // OR this app is unbound from the parent ActivityView. In this case,
+                            // calling updateCursorAnchorInfo() isn't safe. Only clear the matrix.
                             mActivityViewToScreenMatrix = null;
                             return;
                         }
diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java
index ccafa64..d3c6972 100644
--- a/core/java/android/widget/Magnifier.java
+++ b/core/java/android/widget/Magnifier.java
@@ -1035,7 +1035,7 @@
             // Destroy the renderer. This will not proceed until pending frame callbacks complete.
             mRenderer.destroy();
             mSurface.destroy();
-            mSurfaceControl.remove();
+            new SurfaceControl.Transaction().remove(mSurfaceControl).apply();
             mSurfaceSession.kill();
             mHandler.removeCallbacks(mMagnifierUpdater);
             if (mBitmap != null) {
diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java
index 51ca805..d0f8093 100644
--- a/core/java/android/widget/SelectionActionModeHelper.java
+++ b/core/java/android/widget/SelectionActionModeHelper.java
@@ -999,6 +999,7 @@
         }
 
         private void onTimeOut() {
+            Log.d(LOG_TAG, "Timeout in TextClassificationAsyncTask");
             if (getStatus() == Status.RUNNING) {
                 onPostExecute(mTimeOutResultSupplier.get());
             }
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 00206fc..cae1f38 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -24,6 +24,7 @@
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.ActivityManager;
@@ -120,6 +121,7 @@
 
 import java.io.IOException;
 import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.text.Collator;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -164,6 +166,8 @@
     public static final String LAUNCH_LOCATON_DIRECT_SHARE = "direct_share";
     private static final int APP_PREDICTION_SHARE_TARGET_QUERY_PACKAGE_LIMIT = 20;
     public static final String APP_PREDICTION_INTENT_FILTER_KEY = "intent_filter";
+
+    private boolean mIsAppPredictorComponentAvailable;
     private AppPredictor mAppPredictor;
     private AppPredictor.Callback mAppPredictorCallback;
     private Map<ChooserTarget, AppTarget> mDirectShareAppTargetCache;
@@ -176,6 +180,20 @@
     private static final boolean USE_SHORTCUT_MANAGER_FOR_DIRECT_TARGETS = true;
     private static final boolean USE_CHOOSER_TARGET_SERVICE_FOR_DIRECT_TARGETS = true;
 
+    public static final int TARGET_TYPE_DEFAULT = 0;
+    public static final int TARGET_TYPE_CHOOSER_TARGET = 1;
+    public static final int TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER = 2;
+    public static final int TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE = 3;
+
+    @IntDef(flag = false, prefix = { "TARGET_TYPE_" }, value = {
+            TARGET_TYPE_DEFAULT,
+            TARGET_TYPE_CHOOSER_TARGET,
+            TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER,
+            TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ShareTargetType {}
+
     /**
      * The transition time between placeholders for direct share to a message
      * indicating that non are available.
@@ -216,9 +234,9 @@
     private int mCurrAvailableWidth = 0;
 
     /** {@link ChooserActivity#getBaseScore} */
-    private static final float CALLER_TARGET_SCORE_BOOST = 900.f;
+    public static final float CALLER_TARGET_SCORE_BOOST = 900.f;
     /** {@link ChooserActivity#getBaseScore} */
-    private static final float SHORTCUT_TARGET_SCORE_BOOST = 90.f;
+    public static final float SHORTCUT_TARGET_SCORE_BOOST = 90.f;
     private static final String TARGET_DETAILS_FRAGMENT_TAG = "targetDetailsFragment";
     // TODO: Update to handle landscape instead of using static value
     private static final int MAX_RANKED_TARGETS = 4;
@@ -441,7 +459,7 @@
                     }
                     if (sri.resultTargets != null) {
                         mChooserListAdapter.addServiceResults(sri.originalTarget,
-                                sri.resultTargets, false);
+                                sri.resultTargets, TARGET_TYPE_CHOOSER_TARGET);
                     }
                     unbindService(sri.connection);
                     sri.connection.destroy();
@@ -472,7 +490,7 @@
                     final ServiceResultInfo resultInfo = (ServiceResultInfo) msg.obj;
                     if (resultInfo.resultTargets != null) {
                         mChooserListAdapter.addServiceResults(resultInfo.originalTarget,
-                                resultInfo.resultTargets, true);
+                                resultInfo.resultTargets, msg.arg1);
                     }
                     break;
 
@@ -491,6 +509,9 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         final long intentReceivedTime = System.currentTimeMillis();
+        // This is the only place this value is being set. Effectively final.
+        mIsAppPredictorComponentAvailable = isAppPredictionServiceAvailable();
+
         mIsSuccessfullySelected = false;
         Intent intent = getIntent();
         Parcelable targetParcelable = intent.getParcelableExtra(Intent.EXTRA_INTENT);
@@ -707,6 +728,38 @@
     }
 
     /**
+     * Returns true if app prediction service is defined and the component exists on device.
+     */
+    @VisibleForTesting
+    public boolean isAppPredictionServiceAvailable() {
+        if (getPackageManager().getAppPredictionServicePackageName() == null) {
+            // Default AppPredictionService is not defined.
+            return false;
+        }
+
+        final String appPredictionServiceName =
+                getString(R.string.config_defaultAppPredictionService);
+        if (appPredictionServiceName == null) {
+            return false;
+        }
+        final ComponentName appPredictionComponentName =
+                ComponentName.unflattenFromString(appPredictionServiceName);
+        if (appPredictionComponentName == null) {
+            return false;
+        }
+
+        // Check if the app prediction component actually exists on the device.
+        Intent intent = new Intent();
+        intent.setComponent(appPredictionComponentName);
+        if (getPackageManager().resolveService(intent, PackageManager.MATCH_ALL) == null) {
+            Log.e(TAG, "App prediction service is defined, but does not exist: "
+                    + appPredictionServiceName);
+            return false;
+        }
+        return true;
+    }
+
+    /**
      * Check if the profile currently used is a work profile.
      * @return true if it is work profile, false if it is parent profile (or no work profile is
      * set up)
@@ -766,6 +819,11 @@
             clipboardManager.setPrimaryClip(clipData);
             Toast.makeText(getApplicationContext(), R.string.copied, Toast.LENGTH_SHORT).show();
 
+            // Log share completion via copy
+            LogMaker targetLogMaker = new LogMaker(
+                    MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SYSTEM_TARGET).setSubtype(1);
+            getMetricsLogger().write(targetLogMaker);
+
             finish();
         }
     }
@@ -1178,7 +1236,7 @@
         mChooserListAdapter = (ChooserListAdapter) adapter;
         if (mCallerChooserTargets != null && mCallerChooserTargets.length > 0) {
             mChooserListAdapter.addServiceResults(null, Lists.newArrayList(mCallerChooserTargets),
-                    false);
+                    TARGET_TYPE_DEFAULT);
         }
         mChooserRowAdapter = new ChooserRowAdapter(mChooserListAdapter);
         if (listView != null) {
@@ -1524,33 +1582,32 @@
             }
         }
 
+        // If |appTargets| is not null, results are from AppPredictionService and already sorted.
+        final int shortcutType = (appTargets == null ? TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER :
+                TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE);
+
         // Match ShareShortcutInfos with DisplayResolveInfos to be able to use the old code path
         // for direct share targets. After ShareSheet is refactored we should use the
         // ShareShortcutInfos directly.
         boolean resultMessageSent = false;
         for (int i = 0; i < driList.size(); i++) {
-            List<ChooserTarget> chooserTargets = new ArrayList<>();
+            List<ShortcutManager.ShareShortcutInfo> matchingShortcuts = new ArrayList<>();
             for (int j = 0; j < resultList.size(); j++) {
                 if (driList.get(i).getResolvedComponentName().equals(
                             resultList.get(j).getTargetComponent())) {
-                    ShortcutManager.ShareShortcutInfo shareShortcutInfo = resultList.get(j);
-                    // Incoming results are ordered but without a score. Create a score
-                    // based on the index in order to be sorted appropriately when joined
-                    // with legacy direct share api results.
-                    float score = Math.max(1.0f - (0.05f * j), 0.0f);
-                    ChooserTarget chooserTarget = convertToChooserTarget(shareShortcutInfo, score);
-                    chooserTargets.add(chooserTarget);
-                    if (mDirectShareAppTargetCache != null && appTargets != null) {
-                        mDirectShareAppTargetCache.put(chooserTarget, appTargets.get(j));
-                    }
+                    matchingShortcuts.add(resultList.get(j));
                 }
             }
-            if (chooserTargets.isEmpty()) {
+            if (matchingShortcuts.isEmpty()) {
                 continue;
             }
+            List<ChooserTarget> chooserTargets = convertToChooserTarget(
+                    matchingShortcuts, resultList, appTargets, shortcutType);
+
             final Message msg = Message.obtain();
             msg.what = ChooserHandler.SHORTCUT_MANAGER_SHARE_TARGET_RESULT;
             msg.obj = new ServiceResultInfo(driList.get(i), chooserTargets, null);
+            msg.arg1 = shortcutType;
             mChooserHandler.sendMessage(msg);
             resultMessageSent = true;
         }
@@ -1584,23 +1641,69 @@
         return false;
     }
 
-    private ChooserTarget convertToChooserTarget(ShortcutManager.ShareShortcutInfo shareShortcut,
-                                                 float score) {
-        ShortcutInfo shortcutInfo = shareShortcut.getShortcutInfo();
-        Bundle extras = new Bundle();
-        extras.putString(Intent.EXTRA_SHORTCUT_ID, shortcutInfo.getId());
-        return new ChooserTarget(
-                // The name of this target.
-                shortcutInfo.getShortLabel(),
-                // Don't load the icon until it is selected to be shown
-                null,
-                // The ranking score for this target (0.0-1.0); the system will omit items with low
-                // scores when there are too many Direct Share items.
-                score,
-                // The name of the component to be launched if this target is chosen.
-                shareShortcut.getTargetComponent().clone(),
-                // The extra values here will be merged into the Intent when this target is chosen.
-                extras);
+    /**
+     * Converts a list of ShareShortcutInfos to ChooserTargets.
+     * @param matchingShortcuts List of shortcuts, all from the same package, that match the current
+     *                         share intent filter.
+     * @param allShortcuts List of all the shortcuts from all the packages on the device that are
+     *                    returned for the current sharing action.
+     * @param allAppTargets List of AppTargets. Null if the results are not from prediction service.
+     * @param shortcutType One of the values TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER or
+     *                    TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE
+     * @return A list of ChooserTargets sorted by score in descending order.
+     */
+    @VisibleForTesting
+    @NonNull
+    public List<ChooserTarget> convertToChooserTarget(
+            @NonNull List<ShortcutManager.ShareShortcutInfo> matchingShortcuts,
+            @NonNull List<ShortcutManager.ShareShortcutInfo> allShortcuts,
+            @Nullable List<AppTarget> allAppTargets, @ShareTargetType int shortcutType) {
+        // A set of distinct scores for the matched shortcuts. We use index of a rank in the sorted
+        // list instead of the actual rank value when converting a rank to a score.
+        List<Integer> scoreList = new ArrayList<>();
+        if (shortcutType == TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER) {
+            for (int i = 0; i < matchingShortcuts.size(); i++) {
+                int shortcutRank = matchingShortcuts.get(i).getShortcutInfo().getRank();
+                if (!scoreList.contains(shortcutRank)) {
+                    scoreList.add(shortcutRank);
+                }
+            }
+            Collections.sort(scoreList);
+        }
+
+        List<ChooserTarget> chooserTargetList = new ArrayList<>(matchingShortcuts.size());
+        for (int i = 0; i < matchingShortcuts.size(); i++) {
+            ShortcutInfo shortcutInfo = matchingShortcuts.get(i).getShortcutInfo();
+            int indexInAllShortcuts = allShortcuts.indexOf(matchingShortcuts.get(i));
+
+            float score;
+            if (shortcutType == TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE) {
+                // Incoming results are ordered. Create a score based on index in the original list.
+                score = Math.max(1.0f - (0.01f * indexInAllShortcuts), 0.0f);
+            } else {
+                // Create a score based on the rank of the shortcut.
+                int rankIndex = scoreList.indexOf(shortcutInfo.getRank());
+                score = Math.max(1.0f - (0.01f * rankIndex), 0.0f);
+            }
+
+            Bundle extras = new Bundle();
+            extras.putString(Intent.EXTRA_SHORTCUT_ID, shortcutInfo.getId());
+            ChooserTarget chooserTarget = new ChooserTarget(shortcutInfo.getShortLabel(),
+                    null, // Icon will be loaded later if this target is selected to be shown.
+                    score, matchingShortcuts.get(i).getTargetComponent().clone(), extras);
+
+            chooserTargetList.add(chooserTarget);
+            if (mDirectShareAppTargetCache != null && allAppTargets != null) {
+                mDirectShareAppTargetCache.put(chooserTarget,
+                        allAppTargets.get(indexInAllShortcuts));
+            }
+        }
+
+        // Sort ChooserTargets by score in descending order
+        Comparator<ChooserTarget> byScore =
+                (ChooserTarget a, ChooserTarget b) -> -Float.compare(a.getScore(), b.getScore());
+        Collections.sort(chooserTargetList, byScore);
+        return chooserTargetList;
     }
 
     private String convertServiceName(String packageName, String serviceName) {
@@ -1635,10 +1738,6 @@
         mServiceConnections.clear();
     }
 
-    public void onSetupVoiceInteraction() {
-        // Do nothing. We'll send the voice stuff ourselves.
-    }
-
     private void logDirectShareTargetReceived(int logCategory) {
         final long queryTime =
                 logCategory == MetricsEvent.ACTION_DIRECT_SHARE_TARGETS_LOADED_SHORTCUT_MANAGER
@@ -1693,8 +1792,10 @@
 
     @Nullable
     private AppPredictor getAppPredictor() {
-        if (mAppPredictor == null
-                    && getPackageManager().getAppPredictionServicePackageName() != null) {
+        if (!mIsAppPredictorComponentAvailable) {
+            return null;
+        }
+        if (mAppPredictor == null) {
             final IntentFilter filter = getTargetIntentFilter();
             Bundle extras = new Bundle();
             extras.putParcelable(APP_PREDICTION_INTENT_FILTER_KEY, filter);
@@ -2642,7 +2743,7 @@
          * if score is too low.
          */
         public void addServiceResults(DisplayResolveInfo origTarget, List<ChooserTarget> targets,
-                boolean isShortcutResult) {
+                @ShareTargetType int targetType) {
             if (DEBUG) {
                 Log.d(TAG, "addServiceResults " + origTarget + ", " + targets.size()
                         + " targets");
@@ -2652,9 +2753,12 @@
                 return;
             }
 
-            final float baseScore = getBaseScore(origTarget, isShortcutResult);
+            final float baseScore = getBaseScore(origTarget, targetType);
             Collections.sort(targets, mBaseTargetComparator);
 
+            final boolean isShortcutResult =
+                    (targetType == TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER
+                            || targetType == TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE);
             final int maxTargets = isShortcutResult ? mMaxShortcutTargetsPerApp
                                        : MAX_CHOOSER_TARGETS_PER_APP;
             float lastScore = 0;
@@ -2705,17 +2809,17 @@
           *   <li>Legacy direct share targets
           * </ol>
           */
-        private float getBaseScore(DisplayResolveInfo target, boolean isShortcutResult) {
+        public float getBaseScore(DisplayResolveInfo target, @ShareTargetType int targetType) {
             if (target == null) {
                 return CALLER_TARGET_SCORE_BOOST;
             }
 
-            if (isShortcutResult && getAppPredictorForDirectShareIfEnabled() != null) {
+            if (targetType == TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE) {
                 return SHORTCUT_TARGET_SCORE_BOOST;
             }
 
             float score = super.getScore(target);
-            if (isShortcutResult) {
+            if (targetType == TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER) {
                 return score * SHORTCUT_TARGET_SCORE_BOOST;
             }
 
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index d60d543..15b1d75 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -106,7 +106,7 @@
     void notePhoneOn();
     void notePhoneOff();
     void notePhoneSignalStrength(in SignalStrength signalStrength);
-    void notePhoneDataConnectionState(int dataType, boolean hasData);
+    void notePhoneDataConnectionState(int dataType, boolean hasData, int serviceType);
     void notePhoneState(int phoneState);
     void noteWifiOn();
     void noteWifiOff();
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 58ce03b..407a85f 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -361,9 +361,6 @@
 
         initSuspendedColorMatrix();
 
-        if (isVoiceInteraction()) {
-            onSetupVoiceInteraction();
-        }
         final Set<String> categories = intent.getCategories();
         MetricsLogger.action(this, mAdapter.hasFilteredItem()
                 ? MetricsProto.MetricsEvent.ACTION_SHOW_APP_DISAMBIG_APP_FEATURED
@@ -442,24 +439,21 @@
         mSuspendedMatrixColorFilter = new ColorMatrixColorFilter(matrix);
     }
 
-    /**
-     * Perform any initialization needed for voice interaction.
-     */
-    public void onSetupVoiceInteraction() {
-        // Do it right now. Subclasses may delay this and send it later.
-        sendVoiceChoicesIfNeeded();
-    }
-
     public void sendVoiceChoicesIfNeeded() {
         if (!isVoiceInteraction()) {
             // Clearly not needed.
             return;
         }
 
-
         final Option[] options = new Option[mAdapter.getCount()];
         for (int i = 0, N = options.length; i < N; i++) {
-            options[i] = optionForChooserTarget(mAdapter.getItem(i), i);
+            TargetInfo target = mAdapter.getItem(i);
+            if (target == null) {
+                // If this occurs, a new set of targets is being loaded. Let that complete,
+                // and have the next call to send voice choices proceed instead.
+                return;
+            }
+            options[i] = optionForChooserTarget(target, i);
         }
 
         mPickOptionRequest = new PickTargetOptionRequest(
@@ -1872,7 +1866,7 @@
                 }
             }
 
-
+            sendVoiceChoicesIfNeeded();
             postListReadyRunnable();
         }
 
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 3a7caa4..4573084 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -906,8 +906,6 @@
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
     protected StopwatchTimer mBluetoothScanTimer;
 
-    boolean mIsCellularTxPowerHigh = false;
-
     int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
     long mMobileRadioActiveStartTime;
     StopwatchTimer mMobileRadioActiveTimer;
@@ -5261,16 +5259,26 @@
     }
 
     @UnsupportedAppUsage
-    public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
+    public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData, int serviceType) {
         // BatteryStats uses 0 to represent no network type.
         // Telephony does not have a concept of no network type, and uses 0 to represent unknown.
         // Unknown is included in DATA_CONNECTION_OTHER.
-        int bin = DATA_CONNECTION_NONE;
+        int bin = DATA_CONNECTION_OUT_OF_SERVICE;
         if (hasData) {
             if (dataType > 0 && dataType <= TelephonyManager.MAX_NETWORK_TYPE) {
                 bin = dataType;
             } else {
-                bin = DATA_CONNECTION_OTHER;
+                switch (serviceType) {
+                    case ServiceState.STATE_OUT_OF_SERVICE:
+                        bin = DATA_CONNECTION_OUT_OF_SERVICE;
+                        break;
+                    case ServiceState.STATE_EMERGENCY_ONLY:
+                        bin = DATA_CONNECTION_EMERGENCY_SERVICE;
+                        break;
+                    default:
+                        bin = DATA_CONNECTION_OTHER;
+                        break;
+                }
             }
         }
         if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
@@ -11190,19 +11198,9 @@
             }
         }
         if (levelMaxTimeSpent == ModemActivityInfo.TX_POWER_LEVELS - 1) {
-            if (!mIsCellularTxPowerHigh) {
-                mHistoryCur.states2 |= HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG;
-                addHistoryRecordLocked(elapsedRealtime, uptime);
-                mIsCellularTxPowerHigh = true;
-            }
-            return;
-        }
-        if (mIsCellularTxPowerHigh) {
-            mHistoryCur.states2 &= ~HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG;
+            mHistoryCur.states2 |= HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG;
             addHistoryRecordLocked(elapsedRealtime, uptime);
-            mIsCellularTxPowerHigh = false;
         }
-        return;
     }
 
     private final class BluetoothActivityInfoCache {
@@ -13660,7 +13658,6 @@
         mCameraOnTimer.readSummaryFromParcelLocked(in);
         mBluetoothScanNesting = 0;
         mBluetoothScanTimer.readSummaryFromParcelLocked(in);
-        mIsCellularTxPowerHigh = false;
 
         int NRPMS = in.readInt();
         if (NRPMS > 10000) {
@@ -14644,7 +14641,6 @@
         mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase, in);
         mBluetoothScanNesting = 0;
         mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase, in);
-        mIsCellularTxPowerHigh = false;
         mDischargeUnplugLevel = in.readInt();
         mDischargePlugLevel = in.readInt();
         mDischargeCurrentLevel = in.readInt();
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 7c52a40..07002d7 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -796,7 +796,9 @@
         updateElevation();
         mAllowUpdateElevation = true;
 
-        if (changed && mResizeMode == RESIZE_MODE_DOCKED_DIVIDER) {
+        if (changed
+                && (mResizeMode == RESIZE_MODE_DOCKED_DIVIDER
+                    || mDrawLegacyNavigationBarBackground)) {
             getViewRootImpl().requestInvalidateRootRenderNode();
         }
     }
diff --git a/core/java/com/android/internal/util/ScreenshotHelper.java b/core/java/com/android/internal/util/ScreenshotHelper.java
index 7fd94c6..cac691c 100644
--- a/core/java/com/android/internal/util/ScreenshotHelper.java
+++ b/core/java/com/android/internal/util/ScreenshotHelper.java
@@ -1,6 +1,7 @@
 package com.android.internal.util;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -13,6 +14,8 @@
 import android.os.UserHandle;
 import android.util.Log;
 
+import java.util.function.Consumer;
+
 public class ScreenshotHelper {
     private static final String TAG = "ScreenshotHelper";
 
@@ -34,17 +37,58 @@
     }
 
     /**
-     * Request a screenshot be taken.
+     * Request a screenshot be taken with a specific timeout.
      *
-     * @param screenshotType The type of screenshot, for example either
-     *                       {@link android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN}
-     *                       or {@link android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION}
-     * @param hasStatus {@code true} if the status bar is currently showing. {@code false} if not.
-     * @param hasNav {@code true} if the navigation bar is currently showing. {@code false} if not.
-     * @param handler A handler used in case the screenshot times out
+     * Added to support reducing unit test duration; the method variant without a timeout argument
+     * is recommended for general use.
+     *
+     * @param screenshotType     The type of screenshot, for example either
+     *                           {@link android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN}
+     *                           or
+     *                           {@link android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION}
+     * @param hasStatus          {@code true} if the status bar is currently showing. {@code false}
+     *                           if
+     *                           not.
+     * @param hasNav             {@code true} if the navigation bar is currently showing. {@code
+     *                           false}
+     *                           if not.
+     * @param handler            A handler used in case the screenshot times out
+     * @param completionConsumer Consumes `false` if a screenshot was not taken, and `true` if the
+     *                           screenshot was taken.
      */
     public void takeScreenshot(final int screenshotType, final boolean hasStatus,
-            final boolean hasNav, @NonNull Handler handler) {
+            final boolean hasNav, @NonNull Handler handler,
+            @Nullable Consumer<Boolean> completionConsumer) {
+        takeScreenshot(screenshotType, hasStatus, hasNav, SCREENSHOT_TIMEOUT_MS, handler,
+                completionConsumer);
+    }
+
+    /**
+     * Request a screenshot be taken.
+     *
+     * Added to support reducing unit test duration; the method variant without a timeout argument
+     * is recommended for general use.
+     *
+     * @param screenshotType     The type of screenshot, for example either
+     *                           {@link android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN}
+     *                           or
+     *                           {@link android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION}
+     * @param hasStatus          {@code true} if the status bar is currently showing. {@code false}
+     *                           if
+     *                           not.
+     * @param hasNav             {@code true} if the navigation bar is currently showing. {@code
+     *                           false}
+     *                           if not.
+     * @param timeoutMs          If the screenshot hasn't been completed within this time period,
+     *                           the screenshot attempt will be cancelled and `completionConsumer`
+     *                           will be run.
+     * @param handler            A handler used in case the screenshot times out
+     * @param completionConsumer Consumes `false` if a screenshot was not taken, and `true` if the
+     *                           screenshot was taken.
+     */
+    public void takeScreenshot(final int screenshotType, final boolean hasStatus,
+            final boolean hasNav, long timeoutMs, @NonNull Handler handler,
+            @Nullable Consumer<Boolean> completionConsumer) {
         synchronized (mScreenshotLock) {
             if (mScreenshotConnection != null) {
                 return;
@@ -54,7 +98,8 @@
             final Intent serviceIntent = new Intent();
 
             final Runnable mScreenshotTimeout = new Runnable() {
-                @Override public void run() {
+                @Override
+                public void run() {
                     synchronized (mScreenshotLock) {
                         if (mScreenshotConnection != null) {
                             mContext.unbindService(mScreenshotConnection);
@@ -62,6 +107,9 @@
                             notifyScreenshotError();
                         }
                     }
+                    if (completionConsumer != null) {
+                        completionConsumer.accept(false);
+                    }
                 }
             };
 
@@ -86,15 +134,22 @@
                                         handler.removeCallbacks(mScreenshotTimeout);
                                     }
                                 }
+                                if (completionConsumer != null) {
+                                    completionConsumer.accept(true);
+                                }
                             }
                         };
                         msg.replyTo = new Messenger(h);
-                        msg.arg1 = hasStatus ? 1: 0;
-                        msg.arg2 = hasNav ? 1: 0;
+                        msg.arg1 = hasStatus ? 1 : 0;
+                        msg.arg2 = hasNav ? 1 : 0;
+
                         try {
                             messenger.send(msg);
                         } catch (RemoteException e) {
                             Log.e(TAG, "Couldn't take screenshot: " + e);
+                            if (completionConsumer != null) {
+                                completionConsumer.accept(false);
+                            }
                         }
                     }
                 }
@@ -115,7 +170,7 @@
                     Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
                     UserHandle.CURRENT)) {
                 mScreenshotConnection = conn;
-                handler.postDelayed(mScreenshotTimeout, SCREENSHOT_TIMEOUT_MS);
+                handler.postDelayed(mScreenshotTimeout, timeoutMs);
             }
         }
     }
diff --git a/core/java/com/android/internal/util/XmlUtils.java b/core/java/com/android/internal/util/XmlUtils.java
index 344d7ef..8799e3d 100644
--- a/core/java/com/android/internal/util/XmlUtils.java
+++ b/core/java/com/android/internal/util/XmlUtils.java
@@ -26,6 +26,8 @@
 import android.util.Base64;
 import android.util.Xml;
 
+import libcore.util.HexEncoding;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
@@ -396,16 +398,7 @@
         final int N = val.length;
         out.attribute(null, "num", Integer.toString(N));
 
-        StringBuilder sb = new StringBuilder(val.length*2);
-        for (int i=0; i<N; i++) {
-            int b = val[i];
-            int h = (b >> 4) & 0x0f;
-            sb.append((char)(h >= 10 ? ('a'+h-10) : ('0'+h)));
-            h = b & 0x0f;
-            sb.append((char)(h >= 10 ? ('a'+h-10) : ('0'+h)));
-        }
-
-        out.text(sb.toString());
+        out.text(HexEncoding.encodeToString(val).toLowerCase());
 
         out.endTag(null, "byte-array");
     }
@@ -1032,7 +1025,9 @@
                     "Not a number in num attribute in byte-array");
         }
 
-        byte[] array = new byte[num];
+        // 0 len byte array does not have a text in the XML tag. So, initialize to 0 len array.
+        // For all other array lens, HexEncoding.decode() below overrides the array.
+        byte[] array = new byte[0];
 
         int eventType = parser.getEventType();
         do {
@@ -1043,16 +1038,7 @@
                         throw new XmlPullParserException(
                                 "Invalid value found in byte-array: " + values);
                     }
-                    // This is ugly, but keeping it to mirror the logic in #writeByteArrayXml.
-                    for (int i = 0; i < num; i ++) {
-                        char nibbleHighChar = values.charAt(2 * i);
-                        char nibbleLowChar = values.charAt(2 * i + 1);
-                        int nibbleHigh = nibbleHighChar > 'a' ? (nibbleHighChar - 'a' + 10)
-                                : (nibbleHighChar - '0');
-                        int nibbleLow = nibbleLowChar > 'a' ? (nibbleLowChar - 'a' + 10)
-                                : (nibbleLowChar - '0');
-                        array[i] = (byte) ((nibbleHigh & 0x0F) << 4 | (nibbleLow & 0x0F));
-                    }
+                    array = HexEncoding.decode(values);
                 }
             } else if (eventType == parser.END_TAG) {
                 if (parser.getName().equals(endTag)) {
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index 9fc79cb..510b321 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -53,6 +53,8 @@
 
 /**
  * Loads global system configuration info.
+ * Note: Initializing this class hits the disk and is slow.  This class should generally only be
+ * accessed by the system_server process.
  */
 public class SystemConfig {
     static final String TAG = "SystemConfig";
@@ -209,6 +211,11 @@
     private final ArraySet<String> mBugreportWhitelistedPackages = new ArraySet<>();
 
     public static SystemConfig getInstance() {
+        if (!isSystemProcess()) {
+            Slog.wtf(TAG, "SystemConfig is being accessed by a process other than "
+                    + "system_server.");
+        }
+
         synchronized (SystemConfig.class) {
             if (sInstance == null) {
                 sInstance = new SystemConfig();
@@ -1154,4 +1161,8 @@
             mSplitPermissions.add(new SplitPermissionInfo(splitPerm, newPermissions, targetSdk));
         }
     }
+
+    private static boolean isSystemProcess() {
+        return Process.myUid() == Process.SYSTEM_UID;
+    }
 }
diff --git a/core/jni/android/graphics/ByteBufferStreamAdaptor.cpp b/core/jni/android/graphics/ByteBufferStreamAdaptor.cpp
index 173818b..d443fd8 100644
--- a/core/jni/android/graphics/ByteBufferStreamAdaptor.cpp
+++ b/core/jni/android/graphics/ByteBufferStreamAdaptor.cpp
@@ -1,6 +1,7 @@
 #include "ByteBufferStreamAdaptor.h"
 #include "core_jni_helpers.h"
 #include "Utils.h"
+#include <jni.h>
 
 #include <SkStream.h>
 
@@ -9,6 +10,24 @@
 static jmethodID gByteBuffer_getMethodID;
 static jmethodID gByteBuffer_setPositionMethodID;
 
+/**
+ * Helper method for accessing the JNI interface pointer.
+ *
+ * Image decoding (which this supports) is started on a thread that is already
+ * attached to the Java VM. But an AnimatedImageDrawable continues decoding on
+ * the AnimatedImageThread, which is not attached. This will attach if
+ * necessary.
+ */
+static JNIEnv* requireEnv(JavaVM* jvm) {
+    JNIEnv* env;
+    if (jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+        if (jvm->AttachCurrentThreadAsDaemon(&env, nullptr) != JNI_OK) {
+            LOG_ALWAYS_FATAL("Failed to AttachCurrentThread!");
+        }
+    }
+    return env;
+}
+
 class ByteBufferStream : public SkStreamAsset {
 private:
     ByteBufferStream(JavaVM* jvm, jobject jbyteBuffer, size_t initialPosition, size_t length,
@@ -46,7 +65,7 @@
     }
 
     ~ByteBufferStream() override {
-        auto* env = get_env_or_die(mJvm);
+        auto* env = requireEnv(mJvm);
         env->DeleteGlobalRef(mByteBuffer);
         env->DeleteGlobalRef(mStorage);
     }
@@ -63,7 +82,7 @@
             return this->setPosition(mPosition + size) ? size : 0;
         }
 
-        auto* env = get_env_or_die(mJvm);
+        auto* env = requireEnv(mJvm);
         size_t bytesRead = 0;
         do {
             const size_t requested = (size > kStorageSize) ? kStorageSize : size;
@@ -146,7 +165,7 @@
 
     // Range has already been checked by the caller.
     bool setPosition(size_t newPosition) {
-        auto* env = get_env_or_die(mJvm);
+        auto* env = requireEnv(mJvm);
         env->CallObjectMethod(mByteBuffer, gByteBuffer_setPositionMethodID,
                               newPosition + mInitialPosition);
         if (env->ExceptionCheck()) {
@@ -185,7 +204,7 @@
     }
 
     ~ByteArrayStream() override {
-        auto* env = get_env_or_die(mJvm);
+        auto* env = requireEnv(mJvm);
         env->DeleteGlobalRef(mByteArray);
     }
 
@@ -197,7 +216,7 @@
             return 0;
         }
 
-        auto* env = get_env_or_die(mJvm);
+        auto* env = requireEnv(mJvm);
         if (buffer) {
             env->GetByteArrayRegion(mByteArray, mPosition + mOffset, size,
                                     reinterpret_cast<jbyte*>(buffer));
diff --git a/core/jni/android_hardware_input_InputWindowHandle.cpp b/core/jni/android_hardware_input_InputWindowHandle.cpp
index a1d1d4f..57d1649 100644
--- a/core/jni/android_hardware_input_InputWindowHandle.cpp
+++ b/core/jni/android_hardware_input_InputWindowHandle.cpp
@@ -28,6 +28,7 @@
 #include "android_hardware_input_InputWindowHandle.h"
 #include "android_hardware_input_InputApplicationHandle.h"
 #include "android_util_Binder.h"
+#include <binder/IPCThreadState.h>
 
 namespace android {
 
@@ -78,6 +79,12 @@
 NativeInputWindowHandle::~NativeInputWindowHandle() {
     JNIEnv* env = AndroidRuntime::getJNIEnv();
     env->DeleteWeakGlobalRef(mObjWeak);
+
+    // Clear the weak reference to the layer handle and flush any binder ref count operations so we
+    // do not hold on to any binder references.
+    // TODO(b/139697085) remove this after it can be flushed automatically
+    mInfo.touchableRegionCropHandle.clear();
+    IPCThreadState::self()->flushCommands();
 }
 
 jobject NativeInputWindowHandle::getInputWindowHandleObjLocalRef(JNIEnv* env) {
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 986771d..030d3be 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -217,12 +217,6 @@
     ctrl->decStrong((void *)nativeCreate);
 }
 
-static void nativeDestroy(JNIEnv* env, jclass clazz, jlong nativeObject) {
-    sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(nativeObject));
-    ctrl->destroy();
-    ctrl->decStrong((void *)nativeCreate);
-}
-
 static void nativeDisconnect(JNIEnv* env, jclass clazz, jlong nativeObject) {
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     if (ctrl != NULL) {
@@ -1268,8 +1262,6 @@
             (void*)nativeWriteToParcel },
     {"nativeRelease", "(J)V",
             (void*)nativeRelease },
-    {"nativeDestroy", "(J)V",
-            (void*)nativeDestroy },
     {"nativeDisconnect", "(J)V",
             (void*)nativeDisconnect },
     {"nativeCreateTransaction", "()J",
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index c023438..f817c9b 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2401,4 +2401,9 @@
     // OS: Q
     // Note: Gear icon is shown next to gesture navigation preference and opens sensitivity dialog
     SETTINGS_GESTURE_NAV_BACK_SENSITIVITY_DLG = 1748;
+
+    // OPEN: Settings > System > Aware > Aware Display
+    // CATEGORY: SETTINGS
+    // OS: Q
+    SETTINGS_AWARE_DISPLAY = 1750;
 }
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index 0070694..ca71314 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -688,6 +688,7 @@
         // Configuration options for smart replies and smart actions in notifications. This is
         // encoded as a key=value list separated by commas.
         optional SettingProto smart_suggestions_in_notifications_flags = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        optional SettingProto bubbles = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
     }
     optional Notification notification = 82;
 
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 10e851b..6f89edc 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1072,7 +1072,7 @@
     <string name="Midnight" msgid="5630806906897892201">"Middernag"</string>
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
-    <string name="selectAll" msgid="6876518925844129331">"Kies alle"</string>
+    <string name="selectAll" msgid="6876518925844129331">"Kies alles"</string>
     <string name="cut" msgid="3092569408438626261">"Sny"</string>
     <string name="copy" msgid="2681946229533511987">"Kopieer"</string>
     <string name="failed_to_copy_to_clipboard" msgid="1833662432489814471">"Kon nie na knipbord toe kopieer nie"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tik om alle netwerke te sien"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Koppel"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alle netwerke"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Koppel aan Wi-Fi-netwerke?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Voorgestel deur <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nee"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Laat voorgestelde Wi‑Fi-netwerke toe?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Netwerke wat deur <xliff:g id="NAME">%s</xliff:g> voorgestel is. Toestel sal dalk outomaties koppel."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Laat toe"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nee, dankie"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi sal outomaties aanskakel"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Wanneer jy naby \'n gestoorde hoëgehaltenetwerk is"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Moenie weer aanskakel nie"</string>
@@ -1354,7 +1354,7 @@
     <string name="usb_power_notification_message" msgid="4647527153291917218">"Laai tans gekoppelde toestel. Tik vir meer opsies."</string>
     <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analoë oudiobykomstigheid bespeur"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Die aangehegde toestel is nie met hierdie foon versoenbaar nie. Tik om meer te wete te kom."</string>
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-ontfouter gekoppel"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-ontfouting gekoppel"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Tik om USB-ontfouting af te skakel"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Kies om USB-ontfouting te deaktiveer."</string>
     <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Toetsraamwerkmodus is geaktiveer"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Ongekategoriseer"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Jy stel die belangrikheid van hierdie kennisgewings."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Dit is belangrik as gevolg van die mense wat betrokke is."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Laat <xliff:g id="APP">%1$s</xliff:g> toe om \'n nuwe gebruiker met <xliff:g id="ACCOUNT">%2$s</xliff:g> te skep?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Laat <xliff:g id="APP">%1$s</xliff:g> toe om \'n nuwe gebruiker met <xliff:g id="ACCOUNT">%2$s</xliff:g> te skep (\'n gebruiker met hierdie rekening bestaan reeds)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Laat <xliff:g id="APP">%1$s</xliff:g> toe om \'n nuwe gebruiker met <xliff:g id="ACCOUNT">%2$s</xliff:g> te skep (\'n gebruiker met hierdie rekening bestaan reeds)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Laat <xliff:g id="APP">%1$s</xliff:g> toe om \'n nuwe gebruiker met <xliff:g id="ACCOUNT">%2$s</xliff:g> te skep?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Voeg \'n taal by"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Streekvoorkeur"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Voer taalnaam in"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 06654c4..bce5e05 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ሁሉንም አውታረ መረቦችን ለማየት መታ ያድርጉ"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"አገናኝ"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ሁሉም አውታረ መረቦች"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"ከWi-Fi አውታረ መረቦች ጋር ይገናኝ?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"በ<xliff:g id="NAME">%s</xliff:g> የተጠቆሙ"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"አዎ"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"አይ"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"የተጠቆሙ የWi‑Fi አውታረ መረቦች ይፈቀዱ?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"በ<xliff:g id="NAME">%s</xliff:g> የተጠቆሙ አውታረ መረቦች። መሣሪያ በራስ-ሰር ሊገናኝ ይችላል።"</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"ፍቀድ"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"አይ፣ አመሰግናለሁ"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi በራስ-ሰር ይበራል"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"ከፍተኛ ጥራት ያለው የተቀመጠ አውታረ መረብ አቅራቢያ ሲሆኑ"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"መልሰህ አታብራ"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"ያልተመደቡ"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"የእነዚህን ማሳወቂያዎች አስፈላጊነት አዘጋጅተዋል።"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"ይሄ በሚሳተፉ ሰዎች ምክንያት አስፈላጊ ነው።"</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g> በ<xliff:g id="ACCOUNT">%2$s</xliff:g> አዲስ ተጠቃሚ እንዲፈጥር ይፈቀድለት?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g> በ<xliff:g id="ACCOUNT">%2$s</xliff:g> አዲስ ተጠቃሚ እንዲፈጥር ይፈቀድለት (ይህ መለያ ያለው ተጠቃሚ አስቀድሞ አለ)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> በ<xliff:g id="ACCOUNT">%2$s</xliff:g> አዲስ ተጠቃሚ እንዲፈጥር ይፈቀድለት (ይህ መለያ ያለው ተጠቃሚ አስቀድሞ አለ)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> አዲስ ተጠቃሚ ከ <xliff:g id="ACCOUNT">%2$s</xliff:g> ጋር መፍጠር እንዲችል ይፍቀዱ?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"ቋንቋ ያክሉ"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"የክልል ምርጫ"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"የቋንቋ ስም ይተይቡ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 4cf4c9f..8b6226a 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -471,7 +471,7 @@
     <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"للسماح للتطبيق باستخدام مرسل الأشعة تحت الحمراء الخاص بالجهاز اللوحي."</string>
     <string name="permdesc_transmitIr" product="tv" msgid="3926790828514867101">"يتيح للتطبيق استخدام مرسل الأشعة تحت الحمراء في جهاز التلفزيون."</string>
     <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"للسماح للتطبيق باستخدام مرسل الأشعة تحت الحمراء الخاص بالهاتف."</string>
-    <string name="permlab_setWallpaper" msgid="6627192333373465143">"تعيين الخلفية"</string>
+    <string name="permlab_setWallpaper" msgid="6627192333373465143">"ضبط الخلفية"</string>
     <string name="permdesc_setWallpaper" msgid="7373447920977624745">"للسماح للتطبيق بتعيين خلفية النظام."</string>
     <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"تعديل حجم الخلفية"</string>
     <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"للسماح للتطبيق بتعيين تلميحات حجم خلفية النظام."</string>
@@ -533,7 +533,7 @@
     <string name="permdesc_imagesWrite" msgid="7073662756617474375">"للسماح للتطبيق بتعديل مجموعة صورك."</string>
     <string name="permlab_mediaLocation" msgid="8675148183726247864">"قراءة المواقع من مجموعة الوسائط التابعة لك"</string>
     <string name="permdesc_mediaLocation" msgid="2237023389178865130">"للسماح للتطبيق بقراءة المواقع من مجموعة الوسائط التابعة لك."</string>
-    <string name="biometric_dialog_default_title" msgid="881952973720613213">"التحقق من هويتك"</string>
+    <string name="biometric_dialog_default_title" msgid="881952973720613213">"إثبات هويتك"</string>
     <string name="biometric_error_hw_unavailable" msgid="645781226537551036">"معدّات المقاييس الحيوية غير متاحة."</string>
     <string name="biometric_error_user_canceled" msgid="2260175018114348727">"تم إلغاء المصادقة."</string>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"لم يتم التعرف عليها."</string>
@@ -1152,7 +1152,7 @@
     <string name="Midnight" msgid="5630806906897892201">"منتصف الليل"</string>
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
-    <string name="selectAll" msgid="6876518925844129331">"تحديد الكل"</string>
+    <string name="selectAll" msgid="6876518925844129331">"اختيار الكل"</string>
     <string name="cut" msgid="3092569408438626261">"قص"</string>
     <string name="copy" msgid="2681946229533511987">"نسخ"</string>
     <string name="failed_to_copy_to_clipboard" msgid="1833662432489814471">"تعذّر النسخ في الحافظة"</string>
@@ -1343,10 +1343,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"انقر للاطلاع على جميع الشبكات"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"اتصال"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"جميع الشبكات"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"‏هل تريد الاتصال بشبكات Wi-Fi؟"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"اقتراح من <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"نعم"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"لا"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"‏هل تريد السماح لشبكات Wi‑Fi المقترحة؟"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"شبكات <xliff:g id="NAME">%s</xliff:g> المقترحة - قد يتم توصيل الجهاز تلقائيًا."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"سماح"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"لا، شكرًا"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"‏سيتم تشغيل شبكة Wi-Fi تلقائيًا."</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"عندما تكون بالقرب من شبكة محفوظة عالية الجودة"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"عدم إعادة التشغيل"</string>
@@ -1442,8 +1442,8 @@
     <string name="usb_power_notification_message" msgid="4647527153291917218">"جارٍ شحن الجهاز المتصل. انقر لعرض خيارات أكثر."</string>
     <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"تم اكتشاف ملحق صوتي تناظري"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"الجهاز الذي تم توصيله بالهاتف غير متوافق معه. انقر للحصول على المزيد من المعلومات."</string>
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"‏تم توصيل تصحيح أخطاء USB"</string>
-    <string name="adb_active_notification_message" msgid="7463062450474107752">"‏انقر لإيقاف تصحيح أخطاء USB."</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"‏تم توصيل تصحيح أخطاء الجهاز عبر USB"</string>
+    <string name="adb_active_notification_message" msgid="7463062450474107752">"‏انقر لإيقاف تصحيح أخطاء الجهاز عبر USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"‏اختيار إيقاف تصحيح أخطاء USB."</string>
     <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"تم تفعيل وضع \"مفعّل الاختبار\""</string>
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"يمكنك إجراء إعادة ضبط على إعدادات المصنع لإيقاف وضع \"مفعِّل اختبار\"."</string>
@@ -2024,8 +2024,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"غير مصنفة"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"لقد عيَّنت أهمية هذه الإشعارات."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"هذه الرسالة مهمة نظرًا لأهمية الأشخاص المعنيين."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"هل تسمح لـ <xliff:g id="APP">%1$s</xliff:g> بإنشاء مستخدم جديد باستخدام <xliff:g id="ACCOUNT">%2$s</xliff:g>؟"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"هل تسمح لـ <xliff:g id="APP">%1$s</xliff:g> بإنشاء مستخدم جديد باستخدام <xliff:g id="ACCOUNT">%2$s</xliff:g> (يوجد مستخدم بهذا الحساب مسبقًا)؟"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"هل تسمح لتطبيق <xliff:g id="APP">%1$s</xliff:g> بإنشاء مستخدم جديد باستخدام <xliff:g id="ACCOUNT">%2$s</xliff:g> (يوجد مستخدم بهذا الحساب مسبقًا)؟"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"هل تسمح لتطبيق <xliff:g id="APP">%1$s</xliff:g> بإنشاء مستخدم جديد باستخدام <xliff:g id="ACCOUNT">%2$s</xliff:g> ؟"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"إضافة لغة"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"تفضيل المنطقة"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"اكتب اسم اللغة"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index c53af2b..34e020e 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"সকলো নেটৱৰ্ক চাবলৈ টিপক"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"সংযোগ কৰক"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"সকলো নেটৱৰ্ক"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"ৱাই-ফাই নেটৱৰ্কৰ সৈতে সংযোগ কৰিবনে?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g>এ প্ৰস্তাব দিয়া"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"হয়"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"নহয়"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"পৰামর্শ হিচাপে পোৱা নেটৱর্কবোৰক অনুমতি দিবনে?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g>এ পৰামর্শ হিচাপে দিয়া নেটৱর্কবোৰ। ডিভাইচটো স্বয়ংক্ৰিয়ভাৱে সংযোগ হ\'ব পাৰে।"</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"অনুমতি দিয়ক"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"নালাগে, ধন্যবাদ"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"ৱাই-ফাই স্বয়ংক্ৰিয়ভাৱে অন হ\'ব"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"যেতিয়া আপুনি ছেভ কৰি থোৱা উচ্চ মানৰ নেটৱৰ্কৰ কাষত থাকে"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"পুনৰাই অন নকৰিব"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"শ্ৰেণীবদ্ধ নকৰা"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"এই জাননীবোৰৰ গুৰুত্ব আপুনি ছেট কৰব লাগিব।"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"এই কার্যৰ সৈতে জড়িত থকা লোকসকলক ভিত্তি কৰি এইয়া গুৰুত্বপূর্ণ বুলি বিবেচনা কৰা হৈছ।"</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g> ক <xliff:g id="ACCOUNT">%2$s</xliff:g>ৰ জৰিয়তে নতুন ব্য়ৱহাৰকাৰী সৃষ্টি কৰিবলৈ অনুমতি দিবনে?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g>ক <xliff:g id="ACCOUNT">%2$s</xliff:g>ৰ (এই একাউন্টৰ এজন ব্য়ৱহাৰকাৰী ইতিমধ্যে আছে) জৰিয়তে নতুন ব্য়ৱহাৰকাৰী সৃষ্টি কৰিবলৈ অনুমতি দিবনে?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g>ক <xliff:g id="ACCOUNT">%2$s</xliff:g>ৰ (এই একাউণ্টটোৰ এজন ব্যৱহাৰকাৰী ইতিমধ্যে আছে) জৰিয়তে এজন নতুন ব্যৱহাৰকাৰী সৃষ্টি কৰিবলৈ অনুমতি দিবনে ?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g>ক <xliff:g id="ACCOUNT">%2$s</xliff:g>ৰ জৰিয়তে এজন নতুন ব্যৱহাৰকাৰী সৃষ্টি কৰিবলৈ অনুমতি দিবনে?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"ভাষা যোগ কৰক"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"অঞ্চলৰ অগ্ৰাধিকাৰ"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"ভাষাৰ নাম লিখক"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index a3a2f2a..6672204 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Bütün şəbəkələri görmək üçün klikləyin"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Qoşulun"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Bütün şəbəkələr"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi-Fi şəbəkələrinə qoşulsun?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> tərəfindən təklif edildi"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Bəli"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Xeyr"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Təklif edilən Wi‑Fi şəbəkələrinə icazə verilsin?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> təklif edilən şəbəkə. Cihaz avtomatik qoşula bilər."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"İcazə verin"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Xeyr, təşəkkürlər"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi avtomatik olaraq aktiv ediləcək"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Yadda saxlanmış yüksək keyfiyyətli şəbəkələr yaxınlıqda olduqda"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Yenidən aktiv etməyin"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Kateqoriyasız"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Bildirişlərin əhəmiyyətini Siz ayarlaryırsınız."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"İnsanlar cəlb olunduğu üçün bu vacibdir."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g> tətbiqinə <xliff:g id="ACCOUNT">%2$s</xliff:g> hesabı ilə yeni İstifadəçi yaratmağa icazə verilsin?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g> tətbiqinə<xliff:g id="ACCOUNT">%2$s</xliff:g> (bu hesab ilə İstifadəçi artıq mövcuddur) hesabı ilə yeni İstifadəçi yaratmağa icazə verilsin?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> tətbiqinə <xliff:g id="ACCOUNT">%2$s</xliff:g> (artıq bu hesabı olan İstifadəçi mövcuddur) ilə yeni İstifadəçi yaratmağa icazə verilsin?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> tətbiqinə <xliff:g id="ACCOUNT">%2$s</xliff:g> ilə yeni İstifadəçi yartmağa icazə verilsin?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Dil əlavə edin"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Region seçimi"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Dil adını daxil edin"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 61a2167..f21cabf 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -27,7 +27,7 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="untitled" msgid="4638956954852782576">"&lt;Bez naslova&gt;"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;Bez imena&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nema broja telefona)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Nepoznato"</string>
     <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Glasovna pošta"</string>
@@ -1277,10 +1277,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite da biste videli sve mreže"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Poveži"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Sve mreže"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Želite li da se povežete sa Wi-Fi mrežama?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> predlaže"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Da"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Želite da dozvolite predložene Wi‑Fi mreže?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Mreže koje predlaže <xliff:g id="NAME">%s</xliff:g>. Uređaj će se možda povezati automatski."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Dozvoli"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ne, hvala"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi će se automatski uključiti"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kada ste u blizini sačuvane mreže visokog kvaliteta"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ne uključuj ponovo"</string>
@@ -1922,8 +1922,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Nekategorizovano"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Vi podešavate važnost ovih obaveštenja."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ovo je važno zbog ljudi koji učestvuju."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Želite li da dozvolite aplikaciji <xliff:g id="APP">%1$s</xliff:g> da napravi novog korisnika za <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Želite li da dozvolite aplikaciji <xliff:g id="APP">%1$s</xliff:g> da napravi novog korisnika za <xliff:g id="ACCOUNT">%2$s</xliff:g> (korisnik sa ovim nalogom već postoji)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Želite li da dozvolite da <xliff:g id="APP">%1$s</xliff:g> napravi novog korisnika sa nalogom <xliff:g id="ACCOUNT">%2$s</xliff:g> (korisnik sa tim nalogom već postoji)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Želite li da dozvolite da <xliff:g id="APP">%1$s</xliff:g> napravi novog korisnika sa nalogom <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Dodajte jezik"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Podešavanje regiona"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Unesite naziv jezika"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 1bc5320..918c51f 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1299,10 +1299,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Дакраніцеся, каб убачыць усе сеткі"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Падключыцца"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Усе сеткі"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Падключыцца да сетак Wi-Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Прапанавана ўладальнікам <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Так"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Не"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Дазволіць падключэнне да прапанаваных сетак Wi‑Fi?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Праграма \"<xliff:g id="NAME">%s</xliff:g>\" прапанавала сеткі. Прылада можа падключыцца да ніх аўтаматычна."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Дазволіць"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Не, дзякуй"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi уключыцца аўтаматычна"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Побач з захаванай сеткай з высакаякасным сігналам"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Не ўключаць зноў"</string>
@@ -1387,7 +1387,7 @@
     <string name="no_permissions" msgid="7283357728219338112">"Дазволу не патрабуецца"</string>
     <string name="perm_costs_money" msgid="4902470324142151116">"за гэта можа спаганяцца плата"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"ОК"</string>
-    <string name="usb_charging_notification_title" msgid="1595122345358177163">"Зарадка гэтай прылады праз USB"</string>
+    <string name="usb_charging_notification_title" msgid="1595122345358177163">"Прылада зараджаецца праз USB"</string>
     <string name="usb_supplying_notification_title" msgid="4631045789893086181">"Зарадка падключанай прылады праз USB"</string>
     <string name="usb_mtp_notification_title" msgid="4238227258391151029">"Перадача файлаў праз USB"</string>
     <string name="usb_ptp_notification_title" msgid="5425857879922006878">"Перадача фота (PTP) праз USB"</string>
@@ -1718,8 +1718,8 @@
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> быў адключаны з дапамогай камбінацыі хуткага доступу для спецыяльных магчымасцей"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Каб карыстацца сэрвісам \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\", націсніце і ўтрымлівайце на працягу трох секунд абедзве клавішы гучнасці"</string>
     <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Выберыце службу для выкарыстання пры націску кнопкі \"Спецыяльныя магчымасці\":"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"З дапамогай жэста спецыяльных магчымасцей (правесці двума пальцамі па экране знізу ўверх) выберыце службу для выкарыстання:"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"З дапамогай жэста спецыяльных магчымасцей (правесці трыма пальцамі па экране знізу ўверх) выберыце службу для выкарыстання:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Выберыце службу, дзе будзе выкарыстоўвацца жэст спецыяльных магчымасцей (правесці двума пальцамі па экране знізу ўверх):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Выберыце службу, дзе будзе выкарыстоўвацца жэст спецыяльных магчымасцей (правесці двума пальцамі па экране знізу ўверх):"</string>
     <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Каб пераключыцца на другую службу, націсніце і ўтрымлівайце кнопку спецыяльных магчымасцей."</string>
     <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Каб пераключыцца на другую службу, правядзіце ўверх двума пальцамі, утрымліваючы іх на экране."</string>
     <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Каб пераключыцца на іншую службу, правядзіце ўверх трыма пальцамі, утрымліваючы іх на экране."</string>
@@ -1956,8 +1956,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Некатэгарызаванае"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Вы задалі важнасць гэтых апавяшчэнняў."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Гэта важна, бо з гэтым звязаны пэўныя людзі."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Дазволіць <xliff:g id="APP">%1$s</xliff:g> стварыць новага Карыстальніка з уліковым запісам <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Дазволіць <xliff:g id="APP">%1$s</xliff:g> стварыць новага Карыстальніка з уліковым запісам <xliff:g id="ACCOUNT">%2$s</xliff:g> (Карыстальнік з гэтым уліковым запісам ужо існуе)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Дазволіць праграме \"<xliff:g id="APP">%1$s</xliff:g>\" стварыць новага Карыстальніка з уліковым запісам <xliff:g id="ACCOUNT">%2$s</xliff:g> (Карыстальнік з гэтым уліковым запісам ужо існуе)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Дазволіць праграме \"<xliff:g id="APP">%1$s</xliff:g>\" стварыць новага Карыстальніка з уліковым запісам <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Дадаць мову"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Параметры рэгіёна"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Увядзіце назву мовы"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 49d0a37..542a550 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Докоснете, за да видите всички мрежи"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Свързване"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Всички мрежи"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Да се установи ли връзка с Wi-Fi мрежи?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Предложено от <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Да"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Не"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Да се разрешат ли предложените Wi‑Fi мрежи?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Предложени от <xliff:g id="NAME">%s</xliff:g> мрежи. Устройството може да се свърже автоматично."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Разрешаване"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Не, благодаря"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi ще се включи автоматично"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Когато сте в района на запазена мрежа с високо качество"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Без повторно включване"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Некатегоризирани"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Зададохте важността на тези известия."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Това е важно заради участващите хора."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Да се разреши ли на <xliff:g id="APP">%1$s</xliff:g> да създаде нов потребител с профила <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Да се разреши ли на <xliff:g id="APP">%1$s</xliff:g> да създаде нов потребител с профила <xliff:g id="ACCOUNT">%2$s</xliff:g> (вече съществува потребител с този профил)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Да се разреши ли на <xliff:g id="APP">%1$s</xliff:g> да създаде нов потребител с профила <xliff:g id="ACCOUNT">%2$s</xliff:g> (вече съществува потребител с този профил)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Да се разреши ли на <xliff:g id="APP">%1$s</xliff:g> да създаде нов потребител с профила <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Добавяне на език"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Предпочитание за региона"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Въведете име на език"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index ae4e123..b8ee884 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"সমস্ত নেটওয়ার্ক দেখতে ট্যাপ করুন"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"সংযুক্ত করুন"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"সব নেটওয়ার্ক"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"ওয়াই-ফাই নেটওয়ার্কের সাথে কানেক্ট করতে চান?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> সাজেস্ট করেছে"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"হ্যাঁ"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"না"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"সাজেস্ট করা ওয়াই-ফাই নেটওয়ার্কে কানেক্ট করার অনুমতি দিতে চান?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g>-এর সাজেস্ট করা নেটওয়ার্ক। ডিভাইস নিজে থেকে কানেক্ট হতে পারে।"</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"অনুমতি দিন"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"না থাক"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"ওয়াই-ফাই অটোমেটিক চালু হবে"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"যখন আপনি একটি উচ্চ মানের সংরক্ষিত নেটওয়ার্ক কাছাকাছি থাকেন"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"আবার চালু করবেন না"</string>
@@ -1889,8 +1889,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"বিভাগ নির্ধারিত নয়"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"আপনি এই বিজ্ঞপ্তিগুলির গুরুত্ব সেট করেছেন।"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"লোকজন জড়িত থাকার কারণে এটি গুরুত্বপূর্ণ।"</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g> কে <xliff:g id="ACCOUNT">%2$s</xliff:g> এর সাথে একজন নতুন ব্যবহারকারী তৈরি করার অনুমতি দেবেন কি?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g> কে <xliff:g id="ACCOUNT">%2$s</xliff:g> (একজন ব্যবহারকারী এই অ্যাকাউন্টে ইতিমধ্যেই বিদ্যমান আছেন) এর সাথে একজন নতুন ব্যবহারকারী তৈরি করার অনুমতি দেবেন কি?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g>-এ (একজন ব্যবহারকারী এই অ্যাকাউন্টে আগে থেকেই রয়েছেন) একজন নতুন ব্যবহারকারী তৈরি করার অনুমতি <xliff:g id="APP">%1$s</xliff:g>-কে দেবেন?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g>-এ একজন নতুন ব্যবহারকারী তৈরি করার অনুমতি <xliff:g id="APP">%1$s</xliff:g>-কে দেবেন?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"একটি ভাষা যোগ করুন"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"পছন্দের অঞ্চল"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"ভাষার নাম লিখুন"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 54e146b..6a2a63a 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -294,7 +294,7 @@
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Dozvoliti aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; da pristupi vašem kalendaru?"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"šalje i pregleda SMS poruke"</string>
-    <string name="permgrouprequest_sms" msgid="7168124215838204719">"Dozvoliti aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; slanje i pregled SMS poruka?"</string>
+    <string name="permgrouprequest_sms" msgid="7168124215838204719">"Dozvoliti aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; da šalje i pregleda SMS poruke?"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Pohrana"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"pristupa slikama, medijskim fajlovima i fajlovima na vašem uređaju"</string>
     <string name="permgrouprequest_storage" msgid="7885942926944299560">"Dozvoliti aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; da pristupa fotografijama, medijima i fajlovima na vašem uređaju?"</string>
@@ -1279,10 +1279,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite da vidite sve mreže"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Povežite se"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Sve mreže"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Povezivati na WiFi mreže?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Predlaže <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Da"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Dozvoliti predložene WiFi mreže?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Mreže koje predlaže <xliff:g id="NAME">%s</xliff:g>. Uređaj će se možda povezati automatski."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Dozvoli"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ne, hvala"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"WiFi će se uključiti automatski"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kada ste u blizini sačuvane mreže visokog kvaliteta"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Nemoj ponovo uključiti"</string>
@@ -1378,7 +1378,7 @@
     <string name="usb_power_notification_message" msgid="4647527153291917218">"Punjenje povezanog uređaja. Dodirnite za više opcija."</string>
     <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Otkriven je analogni periferni uređaj"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Priključeni uređaj nije kompatibilan s ovim telefonom. Dodirnite da saznate više."</string>
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"Otklanjanje grešaka putem uređaja spojenog na USB je uspostavljeno"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"Otklanjanje grešaka putem USB-a je uspostavljeno"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Dodirnite da isključite otklanjanje grešaka putem USB-a"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Odaberite da onemogućite ispravljanje grešaka koristeći USB"</string>
     <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Omogućen način rada okvira za testiranje"</string>
@@ -1924,8 +1924,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Nije kategorizirano"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Vi određujete značaj ovih obavještenja."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ovo je značajno zbog osoba koje su uključene."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Da li dozvoljavate aplikaciji <xliff:g id="APP">%1$s</xliff:g> da kreira novog korisnika s računom <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Da li dozvoljavate da <xliff:g id="APP">%1$s</xliff:g> kreira novog korisnika za <xliff:g id="ACCOUNT">%2$s</xliff:g> (Korisnik sa ovim nalogom već postoji)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Dozvoliti aplikaciji <xliff:g id="APP">%1$s</xliff:g> da kreira novog korisnika s računom <xliff:g id="ACCOUNT">%2$s</xliff:g> (korisnik s ovim računom već postoji)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Dozvoliti aplikaciji <xliff:g id="APP">%1$s</xliff:g> da kreira novog korisnika s računom <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Dodajte jezik"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Izbor regije"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Upišite ime jezika"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 3a74d2a..ad04543 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca per veure totes les xarxes"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connecta"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Totes les xarxes"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Vols connectar-te a una xarxa Wi‑Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Suggerida per <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sí"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Vols permetre les xarxes Wi‑Fi suggerides?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Xarxes suggerides de l\'aplicació <xliff:g id="NAME">%s</xliff:g>. El dispositiu pot connectar-se automàticament."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Permet"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"No, gràcies"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"La Wi-Fi s\'activarà automàticament"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Quan siguis a prop d\'una xarxa de qualitat desada"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"No tornis a activar"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Sense classificar"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Has definit la importància d\'aquestes notificacions."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Aquest missatge és important per les persones implicades."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Concedeixes permís a <xliff:g id="APP">%1$s</xliff:g> per crear un usuari amb el compte <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Concedeixes permís a <xliff:g id="APP">%1$s</xliff:g> per crear un usuari amb el compte <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Ja hi ha un usuari amb aquest compte.)"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Concedeixes permís a <xliff:g id="APP">%1$s</xliff:g> per crear un usuari amb el compte <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Ja hi ha un usuari amb aquest compte.)"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Concedeixes permís a <xliff:g id="APP">%1$s</xliff:g> per crear un usuari amb el compte <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Afegeix un idioma"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Preferència de regió"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Nom de l\'idioma"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 63b3e4c..61b5395 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1299,10 +1299,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Klepnutím zobrazíte všechny sítě"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Připojit"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Všechny sítě"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Připojit k sítím Wi-Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Navrženo kanálem <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ano"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Povolit navrhované sítě Wi-Fi?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Sítě navrhované aplikací <xliff:g id="NAME">%s</xliff:g>. Zařízení se může připojovat automaticky."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Povolit"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ne, díky"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi se zapne automaticky"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Když budete v dosahu kvalitní uložené sítě"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Znovu nezapínat"</string>
@@ -1956,8 +1956,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Neklasifikováno"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Důležitost oznámení určujete vy."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Tato zpráva je důležitá kvůli lidem zapojeným do konverzace."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Povolit aplikaci <xliff:g id="APP">%1$s</xliff:g> vytvořit nového uživatele s účtem <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Povolit aplikaci <xliff:g id="APP">%1$s</xliff:g> vytvořit nového uživatele s účtem <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Uživatel s tímto účtem již existuje.)"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Povolit aplikaci <xliff:g id="APP">%1$s</xliff:g> vytvořit nového uživatele s účtem <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Uživatel s tímto účtem již existuje.)"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Povolit aplikaci <xliff:g id="APP">%1$s</xliff:g> vytvořit nového uživatele s účtem <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Přidat jazyk"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Preferovaná oblast"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Zadejte název jazyka"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index ee5597f..8817636 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -226,7 +226,7 @@
     <string name="global_actions" product="default" msgid="2406416831541615258">"Indstillinger for telefon"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"Skærmlås"</string>
     <string name="global_action_power_off" msgid="4471879440839879722">"Sluk"</string>
-    <string name="global_action_emergency" msgid="7112311161137421166">"Nødopkald"</string>
+    <string name="global_action_emergency" msgid="7112311161137421166">"Nødsituation"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"Fejlrapport"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Afslut sessionen"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tryk for at se alle netværk"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Opret forbindelse"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alle netværk"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Vil du oprette forbindelse til Wi-Fi-netværk?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Foreslået af <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nej"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Vil du tillade foreslåede Wi‑Fi-netværk?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Netværk foreslået af <xliff:g id="NAME">%s</xliff:g>. Enheden opretter muligvis forbindelse automatisk."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Tillad"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nej tak"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi aktiveres automatisk"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Når du er i nærheden af et gemt netværk af høj kvalitet"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Aktivér ikke igen"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Uden kategori"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Du angiver, hvor vigtige disse notifikationer er."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Dette er vigtigt på grund af de personer, det handler om."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Vil du give <xliff:g id="APP">%1$s</xliff:g> tilladelse til at oprette en ny bruger med <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Vil du give <xliff:g id="APP">%1$s</xliff:g> tilladelse til at oprette en ny bruger med <xliff:g id="ACCOUNT">%2$s</xliff:g> (der findes allerede en bruger med denne konto)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Vil du give <xliff:g id="APP">%1$s</xliff:g> tilladelse til at oprette en ny bruger med <xliff:g id="ACCOUNT">%2$s</xliff:g> (der findes allerede en bruger med denne konto)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Vil du give <xliff:g id="APP">%1$s</xliff:g> tilladelse til at oprette en nye bruger med <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Tilføj et sprog"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Områdeindstilling"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Angiv sprog"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 8083aeb0..3d307af 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -282,7 +282,7 @@
     <string name="permgrouprequest_contacts" msgid="6032805601881764300">"Zulassen, dass &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; auf deine Kontakte zugreift?"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"Standort"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"auf den Standort deines Geräts zugreifen"</string>
-    <string name="permgrouprequest_location" msgid="3788275734953323491">"Zulassen, dass &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; den Gerätestandort abruft?"</string>
+    <string name="permgrouprequest_location" msgid="3788275734953323491">"Zulassen, dass die App &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; den Gerätestandort abruft?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Die App hat nur Zugriff auf den Gerätestandort, solange du sie verwendest"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Zulassen, dass &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; &lt;b&gt;ständig&lt;/b&gt; auf deinen Standort zugreift?"</string>
     <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Die App hat gegenwärtig nur dann Zugriff auf den Gerätestandort, wenn du sie verwendest"</string>
@@ -291,7 +291,7 @@
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Zulassen, dass &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; auf deinen Kalender zugreift?"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS senden und abrufen"</string>
-    <string name="permgrouprequest_sms" msgid="7168124215838204719">"Zulassen, dass &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; SMS sendet und aufruft?"</string>
+    <string name="permgrouprequest_sms" msgid="7168124215838204719">"Zulassen, dass die App &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; SMS sendet und aufruft?"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Speicher"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"auf Fotos, Medien und Dateien auf deinem Gerät zugreifen"</string>
     <string name="permgrouprequest_storage" msgid="7885942926944299560">"Zulassen, dass &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; auf Fotos, Medien und Dateien auf deinem Gerät zugreift?"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tippen, um alle Netzwerke zu sehen"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Verbinden"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alle Netzwerke"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Verbindung mit WLANs herstellen?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Vorschlag von <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nein"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Vorgeschlagene WLANs zulassen?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Von <xliff:g id="NAME">%s</xliff:g> vorgeschlagene Netzwerke. Gerät verbindet sich möglicherweise automatisch."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Zulassen"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nein danke"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"WLAN wird automatisch aktiviert"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Wenn du in der Nähe eines sicheren gespeicherten Netzwerks bist"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Nicht wieder aktivieren"</string>
@@ -1359,7 +1359,7 @@
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB-Debugging deaktivieren: auswählen"</string>
     <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Test-Harnischmodus aktiviert"</string>
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Setz das Gerät auf die Werkseinstellungen zurück, um den Test-Harnischmodus zu deaktivieren."</string>
-    <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Flüssigkeiten oder Fremdkörper im USB-Port"</string>
+    <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Flüssigkeit oder Fremdkörper im USB-Port"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Der USB-Port wird automatisch deaktiviert. Für weitere Informationen tippen."</string>
     <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-Port kann wieder verwendet werden"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Das Smartphone erkennt keine Flüssigkeiten oder Fremdkörper mehr."</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Unkategorisiert"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Du hast die Wichtigkeit dieser Benachrichtigungen festgelegt."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Diese Benachrichtigung ist aufgrund der beteiligten Personen wichtig."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Möchtest du zulassen, dass <xliff:g id="APP">%1$s</xliff:g> einen neuen Nutzer mit <xliff:g id="ACCOUNT">%2$s</xliff:g> erstellt?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Möchtest du zulassen, dass <xliff:g id="APP">%1$s</xliff:g> einen neuen Nutzer mit <xliff:g id="ACCOUNT">%2$s</xliff:g> erstellt? Dieses Konto wird jedoch bereits von einem anderen Nutzer verwendet."</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Es gibt bereits einen Nutzer mit <xliff:g id="ACCOUNT">%2$s</xliff:g>. Möchtest du zulassen, dass <xliff:g id="APP">%1$s</xliff:g> einen neuen Nutzer mit diesem Konto erstellt?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Möchtest du zulassen, dass <xliff:g id="APP">%1$s</xliff:g> einen neuen Nutzer mit <xliff:g id="ACCOUNT">%2$s</xliff:g> erstellt?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Sprache hinzufügen"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Region auswählen"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Sprache eingeben"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index d74bc59..91105bb 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Πατήστε για να δείτε όλα τα δίκτυα"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Σύνδεση"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Όλα τα δίκτυα"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Σύνδεση σε δίκτυα Wi-Fi;"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Προτείνεται από <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ναι"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Όχι"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Να επιτρέπονται προτεινόμενα δίκτυα Wi‑Fi;"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Προτεινόμενα δίκτυα <xliff:g id="NAME">%s</xliff:g>. Η συσκευή μπορεί να συνδεθεί αυτόματα."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Αποδοχή"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Όχι, ευχαριστώ"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Το Wi‑Fi θα ενεργοποιηθεί αυτόματα"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Όταν βρίσκεστε κοντά σε αποθηκευμένο δίκτυο υψηλής ποιότητας"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Να μην ενεργοποιηθεί ξανά"</string>
@@ -1673,7 +1673,7 @@
     <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Επιλέξτε μια υπηρεσία που θα χρησιμοποιείται με την κίνηση προσβασιμότητας (σύρετε με δύο δάχτυλα προς τα επάνω από το κάτω μέρος της οθόνης):"</string>
     <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Επιλέξτε μια υπηρεσία που θα χρησιμοποιείται με την κίνηση προσβασιμότητας (σύρετε με τρία δάχτυλα προς τα επάνω από το κάτω μέρος της οθόνης):"</string>
     <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Για εναλλαγή μεταξύ υπηρεσιών, αγγίξτε παρατεταμένα το κουμπί προσβασιμότητας."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Για εναλλαγή μεταξύ υπηρεσιών, σύρετε παρατεταμένα με δύο δάχτυλα προς τα επάνω."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Για εναλλαγή μεταξύ υπηρεσιών, σύρετε παρατεταμένα με δύο δάχτυλα προς τα επάνω και μην τα απομακρύνετε από την οθόνη."</string>
     <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Για εναλλαγή μεταξύ υπηρεσιών, σύρετε παρατεταμένα με τρία δάχτυλα προς τα επάνω."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Μεγιστοποίηση"</string>
     <string name="user_switched" msgid="3768006783166984410">"Τρέχων χρήστης <xliff:g id="NAME">%1$s</xliff:g>."</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Μη κατηγοριοποιημένο"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Μπορείτε να ρυθμίσετε τη βαρύτητα αυτών των ειδοποιήσεων."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Αυτό είναι σημαντικό λόγω των ατόμων που συμμετέχουν."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Να επιτραπεί στην εφαρμογή <xliff:g id="APP">%1$s</xliff:g> να δημιουργήσει έναν νέο χρήστη με το λογαριασμό <xliff:g id="ACCOUNT">%2$s</xliff:g>;"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Να επιτραπεί στην εφαρμογή <xliff:g id="APP">%1$s</xliff:g> να δημιουργήσει έναν νέο χρήστη με το λογαριασμό <xliff:g id="ACCOUNT">%2$s</xliff:g> (υπάρχει ήδη χρήστης με αυτόν το λογαριασμό);"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Επιτρέπετε στην εφαρμογή <xliff:g id="APP">%1$s</xliff:g> να δημιουργήσει έναν νέο χρήστη με τον λογαριασμό <xliff:g id="ACCOUNT">%2$s</xliff:g> (υπάρχει ήδη χρήστης με αυτόν τον λογαριασμό);"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Επιτρέπετε στην εφαρμογή <xliff:g id="APP">%1$s</xliff:g> να δημιουργήσει έναν νέο χρήστη με τον λογαριασμό <xliff:g id="ACCOUNT">%2$s</xliff:g>;"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Προσθήκη γλώσσας"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Προτίμηση περιοχής"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Εισαγ. όνομα γλώσσας"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index f5a5698..53fd166 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -551,10 +551,10 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Fingerprint icon"</string>
-    <string name="permlab_manageFace" msgid="7262837876352591553">"manage Face Unlock hardware"</string>
+    <string name="permlab_manageFace" msgid="7262837876352591553">"manage face unlock hardware"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Allows the app to invoke methods to add and delete facial templates for use."</string>
-    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"use Face Unlock hardware"</string>
-    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Allows the app to use Face Unlock hardware for authentication"</string>
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"use face unlock hardware"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Allows the app to use face unlock hardware for authentication"</string>
     <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Face unlock"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Re-enrol your face"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"To improve recognition, please re-enrol your face"</string>
@@ -581,15 +581,15 @@
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Can’t verify face. Hardware not available."</string>
-    <string name="face_error_timeout" msgid="981512090365729465">"Try Face Unlock again."</string>
+    <string name="face_error_timeout" msgid="981512090365729465">"Try face unlock again."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Can’t store new face data. Delete an old one first."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Face operation cancelled."</string>
-    <string name="face_error_user_canceled" msgid="5317030072349668946">"Face Unlock cancelled by user."</string>
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Face unlock cancelled by user."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Too many attempts. Try again later."</string>
-    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Too many attempts. Face Unlock disabled."</string>
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Too many attempts. Face unlock disabled."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Can’t verify face. Try again."</string>
-    <string name="face_error_not_enrolled" msgid="4016937174832839540">"You haven’t set up Face Unlock."</string>
-    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Face Unlock is not supported on this device."</string>
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"You haven’t set up face unlock."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Face unlock is not supported on this device."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -818,7 +818,7 @@
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Try again"</string>
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Try again"</string>
     <string name="lockscreen_storage_locked" msgid="9167551160010625200">"Unlock for all features and data"</string>
-    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maximum Face Unlock attempts exceeded"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maximum face unlock attempts exceeded"</string>
     <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"No SIM card"</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"No SIM card in tablet."</string>
     <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"No SIM card in TV."</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"All networks"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Connect to Wi‑Fi networks?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Suggested by <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Allow suggested Wi‑Fi networks?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> suggested networks. Device may connect automatically."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Allow"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"No, thanks"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi will turn on automatically"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"When you\'re near a high‑quality saved network"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Don\'t turn back on"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Uncategorised"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"You set the importance of these notifications."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"This is important because of the people involved."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> (a User with this account already exists) ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> (a User with this account already exists)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Add a language"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Region preference"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Type language name"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 4731886..661c802 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -551,10 +551,10 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Fingerprint icon"</string>
-    <string name="permlab_manageFace" msgid="7262837876352591553">"manage Face Unlock hardware"</string>
+    <string name="permlab_manageFace" msgid="7262837876352591553">"manage face unlock hardware"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Allows the app to invoke methods to add and delete facial templates for use."</string>
-    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"use Face Unlock hardware"</string>
-    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Allows the app to use Face Unlock hardware for authentication"</string>
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"use face unlock hardware"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Allows the app to use face unlock hardware for authentication"</string>
     <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Face unlock"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Re-enrol your face"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"To improve recognition, please re-enrol your face"</string>
@@ -581,15 +581,15 @@
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Can’t verify face. Hardware not available."</string>
-    <string name="face_error_timeout" msgid="981512090365729465">"Try Face Unlock again."</string>
+    <string name="face_error_timeout" msgid="981512090365729465">"Try face unlock again."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Can’t store new face data. Delete an old one first."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Face operation cancelled."</string>
-    <string name="face_error_user_canceled" msgid="5317030072349668946">"Face Unlock cancelled by user."</string>
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Face unlock cancelled by user."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Too many attempts. Try again later."</string>
-    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Too many attempts. Face Unlock disabled."</string>
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Too many attempts. Face unlock disabled."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Can’t verify face. Try again."</string>
-    <string name="face_error_not_enrolled" msgid="4016937174832839540">"You haven’t set up Face Unlock."</string>
-    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Face Unlock is not supported on this device."</string>
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"You haven’t set up face unlock."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Face unlock is not supported on this device."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -818,7 +818,7 @@
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Try again"</string>
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Try again"</string>
     <string name="lockscreen_storage_locked" msgid="9167551160010625200">"Unlock for all features and data"</string>
-    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maximum Face Unlock attempts exceeded"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maximum face unlock attempts exceeded"</string>
     <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"No SIM card"</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"No SIM card in tablet."</string>
     <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"No SIM card in TV."</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"All networks"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Connect to Wi‑Fi networks?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Suggested by <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Allow suggested Wi‑Fi networks?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> suggested networks. Device may connect automatically."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Allow"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"No, thanks"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi will turn on automatically"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"When you\'re near a high‑quality saved network"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Don\'t turn back on"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Uncategorised"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"You set the importance of these notifications."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"This is important because of the people involved."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> (a User with this account already exists) ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> (a User with this account already exists)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Add a language"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Region preference"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Type language name"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index f5a5698..53fd166 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -551,10 +551,10 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Fingerprint icon"</string>
-    <string name="permlab_manageFace" msgid="7262837876352591553">"manage Face Unlock hardware"</string>
+    <string name="permlab_manageFace" msgid="7262837876352591553">"manage face unlock hardware"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Allows the app to invoke methods to add and delete facial templates for use."</string>
-    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"use Face Unlock hardware"</string>
-    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Allows the app to use Face Unlock hardware for authentication"</string>
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"use face unlock hardware"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Allows the app to use face unlock hardware for authentication"</string>
     <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Face unlock"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Re-enrol your face"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"To improve recognition, please re-enrol your face"</string>
@@ -581,15 +581,15 @@
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Can’t verify face. Hardware not available."</string>
-    <string name="face_error_timeout" msgid="981512090365729465">"Try Face Unlock again."</string>
+    <string name="face_error_timeout" msgid="981512090365729465">"Try face unlock again."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Can’t store new face data. Delete an old one first."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Face operation cancelled."</string>
-    <string name="face_error_user_canceled" msgid="5317030072349668946">"Face Unlock cancelled by user."</string>
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Face unlock cancelled by user."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Too many attempts. Try again later."</string>
-    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Too many attempts. Face Unlock disabled."</string>
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Too many attempts. Face unlock disabled."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Can’t verify face. Try again."</string>
-    <string name="face_error_not_enrolled" msgid="4016937174832839540">"You haven’t set up Face Unlock."</string>
-    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Face Unlock is not supported on this device."</string>
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"You haven’t set up face unlock."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Face unlock is not supported on this device."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -818,7 +818,7 @@
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Try again"</string>
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Try again"</string>
     <string name="lockscreen_storage_locked" msgid="9167551160010625200">"Unlock for all features and data"</string>
-    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maximum Face Unlock attempts exceeded"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maximum face unlock attempts exceeded"</string>
     <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"No SIM card"</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"No SIM card in tablet."</string>
     <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"No SIM card in TV."</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"All networks"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Connect to Wi‑Fi networks?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Suggested by <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Allow suggested Wi‑Fi networks?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> suggested networks. Device may connect automatically."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Allow"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"No, thanks"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi will turn on automatically"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"When you\'re near a high‑quality saved network"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Don\'t turn back on"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Uncategorised"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"You set the importance of these notifications."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"This is important because of the people involved."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> (a User with this account already exists) ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> (a User with this account already exists)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Add a language"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Region preference"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Type language name"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index f5a5698..53fd166 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -551,10 +551,10 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Fingerprint icon"</string>
-    <string name="permlab_manageFace" msgid="7262837876352591553">"manage Face Unlock hardware"</string>
+    <string name="permlab_manageFace" msgid="7262837876352591553">"manage face unlock hardware"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Allows the app to invoke methods to add and delete facial templates for use."</string>
-    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"use Face Unlock hardware"</string>
-    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Allows the app to use Face Unlock hardware for authentication"</string>
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"use face unlock hardware"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Allows the app to use face unlock hardware for authentication"</string>
     <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Face unlock"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Re-enrol your face"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"To improve recognition, please re-enrol your face"</string>
@@ -581,15 +581,15 @@
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Can’t verify face. Hardware not available."</string>
-    <string name="face_error_timeout" msgid="981512090365729465">"Try Face Unlock again."</string>
+    <string name="face_error_timeout" msgid="981512090365729465">"Try face unlock again."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Can’t store new face data. Delete an old one first."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Face operation cancelled."</string>
-    <string name="face_error_user_canceled" msgid="5317030072349668946">"Face Unlock cancelled by user."</string>
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Face unlock cancelled by user."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Too many attempts. Try again later."</string>
-    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Too many attempts. Face Unlock disabled."</string>
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Too many attempts. Face unlock disabled."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Can’t verify face. Try again."</string>
-    <string name="face_error_not_enrolled" msgid="4016937174832839540">"You haven’t set up Face Unlock."</string>
-    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Face Unlock is not supported on this device."</string>
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"You haven’t set up face unlock."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Face unlock is not supported on this device."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -818,7 +818,7 @@
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Try again"</string>
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Try again"</string>
     <string name="lockscreen_storage_locked" msgid="9167551160010625200">"Unlock for all features and data"</string>
-    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maximum Face Unlock attempts exceeded"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maximum face unlock attempts exceeded"</string>
     <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"No SIM card"</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"No SIM card in tablet."</string>
     <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"No SIM card in TV."</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"All networks"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Connect to Wi‑Fi networks?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Suggested by <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Allow suggested Wi‑Fi networks?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> suggested networks. Device may connect automatically."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Allow"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"No, thanks"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi will turn on automatically"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"When you\'re near a high‑quality saved network"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Don\'t turn back on"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Uncategorised"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"You set the importance of these notifications."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"This is important because of the people involved."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> (a User with this account already exists) ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> (a User with this account already exists)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Add a language"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Region preference"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Type language name"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 95ebcdc..2d1220f6 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‏‎‎‏‏‎‏‎‏‎‏‎Tap to see all networks‎‏‎‎‏‎"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‏‏‏‏‎‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‎‎Connect‎‏‎‎‏‎"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‏‎‏‏‎‎‎‏‏‏‎‏‎‎‎‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎All networks‎‏‎‎‏‎"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‎‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‏‎‏‎‎‏‎‎‏‏‏‏‏‏‏‎‏‎‏‏‏‎Connect to Wi‑Fi networks?‎‏‎‎‏‎"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‎‏‎‏‎‏‎‎‎‎‏‎‎‎‏‎‎‎‏‎‏‏‏‎‎‎‏‏‎‏‏‏‎‎‎‏‎‎‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎Suggested by ‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎‏‎‏‎‏‎‏‎‎‏‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‎‏‎‏‎Yes‎‏‎‎‏‎"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‏‏‏‎‏‎‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‎‏‎No‎‏‎‎‏‎"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‎‎‎‏‎‏‎‎‏‎‏‏‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‎‏‎‎‏‏‎‎‎‎‎‏‎Allow suggested Wi‑Fi networks?‎‏‎‎‏‎"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎ suggested networks. Device may connect automatically.‎‏‎‎‏‎"</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‎‏‏‎‎‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‏‎‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎‏‏‎‏‎Allow‎‏‎‎‏‎"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‎‎‎‎‏‎‏‏‎‎‎‏‎‎‎‎‏‏‎‎‎‎‏‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‎‎‏‎‏‎‎‎No thanks‎‏‎‎‏‎"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎‏‏‎‏‎‎‎‏‎‏‎‎‎‏‎‎‎‏‏‏‎‏‎‎‎Wi‑Fi will turn on automatically‎‏‎‎‏‎"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎‎‎‎‏‏‎‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‎When you\'re near a high quality saved network‎‏‎‎‏‎"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‎‏‏‎‏‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‎Don\'t turn back on‎‏‎‎‏‎"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‎‏‎‏‎‎‏‏‎‎‏‎‏‏‎‎‏‎‏‏‏‏‏‎‎‏‏‎‎‎‏‎‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‎‎Uncategorized‎‏‎‎‏‎"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‏‎‏‎‏‏‎You set the importance of these notifications.‎‏‎‎‏‎"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‎‎‏‎‏‏‏‎‎‎‎This is important because of the people involved.‎‏‎‎‏‎"</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‎‎‎‎‎‏‎‏‎‎‏‏‎‏‎‏‎‎‎‏‏‏‎‎‎‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‎Allow ‎‏‎‎‏‏‎<xliff:g id="APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎ to create a new User with ‎‏‎‎‏‏‎<xliff:g id="ACCOUNT">%2$s</xliff:g>‎‏‎‎‏‏‏‎ ?‎‏‎‎‏‎"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‎‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‎‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‏‎‏‏‎‎‏‏‎‏‏‎‏‏‏‏‏‏‎‏‎Allow ‎‏‎‎‏‏‎<xliff:g id="APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎ to create a new User with ‎‏‎‎‏‏‎<xliff:g id="ACCOUNT">%2$s</xliff:g>‎‏‎‎‏‏‏‎ (a User with this account already exists) ?‎‏‎‎‏‎"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‏‏‎‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‏‏‏‎‎‏‎‎‏‏‎Allow ‎‏‎‎‏‏‎<xliff:g id="APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎ to create a new User with ‎‏‎‎‏‏‎<xliff:g id="ACCOUNT">%2$s</xliff:g>‎‏‎‎‏‏‏‎ (a User with this account already exists) ?‎‏‎‎‏‎"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‏‎‎‏‎‏‏‏‎‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‏‎‏‏‏‎‏‎‎‎‏‏‎Allow ‎‏‎‎‏‏‎<xliff:g id="APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎ to create a new User with ‎‏‎‎‏‏‎<xliff:g id="ACCOUNT">%2$s</xliff:g>‎‏‎‎‏‏‏‎ ?‎‏‎‎‏‎"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‏‏‎‎‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‎‎‎‎‎‎‏‏‎‏‎‎‎‏‎‎‏‎‏‎‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎Add a language‎‏‎‎‏‎"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‎‎‏‏‏‎‎‎‏‎‏‎‎‎‎‎‎‎‏‏‎‏‏‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‏‏‎‏‏‎‎‏‎Region preference‎‏‎‎‏‎"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‎‎‎‏‏‏‏‎‏‏‏‏‎‎Type language name‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 7a22a8e..19598d9 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -30,7 +30,7 @@
     <string name="untitled" msgid="4638956954852782576">"&lt;Sin título&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(No hay número de teléfono)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Desconocido"</string>
-    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Correo de voz"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Buzón de voz"</string>
     <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
     <string name="mmiError" msgid="5154499457739052907">"Problema de conexión o código incorrecto de MMI."</string>
     <string name="mmiFdnError" msgid="5224398216385316471">"La operación está limitada a números de marcación fija."</string>
@@ -941,7 +941,7 @@
     <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permite que la aplicación modifique el historial o los favoritos del navegador almacenados en el dispositivo. La aplicación puede utilizar este permiso para borrar o modificar los datos del navegador. Nota: Este permiso no puede ser utilizado por navegadores externos ni otras aplicaciones que tengan funciones de navegación por Internet."</string>
     <string name="permlab_setAlarm" msgid="1379294556362091814">"programar una alarma"</string>
     <string name="permdesc_setAlarm" msgid="316392039157473848">"Permite que la aplicación establezca una alarma en una aplicación de alarma instalada. Es posible que algunas aplicaciones de alarma no incluyan esta función."</string>
-    <string name="permlab_addVoicemail" msgid="5525660026090959044">"agregar correo de voz"</string>
+    <string name="permlab_addVoicemail" msgid="5525660026090959044">"agregar buzón de voz"</string>
     <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Permite que la aplicación agregue mensajes a la bandeja de entrada de tu buzón de voz."</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Modificar los permisos de ubicación geográfica del navegador"</string>
     <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Permite que la aplicación modifique los permisos de ubicación geográfica del navegador. Las aplicaciones maliciosas pueden utilizar esto para permitir el envío de información de ubicación a sitios web arbitrarios."</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Presiona para ver todas las redes"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas las redes"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"¿Quieres conectarte a redes Wi-Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Sugerido por <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sí"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"¿Quieres permitir las redes Wi‑Fi sugeridas?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> sugirió redes. Es posible que el dispositivo se conecte automáticamente."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Permitir"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"No, gracias"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Se activará la conexión Wi-Fi automáticamente"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Cuando estés cerca de una red guardada de alta calidad"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"No volver a activar"</string>
@@ -1355,7 +1355,7 @@
     <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Se detectó un accesorio de audio analógico"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"El dispositivo adjunto no es compatible con este teléfono. Presiona para obtener más información."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración por USB conectada"</string>
-    <string name="adb_active_notification_message" msgid="7463062450474107752">"Presiona para desactivar la depuración USB"</string>
+    <string name="adb_active_notification_message" msgid="7463062450474107752">"Presiona para desactivar la depuración por USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleccionar para desactivar la depuración por USB"</string>
     <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Se habilitó el modo de agente de prueba"</string>
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Restablece la configuración de fábrica para inhabilitar el modo de agente de prueba."</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Sin categoría"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Estableciste la importancia de estas notificaciones."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Es importante debido a las personas involucradas."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"¿Quieres permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario nuevo con <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"¿Quieres permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario nuevo con <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Ya existe un usuario con esta cuenta)"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"¿Quieres permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario nuevo con <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Ya existe un usuario con esta cuenta)"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"¿Deseas permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario nuevo con <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Agregar un idioma"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Preferencia de región"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Nombre del idioma"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index ae7f38a..7bb51b2 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca para ver todas las redes"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectarse"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas las redes"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"¿Quieres conectarte a redes Wi-Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Sugerido por <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sí"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"¿Permitir sugerencias de redes Wi‑Fi?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> te ha sugerido alguna red. El dispositivo puede que se conecte automáticamente."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Permitir"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"No, gracias"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"La conexión Wi‑Fi se activará automáticamente"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Cuando estés cerca de una red de alta calidad guardada"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"No volver a activar"</string>
@@ -1355,7 +1355,7 @@
     <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Se ha detectado un accesorio de audio analógico"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"El dispositivo adjunto no es compatible con este teléfono. Toca para obtener más información."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB habilitada"</string>
-    <string name="adb_active_notification_message" msgid="7463062450474107752">"Toca para desactivar la depuración USB."</string>
+    <string name="adb_active_notification_message" msgid="7463062450474107752">"Tocar para desactivar depuración USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleccionar para inhabilitar la depuración USB"</string>
     <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Modo de agente de prueba habilitado"</string>
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Restablece los ajustes de fábrica para inhabilitar el modo de agente de prueba."</string>
@@ -1670,8 +1670,8 @@
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"El acceso directo a accesibilidad ha desactivado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Para utilizar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, mantén pulsadas ambas teclas de volumen durante 3 segundos"</string>
     <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Selecciona el servicio que se utilizará cuando toques el botón Accesibilidad:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Elige el servicio que se utilizará con el gesto de accesibilidad (desliza dos dedos hacia arriba desde la parte inferior de la pantalla):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Elige el servicio que se utilizará con el gesto de accesibilidad (desliza tres dedos hacia arriba desde la parte inferior de la pantalla):"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Elige el servicio que se utilizará con el gesto de accesibilidad (deslizar dos dedos hacia arriba desde la parte inferior de la pantalla):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Elige el servicio que se utilizará con el gesto de accesibilidad (deslizar tres dedos hacia arriba desde la parte inferior de la pantalla):"</string>
     <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Para cambiar de un servicio a otro, mantén pulsado el botón de accesibilidad."</string>
     <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Para cambiar de un servicio a otro, desliza dos dedos hacia arriba y mantén pulsada la pantalla."</string>
     <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Para cambiar de un servicio a otro, desliza tres dedos hacia arriba y mantén pulsada la pantalla."</string>
@@ -1888,9 +1888,9 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Sin clasificar"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Tú determinas la importancia de estas notificaciones."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Esto es importante por los usuarios implicados."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"¿Permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario con la cuenta <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"¿Permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario con la cuenta <xliff:g id="ACCOUNT">%2$s</xliff:g> (ya existe un usuario con esta cuenta)?"</string>
-    <string name="language_selection_title" msgid="2680677278159281088">"Añade un idioma"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"¿Permitir que <xliff:g id="APP">%1$s</xliff:g> cree otro usuario con la cuenta <xliff:g id="ACCOUNT">%2$s</xliff:g>, que ya tiene uno?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"¿Permitir que <xliff:g id="APP">%1$s</xliff:g> cree otro usuario con la cuenta <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
+    <string name="language_selection_title" msgid="2680677278159281088">"Añadir un idioma"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Preferencia de región"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Nombre de idioma"</string>
     <string name="language_picker_section_suggested" msgid="8414489646861640885">"Sugeridos"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index d3404a6..e2afa3b 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -243,7 +243,7 @@
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Hääletu režiim"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Heli on VÄLJAS"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Heli on SEES"</string>
-    <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Lennurežiim"</string>
+    <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Lennukirežiim"</string>
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Lennurežiim on SEES"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Lennurežiim on VÄLJAS"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Seaded"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Puudutage kõikide võrkude nägemiseks"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ühenda"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Kõik võrgud"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Kas soovite luua ühenduse WiFi-võrkudega?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Soovitas <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Jah"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ei"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Kas lubada soovitatud WiFi-võrgud?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Rakenduse <xliff:g id="NAME">%s</xliff:g> soovitatud võrgud. Seade võib automaatselt ühenduse luua."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Luba"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Tänan, ei"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"WiFi lülitub sisse automaatselt"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kui olete kvaliteetse salvestatud võrgu läheduses"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ära lülita tagasi sisse"</string>
@@ -1670,7 +1670,7 @@
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Juurdepääsetavuse otsetee lülitas teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> välja"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kasutamiseks hoidke kolm sekundit all mõlemat helitugevuse klahvi"</string>
     <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Valige, millist teenust kasutada, kui puudutate juurdepääsetavuse nuppu:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Valige, millist teenust kasutada koos juurdepääsetavuse liigutusega (pühkige kahe sõrmega ekraanikuval alt üles):"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Valige, millist teenust kasutada koos juurdepääsetavuse liigutusega (kahe sõrmega ekraanikuval alt üles pühkimine):"</string>
     <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Valige, millist teenust kasutada koos juurdepääsetavuse liigutusega (kolme sõrmega ekraanikuval alt üles pühkimine):"</string>
     <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Teenuste vahel vahetamiseks vajutage pikalt juurdepääsetavuse nuppu."</string>
     <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Teenuste vahel vahetamiseks pühkige kahe sõrmega üles ja hoidke."</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Kategoriseerimata"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Teie määrasite nende märguannete tähtsuse."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"See on tähtis osalevate inimeste tõttu."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Kas lubada rakendusel <xliff:g id="APP">%1$s</xliff:g> luua uus kasutaja kontoga <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Kas lubada rakendusel <xliff:g id="APP">%1$s</xliff:g> luua uus kasutaja kontoga <xliff:g id="ACCOUNT">%2$s</xliff:g> (selle kontoga kasutaja on juba olemas)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Kas lubada rakendusel <xliff:g id="APP">%1$s</xliff:g> luua uus kasutaja kontoga <xliff:g id="ACCOUNT">%2$s</xliff:g> (selle kontoga kasutaja on juba olemas)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Kas lubada rakendusel <xliff:g id="APP">%1$s</xliff:g> luua uus kasutaja kontoga <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Keele lisamine"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Piirkonnaeelistus"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Sisestage keele nimi"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 8897b9f..3eed140 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -279,37 +279,37 @@
     <string name="managed_profile_label" msgid="8947929265267690522">"Aldatu laneko profilera"</string>
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktuak"</string>
     <string name="permgroupdesc_contacts" msgid="6951499528303668046">"atzitu kontaktuak"</string>
-    <string name="permgrouprequest_contacts" msgid="6032805601881764300">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari kontaktuak atzitzeko baimena eman nahi diozu?"</string>
+    <string name="permgrouprequest_contacts" msgid="6032805601881764300">"Kontaktuak atzitzeko baimena eman nahi diozu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari?"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"Kokapena"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"atzitu gailuaren kokapena"</string>
-    <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari gailuaren kokapena atzitzeko baimena eman nahi diozu?"</string>
+    <string name="permgrouprequest_location" msgid="3788275734953323491">"Gailuaren kokapena atzitzeko baimena eman nahi diozu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Hura erabiltzen ari zarenean soilik atzituko du aplikazioak kokapena"</string>
-    <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari gailuaren kokapena &lt;b&gt;beti&lt;/b&gt; atzitzeko baimena eman nahi diozu?"</string>
+    <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Gailuaren kokapena &lt;b&gt;beti&lt;/b&gt; atzitzeko baimena eman nahi diozu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari?"</string>
     <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Aplikazioak hura darabilzunean atzi dezake kokapena"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Egutegia"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"atzitu egutegia"</string>
-    <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari egutegia atzitzeko baimena eman nahi diozu?"</string>
+    <string name="permgrouprequest_calendar" msgid="289900767793189421">"Egutegia atzitzeko baimena eman nahi diozu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari?"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS mezuak"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"bidali eta ikusi SMS mezuak"</string>
-    <string name="permgrouprequest_sms" msgid="7168124215838204719">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari SMS mezuak bidaltzeko eta ikusteko baimena eman nahi diozu?"</string>
+    <string name="permgrouprequest_sms" msgid="7168124215838204719">"SMS mezuak bidaltzeko eta ikusteko baimena eman nahi diozu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari?"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Memoria"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"atzitu gailuko argazkiak, multimedia-edukia eta fitxategiak"</string>
-    <string name="permgrouprequest_storage" msgid="7885942926944299560">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari gailuko argazkiak, multimedia-edukia eta fitxategiak atzitzeko baimena eman nahi diozu?"</string>
+    <string name="permgrouprequest_storage" msgid="7885942926944299560">"Gailuko argazkiak, multimedia-edukia eta fitxategiak atzitzeko baimena eman nahi diozu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari?"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofonoa"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"grabatu audioa"</string>
-    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari audioa grabatzeko baimena eman nahi diozu?"</string>
+    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"Audioa grabatzeko baimena eman nahi diozu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari?"</string>
     <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"Ariketa fisikoa"</string>
     <string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"ariketa fisikoak atzitu"</string>
     <string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"Zure ariketa fisikoak atzitzeko baimena eman nahi diozu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari?"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
     <string name="permgroupdesc_camera" msgid="3250611594678347720">"atera argazkiak eta grabatu bideoak"</string>
-    <string name="permgrouprequest_camera" msgid="1299833592069671756">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari argazkiak ateratzeko eta bideoak grabatzeko baimena eman nahi diozu?"</string>
+    <string name="permgrouprequest_camera" msgid="1299833592069671756">"Argazkiak ateratzeko eta bideoak grabatzeko baimena eman nahi diozu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari?"</string>
     <string name="permgrouplab_calllog" msgid="8798646184930388160">"Deien erregistroa"</string>
     <string name="permgroupdesc_calllog" msgid="3006237336748283775">"irakurri telefonoko deien erregistroa eta idatzi bertan"</string>
-    <string name="permgrouprequest_calllog" msgid="8487355309583773267">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari telefonoko deien erregistroa atzitzeko baimena eman nahi diozu?"</string>
+    <string name="permgrouprequest_calllog" msgid="8487355309583773267">"Telefonoko deien erregistroa atzitzeko baimena eman nahi diozu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari?"</string>
     <string name="permgrouplab_phone" msgid="5229115638567440675">"Telefonoa"</string>
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"egin eta kudeatu telefono-deiak"</string>
-    <string name="permgrouprequest_phone" msgid="9166979577750581037">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari telefono-deiak egiteko eta kudeatzeko baimena eman nahi diozu?"</string>
+    <string name="permgrouprequest_phone" msgid="9166979577750581037">"Telefono-deiak egiteko eta kudeatzeko baimena eman nahi diozu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari?"</string>
     <string name="permgrouplab_sensors" msgid="4838614103153567532">"Gorputz-sentsoreak"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"atzitu bizi-konstanteei buruzko sentsorearen datuak"</string>
     <string name="permgrouprequest_sensors" msgid="6349806962814556786">"Bizi-konstanteei buruzko sentsorearen datuak atzitzeko baimena eman nahi diozu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari?"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Sakatu hau sare guztiak ikusteko"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Konektatu"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Sare guztiak"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wifi-sareetara konektatu nahi duzu?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> aplikazioak iradoki du"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Bai"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ez"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Iradokitako wifi-sareak baimendu nahi dituzu?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> aplikazioak sare batzuk iradoki ditu. Baliteke gailua automatikoki konektatzea."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Baimendu"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ez, eskerrik asko"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi konexioa automatikoki aktibatuko da"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Gordeta daukazun kalitate handiko sare batetik gertu zaudenean"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ez aktibatu berriro"</string>
@@ -1636,7 +1636,7 @@
     <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PIN kode okerra."</string>
     <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Idatzi 4 eta 8 zenbaki arteko PINa."</string>
     <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK kodeak 8 zenbaki izan behar ditu."</string>
-    <string name="kg_invalid_puk" msgid="3638289409676051243">"Idatzi berriro PUK kode zuzena. Hainbat saiakera oker eginez gero, betirako desgaituko da SIMa."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Idatzi berriro PUK kode zuzena. Hainbat saiakera oker eginez gero, betiko desgaituko da SIMa."</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN kodeak ez datoz bat"</string>
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Eredua marrazteko saiakera gehiegi egin dira"</string>
     <string name="kg_login_instructions" msgid="1100551261265506448">"Desblokeatzeko, hasi saioa Google kontuarekin."</string>
@@ -1889,8 +1889,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Kategoriarik gabea"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Zuk ezarri duzu jakinarazpen hauen garrantzia."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Garrantzitsua da eragiten dien pertsonengatik."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g> aplikazioari <xliff:g id="ACCOUNT">%2$s</xliff:g> kontua duen erabiltzailea sortzeko baimena eman nahi diozu?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g> aplikazioari <xliff:g id="ACCOUNT">%2$s</xliff:g> kontua duen erabiltzailea sortzeko baimena eman nahi diozu? (Badago kontu hori duen erabiltzaile bat)"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g> kontua duen erabiltzailea sortzeko baimena eman nahi diozu <xliff:g id="APP">%1$s</xliff:g> aplikazioari? (Badago kontu hori duen erabiltzaile bat)"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> kontua duen erabiltzailea sortzeko baimena eman nahi diozu <xliff:g id="APP">%1$s</xliff:g> aplikazioari?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Gehitu hizkuntza"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Lurralde-hobespena"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Adierazi hizkuntza"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 7d86be9..2f90fc9 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -291,7 +291,7 @@
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"‏به &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; اجازه داده شود به تقویم شما دسترسی پیدا کند؟"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"پیامک"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"ارسال و مشاهده پیامک‌ها"</string>
-    <string name="permgrouprequest_sms" msgid="7168124215838204719">"‏به &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;b&gt; اجازه داده شود پیامک‌ها را ارسال و مشاهده کند؟"</string>
+    <string name="permgrouprequest_sms" msgid="7168124215838204719">"‏به «&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;b&gt;» اجازه داده شود پیامک ارسال و مشاهده کند؟"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"حافظه"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"دسترسی به عکس‌ها، رسانه‌ها و فایل‌های روی دستگاهتان"</string>
     <string name="permgrouprequest_storage" msgid="7885942926944299560">"‏به برنامه &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;b&gt; اجازه داده شود به عکس‌ها، رسانه، و فایل‌های موجود در دستگاهتان دسترسی داشته باشد؟"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"برای دیدن همه شبکه‌ها ضربه بزنید"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"اتصال"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"همه شبکه‌ها"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"‏به شبکه‌های Wi-Fi متصل می‌شوید؟"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"پیشنهاد <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"بله"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"خیر"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"‏شبکه‌های Wi‑Fi پیشنهادی مجاز شود؟"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"شبکه‌های پیشنهادی <xliff:g id="NAME">%s</xliff:g>. ممکن است دستگاه به‌طور خودکار متصل شود."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"مجاز"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"نه متشکرم"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"‏Wi‑Fi به‌طور خودکار روشن خواهد شد"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"وقتی نزدیک شبکه ذخیره‌شده با کیفیت بالا هستید"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"دوباره روشن نشود"</string>
@@ -1808,8 +1808,8 @@
     <string name="package_updated_device_owner" msgid="1847154566357862089">"توسط سرپرست سیستم به‌روزرسانی شد"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"توسط سرپرست سیستم حذف شد"</string>
     <string name="confirm_battery_saver" msgid="639106420541753635">"تأیید"</string>
-    <string name="battery_saver_description_with_learn_more" msgid="2108984221113106294">"بهینه‌سازی باتری فعالیت پس‌زمینه، برخی جلوه‌های دیداری، و سایر ویژگی‌های با مصرف بالای نیرو را خاموش یا محدود می‌کند تا عمر باتری افزایش یابد. "<annotation id="url">"بیشتر بدانید"</annotation></string>
-    <string name="battery_saver_description" msgid="6413346684861241431">"بهینه‌سازی باتری فعالیت پس‌زمینه، برخی جلوه‌های دیداری، و سایر ویژگی‌های با مصرف بالای نیرو را خاموش یا محدود می‌کند تا عمر باتری افزایش یابد."</string>
+    <string name="battery_saver_description_with_learn_more" msgid="2108984221113106294">"«بهینه‌سازی باتری» فعالیت پس‌زمینه، برخی جلوه‌های دیداری، و سایر ویژگی‌های پرمصرف نیرو را خاموش یا محدود می‌کند تا عمر باتری افزایش یابد. "<annotation id="url">"بیشتر بدانید"</annotation></string>
+    <string name="battery_saver_description" msgid="6413346684861241431">"«بهینه‌سازی باتری» فعالیت پس‌زمینه، برخی جلوه‌های دیداری، و سایر ویژگی‌های پرمصرف نیرو را خاموش یا محدود می‌کند تا عمر باتری افزایش یابد."</string>
     <string name="data_saver_description" msgid="6015391409098303235">"برای کمک به کاهش مصرف داده، «صرفه‌جویی داده» از ارسال و دریافت داده در پس‌زمینه ازطرف بعضی برنامه‌ها جلوگیری می‌کند. برنامه‌ای که درحال‌حاضر استفاده می‌کنید می‌تواند به داده‌ها دسترسی داشته باشد اما دفعات دسترسی آن محدود است.این یعنی، برای مثال، تصاویر تا زمانی که روی آن‌ها ضربه نزنید نشان داده نمی‌شوند."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"صرفه‌جویی داده روشن شود؟"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"روشن کردن"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"دسته‌بندی‌نشده"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"شما اهمیت این اعلان‌ها را تنظیم می‌کنید."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"به دلیل افراد درگیر مهم است."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"به <xliff:g id="APP">%1$s</xliff:g> امکان داده شود کاربر جدیدی با <xliff:g id="ACCOUNT">%2$s</xliff:g> اضافه کند؟"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"به <xliff:g id="APP">%1$s</xliff:g> امکان داده شود کاربر جدیدی با <xliff:g id="ACCOUNT">%2$s</xliff:g> ایجاد کند (کاربری با این حساب از قبل وجود دارد)؟"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"به<xliff:g id="APP">%1$s</xliff:g> اجازه می‌دهید با <xliff:g id="ACCOUNT">%2$s</xliff:g> (کاربری با این حساب درحال‌حاضر وجود دارد) کاربری جدید ایجاد کند؟"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"به <xliff:g id="APP">%1$s</xliff:g> اجازه می‌دهید با <xliff:g id="ACCOUNT">%2$s</xliff:g> کاربری جدید ایجاد کند؟"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"افزودن زبان"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"اولویت‌های منطقه"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"نام زبان را تایپ کنید"</string>
@@ -2001,15 +2001,15 @@
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"نمایش روی برنامه‌های دیگر در صفحه‌نمایش"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"اعلان اطلاعات حالت روال معمول"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"ممکن است شارژ باتری قبل از شارژ معمول تمام شود"</string>
-    <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"جهت افزایش عمر باتری، بهینه‌سازی باتری فعال شد"</string>
+    <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"جهت افزایش عمر باتری، «بهینه‌سازی باتری» فعال شد"</string>
     <string name="battery_saver_notification_channel_name" msgid="2083316159716201806">"بهینه‌سازی باتری"</string>
-    <string name="battery_saver_sticky_disabled_notification_title" msgid="6376147579378764641">"تا وقتی شارژ باتری دوباره به سطح پایین نرسد، بهینه‌سازی باتری مجدداً فعال نخواهد شد"</string>
-    <string name="battery_saver_sticky_disabled_notification_summary" msgid="8090192609249817945">"باتری تا سطحی کافی شارژ شده است. تا وقتی شارژ باتری دوباره به سطح پایین نرسد، بهینه‌سازی باتری مجدداً فعال نخواهد شد."</string>
+    <string name="battery_saver_sticky_disabled_notification_title" msgid="6376147579378764641">"تا وقتی شارژ باتری دوباره به سطح پایین نرسد، «بهینه‌سازی باتری» مجدداً فعال نخواهد شد"</string>
+    <string name="battery_saver_sticky_disabled_notification_summary" msgid="8090192609249817945">"باتری درحد کافی شارژ شده است. تا وقتی شارژ باتری دوباره به سطح پایین نرسد، «بهینه‌سازی باتری» مجدداً فعال نخواهد شد."</string>
     <string name="battery_saver_charged_notification_title" product="default" msgid="2960978289873161288">"تلفن <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> شارژ شد"</string>
     <string name="battery_saver_charged_notification_title" product="tablet" msgid="7555713825806482451">"رایانه لوحی <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> شارژ شد"</string>
     <string name="battery_saver_charged_notification_title" product="device" msgid="5954873381559605660">"دستگاه <xliff:g id="CHARGE_LEVEL">%1$s</xliff:g> شارژ شد"</string>
-    <string name="battery_saver_off_notification_summary" msgid="1374222493681267143">"بهینه‌سازی باتری خاموش است. ویژگی‌ها دیگر محدود نمی‌شوند."</string>
-    <string name="battery_saver_off_alternative_notification_summary" msgid="4340727818546508436">"بهینه‌سازی باتری خاموش شد. ویژگی‌ها دیگر محدود نمی‌شوند."</string>
+    <string name="battery_saver_off_notification_summary" msgid="1374222493681267143">"«بهینه‌سازی باتری» خاموش است. ویژگی‌ها دیگر محدود نمی‌شوند."</string>
+    <string name="battery_saver_off_alternative_notification_summary" msgid="4340727818546508436">"«بهینه‌سازی باتری» خاموش شد. ویژگی‌ها دیگر محدود نمی‌شوند."</string>
     <string name="mime_type_folder" msgid="7111951698626315204">"پوشه"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"‏برنامه Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"فایل"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 0a6132d..6260c55 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -282,7 +282,7 @@
     <string name="permgrouprequest_contacts" msgid="6032805601881764300">"Saako &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; yhteystietojesi käyttöoikeuden?"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"Sijainti"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"käyttää laitteen sijaintia"</string>
-    <string name="permgrouprequest_location" msgid="3788275734953323491">"Saako &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tämän laitteen sijainnin käyttöoikeuden?"</string>
+    <string name="permgrouprequest_location" msgid="3788275734953323491">"Saako &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; oikeuden nähdä tämän laitteen sijainnin?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Sovellus saa sijainnin käyttöoikeuden vain silloin, kun käytät sovellusta"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Saako &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; käyttää laitteen sijaintia &lt;b&gt;aina&lt;/b&gt;?"</string>
     <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Sovellus saa tällä hetkellä sijainnin käyttöoikeuden vain, jos käytät sovellusta"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Napauta, niin näet kaikki verkot."</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Yhdistä"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Kaikki verkot"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Yhdistetäänkö Wi-Fi-verkkoihin?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Ehdottaja: <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Kyllä"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ei"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Sallitaanko ehdotetut Wi-Fi-verkot?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> ehdotti verkkoja. Laite voi muodostaa yhteyden automaattisesti."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Salli"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ei kiitos"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi käynnistyy automaattisesti"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kun olet lähellä laadukasta tallennettua verkkoa"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Älä käynnistä uudelleen"</string>
@@ -1627,7 +1627,7 @@
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Piirrä kuvio"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Anna SIM-kortin PIN-koodi"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Anna PIN-koodi"</string>
-    <string name="kg_password_instructions" msgid="5753646556186936819">"Anna salasana"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Lisää salasana"</string>
     <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM-kortti on nyt poistettu käytöstä. Jatka antamalla PUK-koodi. Saat lisätietoja ottamalla yhteyttä operaattoriin."</string>
     <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Anna haluamasi PIN-koodi"</string>
     <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Vahvista haluamasi PIN-koodi"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Luokittelematon"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Voit valita näiden ilmoitusten tärkeyden."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Tämä on tärkeää siihen liittyvien ihmisten perusteella."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Myönnetäänkö sovellukselle <xliff:g id="APP">%1$s</xliff:g> oikeus luoda käyttäjä tilille <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Myönnetäänkö sovellukselle <xliff:g id="APP">%1$s</xliff:g> oikeus luoda käyttäjä tilille <xliff:g id="ACCOUNT">%2$s</xliff:g> (tilillä on jo käyttäjä)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Saako <xliff:g id="APP">%1$s</xliff:g> luoda uuden käyttäjän (<xliff:g id="ACCOUNT">%2$s</xliff:g>) – tällä käyttäjällä on jo tili?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Saako <xliff:g id="APP">%1$s</xliff:g> luoda uuden käyttäjän (<xliff:g id="ACCOUNT">%2$s</xliff:g>)?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Lisää kieli"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Alueasetus"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Anna kielen nimi"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index aec3c11..dbc4aee 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -527,9 +527,9 @@
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Données biométriques non reconnues"</string>
     <string name="biometric_error_canceled" msgid="349665227864885880">"Authentification annulée"</string>
     <string name="biometric_error_device_not_secured" msgid="6583143098363528349">"Aucun NIP, schéma ou mot de passe défini"</string>
-    <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Empreinte digitale partielle détectée. Veuillez essayer de nouveau."</string>
+    <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Empreinte digitale partielle détectée. Veuillez réessayer."</string>
     <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Impossible de reconnaître l\'empreinte digitale. Veuillez réessayer."</string>
-    <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Le capteur d\'empreintes digitales est sale. Veuillez le nettoyer et essayer de nouveau."</string>
+    <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Le capteur d\'empreintes digitales est sale. Veuillez le nettoyer et réessayer."</string>
     <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Vous avez déplacé votre doigt trop rapidement. Veuillez réessayer."</string>
     <string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"Vous avez déplacé votre doigt trop lentement. Veuillez réessayer."</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -537,10 +537,10 @@
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"Empreinte digitale authentifiée"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Visage authentifié"</string>
     <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Visage authentifié, veuillez appuyer sur le bouton Confirmer"</string>
-    <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Matériel d\'empreinte numérique indisponible."</string>
+    <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Matériel d\'empreinte digitale numérique indisponible."</string>
     <string name="fingerprint_error_no_space" msgid="1055819001126053318">"L\'empreinte digitale ne peut pas être enregistrée. Veuillez supprimer une empreinte existante."</string>
-    <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Le temps attribué pour lire l\'empreinte est écoulé. Veuillez essayer de nouveau."</string>
-    <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Opération d\'empreinte numérique annulée."</string>
+    <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Le temps attribué pour lire l\'empreinte digitale est écoulé. Veuillez réessayer."</string>
+    <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Opération d\'empreinte digitale numérique annulée."</string>
     <string name="fingerprint_error_user_canceled" msgid="7999639584615291494">"L\'opération d\'empreinte digitale a été annulée par l\'utilisateur."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Trop de tentatives. Veuillez réessayer plus tard."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Trop de tentatives. Capteur d\'empreintes digitales désactivé."</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Touchez pour afficher tous les réseaux"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connexion"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Tous les réseaux"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Se connecter aux réseaux Wi-Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Suggéré par <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Oui"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Non"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Autoriser les suggestions de réseaux Wi‑Fi?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Réseaux suggérés par <xliff:g id="NAME">%s</xliff:g>. L\'appareil peut s\'y connecter automatiquement."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Autoriser"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Non merci"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Le Wi-Fi s\'activera automatiquement"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Lorsque vous êtes près d\'un réseau enregistré de haute qualité"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ne pas réactiver"</string>
@@ -1577,8 +1577,8 @@
     <string name="expires_on" msgid="3676242949915959821">"Expire le :"</string>
     <string name="serial_number" msgid="758814067660862493">"Numéro de série :"</string>
     <string name="fingerprints" msgid="4516019619850763049">"Empreintes :"</string>
-    <string name="sha256_fingerprint" msgid="4391271286477279263">"Empreinte SHA-256 :"</string>
-    <string name="sha1_fingerprint" msgid="7930330235269404581">"Empreinte SHA-1 :"</string>
+    <string name="sha256_fingerprint" msgid="4391271286477279263">"Empreinte digitale SHA-256 :"</string>
+    <string name="sha1_fingerprint" msgid="7930330235269404581">"Empreinte digitale SHA-1 :"</string>
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Tout afficher"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Sélectionnez une activité"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Partagez avec"</string>
@@ -1670,10 +1670,10 @@
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Le raccourci d\'accessibilité a désactivé la fonction <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Maintenez enfoncées les deux touches de volume pendant trois secondes pour utiliser <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Choisissez un service à utiliser lorsque vous touchez le bouton d\'accessibilité :"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Choisissez un service à utiliser lorsque vous utilisez le geste d\'accessibilité (balayer deux doigts du bas de l\'écran vers le haut) :"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Choisissez un service à utiliser lorsque vous utilisez le geste d\'accessibilité (balayer trois doigts du bas de l\'écran vers le haut) :"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Choisissez un service à utiliser lorsque vous utilisez le geste d\'accessibilité (balayer l\'écran de bas en haut avec deux doigts) :"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Choisissez un service à utiliser lorsque vous utilisez le geste d\'accessibilité (balayer l\'écran de bas en haut avec trois doigts) :"</string>
     <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Pour basculer entre les services, maintenez le doigt sur le bouton d\'accessibilité."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Pour basculer entre les services, balayez deux doigts vers le haut et maintenez-les sur l\'écran."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Pour basculer entre les services, balayez l\'écrfan vers le haut avec deux doigts et maintenez-les-y."</string>
     <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Pour changer de service, balayez trois doigts vers le haut et maintenez-les sur l\'écran."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Zoom"</string>
     <string name="user_switched" msgid="3768006783166984410">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Sans catégorie"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Vous définissez l\'importance de ces notifications."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ces notifications sont importantes en raison des participants."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à créer un profil d\'utilisateur avec le compte <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à créer un profil d\'utilisateur avec le compte <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Un utilisateur associé à ce compte existe déjà.)"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à créer un utilisateur <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Un utilisateur est déjà associé à ce compte)"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à créer un profil d\'utilisateur avec le compte <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Ajouter une langue"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Préférences régionales"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Entrez la langue"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 35553c4..993101b 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -291,7 +291,7 @@
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Permettre à &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; d\'accéder à votre agenda ?"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"envoyer et consulter des SMS"</string>
-    <string name="permgrouprequest_sms" msgid="7168124215838204719">"Permettre à &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; d\'envoyer et d\'afficher des SMS ?"</string>
+    <string name="permgrouprequest_sms" msgid="7168124215838204719">"Autoriser l\'application &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; à envoyer et afficher des SMS ?"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Stockage"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"accéder aux photos, contenus multimédias et fichiers sur votre appareil"</string>
     <string name="permgrouprequest_storage" msgid="7885942926944299560">"Autoriser l\'appli &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; à accéder aux photos, contenus multimédias et fichiers sur votre appareil ?"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Appuyer pour afficher tous les réseaux"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Se connecter"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Tous les réseaux"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Se connecter à des réseaux Wi-Fi ?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Suggérée par <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Oui"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Non"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Autoriser les suggestions de réseaux Wi‑Fi ?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Réseaux suggérés par <xliff:g id="NAME">%s</xliff:g>. L\'appareil pourra se connecter automatiquement."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Autoriser"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Non, merci"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Le Wi-Fi sera activé automatiquement"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Lorsque vous êtes à proximité d\'un réseau enregistré de haute qualité"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ne pas réactiver"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Sans catégorie"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Vous définissez l\'importance de ces notifications."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ces notifications sont importantes en raison des participants."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à créer un profil utilisateur avec le compte <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à créer un profil utilisateur avec le compte <xliff:g id="ACCOUNT">%2$s</xliff:g> (un utilisateur associé à ce compte existe déjà) ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à créer un profil utilisateur avec le compte <xliff:g id="ACCOUNT">%2$s</xliff:g> (un utilisateur associé à ce compte existe déjà) ?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à créer un profil utilisateur avec le compte <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Ajouter une langue"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Préférences régionales"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Saisissez la langue"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 6bdf045..d973c7c4 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -387,7 +387,7 @@
     <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Permite á aplicación executarse unha vez o sistema se inicie completamente. Isto pode provocar que o teléfono tarde máis tempo en iniciarse e permitir á aplicación reducir a velocidade xeral do teléfono ao manterse sempre en execución."</string>
     <string name="permlab_broadcastSticky" msgid="7919126372606881614">"enviar difusión persistente"</string>
     <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Permite á aplicación enviar difusións permanentes que continúan unha vez finalizada a difusión. Un uso excesivo pode provocar que a tableta funcione con lentitude ou de forma inestable debido á necesidade de utilizar demasiada memoria."</string>
-    <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"Permite que a aplicación envíe emisións permanentes, que continúan unha vez finalizada a emisión. O uso excesivo pode volver a televisión máis lenta ou inestable, facendo que utilice moita memoria."</string>
+    <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"Permite que a aplicación envíe emisións atractivas, que permanecen unha vez finalizada a emisión. O uso excesivo pode volver a televisión máis lenta ou inestable, facendo que utilice moita memoria."</string>
     <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Permite á aplicación enviar difusións permanentes que continúan unha vez finalizada a difusión. Un uso excesivo pode provocar que o teléfono funcione con lentitude ou de forma inestable debido á necesidade de utilizar demasiada memoria."</string>
     <string name="permlab_readContacts" msgid="8348481131899886131">"ler os teus contactos"</string>
     <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Permite á aplicación ler datos acerca dos teus contactos almacenados na tableta, incluída a frecuencia coa que os chamaches, lles enviaches un correo electrónico ou te comunicaches con individuos específicos doutras formas. Con este permiso as aplicacións poden gardar os teus datos de contacto e as aplicacións maliciosas poden compartir os datos de contacto sen o teu coñecemento."</string>
@@ -1091,27 +1091,27 @@
     <string name="inputMethod" msgid="1653630062304567879">"Método de introdución de texto"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Accións de texto"</string>
     <string name="email" msgid="4560673117055050403">"Correo electrónico"</string>
-    <string name="email_desc" msgid="3638665569546416795">"Envía un correo electrónico ao enderezo seleccionado"</string>
+    <string name="email_desc" msgid="3638665569546416795">"Enviar un correo electrónico ao enderezo seleccionado"</string>
     <string name="dial" msgid="1253998302767701559">"Chamar"</string>
-    <string name="dial_desc" msgid="6573723404985517250">"Chama ao número de teléfono seleccionado"</string>
+    <string name="dial_desc" msgid="6573723404985517250">"Chamar ao número de teléfono seleccionado"</string>
     <string name="map" msgid="5441053548030107189">"Mapa"</string>
-    <string name="map_desc" msgid="1836995341943772348">"Localiza o enderezo seleccionado"</string>
+    <string name="map_desc" msgid="1836995341943772348">"Localizar o enderezo seleccionado"</string>
     <string name="browse" msgid="1245903488306147205">"Abrir"</string>
-    <string name="browse_desc" msgid="8220976549618935044">"Abre o URL seleccionado"</string>
+    <string name="browse_desc" msgid="8220976549618935044">"Abrir o URL seleccionado"</string>
     <string name="sms" msgid="4560537514610063430">"Enviar SMS"</string>
-    <string name="sms_desc" msgid="7526588350969638809">"Envía unha mensaxe ao número de teléfono seleccionado"</string>
+    <string name="sms_desc" msgid="7526588350969638809">"Enviar unha mensaxe ao número de teléfono seleccionado"</string>
     <string name="add_contact" msgid="7867066569670597203">"Engadir"</string>
-    <string name="add_contact_desc" msgid="4830217847004590345">"Engade o elemento aos contactos"</string>
+    <string name="add_contact_desc" msgid="4830217847004590345">"Engadir o elemento aos contactos"</string>
     <string name="view_calendar" msgid="979609872939597838">"Ver"</string>
-    <string name="view_calendar_desc" msgid="5828320291870344584">"Consulta a hora seleccionada no calendario"</string>
+    <string name="view_calendar_desc" msgid="5828320291870344584">"Consultar a hora seleccionada no calendario"</string>
     <string name="add_calendar_event" msgid="1953664627192056206">"Programar"</string>
-    <string name="add_calendar_event_desc" msgid="4326891793260687388">"Programa un evento para a data seleccionada"</string>
+    <string name="add_calendar_event_desc" msgid="4326891793260687388">"Programar un evento para a data seleccionada"</string>
     <string name="view_flight" msgid="7691640491425680214">"Realizar seguimento"</string>
-    <string name="view_flight_desc" msgid="3876322502674253506">"Fai un seguimento do voo seleccionado"</string>
+    <string name="view_flight_desc" msgid="3876322502674253506">"Facer un seguimento do voo seleccionado"</string>
     <string name="translate" msgid="9218619809342576858">"Traducir"</string>
-    <string name="translate_desc" msgid="4502367770068777202">"Traduce o texto seleccionado"</string>
+    <string name="translate_desc" msgid="4502367770068777202">"Traducir o texto seleccionado"</string>
     <string name="define" msgid="7394820043869954211">"Definir"</string>
-    <string name="define_desc" msgid="7910883642444919726">"Define o texto seleccionado"</string>
+    <string name="define_desc" msgid="7910883642444919726">"Definir o texto seleccionado"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Estase esgotando o espazo de almacenamento"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"É posible que algunhas funcións do sistema non funcionen"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Non hai almacenamento suficiente para o sistema. Asegúrate de ter un espazo libre de 250 MB e reinicia o dispositivo."</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca para ver todas as redes"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectarse"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas as redes"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Queres conectarte a redes wifi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Suxerido por <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Si"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Non"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Queres permitir as redes wifi suxeridas?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Redes suxeridas de <xliff:g id="NAME">%s</xliff:g>. O dispositivo pode conectarse automaticamente."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Permitir"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Non, grazas"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"A wifi activarase automaticamente"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Cando esteas preto dunha rede gardada de alta calidade"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Non volver activar"</string>
@@ -1889,8 +1889,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Sen clasificar"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Ti defines a importancia destas notificacións."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"É importante polas persoas involucradas."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Queres permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario novo con <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Queres permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario novo con <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Xa existe un usuario con esta conta)"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Queres permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario novo con <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Xa existe un usuario con esta conta)"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Queres permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario novo con <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Engadir un idioma"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Preferencia de rexión"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Nome do idioma"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index c86c9e6..16386cf 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -282,7 +282,7 @@
     <string name="permgrouprequest_contacts" msgid="6032805601881764300">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને તમારા સંપર્કોને ઍક્સેસ કરવાની મંજૂરી આપીએ?"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"સ્થાન"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"આ ઉપકરણના સ્થાનને ઍક્સેસ કરવાની"</string>
-    <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને આ ઉપકરણના સ્થાનને ઍક્સેસ કરવાની મંજૂરી આપીએ?"</string>
+    <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને આ ડિવાઇસના સ્થાનને ઍક્સેસ કરવાની મંજૂરી આપીએ?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"જ્યારે તમે ઍપનો ઉપયોગ કરી રહ્યા હશો માત્ર ત્યારે જ ઍપ સ્થાનને ઍક્સેસ કરી શકશે"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને આ ડિવાઇસનું સ્થાન &lt;b&gt;હંમેશાં&lt;/b&gt; ઍક્સેસ કરવાની મંજૂરી આપીએ?"</string>
     <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"હાલમાં માત્ર જ્યારે તમે ઍપનો ઉપયોગ કરી રહ્યા હશો હોય ત્યારે જ ઍપ સ્થાનને ઍક્સેસ કરી શકશે"</string>
@@ -294,10 +294,10 @@
     <string name="permgrouprequest_sms" msgid="7168124215838204719">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને SMS સંદેશા મોકલવા અને જોવાની મંજૂરી આપીએ?"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"સ્ટોરેજ"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"તમારા ઉપકરણ પર ફોટો, મીડિયા અને ફાઇલો ઍક્સેસ કરવાની"</string>
-    <string name="permgrouprequest_storage" msgid="7885942926944299560">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને તમારા ઉપકરણ પર ફોટા, મીડિયા અને ફાઇલોને ઍક્સેસ કરવાની મંજૂરી આપીએ?"</string>
+    <string name="permgrouprequest_storage" msgid="7885942926944299560">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને તમારા ડિવાઇસ પર ફોટા, મીડિયા અને ફાઇલોને ઍક્સેસ કરવાની મંજૂરી આપીએ?"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"માઇક્રોફોન"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ઑડિઓ રેકોર્ડ કરવાની"</string>
-    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને ઑડિઓ રેકૉર્ડ કરવાની મંજૂરી આપીએ?"</string>
+    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને ઑડિયો રેકૉર્ડ કરવાની મંજૂરી આપીએ?"</string>
     <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"શારીરિક પ્રવૃત્તિ"</string>
     <string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"તમારી શારીરિક પ્રવૃત્તિને ઍક્સેસ કરવી"</string>
     <string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને તમારી શારીરિક પ્રવૃત્તિને ઍક્સેસ કરવાની મંજૂરી આપવી છે?"</string>
@@ -324,7 +324,7 @@
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"હાવભાવ કરો"</string>
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"ટૅપ, સ્વાઇપ, પિંચ કરી અને અન્ય હાવભાવ કરી શકે છે."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"ફિંગરપ્રિન્ટ સંકેતો"</string>
-    <string name="capability_desc_canCaptureFingerprintGestures" msgid="4386487962402228670">"ઉપકરણના ફિંગરપ્રિન્ટ સેન્સર પર કરવામાં આવેલા સંકેતો કૅપ્ચર કરી શકે છે."</string>
+    <string name="capability_desc_canCaptureFingerprintGestures" msgid="4386487962402228670">"ડિવાઇસના ફિંગરપ્રિન્ટ સેન્સર પર કરવામાં આવેલા સંકેતો કૅપ્ચર કરી શકે છે."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"સ્ટેટસ બારને અક્ષમ કરો અથવા તેમાં ફેરફાર કરો"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"ઍપ્લિકેશનને સ્ટેટસ બાર અક્ષમ કરવાની અથવા સિસ્ટમ આયકન્સ ઉમેરવા અને દૂર કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"સ્ટેટસ બારમાં બતાવો"</string>
@@ -510,9 +510,9 @@
     <string name="permlab_useBiometric" msgid="8837753668509919318">"બાયોમેટ્રિક હાર્ડવેરનો ઉપયોગ કરો"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"ઍપને પ્રમાણીકરણ માટે બાયોમેટ્રિક હાર્ડવેરનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ફિંગરપ્રિન્ટ હાર્ડવેરને સંચાલિત કરો"</string>
-    <string name="permdesc_manageFingerprint" msgid="178208705828055464">"એપ્લિકેશનને ઉપયોગ માટે ફિંગરપ્રિન્ટ નમૂના ઉમેરવા અને કાઢી નાખવા માટે પદ્ધતિઓની વિનંતી કરવાની મંજૂરી આપે છે."</string>
+    <string name="permdesc_manageFingerprint" msgid="178208705828055464">"ઍપને ઉપયોગ માટે ફિંગરપ્રિન્ટ નમૂના ઉમેરવા અને કાઢી નાખવા માટે પદ્ધતિઓની વિનંતી કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_useFingerprint" msgid="3150478619915124905">"ફિંગરપ્રિન્ટ હાર્ડવેરનો ઉપયોગ કરો"</string>
-    <string name="permdesc_useFingerprint" msgid="9165097460730684114">"એપ્લિકેશનને પ્રમાણીકરણ માટે ફિંગરપ્રિન્ટ હાર્ડવેરનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string>
+    <string name="permdesc_useFingerprint" msgid="9165097460730684114">"ઍપને પ્રમાણીકરણ માટે ફિંગરપ્રિન્ટ હાર્ડવેરનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string>
     <string name="permlab_audioWrite" msgid="2661772059799779292">"આપનો સંગીત સંગ્રહ સંશોધિત કરવો"</string>
     <string name="permdesc_audioWrite" msgid="8888544708166230494">"એપને તમારો સંગીત સંગ્રહ સંશોધિત કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_videoWrite" msgid="128769316366746446">"આપનો વિડિઓ સંગ્રહ સંશોધિત કરવો"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"બધા નેટવર્ક જોવા ટૅપ કરો"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"કનેક્ટ કરો"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"બધા નેટવર્કો"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"વાઇ-ફાઇ નેટવર્ક સાથે કનેક્ટ કરીએ?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> દ્વારા સૂચવાયેલ"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"હા"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ના"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"સૂચવેલા વાઇ-ફાઇ નેટવર્કને મંજૂરી આપીએ?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> સૂચવેલા નેટવર્ક. ડિવાઇસ ઑટોમૅટિક રીતે કનેક્ટ થાય તેમ બની શકે છે."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"મંજૂરી આપો"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"ના, આભાર"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"વાઇ-ફાઇ આપમેળે ચાલુ થઈ જશે"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"જ્યારે તમે એક ઉચ્ચ ક્વૉલિટીવાળા સાચવેલ નેટવર્કની નજીક હોવ"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"પાછું ચાલુ કરશો નહીં"</string>
@@ -1578,8 +1578,8 @@
     <string name="expires_on" msgid="3676242949915959821">"આ રોજ સમાપ્ત:"</string>
     <string name="serial_number" msgid="758814067660862493">"શૃંખલા ક્રમાંક:"</string>
     <string name="fingerprints" msgid="4516019619850763049">"ફિંગરપ્રિંટ્સ:"</string>
-    <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 ફિંગરપ્રિંટ:"</string>
-    <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 ફિંગરપ્રિંટ:"</string>
+    <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 ફિંગરપ્રિન્ટ:"</string>
+    <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 ફિંગરપ્રિન્ટ:"</string>
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"બધું જુઓ"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"પ્રવૃત્તિ પસંદ કરો"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"આની સાથે શેર કરો"</string>
@@ -1889,8 +1889,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"અવર્ગીકૃત"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"તમે આ સૂચનાઓનું મહત્વ સેટ કર્યું છે."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"શામેલ થયેલ લોકોને કારણે આ મહત્વપૂર્ણ છે."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g> ને <xliff:g id="ACCOUNT">%2$s</xliff:g> સાથે એક નવા વપરાશકર્તાને બનાવવાની મંજૂરી આપીએ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="ACCOUNT">%2$s</xliff:g> સાથે <xliff:g id="APP">%1$s</xliff:g> ને એક નવા વપરાશકર્તાને બનાવવાની મંજૂરી આપીએ (આ એકાઉન્ટ સાથેના એક વપરાશકર્તા પહેલાંથી અસ્તિત્વમાં છે)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g>ને <xliff:g id="ACCOUNT">%2$s</xliff:g> માટે એક નવા વપરાશકર્તા બનાવવાની મંજૂરી આપીએ (આ એકાઉન્ટ માટે એક વપરાશકર્તા પહેલાંથી અસ્તિત્વમાં છે) ?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g>ને <xliff:g id="ACCOUNT">%2$s</xliff:g> માટે એક નવા વપરાશકર્તા બનાવવાની મંજૂરી આપીએ ?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"ભાષા ઉમેરો"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"પ્રદેશ પસંદગી"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"ભાષાનું નામ ટાઇપ કરો"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index d7a8ea5..28c7569 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1152,7 +1152,7 @@
     <string name="whichImageCaptureApplicationNamed" msgid="8619384150737825003">"%1$s के साथ चित्र कैप्चर करें"</string>
     <string name="whichImageCaptureApplicationLabel" msgid="6390303445371527066">"चित्र कैप्चर करें"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"इस कार्रवाई के लिए डिफ़ॉल्‍ट के तौर पर इस्तेमाल करें"</string>
-    <string name="use_a_different_app" msgid="8134926230585710243">"किसी भिन्न ऐप्स का उपयोग करें"</string>
+    <string name="use_a_different_app" msgid="8134926230585710243">"किसी दूसरे ऐप्लिकेशन का इस्तेमाल करें"</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"सिस्‍टम सेटिंग और डाउनलोड किए गए ऐप में डिफ़ॉल्‍ट साफ़ करें."</string>
     <string name="chooseActivity" msgid="7486876147751803333">"कोई कार्रवाई चुनें"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"USB डिवाइस के लिए कोई ऐप्स  चुनें"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सभी नेटवर्क देखने के लिए यहां पर टैप करें"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"कनेक्ट करें"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"सभी नेटवर्क"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"वाई-फ़ाई नेटवर्क से कनेक्ट करना चाहते हैं?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> का सुझाया हुआ"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"हां"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"नहीं"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"सुझाए गए वाई-फ़ाई नेटवर्क को अनुमति देना चाहते हैं?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> के सुझाए गए नेटवर्क. डिवाइस अपने आप कनेक्ट हो सकता है."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"अनुमति दें"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"रहने दें"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"वाई-फ़ाई अपने आप चालू हो जाएगा"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"जब आप किसी अच्छी क्वालिटी वाले सेव किए गए नेटवर्क के पास हों"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"वापस चालू न करें"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"बिना किसी श्रेणी के"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"आपने इन सूचनाओं की अहमियत सेट की है."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"यह मौजूद व्यक्तियों के कारण महत्वपूर्ण है."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g> को <xliff:g id="ACCOUNT">%2$s</xliff:g> के ज़रिये एक नया उपयोगकर्ता बनाने दें?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g> को <xliff:g id="ACCOUNT">%2$s</xliff:g> के ज़रिये एक नया उपयोगकर्ता बनाने दें (इस खाते वाले एक उपयोगकर्ता पहले से मौजूद हैं)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> को <xliff:g id="ACCOUNT">%2$s</xliff:g> के नाम से एक नया उपयोगकर्ता बनाने की अनुमति दें (इस नाम से एक खाता पहले से मौजूद है)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"भाषा जोड़ें"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"क्षेत्र प्राथमिकता"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"भाषा का नाम लिखें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index aca3b2d..f7afea5 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1277,10 +1277,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite za prikaz svih mreža"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Poveži"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Sve mreže"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Želite li se povezati s Wi-Fi mrežama?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Preporuka aplikacije <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Da"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Želite li dopustiti predložene Wi‑Fi mreže?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Mreže koje predlaže aplikacija <xliff:g id="NAME">%s</xliff:g>. Uređaji se mogu povezati automatski."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Dopusti"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ne, hvala"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi će se uključiti automatski"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kada ste u blizini spremljene mreže visoke kvalitete"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Više ne uključuj"</string>
@@ -1694,7 +1694,7 @@
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Prečac pristupačnosti isključio je uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Pritisnite i zadržite tipke za glasnoću na tri sekunde da biste koristili uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Odaberite uslugu koju ćete upotrebljavati kad dodirnete gumb pristupačnosti:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Odaberite uslugu koju ćete upotrebljavati uz pokret pristupačnosti (prelazak s dva prsta prema gore od dna zaslona):"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Odaberite za što će se upotrebljavati pokret pristupačnosti (prelazak s dva prsta prema gore od dna zaslona):"</string>
     <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Odaberite uslugu koju ćete upotrebljavati uz pokret pristupačnosti (prelazak s tri prsta prema gore od dna zaslona):"</string>
     <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Da biste prešli na neku drugu uslugu, dodirnite i zadržite gumb pristupačnosti."</string>
     <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Da biste prešli na neku drugu uslugu, prijeđite s dva prsta prema gore i zadržite."</string>
@@ -1922,8 +1922,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Nema kategorije"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Postavili ste važnost tih obavijesti."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Važno je zbog uključenih osoba."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Želite li dopustiti aplikaciji <xliff:g id="APP">%1$s</xliff:g> da izradi novog korisnika s računom <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Želite li dopustiti aplikaciji <xliff:g id="APP">%1$s</xliff:g> da izradi novog korisnika s računom <xliff:g id="ACCOUNT">%2$s</xliff:g> (korisnik s tim računom već postoji)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Dopustiti aplikaciji <xliff:g id="APP">%1$s</xliff:g> da izradi novog korisnika s računom <xliff:g id="ACCOUNT">%2$s</xliff:g> (korisnik s ovim računom već postoji)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Dopustiti aplikaciji <xliff:g id="APP">%1$s</xliff:g> da izradi novog korisnika s računom <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Dodavanje jezika"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Postavke regije"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Unesite naziv jezika"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 6d81d02..351b5b8 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Koppintással megjelenítheti az összes hálózatot"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kapcsolódás"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Összes hálózat"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Kapcsolódik a Wi-Fi-hálózathoz?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> javasolta"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Igen"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nem"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Engedélyezi a javasolt Wi-Fi-hálózatokat?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"A(z) <xliff:g id="NAME">%s</xliff:g> hálózatokat javasolt. Az eszköz automatikusan csatlakozhat hozzájuk."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Engedélyezés"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nem, köszönöm"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"A Wi-Fi automatikusan bekapcsol"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Amikor jó minőségű mentett hálózat közelében tartózkodik"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ne kapcsolódjon vissza"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Nincs kategóriába sorolva"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Ön állította be ezen értesítések fontossági szintjét."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ez az üzenet a résztvevők miatt fontos."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Engedélyezi a(z) <xliff:g id="APP">%1$s</xliff:g> számára, hogy új felhasználót hozzon létre a(z) <xliff:g id="ACCOUNT">%2$s</xliff:g> fiókkal?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Engedélyezi a(z) <xliff:g id="APP">%1$s</xliff:g> számára, hogy új felhasználót hozzon létre a(z) <xliff:g id="ACCOUNT">%2$s</xliff:g> fiókkal? (Már létezik felhasználó ezzel a fiókkal.)"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Engedélyezi a(z) <xliff:g id="APP">%1$s</xliff:g> számára, hogy új felhasználót hozzon létre a(z) <xliff:g id="ACCOUNT">%2$s</xliff:g> fiókkal? (Már létezik felhasználó ezzel a fiókkal.)"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Engedélyezi a(z) <xliff:g id="APP">%1$s</xliff:g> számára, hogy új felhasználót hozzon létre a(z) <xliff:g id="ACCOUNT">%2$s</xliff:g> fiókkal?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Nyelv hozzáadása"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Régió beállítása"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Adja meg a nyelvet"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 4e07d88..21c6aa9 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Հպեք՝ բոլոր ցանցերը տեսնելու համար"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Միանալ"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Բոլոր ցանցերը"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Միանա՞լ Wi-Fi ցանցերին"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Առաջարկվել է <xliff:g id="NAME">%s</xliff:g>-ի կողմից"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Այո"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ոչ"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Թույլատրե՞լ առաջարկվող Wi‑Fi ցանցերի օգտագործումը"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> հավելվածի առաջարկվող ցանցեր: Սարքը կարող է ավտոմատ միանալ:"</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Թույլատրել"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ոչ, շնորհակալություն"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi-ն ավտոմատ կմիանա"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Լավ ազդանշանով պահված ցանցի տարածքում գտնվելիս"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Նորից չմիացնել"</string>
@@ -1354,9 +1354,9 @@
     <string name="usb_power_notification_message" msgid="4647527153291917218">"Միացված սարքի լիցքավորում: Հպեք՝ ավելի շատ ընտրանքների համար:"</string>
     <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Հայտնաբերված է անալոգային աուդիո լրասարք"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Կցված սարքը համատեղելի չէ այս հեռախոսի հետ: Հպեք` ավելին իմանալու համար:"</string>
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB վրիպազերծումը միացված է"</string>
-    <string name="adb_active_notification_message" msgid="7463062450474107752">"Հպեք՝ USB վրիպազերծումն անջատելու համար"</string>
-    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Ընտրել` USB կարգաբերումը կասեցնելու համար:"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-ով վրիպազերծումը միացված է"</string>
+    <string name="adb_active_notification_message" msgid="7463062450474107752">"Հպեք՝ USB-ով վրիպազերծումն անջատելու համար"</string>
+    <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Սեղմեք՝ USB-ով վրիպազերծումն անջատելու համար:"</string>
     <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Թեստային ռեժիմը միացված է"</string>
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Թեստային ռեժիմն անջատելու համար զրոյացրեք կարգավորումները։"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB միացքում ջուր կամ աղտ է հայտնաբերվել"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Չդասակարգված"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Դուք սահմանել եք այս ծանուցումների կարևորությունը:"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Կարևոր է, քանի որ որոշակի մարդիկ են ներգրավված:"</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Թույլատրե՞լ <xliff:g id="APP">%1$s</xliff:g> հավելվածին <xliff:g id="ACCOUNT">%2$s</xliff:g> հաշվով նոր Օգտատեր ստեղծել:"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Թույլատրե՞լ <xliff:g id="APP">%1$s</xliff:g> հավելվածին <xliff:g id="ACCOUNT">%2$s</xliff:g> հաշվով նոր Օգտատեր ստեղծել (նման հաշվով Օգտատեր արդեն գոյություն ունի):"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Թույլատրե՞լ <xliff:g id="APP">%1$s</xliff:g> հավելվածին <xliff:g id="ACCOUNT">%2$s</xliff:g> հաշվով նոր Օգտատեր ստեղծել (նման հաշվով Օգտատեր արդեն գոյություն ունի):"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Թույլատրե՞լ <xliff:g id="APP">%1$s</xliff:g> հավելվածին <xliff:g id="ACCOUNT">%2$s</xliff:g> հաշվով նոր Օգտատեր ստեղծել:"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Ավելացնել լեզու"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Նախընտրելի տարածաշրջան"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Մուտքագրեք լեզուն"</string>
@@ -1928,7 +1928,7 @@
     <string name="app_category_maps" msgid="5878491404538024367">"Քարտեզներ և նավարկում"</string>
     <string name="app_category_productivity" msgid="3742083261781538852">"Արդյունավետություն"</string>
     <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Սարքի հիշողություն"</string>
-    <string name="adb_debugging_notification_channel_tv" msgid="5537766997350092316">"USB վրիպազերծում"</string>
+    <string name="adb_debugging_notification_channel_tv" msgid="5537766997350092316">"USB-ով վրիպազերծում"</string>
     <string name="time_picker_hour_label" msgid="2979075098868106450">"ժամ"</string>
     <string name="time_picker_minute_label" msgid="5168864173796598399">"րոպե"</string>
     <string name="time_picker_header_text" msgid="143536825321922567">"Ժամը"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 32ec5d5..afdce0e 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Ketuk untuk melihat semua jaringan"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Hubungkan"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Semua jaringan"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Sambungkan perangkat ke jaringan Wi-Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Disarankan oleh <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ya"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Tidak"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Izinkan jaringan Wi-Fi yang disarankan?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Jaringan yang disarankan <xliff:g id="NAME">%s</xliff:g>. Perangkat dapat terhubung secara otomatis."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Izinkan"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Lain kali"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi akan aktif otomatis"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Saat berada di dekat jaringan berkualitas tinggi yang tersimpan"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Jangan aktifkan kembali"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Belum dikategorikan"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Anda menyetel nilai penting notifikasi ini."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ini penting karena orang-orang yang terlibat."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Izinkan <xliff:g id="APP">%1$s</xliff:g> membuat Pengguna baru dengan <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Izinkan <xliff:g id="APP">%1$s</xliff:g> membuat Pengguna baru dengan <xliff:g id="ACCOUNT">%2$s</xliff:g> (Pengguna dengan akun ini sudah ada) ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Izinkan <xliff:g id="APP">%1$s</xliff:g> membuat Pengguna baru dengan <xliff:g id="ACCOUNT">%2$s</xliff:g> (Pengguna dengan akun ini sudah ada) ?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Izinkan <xliff:g id="APP">%1$s</xliff:g> membuat Pengguna baru dengan <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Tambahkan bahasa"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Preferensi wilayah"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Ketik nama bahasa"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index b06a7f0..299f26c 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Ýttu til að sjá öll netkerfi"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Tengjast"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Öll netkerfi"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Tengjast Wi-Fi neti?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Tillaga frá <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Já"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nei"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Leyfa ráðlögð Wi‑Fi net?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> kom með tillögur að netkerfum. Tækið gæti tengst sjálfkrafa."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Leyfa"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nei, takk"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Kveikt verður sjálfkrafa á Wi‑Fi"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Þegar þú ert nálægt vistuðu hágæðaneti"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ekki kveikja aftur"</string>
@@ -1889,8 +1889,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Óflokkað"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Þú stilltir mikilvægi þessara tilkynninga."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Þetta er mikilvægt vegna fólksins sem tekur þátt í þessu."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Leyfa <xliff:g id="APP">%1$s</xliff:g> að stofna nýjan notanda með <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Leyfa <xliff:g id="APP">%1$s</xliff:g> að stofna nýjan notanda með <xliff:g id="ACCOUNT">%2$s</xliff:g> (notandi með þennan reikning er þegar fyrir hendi)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Viltu leyfa <xliff:g id="APP">%1$s</xliff:g> að stofna nýjan notanda með <xliff:g id="ACCOUNT">%2$s</xliff:g> (notandi með þennan reikning er þegar fyrir hendi)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Leyfa <xliff:g id="APP">%1$s</xliff:g> að stofna nýjan notanda með <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Bæta við tungumáli"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Svæðisval"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Sláðu inn heiti tungumáls"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 98f5fb2..da7fa51 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -282,7 +282,7 @@
     <string name="permgrouprequest_contacts" msgid="6032805601881764300">"Consentire all\'app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; di accedere ai tuoi contatti?"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"Geolocalizz."</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"accedere alla posizione di questo dispositivo"</string>
-    <string name="permgrouprequest_location" msgid="3788275734953323491">"Consentire all\'app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; di accedere alla posizione di questo dispositivo?"</string>
+    <string name="permgrouprequest_location" msgid="3788275734953323491">"Consentire all\'app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; di accedere alla posizione del dispositivo?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"L\'app avrà accesso alla posizione soltanto quando la usi"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Consentire a &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; di accedere &lt;b&gt;sempre&lt;/b&gt; alla posizione di questo dispositivo?"</string>
     <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"L\'app al momento può accedere alla posizione soltanto mentre la usi"</string>
@@ -323,8 +323,8 @@
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Controlla il livello di zoom e la posizione del display."</string>
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Eseguire gesti"</string>
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Consente di toccare, far scorrere, pizzicare ed eseguire altri gesti."</string>
-    <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gesti con sensore di impronte digitali"</string>
-    <string name="capability_desc_canCaptureFingerprintGestures" msgid="4386487962402228670">"È in grado di rilevare i gesti compiuti con il sensore di impronte digitali dei dispositivi."</string>
+    <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gesti con sensore di impronte"</string>
+    <string name="capability_desc_canCaptureFingerprintGestures" msgid="4386487962402228670">"È in grado di rilevare i gesti compiuti con il sensore di impronte dei dispositivi."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"disattivazione o modifica della barra di stato"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Consente all\'applicazione di disattivare la barra di stato o di aggiungere e rimuovere icone di sistema."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"ruolo di barra di stato"</string>
@@ -509,10 +509,10 @@
     <string name="permdesc_requestPasswordComplexity" msgid="4730994229754212347">"Consente all\'app di conoscere il livello di complessità del blocco schermo (alto, medio, basso o nessuno), che indica l\'intervallo di caratteri possibile e il tipo di blocco schermo. L\'app può inoltre suggerire agli utenti di aggiornare il blocco schermo a un livello specifico di complessità, ma gli utenti possono ignorare liberamente il suggerimento e uscire. Tieni presente che il blocco schermo non viene memorizzato come testo non crittografato, quindi l\'app non conosce la password esatta."</string>
     <string name="permlab_useBiometric" msgid="8837753668509919318">"utilizzo di hardware biometrico"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Consente all\'app di utilizzare hardware biometrico per eseguire l\'autenticazione"</string>
-    <string name="permlab_manageFingerprint" msgid="5640858826254575638">"gestione di hardware per il riconoscimento delle impronte digitali"</string>
-    <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Consente all\'app di richiamare metodi per aggiungere e rimuovere modelli di impronte digitali da utilizzare."</string>
-    <string name="permlab_useFingerprint" msgid="3150478619915124905">"utilizzo di hardware per il riconoscimento delle impronte digitali"</string>
-    <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Consente all\'app di utilizzare l\'hardware per il riconoscimento delle impronte digitali per eseguire l\'autenticazione"</string>
+    <string name="permlab_manageFingerprint" msgid="5640858826254575638">"gestione di hardware per il riconoscimento delle impronte"</string>
+    <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Consente all\'app di richiamare metodi per aggiungere e rimuovere modelli di impronte da utilizzare."</string>
+    <string name="permlab_useFingerprint" msgid="3150478619915124905">"utilizzo di hardware per il riconoscimento delle impronte"</string>
+    <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Consente all\'app di utilizzare l\'hardware per il riconoscimento delle impronte per eseguire l\'autenticazione"</string>
     <string name="permlab_audioWrite" msgid="2661772059799779292">"modifica della tua raccolta musicale"</string>
     <string name="permdesc_audioWrite" msgid="8888544708166230494">"Consente all\'app di modificare la tua raccolta musicale."</string>
     <string name="permlab_videoWrite" msgid="128769316366746446">"modifica della tua raccolta di video"</string>
@@ -527,30 +527,30 @@
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Non riconosciuto"</string>
     <string name="biometric_error_canceled" msgid="349665227864885880">"Autenticazione annullata"</string>
     <string name="biometric_error_device_not_secured" msgid="6583143098363528349">"Non hai impostato PIN, sequenza o password"</string>
-    <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Rilevata impronta digitale parziale. Riprova."</string>
-    <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Impossibile elaborare l\'impronta digitale. Riprova."</string>
-    <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Il sensore di impronte digitali è sporco. Puliscilo e riprova."</string>
+    <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Rilevata impronta parziale. Riprova."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Impossibile elaborare l\'impronta. Riprova."</string>
+    <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Il sensore di impronte è sporco. Puliscilo e riprova."</string>
     <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Movimento del dito troppo rapido. Riprova."</string>
     <string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"Movimento del dito troppo lento. Riprova."</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <string name="fingerprint_authenticated" msgid="5309333983002526448">"Impronta digitale autenticata"</string>
+    <string name="fingerprint_authenticated" msgid="5309333983002526448">"Impronta autenticata"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Volto autenticato"</string>
     <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Volto autenticato, premi Conferma"</string>
-    <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardware per l\'impronta digitale non disponibile."</string>
-    <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Impossibile memorizzare l\'impronta digitale. Rimuovi un\'impronta esistente."</string>
-    <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Timeout impronta digitale. Riprova."</string>
-    <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operazione associata all\'impronta digitale annullata."</string>
-    <string name="fingerprint_error_user_canceled" msgid="7999639584615291494">"Operazione di autenticazione dell\'impronta digitale annullata dall\'utente."</string>
+    <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardware per l\'impronta non disponibile."</string>
+    <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Impossibile memorizzare l\'impronta. Rimuovi un\'impronta esistente."</string>
+    <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Timeout impronta. Riprova."</string>
+    <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operazione associata all\'impronta annullata."</string>
+    <string name="fingerprint_error_user_canceled" msgid="7999639584615291494">"Operazione di autenticazione dell\'impronta annullata dall\'utente."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Troppi tentativi. Riprova più tardi."</string>
-    <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Troppi tentativi. Sensore di impronte digitali disattivato."</string>
+    <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Troppi tentativi. Sensore di impronte disattivato."</string>
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Riprova."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="7654382120628334248">"Nessuna impronta digitale registrata."</string>
-    <string name="fingerprint_error_hw_not_present" msgid="409523969613176352">"Questo dispositivo non dispone di sensore di impronte digitali."</string>
+    <string name="fingerprint_error_hw_not_present" msgid="409523969613176352">"Questo dispositivo non dispone di sensore di impronte."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Dito <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
-    <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icona dell\'impronta digitale"</string>
+    <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icona dell\'impronta"</string>
     <string name="permlab_manageFace" msgid="7262837876352591553">"gestione dell\'hardware per Sblocco col sorriso"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Consente all\'app di richiamare i metodi per aggiungere e rimuovere i modelli di volti."</string>
     <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"utilizzo dell\'hardware per Sblocco col sorriso"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tocca per vedere tutte le reti"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connetti"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Tutte le reti"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Connettersi a reti Wi-Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Consigliato da <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sì"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Vuoi consentire le reti Wi-Fi suggerite?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> ha suggerito delle reti. Il dispositivo potrebbe collegarsi automaticamente."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Consenti"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"No, grazie"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Il Wi‑Fi verrà attivato automaticamente"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Quando ti trovi nell\'area di una rete salvata di alta qualità"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Non riattivare"</string>
@@ -1577,8 +1577,8 @@
     <string name="expires_on" msgid="3676242949915959821">"Scade il:"</string>
     <string name="serial_number" msgid="758814067660862493">"Numero di serie:"</string>
     <string name="fingerprints" msgid="4516019619850763049">"Fingerprint:"</string>
-    <string name="sha256_fingerprint" msgid="4391271286477279263">"Fingerprint SHA-256:"</string>
-    <string name="sha1_fingerprint" msgid="7930330235269404581">"Fingerprint SHA-1:"</string>
+    <string name="sha256_fingerprint" msgid="4391271286477279263">"Impronta SHA-256:"</string>
+    <string name="sha1_fingerprint" msgid="7930330235269404581">"Impronta SHA-1:"</string>
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Mostra tutto"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Scegli attività"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Condividi con"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Senza categoria"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Stabilisci tu l\'importanza di queste notifiche."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Importante a causa delle persone coinvolte."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Consentire a <xliff:g id="APP">%1$s</xliff:g> di creare un nuovo utente con <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Consentire a <xliff:g id="APP">%1$s</xliff:g> di creare un nuovo utente con <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Esiste già un utente con questo account)"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Consentire a <xliff:g id="APP">%1$s</xliff:g> di creare un nuovo utente con l\'account <xliff:g id="ACCOUNT">%2$s</xliff:g> (esiste già un utente con questo account)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Consentire a <xliff:g id="APP">%1$s</xliff:g> di creare un nuovo utente con l\'account <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Aggiungi una lingua"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Area geografica preferita"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Digita nome lingua"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index cde2861..c8c4f72 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1299,10 +1299,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"יש להקיש כדי לראות את כל הרשתות"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"התחבר"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"כל הרשתות"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"‏להתחבר לרשתות Wi‑Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"הוצע על-ידי <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"כן"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"לא"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"‏לאפשר הצעות לרשתות Wi-Fi?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"הצעות לרשתות <xliff:g id="NAME">%s</xliff:g>. ייתכן שחיבור המכשיר ייעשה באופן אוטומטי."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"אישור"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"לא תודה"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"‏ה-Wi-Fi יופעל אוטומטית"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"כשתימצאו בקרבת רשת באיכות גבוהה ששמרתם"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"אל תפעיל שוב"</string>
@@ -1956,8 +1956,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"ללא שיוך לקטגוריה"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"עליך להגדיר את החשיבות של ההתראות האלה."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"ההודעה חשובה בשל האנשים המעורבים."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"האם לאפשר ל-<xliff:g id="APP">%1$s</xliff:g> ליצור משתמש חדש לחשבון <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"האם לאפשר ל-<xliff:g id="APP">%1$s</xliff:g> ליצור משתמש חדש לחשבון <xliff:g id="ACCOUNT">%2$s</xliff:g> (כבר קיים משתמש לחשבון הזה) ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"האם לאפשר לאפליקציה <xliff:g id="APP">%1$s</xliff:g> ליצור משתמש חדש באמצעות <xliff:g id="ACCOUNT">%2$s</xliff:g> (כבר קיים משתמש לחשבון הזה) ?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"האם לאפשר לאפליקציה <xliff:g id="APP">%1$s</xliff:g> ליצור משתמש חדש באמצעות <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"הוספת שפה"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"העדפת אזור"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"הקלד שם שפה"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index bc0b67d..c7b3b9e 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"すべてのネットワークを表示するにはタップします"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"接続"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"すべてのネットワーク"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi-Fi ネットワークに接続しますか?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> によるおすすめ"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"はい"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"いいえ"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Wi‑Fi ネットワーク候補を許可しますか?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> からのネットワーク候補に、デバイスが自動的に接続される可能性があります。"</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"許可"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"許可しない"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi は自動的にオンになります"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"高品質の保存済みネットワークの検出時"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"再度オンにしない"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"カテゴリなし"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"このような通知の重要度を設定します。"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"関係するユーザーのため、この設定は重要です。"</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g> が <xliff:g id="ACCOUNT">%2$s</xliff:g> で新しいユーザーを作成できるようにしますか?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g> が <xliff:g id="ACCOUNT">%2$s</xliff:g> で新しいユーザーを作成できるようにしますか?(このアカウントのユーザーはすでに存在します)"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> が <xliff:g id="ACCOUNT">%2$s</xliff:g> で新しいユーザーを作成できるようにしますか?(このアカウントのユーザーはすでに存在します)"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> が <xliff:g id="ACCOUNT">%2$s</xliff:g> で新しいユーザーを作成できるようにしますか?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"言語を追加"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"地域設定"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"言語名を入力"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 896ad13..bd4e4dc 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"შეეხეთ ყველა ქსელის სანახავად"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"დაკავშირება"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ყველა ქსელი"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"გსურთ Wi-Fi ქსელებთან დაკავშირება?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"შეთავაზებულია <xliff:g id="NAME">%s</xliff:g>-ის მიერ"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"დიახ"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"არა"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"გსურთ, დაუშვათ შემოთავაზებული Wi‑Fi ქსელები?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> შემოთავაზებული ქსელები. მოწყობილობა შეიძლება ავტომატურად დაუკავშირდეს."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"დაშვება"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"არა, გმადლობთ"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi ავტომატურად ჩაირთვება"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"როცა შენახულ მაღალხარისხიან ქსელებთან ახლოს იმყოფებით"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ხელახლა ნუ ჩართავ"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"კატეგორიის გარეშე"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"ამ შეტყობინებების მნიშვნელობის დონე განისაზღვრა თქვენ მიერ."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"მნიშვნელოვანია ჩართული მომხმარებლების გამო."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"მიეცეს უფლება <xliff:g id="APP">%1$s</xliff:g>-ს, <xliff:g id="ACCOUNT">%2$s</xliff:g>-ის მეშვეობით ახალი მომხმარებელი შექმნას ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"მიეცეს უფლება <xliff:g id="APP">%1$s</xliff:g>-ს, <xliff:g id="ACCOUNT">%2$s</xliff:g>-ის მეშვეობით ახალი მომხმარებელი შექმნას (ამ ანგარიშის მქონე მომხმარებელი უკვე არსებობს) ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"მიეცეს უფლება <xliff:g id="APP">%1$s</xliff:g>-ს <xliff:g id="ACCOUNT">%2$s</xliff:g>-ის მეშვეობით ახალი მომხმარებელი შექმნას (ამ ანგარიშის მქონე მომხმარებელი უკვე არსებობს)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"მიეცეს უფლება <xliff:g id="APP">%1$s</xliff:g>-ს <xliff:g id="ACCOUNT">%2$s</xliff:g>-ის მეშვეობით ახალი მომხმარებელი შექმნას?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"ენის დამატება"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"რეგიონის პარამეტრები"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"აკრიფეთ ენის სახელი"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 801e377..0b69c88 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Барлық желілерді көру үшін түртіңіз"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Қосылу"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Барлық желілер"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi-Fi желісіне жалғансын ба?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> ұсынған."</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Иә"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Жоқ"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Ұсынылған Wi‑Fi желілеріне рұқсат беру керек пе?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> ұсынған желілер. Құрылғы автоматты түрде қосылуы мүмкін."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Рұқсат беру"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Жоқ, рақмет"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi автоматты түрде қосылады"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Сақталған жоғары сапалы желіге жақын болғанда"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Қайта қоспау"</string>
@@ -1889,8 +1889,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Санатқа жатқызылмаған"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Сіз осы хабарландырулардың маңыздылығын орнатасыз."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Қатысты адамдарға байланысты бұл маңызды."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACCOUNT">%2$s</xliff:g> есептік жазбасы бар жаңа пайдаланушы жасауға рұқсат ету керек пе?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACCOUNT">%2$s</xliff:g> есептік жазбасында жаңа пайдаланушы жасауға рұқсат ету керек пе (осы есептік жазбасы бар пайдаланушы әлдеқашан бар) ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> қолданбасына <xliff:g id="ACCOUNT">%2$s</xliff:g> есептік жазбасы бар жаңа пайдаланушы (мұндай есептік жазбаға ие пайдаланушы бұрыннан бар) жасауға рұқсат етілсін бе?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> қолданбасына <xliff:g id="ACCOUNT">%2$s</xliff:g> есептік жазбасы бар жаңа пайдаланушы жасауға рұқсат етілсін бе?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Тілді қосу"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Аймақ параметрі"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Тіл атауын теріңіз"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 8bb03e0..7ad45ae 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1257,10 +1257,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ចុចដើម្បីមើលបណ្តាញទាំងអស់"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"ភ្ជាប់"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"បណ្ដាញ​ទាំងអស់"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"ភ្ជាប់​ប​ណ្តា​ញ Wi​-Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"បាន​ណែនាំដោយ <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"បាទ/ចាស"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ទេ"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"អនុញ្ញាតឱ្យ​ភ្ជាប់​បណ្ដាញ Wi‑Fi ដែលបាន​ណែនាំ?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"បណ្ដាញ​ដែលបាន​ណែនាំ​របស់ <xliff:g id="NAME">%s</xliff:g> ។ ឧបករណ៍​អាច​ភ្ជាប់​ដោយស្វ័យប្រវត្តិ។"</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"អនុញ្ញាត"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"ទេ អរគុណ"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi នឹង​បើក​ដោយ​ស្វ័យប្រវត្តិ"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"នៅពេល​ដែល​អ្នក​នៅ​ជិត​បណ្តាញ​គុណភាព​ខ្ពស់​ដែល​បាន​រក្សាទុក"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"កុំ​បើក​ឡើង​វិញ"</string>
@@ -1579,8 +1579,8 @@
     <string name="expires_on" msgid="3676242949915959821">"ផុត​កំណត់​នៅ៖"</string>
     <string name="serial_number" msgid="758814067660862493">"លេខ​ស៊េរី៖"</string>
     <string name="fingerprints" msgid="4516019619850763049">"ស្នាម​ម្រាមដៃ​៖"</string>
-    <string name="sha256_fingerprint" msgid="4391271286477279263">"ស្នាម​ម្រាមដៃ SHA​-256 ​៖"</string>
-    <string name="sha1_fingerprint" msgid="7930330235269404581">"ស្នាម​ម្រាម​ដៃ SHA-1 ៖"</string>
+    <string name="sha256_fingerprint" msgid="4391271286477279263">"ស្នាម​ម្រាមដៃ SHA​-256៖"</string>
+    <string name="sha1_fingerprint" msgid="7930330235269404581">"ស្នាម​ម្រាម​ដៃ SHA-1៖"</string>
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"មើល​ទាំងអស់"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"ជ្រើស​សកម្មភាព"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"ចែករំលែក​ជា​មួយ"</string>
@@ -1890,8 +1890,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"មិន​​បែងចែក​ប្រភេទ"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"អ្នកបានកំណត់សារៈសំខាន់នៃការជូនដំណឹងទាំងនេះ"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"វាមានសារៈសំខាន់ដោយសារតែមនុស្សដែលពាក់ព័ន្ធ"</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"អនុញ្ញាតឲ្យ <xliff:g id="APP">%1$s</xliff:g> បង្កើតអ្នកប្រើថ្មីដោយប្រើ <xliff:g id="ACCOUNT">%2$s</xliff:g> ឬទេ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"អនុញ្ញាតឲ្យ <xliff:g id="APP">%1$s</xliff:g> បង្កើតអ្នកប្រើថ្មីដោយប្រើ <xliff:g id="ACCOUNT">%2$s</xliff:g> (មានអ្នកប្រើសម្រាប់គណនីនេះរួចហើយ) ឬទេ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"អនុញ្ញាតឱ្យ <xliff:g id="APP">%1$s</xliff:g> បង្កើតអ្នកប្រើប្រាស់​ថ្មីដោយប្រើ <xliff:g id="ACCOUNT">%2$s</xliff:g> (អ្នកប្រើប្រាស់ដែលមានគណនីនេះមានរួចហើយ) ដែរឬទេ?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"អនុញ្ញាតឱ្យ <xliff:g id="APP">%1$s</xliff:g> បង្កើតអ្នកប្រើប្រាស់​ថ្មីដោយប្រើ <xliff:g id="ACCOUNT">%2$s</xliff:g> ដែរឬទេ?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"បន្ថែមភាសា"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"ចំណូលចិត្តតំបន់"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"វាយបញ្ចូលឈ្មោះភាសា"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 46e743b..90ed851 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -1152,7 +1152,7 @@
     <string name="whichImageCaptureApplicationNamed" msgid="8619384150737825003">"%1$s ಜೊತೆ ಚಿತ್ರ ಕ್ಯಾಪ್ಚರ್ ಮಾಡಿ"</string>
     <string name="whichImageCaptureApplicationLabel" msgid="6390303445371527066">"ಚಿತ್ರ ಕ್ಯಾಪ್ಚರ್ ಮಾಡಿ"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"ಈ ಕ್ರಿಯೆಗೆ ಡಿಫಾಲ್ಟ್ ಆಗಿ ಬಳಸಿ."</string>
-    <string name="use_a_different_app" msgid="8134926230585710243">"ಬೇರೆಯ ಅಪ್ಲಿಕೇಶನ್ ಬಳಸಿ"</string>
+    <string name="use_a_different_app" msgid="8134926230585710243">"ಬೇರೊಂದು ಆ್ಯಪ್ ಬಳಸಿ"</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"ಸಿಸ್ಟಂ ಸೆಟ್ಟಿಂಗ್‌ಗಳು &gt; ಅಪ್ಲಿಕೇಶನ್‌ಗಳು &gt; ಡೌನ್‌ಲೋಡ್ ಮಾಡಲಾದ ಡಿಫಾಲ್ಟ್‌‌ ಅನ್ನು ತೆರವುಗೊಳಿಸಿ."</string>
     <string name="chooseActivity" msgid="7486876147751803333">"ಕ್ರಿಯೆಯನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"USB ಸಾಧನಕ್ಕೆ ಅಪ್ಲಿಕೇಶನ್‌‌ವೊಂದನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ಎಲ್ಲಾ ನೆಟ್‌ವರ್ಕ್‌ಗಳನ್ನು ನೋಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"ಸಂಪರ್ಕಿಸಿ"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ಎಲ್ಲಾ ನೆಟ್‌ವರ್ಕ್‌ಗಳು"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗಳಿಗೆ ಸಂಪರ್ಕಿಸುವುದೇ?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"ಸೂಚಿಸಿದವರು: <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ಹೌದು"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ಇಲ್ಲ"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"ಸೂಚಿಸಿರುವ ನೆಟ್‌ವರ್ಕ್‌ಗಳನ್ನು ಅನುಮತಿಸುವುದೇ?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> ಸೂಚಿಸಿರುವ ನೆಟ್‌ವರ್ಕ್‌ಗಳು. ಸಾಧನಗಳು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸಂಪರ್ಕಗೊಳ್ಳಬಹುದು."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"ಅನುಮತಿಸಿ"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"ಬೇಡ"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"ವೈ‑ಫೈ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಆನ್ ಆಗುತ್ತದೆ"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"ನೀವು ಉಳಿಸಿದ ಅಧಿಕ ಗುಣಮಟ್ಟದ ನೆಟ್‌ವರ್ಕ್‌ ಸಮೀಪದಲ್ಲಿದ್ದಾಗ"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ಮತ್ತೆ ಆನ್ ಮಾಡಲು ಹಿಂತಿರುಗಬೇಡಿ"</string>
@@ -1889,8 +1889,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"ವರ್ಗೀಕರಿಸದಿರುವುದು"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"ನೀವು ಈ ಅಧಿಸೂಚನೆಗಳ ಪ್ರಾಮುಖ್ಯತೆಯನ್ನು ಹೊಂದಿಸಿರುವಿರಿ."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"ಜನರು ತೊಡಗಿಕೊಂಡಿರುವ ಕಾರಣ ಇದು ಅತ್ಯಂತ ಪ್ರಮುಖವಾಗಿದೆ."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="ACCOUNT">%2$s</xliff:g> ಮೂಲಕ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ರಚಿಸಲು <xliff:g id="APP">%1$s</xliff:g> ಗೆ ಅನುಮತಿಸುವುದೇ ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="ACCOUNT">%2$s</xliff:g> (ಈ ಖಾತೆಯ ಬಳಕೆದಾರರು ಈಗಾಗಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿದ್ದಾರೆ) ಮೂಲಕ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ರಚಿಸಲು <xliff:g id="APP">%1$s</xliff:g> ಗೆ ಅನುಮತಿಸುವುದೇ ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g> (ಈ ಖಾತೆಯ ಬಳಕೆದಾರರು ಈಗಾಗಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿದ್ದಾರೆ) ಮೂಲಕ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ರಚಿಸಲು <xliff:g id="APP">%1$s</xliff:g> ಗೆ ಅನುಮತಿಸಬೇಕೆ ?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> ಮೂಲಕ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ರಚಿಸಲು <xliff:g id="APP">%1$s</xliff:g> ಗೆ ಅನುಮತಿಸುವುದೇ ?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"ಭಾಷೆ ಸೇರಿಸಿ"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"ಪ್ರದೇಶ ಪ್ರಾಶಸ್ತ್ಯ"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"ಭಾಷೆ ಹೆಸರನ್ನು ಟೈಪ್ ಮಾಡಿ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 9d547ca..f866e21 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"모든 네트워크를 보려면 탭하세요."</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"연결"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"모든 네트워크"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi-Fi 네트워크에 연결하시겠습니까?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g>에서 추천"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"예"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"아니요"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"제안된 Wi‑Fi 네트워크를 허용하시겠습니까?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g>에서 네트워크를 제안했습니다. 기기가 자동으로 연결될 수 있습니다."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"허용"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"허용 안함"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi가 자동으로 사용 설정됨"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"저장된 고품질 네트워크가 가까이 있는 경우"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"다시 사용 설정하지 않음"</string>
@@ -1343,7 +1343,7 @@
     <string name="no_permissions" msgid="7283357728219338112">"권한 필요 없음"</string>
     <string name="perm_costs_money" msgid="4902470324142151116">"비용이 부과될 수 있습니다."</string>
     <string name="dlg_ok" msgid="7376953167039865701">"확인"</string>
-    <string name="usb_charging_notification_title" msgid="1595122345358177163">"이 기기를 USB로 충전"</string>
+    <string name="usb_charging_notification_title" msgid="1595122345358177163">"이 기기를 USB로 충전 중"</string>
     <string name="usb_supplying_notification_title" msgid="4631045789893086181">"USB를 통해 연결된 기기 충전"</string>
     <string name="usb_mtp_notification_title" msgid="4238227258391151029">"USB 파일 전송 사용 설정됨"</string>
     <string name="usb_ptp_notification_title" msgid="5425857879922006878">"USB를 통해 PTP 사용 설정됨"</string>
@@ -1855,8 +1855,8 @@
     <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"다운타임"</string>
     <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"평일 밤"</string>
     <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"주말"</string>
-    <string name="zen_mode_default_events_name" msgid="8158334939013085363">"캘린더 일정 중"</string>
-    <string name="zen_mode_default_every_night_name" msgid="3012363838882944175">"수면 중"</string>
+    <string name="zen_mode_default_events_name" msgid="8158334939013085363">"캘린더 일정"</string>
+    <string name="zen_mode_default_every_night_name" msgid="3012363838882944175">"수면 시간"</string>
     <string name="muted_by" msgid="5942954724562097128">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>(이)가 일부 소리를 음소거함"</string>
     <string name="system_error_wipe_data" msgid="6608165524785354962">"사용 중인 기기 내부에 문제가 발생했습니다. 초기화할 때까지 불안정할 수 있습니다."</string>
     <string name="system_error_manufacturer" msgid="8086872414744210668">"사용 중인 기기 내부에 문제가 발생했습니다. 자세한 내용은 제조업체에 문의하세요."</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"지정된 카테고리 없음"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"이러한 알림의 중요도를 설정했습니다."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"관련된 사용자가 있으므로 중요합니다."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g>이(가) <xliff:g id="ACCOUNT">%2$s</xliff:g>(으)로 신규 사용자를 만들도록 허용하시겠습니까?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g>이(가) <xliff:g id="ACCOUNT">%2$s</xliff:g>(이 계정의 사용자가 이미 있음)(으)로 신규 사용자를 만들도록 허용하시겠습니까?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g>에서 <xliff:g id="ACCOUNT">%2$s</xliff:g> 계정으로 신규 사용자를 만들도록 허용하시겠습니까? 이 계정으로 등록된 사용자가 이미 존재합니다."</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g>에서 <xliff:g id="ACCOUNT">%2$s</xliff:g> 계정으로 신규 사용자를 만들도록 허용하시겠습니까?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"언어 추가"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"지역 환경설정"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"언어 이름 입력"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 9da1240..ef493a1 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -282,7 +282,7 @@
     <string name="permgrouprequest_contacts" msgid="6032805601881764300">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосуна байланыштарыңызды пайдаланууга уруксат берилсинби?"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"Жайгашкан жер"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"түзмөктүн жайгашкан жерин аныктоого"</string>
-    <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосу бул түзмөктүн кайда жүргөнүн көрүп турганга уруксат бересизби?"</string>
+    <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосу бул түзмөктүн кайда жүргөнүн көрүп турсунбу?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Колдонмону колдонуп жаткан маалда гана, ал сиздин кайда жүргөнүңүздү билип турат."</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосу бул түзмөктүн жүргөн жерин &lt;b&gt;ар дайым&lt;/b&gt; билип турсунбу?"</string>
     <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Колдонмону пайдаланып жаткан учурда гана ал жайгашкан жерди көрө алат"</string>
@@ -1072,7 +1072,7 @@
     <string name="Midnight" msgid="5630806906897892201">"Түн ортосу"</string>
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
-    <string name="selectAll" msgid="6876518925844129331">"Бардыгын тандоо"</string>
+    <string name="selectAll" msgid="6876518925844129331">"Баарын тандоо"</string>
     <string name="cut" msgid="3092569408438626261">"Кесүү"</string>
     <string name="copy" msgid="2681946229533511987">"Көчүрүү"</string>
     <string name="failed_to_copy_to_clipboard" msgid="1833662432489814471">"Алмашуу буферине көчүрүлбөй калды"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Бардык тармактарды көрүү үчүн басыңыз"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Туташуу"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Бардык тармактар"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi-Fi тармактарына туташсынбы?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> сунуштайт"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ооба"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Жок"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Сунушталган Wi‑Fi тармактарына туташасызбы?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> сунуштаган тармактар. Түзмөк автоматтык түрдө туташышы мүмкүн."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Уруксат берүү"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Жок, рахмат"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi автоматтык түрдө күйөт"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Байланыш сигналы күчтүү тармактарга жакындаганда"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Өзү кайра күйбөйт"</string>
@@ -1313,7 +1313,7 @@
     <string name="sms_control_title" msgid="7296612781128917719">"SMS билдирүүлөр жөнөтүлүүдө"</string>
     <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; көп SMS билдирүүлөрдү жөнөтүп жатат. Бул колдонмо билдирүүлөрдү жөнөтө берсинби?"</string>
     <string name="sms_control_yes" msgid="3663725993855816807">"Ооба"</string>
-    <string name="sms_control_no" msgid="625438561395534982">"Жок"</string>
+    <string name="sms_control_no" msgid="625438561395534982">"Тыюу салынат"</string>
     <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt; номуруна билдирүү жөнөткөнү жатат."</string>
     <string name="sms_short_code_details" msgid="5873295990846059400">"Бул уюлдук эсебиңиздеги төлөмдөргө "<b>"алып келиши мүмкүн"</b>"."</string>
     <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"Бул уюлдук эсебиңиздеги төлөмдөргө алып келет."</b></string>
@@ -1344,7 +1344,7 @@
     <string name="no_permissions" msgid="7283357728219338112">"Эч уруксаттын кереги жок"</string>
     <string name="perm_costs_money" msgid="4902470324142151116">"бул үчүн акы алынышы мүмкүн"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"Жарайт"</string>
-    <string name="usb_charging_notification_title" msgid="1595122345358177163">"Бул түзмөк USB аркылуу кубатталууда"</string>
+    <string name="usb_charging_notification_title" msgid="1595122345358177163">"USB аркылуу кубатталууда"</string>
     <string name="usb_supplying_notification_title" msgid="4631045789893086181">"USB аркылуу туташкан түзмөк кубатталууда"</string>
     <string name="usb_mtp_notification_title" msgid="4238227258391151029">"USB аркылуу файл өткөрүү режими күйгүзүлдү"</string>
     <string name="usb_ptp_notification_title" msgid="5425857879922006878">"USB аркылуу PTP режими күйгүзүлдү"</string>
@@ -1355,8 +1355,8 @@
     <string name="usb_power_notification_message" msgid="4647527153291917218">"Туташкан түзмөк кубатталууда. Дагы параметрлерди көрүү үчүн таптап коюңуз."</string>
     <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Аналогдук аудио жабдуу табылды"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Тиркелген түзмөк бул телефонго шайкеш келбейт. Көбүрөөк маалымат алуу үчүн таптап коюңуз."</string>
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"Мүчүлүштүктөрдү USB аркылуу оңдоо иштетилген"</string>
-    <string name="adb_active_notification_message" msgid="7463062450474107752">"USB аркылуу мүчүлүштүктөрдү оңдоону өчүрүү үчүн таптаңыз"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"Мүчүлүштүктөрдү USB аркылуу оңдоо иштеп жатат"</string>
+    <string name="adb_active_notification_message" msgid="7463062450474107752">"Өчүрүү үчүн тийип коюңуз"</string>
     <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
     <skip />
     <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Сыноо программасынын режими иштетилди"</string>
@@ -1449,7 +1449,7 @@
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Бул өтүнүчкө уруксат бересизби?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Жетки талабы"</string>
     <string name="allow" msgid="7225948811296386551">"Уруксат берүү"</string>
-    <string name="deny" msgid="2081879885755434506">"Жок"</string>
+    <string name="deny" msgid="2081879885755434506">"Уруксат берилбейт"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Уруксат талап кылуу"</string>
     <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Кийинки эсепке\nуруксат талап кылынууда: <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="forward_intent_to_owner" msgid="1207197447013960896">"Бул колдонмо жумуш профилиңиздин сыртында колдонулуп жатат"</string>
@@ -1890,8 +1890,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Категорияларга бөлүнгөн эмес"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Бул эскертмелердин маанилүүлүгүн белгиледиңиз."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Булар сиз үчүн маанилүү адамдар."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g> колдонмосу <xliff:g id="ACCOUNT">%2$s</xliff:g> аккаунту менен жаңы колдонуучу түзө берсинби?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g> колдонмосуна <xliff:g id="ACCOUNT">%2$s</xliff:g> аккаунту үчүн жаңы колдонуучу түзгөнгө уруксат бересизби (мындай аккаунту бар колдонуучу мурунтан эле бар)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> колдонмосуна <xliff:g id="ACCOUNT">%2$s</xliff:g> аккаунту менен жаңы колдонуучу түзүүгө уруксат бересизби (мындай аккаунту бар колдонуучу мурунтан эле бар)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> колдонмосуна <xliff:g id="ACCOUNT">%2$s</xliff:g> аккаунту менен жаңы колдонуучу түзүүгө уруксат бересизби?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Тил кошуу"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Чөлкөмдүк жөндөөлөр"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Тилди киргизиңиз"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 55747d0..a9e9086 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ແຕະເພື່ອເບິ່ງເຄືອຂ່າຍທັງໝົດ"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"ເຊື່ອມ​ຕໍ່"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ເຄືອຂ່າຍທັງໝົດ"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"ເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi‑Fi ບໍ?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"ແນະນຳໂດຍ <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ແມ່ນ"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ບໍ່ແມ່ນ"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"ອະນຸຍາດເຄືອຂ່າຍ Wi‑Fi ທີ່ແນະນຳບໍ?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"ເຄືອຂ່າຍ <xliff:g id="NAME">%s</xliff:g> ທີ່ແນະນຳ. ອຸປະກອນອາດເຊື່ອມຕໍ່ເອງໂດຍອັດຕະໂນມັດ."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"ອະນຸຍາດ"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"ບໍ່, ຂອບໃຈ"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"ຈະມີການເປີດໃຊ້ Wi‑Fi ອັດຕະໂນມັດ"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"ເມື່ອທ່ານຢູ່ໃກ້ເຄືອຂ່າຍຄຸນນະພາບສູງທີ່ບັນທຶກໄວ້"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ບໍ່ຕ້ອງເປີດໃຊ້ຄືນໃໝ່"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"ບໍ່​ມີ​ໝວດ​ໝູ່"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"ທ່ານຕັ້ງຄວາມສຳຄັນຂອງການແຈ້ງເຕືອນເຫຼົ່ານີ້."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"ຂໍ້ຄວາມນີ້ສຳຄັນເນື່ອງຈາກບຸກຄົນທີ່ກ່ຽວຂ້ອງ."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"ອະນຸຍາດໃຫ້ <xliff:g id="APP">%1$s</xliff:g> ສ້າງຜູ້ໃຊ້ໃໝ່ສຳລັບ <xliff:g id="ACCOUNT">%2$s</xliff:g> ບໍ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"ອະນຸຍາດໃຫ້ <xliff:g id="APP">%1$s</xliff:g> ສ້າງຜູ້ໃຊ້ໃໝ່ສຳລັບ <xliff:g id="ACCOUNT">%2$s</xliff:g> (ຜູ້ໃຊ້ສຳລັບບັນຊີນີ້ມີຢູ່ແລ້ວ) ບໍ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"ອະນຸຍາດໃຫ້ <xliff:g id="APP">%1$s</xliff:g> ສ້າງຜູ້ໃຊ້ໃໝ່ກັບ <xliff:g id="ACCOUNT">%2$s</xliff:g> ໄດ້ບໍ່ (ມີຜູ້ໃຊ້ທີ່ໃຊ້ບັນຊີນີ້ຢູ່ກ່ອນແລ້ວ) ?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"ອະນຸຍາດໃຫ້ <xliff:g id="APP">%1$s</xliff:g> ສ້າງຜູ້ໃຊ້ໃໝ່ກັບ <xliff:g id="ACCOUNT">%2$s</xliff:g> ໄດ້ບໍ?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"ເພີ່ມພາສາ"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"ການຕັ້ງຄ່າພາກພື້ນ"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"ພິມຊື່ພາສາ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index f0ce862..c1b0aa9 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1299,10 +1299,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Palieskite, jei norite matyti visus tinklus"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Prisijungti"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Visi tinklai"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Prisijungti prie „Wi-Fi“ tinklų?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Pasiūlė „<xliff:g id="NAME">%s</xliff:g>“"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Taip"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Leisti siūlomus „Wi‑Fi“ tinklus?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"„<xliff:g id="NAME">%s</xliff:g>“ siūlomi tinklai. Įrenginys gali prisijungti automatiškai."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Leisti"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ne, ačiū"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"„Wi‑Fi“ bus įjungtas automatiškai"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kai būsite netoli išsaugoto aukštos kokybės tinklo"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Neįjunkite vėl"</string>
@@ -1956,8 +1956,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Be kategorijos"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Galite nustatyti šių pranešimų svarbą."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Tai svarbu dėl susijusių žmonių."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Leisti „<xliff:g id="APP">%1$s</xliff:g>“ kurti naują <xliff:g id="ACCOUNT">%2$s</xliff:g> naudotoją?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Leisti „<xliff:g id="APP">%1$s</xliff:g>“ kurti naują <xliff:g id="ACCOUNT">%2$s</xliff:g> naudotoją (šią paskyrą naudojantis naudotojas jau yra)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Leisti „<xliff:g id="APP">%1$s</xliff:g>“ kurti naują <xliff:g id="ACCOUNT">%2$s</xliff:g> naudotoją (šią paskyrą naudojantis naudotojas jau yra)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Leisti „<xliff:g id="APP">%1$s</xliff:g>“ kurti naują <xliff:g id="ACCOUNT">%2$s</xliff:g> naudotoją?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Pridėkite kalbą"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Regiono nuostata"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Įveskite kalbos pav."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index bed07f2..457dbbc 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1277,10 +1277,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Pieskarieties, lai skatītu visus tīklus"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Izveidot savienojumu"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Visi tīkli"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Vai veidot savienojumus ar Wi-Fi tīkliem?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Iesaka <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Jā"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nē"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Vai atļaut ieteiktos Wi‑Fi tīklus?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Lietotnes <xliff:g id="NAME">%s</xliff:g> ieteiktie tīkli. Ierīcē var tikt automātiski izveidots savienojums."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Atļaut"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nē, paldies"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi tiks automātiski ieslēgts"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kad atrodaties saglabāta augstas kvalitātes tīkla tuvumā"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Neieslēgt atkārtoti"</string>
@@ -1922,8 +1922,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Nav kategorijas"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Jūs iestatījāt šo paziņojumu svarīguma līmeni."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Tas ir svarīgi iesaistīto personu dēļ."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Vai atļaut lietotnei <xliff:g id="APP">%1$s</xliff:g> izveidot jaunu lietotāju, izmantojot e-pasta adresi <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Vai atļaut lietotnei <xliff:g id="APP">%1$s</xliff:g> izveidot jaunu lietotāju, izmantojot e-pasta adresi <xliff:g id="ACCOUNT">%2$s</xliff:g> (lietotājs ar šādu kontu jau pastāv)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Vai atļaut lietotnei <xliff:g id="APP">%1$s</xliff:g> izveidot jaunu lietotāju, izmantojot e-pasta adresi <xliff:g id="ACCOUNT">%2$s</xliff:g> (lietotājs ar šādu kontu jau pastāv)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Vai atļaut lietotnei <xliff:g id="APP">%1$s</xliff:g> izveidot jaunu lietotāju, izmantojot e-pasta adresi <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Pievienot valodu"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Reģiona preference"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Ierakstiet valodas nosaukumu"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 357764c..c122a56 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -243,7 +243,7 @@
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Тивок режим"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Звукот е исклучен"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Звукот е вклучен"</string>
-    <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Режим на работа во авион"</string>
+    <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Авионски режим"</string>
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Режимот на работа во авион е вклучен"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Режимот на работа во авион е исклучен"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"Поставки"</string>
@@ -282,7 +282,7 @@
     <string name="permgrouprequest_contacts" msgid="6032805601881764300">"Дали да се дозволи &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; да пристапува до контактите?"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"Локација"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"пристапува до локацијата на овој уред"</string>
-    <string name="permgrouprequest_location" msgid="3788275734953323491">"Дали да се дозволи &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; да пристапува до локацијата на уредот?"</string>
+    <string name="permgrouprequest_location" msgid="3788275734953323491">"Дали да се дозволи &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; да пристапува до локацијата на уредов?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Апликацијата ќе има пристап до локацијата само додека ја користите"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Да се дозволи &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; да пристапува до локацијата на уредов &lt;b&gt;во секое време&lt;/b&gt;?"</string>
     <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Апликацијата во моментов може да пристапува до локацијата само додека ја користите"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Допрете за да ги видите сите мрежи"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Поврзете се"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Сите мрежи"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Да се поврзе со Wi-Fi мрежи?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Предложено од <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Да"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Не"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Да се дозволат предложените Wi‑Fi мрежи?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Предложени мрежи од <xliff:g id="NAME">%s</xliff:g>. Уредот може да се поврзе автоматски."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Дозволи"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Не, фала"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi ќе се вклучи автоматски"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Кога сте во близина на зачувана мрежа со висок квалитет"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Не вклучувај повторно"</string>
@@ -1356,7 +1356,7 @@
     <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Откриен е аналоген аудиододаток"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Приложениот уред не е компатибилен со телефонов. Допрете за да дознаете повеќе."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Поврзано е отстранување грешки преку USB"</string>
-    <string name="adb_active_notification_message" msgid="7463062450474107752">"Допрете за да го исклучите отстранувањето грешки преку USB"</string>
+    <string name="adb_active_notification_message" msgid="7463062450474107752">"Допрете за да го исклучите"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изберете за да се оневозможи отстранување грешки на USB."</string>
     <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Овозможен е режимот на рамка за тестирање"</string>
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Извршете фабричко ресетирање за да го оневозможите режимот на рамка за тестирање."</string>
@@ -1891,8 +1891,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Некатегоризирано"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Ја поставивте важноста на известувањава."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ова е важно заради луѓето кои се вклучени."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Дозволувате ли <xliff:g id="APP">%1$s</xliff:g> да создаде нов корисник со <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Дозволувате ли <xliff:g id="APP">%1$s</xliff:g> да создаде нов корисник со <xliff:g id="ACCOUNT">%2$s</xliff:g> (веќе постои корисник со оваа сметка)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Дозволувате <xliff:g id="APP">%1$s</xliff:g> да создаде нов корисник со <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Веќе постои корисник со оваа сметка.)"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Дозволувате <xliff:g id="APP">%1$s</xliff:g> да создаде нов корисник со <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Додај јазик"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Претпочитувања за регион"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Внеси име на јазик"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 9ad8b13..7dc0ec3 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"എല്ലാ നെറ്റ്‌വർക്കുകളും കാണാൻ ടാപ്പുചെയ്യുക"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"കണക്റ്റുചെയ്യുക"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"എല്ലാ നെറ്റ്‌വർക്കുകളും"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"വൈഫൈ നെറ്റ്‌വർക്കുകളിലേക്ക് കണക്റ്റ് ചെയ്യണോ?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> നിർദ്ദേശിച്ചത്"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ഉവ്വ്"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ഇല്ല"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"നിർദ്ദേശിച്ച വെെഫെെ നെറ്റ്‌വർക്കുകൾ അനുവദിക്കണോ?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> നിർദ്ദേശിച്ച നെറ്റ്‌വർക്കുകൾ. ഉപകരണം സ്വയമേവ കണക്‌റ്റ് ചെയ്‌തേക്കാം."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"അനുവദിക്കുക"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"വേണ്ട"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"വൈഫൈ സ്വമേധയാ ഓണാകും"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"നിങ്ങൾ ഉയർന്ന നിലവാരമുള്ള സംരക്ഷിക്കപ്പെട്ട നെറ്റ്‌വർക്കിനരികിലെത്തുമ്പോൾ"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"തിരികെ ഓണാക്കരുത്"</string>
@@ -1889,8 +1889,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"വർഗ്ഗീകരിച്ചിട്ടില്ലാത്ത"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"ഈ അറിയിപ്പുകളുടെ പ്രാധാന്യം നിങ്ങൾ സജ്ജീകരിച്ചു."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"ഉൾപ്പെട്ടിട്ടുള്ള ആളുകളെ കണക്കിലെടുക്കുമ്പോള്‍ ഇത് പ്രധാനപ്പെട്ടതാണ്‌."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="ACCOUNT">%2$s</xliff:g> എന്ന അക്കൗണ്ട് ഉപയോഗിച്ച് പുതിയൊരു ഉപയോക്താവിനെ സൃഷ്ടിക്കാൻ <xliff:g id="APP">%1$s</xliff:g> എന്ന ആപ്പിനെ അനുവദിക്കണോ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="ACCOUNT">%2$s</xliff:g> എന്ന അക്കൗണ്ട് (ഈ അക്കൗണ്ട് ഉപയോഗിച്ചുള്ള ഒരു ഉപയോക്താവ് ഇതിനകം തന്നെ നിലവിലുണ്ട്) ഉപയോഗിച്ച് പുതിയൊരു ഉപയോക്താവിനെ സൃഷ്ടിക്കാൻ <xliff:g id="APP">%1$s</xliff:g> എന്ന ആപ്പിനെ അനുവദിക്കണോ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g> എന്ന അക്കൗണ്ട് (ഈ അക്കൗണ്ട് ഉപയോഗിക്കുന്ന ഒരു ഉപയോക്താവ് നിലവിലുണ്ട്) ഉപയോഗിച്ച് പുതിയ ഉപയോക്താവിനെ സൃഷ്‌ടിക്കാൻ <xliff:g id="APP">%1$s</xliff:g> എന്നതിനെ അനുവദിക്കണോ?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> എന്ന അക്കൗണ്ട് ഉപയോഗിച്ച് പുതിയ ഉപയോക്താവിനെ സൃഷ്‌ടിക്കാൻ <xliff:g id="APP">%1$s</xliff:g> എന്നതിനെ അനുവദിക്കണോ?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"ഒരു ഭാഷ ചേർക്കുക"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"മേഖലാ മുൻഗണന"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"ഭാഷയുടെ പേര് ടൈപ്പുചെയ്യുക"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index d5f358b..4a2cf63 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Бүх сүлжээг харахын тулд товшино уу"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Холбогдох"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Бүх сүлжээ"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi-Fi сүлжээнд холбогдох уу?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> санал болгосон"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Тийм"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Үгүй"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Санал болгосон Wi‑Fi сүлжээг зөвшөөрөх үү?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> сүлжээ санал болголоо. Төхөөрөмж автоматаар холбогдож магадгүй."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Зөвшөөрөх"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Үгүй, баярлалаа"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi автоматаар асна"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Таныг хадгалсан, өндөр чанартай сүлжээний ойролцоо байх үед"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Буцааж асаахгүй"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Ангилаагүй"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Та эдгээр мэдэгдлийн ач холбогдлыг тогтоосон."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Оролцсон хүмүүсээс шалтгаалан энэ нь өндөр ач холбогдолтой."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g>-г <xliff:g id="ACCOUNT">%2$s</xliff:g>-р шинэ Хэрэглэгч үүсгэхийг зөвшөөрөх үү?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g>-г <xliff:g id="ACCOUNT">%2$s</xliff:g>-р шинэ хэрэглэгч үүсгэхийг зөвшөөрөх үү (ийм бүртгэлтэй хэрэглэгч аль хэдийн байна) ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g>-д <xliff:g id="ACCOUNT">%2$s</xliff:g>-тай (ийм бүртгэлтэй хэрэглэгч аль хэдийн байна) шинэ хэрэглэгч үүсгэхийг зөвшөөрөх үү ?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g>-д <xliff:g id="ACCOUNT">%2$s</xliff:g>-тай шинэ хэрэглэгч үүсгэхийг зөвшөөрөх үү?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Хэл нэмэх"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Бүс нутгийн тохиргоо"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Улсын хэлийг бичнэ үү"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 65ead3b..f790fce 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -996,7 +996,7 @@
     <string name="weeks" msgid="6509623834583944518">"आठवडे"</string>
     <string name="year" msgid="4001118221013892076">"वर्ष"</string>
     <string name="years" msgid="6881577717993213522">"वर्षे"</string>
-    <string name="now_string_shortest" msgid="8912796667087856402">"आत्ता"</string>
+    <string name="now_string_shortest" msgid="8912796667087856402">"आता"</string>
     <plurals name="duration_minutes_shortest" formatted="false" msgid="3957499975064245495">
       <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>मि</item>
       <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>मि</item>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सर्व नेटवर्क पाहण्यासाठी टॅप करा"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"कनेक्ट करा"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"सर्व नेटवर्क"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"वाय-फाय नेटवर्कशी कनेक्ट करायचे?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> ने सुचवले"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"होय"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"नाही"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"सुचवलेल्या वाय-फाय नेटवर्कना अनुमती द्यायची का?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> सुचवलेली नेटवर्क. डिव्हाइस आपोआप कनेक्ट होऊ शकते."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"अनुमती द्या"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"नाही, नको"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"वाय-फाय आपोआप चालू होईल"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"तुम्ही जेव्हा सेव्ह केलेल्या उच्च दर्जाच्या नेटवर्कजवळ असाल तेव्हा"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"पुन्हा चालू करू नका"</string>
@@ -1671,7 +1671,7 @@
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"प्रवेशयोग्यता शॉर्टकटने <xliff:g id="SERVICE_NAME">%1$s</xliff:g> बंद केली"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> वापरण्यासाठी दोन्ही व्हॉल्युम की तीन सेकंद दाबा आणि धरून ठेवा"</string>
     <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"तुम्ही अ‍ॅक्सेसिबिलिटी बटण दाबल्यावर वापरण्यासाठी वैशिष्ट्य निवडा:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"अ‍ॅक्सेसिबिलिटी जेश्चर ज्या सोबत वापराचे आहे अशी सेवा निवडा (स्क्रीनच्या खालच्या बाजूने दोन बोटांनी स्वाइप करा):"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"अ‍ॅक्सेसिबिलिटी जेश्चर ज्यासोबत वापराचे आहे अशी सेवा निवडा (स्क्रीनच्या खालच्या बाजूने दोन बोटांनी स्वाइप करा):"</string>
     <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"अ‍ॅक्सेसिबिलिटी जेश्चर ज्या सोबत वापराचे आहे अशी सेवा निवडा (स्क्रीनच्या खालच्या बाजूने तीन बोटांनी स्वाइप करा):"</string>
     <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"सेवांदरम्यान स्विच करण्यासाठी, अ‍ॅक्सेसिबिलिटी बटणाला स्पर्श करा आणि धरून ठेवा."</string>
     <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"सेवांदरम्यान स्विच करण्यासाठी, दोन बोटांनी वरच्या दिशेला स्वाइप करा आणि धरून ठेवा."</string>
@@ -1889,8 +1889,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"वर्गीकरण न केलेले"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"तुम्ही या सूचनांचे महत्त्व सेट केले."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"सामील असलेल्या लोकांमुळे हे महत्वाचे आहे."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="ACCOUNT">%2$s</xliff:g> सह नवीन वापरकर्ता तयार करण्याची <xliff:g id="APP">%1$s</xliff:g> ला अनुमती द्यायची?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="ACCOUNT">%2$s</xliff:g> सह नवीन वापरकर्ता तयार करण्याची (हे खाते असलेला वापरकर्ता आधीपासून विद्यमान आहे) <xliff:g id="APP">%1$s</xliff:g> ला अनुमती द्यायची?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g> सह नवीन वापरकर्ता तयार करण्याची (हे खाते असलेला वापरकर्ता आधीपासून अस्तित्वात आहे) <xliff:g id="APP">%1$s</xliff:g> ला अनुमती द्यायची आहे का?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> सह नवीन वापरकर्ता तयार करण्याची <xliff:g id="APP">%1$s</xliff:g> ला अनुमती द्यायची आहे का?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"एक भाषा जोडा"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"प्रदेश प्राधान्य"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"भाषा नाव टाइप करा"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index b6743f4..cfbe2ab 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Ketik untuk melihat semua rangkaian"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Sambung"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Semua rangkaian"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Sambung ke rangkaian Wi-Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Dicadangkan oleh <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ya"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Tidak"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Benarkan rangkaian Wi-Fi yang dicadangkan?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Rangkaian yang dicadangkan oleh <xliff:g id="NAME">%s</xliff:g>. Peranti mungkin disambungkan secara automatik."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Benarkan"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Tidak perlu"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi akan dihidupkan secara automatik"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Apabila anda berada berdekatan dengan rangkaian disimpan yang berkualiti tinggi"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Jangan hidupkan kembali"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Tidak dikategorikan"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Anda menetapkan kepentingan pemberitahuan ini."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Mesej ini penting disebabkan orang yang terlibat."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Benarkan <xliff:g id="APP">%1$s</xliff:g> membuat Pengguna baharu dengan <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Benarkan <xliff:g id="APP">%1$s</xliff:g> membuat Pengguna baharu dengan <xliff:g id="ACCOUNT">%2$s</xliff:g> (Pengguna dengan akaun ini sudah wujud)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Benarkan <xliff:g id="APP">%1$s</xliff:g> membuat Pengguna baharu dengan <xliff:g id="ACCOUNT">%2$s</xliff:g> (Pengguna dengan akaun ini sudah wujud) ?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Benarkan <xliff:g id="APP">%1$s</xliff:g> membuat Pengguna baharu dengan <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Tambahkan bahasa"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Pilihan wilayah"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Taipkan nama bahasa"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 25f8545..b4dabd9 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ကွန်ရက်အားလုံးကို ကြည့်ရန် တို့ပါ"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"ချိတ်ဆက်ရန်"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ကွန်ရက်အားလုံး"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi‑Fi ကွန်ရက်များသို့ ချိတ်ဆက်လိုပါသလား။"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> က အကြံပြုထားသည်"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"အကြံပြုထားသည့် Wi‑Fi ကွန်ရက်များ ခွင့်ပြုမလား။"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> သည် ကွန်ရက်များကို အကြံပြုထားသည်။ စက်သည် အလိုအလျောက် ချိတ်ဆက်နိုင်သည်။"</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"ခွင့်ပြုရန်"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"မလိုပါ"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi ကို အလိုအလျောက်​ ပြန်ဖွင့်ပေးလိမ့်ပါမည်"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"သိမ်းဆည်းထားသည့် အရည်အသွေးမြင့်ကွန်ရက်များအနီးသို့ ရောက်ရှိသည့်အခါ"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ပြန်မဖွင့်ပါနှင့်"</string>
@@ -1447,8 +1447,8 @@
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"အောက်ပါထဲက အက်ပ်တစ်ခု သို့မဟုတ် ပိုလျက် သင်၏ အကောင့်ကို၊ ယခု နှင့် အနာဂတ်မှာ ရယူအသုံးချရန် ခွင့်ပြုချက်ကို တောင်းထားသည်။"</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"ဤတောင်းခံမှုအားခွင့်ပြုမည်လား"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"သုံးစွဲခွင့် တောင်းဆိုရန်"</string>
-    <string name="allow" msgid="7225948811296386551">"ခွင့်ပြုသည်"</string>
-    <string name="deny" msgid="2081879885755434506">"ငြင်းပယ်သည်"</string>
+    <string name="allow" msgid="7225948811296386551">"ခွင့်ပြုရန်"</string>
+    <string name="deny" msgid="2081879885755434506">"ငြင်းပယ်ရန်"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"ခွင့်ပြုချက် တောင်းခံထားခြင်း"</string>
     <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"အကောင့် <xliff:g id="ACCOUNT">%s</xliff:g> အတွက် \n ခွင့်ပြုချက် တောင်းခံထားပြီး"</string>
     <string name="forward_intent_to_owner" msgid="1207197447013960896">"သင်သည် ဒီအက်ပ်ကို သင့်အလုပ်ပရိုဖိုင် ပြင်ပတွင် အသုံးပြုနေ၏"</string>
@@ -1889,8 +1889,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"အမျိုးအစားမခွဲရသေးပါ"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"ဤသတိပေးချက်များ၏ အရေးပါမှုကိုသတ်မှတ်ပြီးပါပြီ။"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"ပါဝင်သည့်လူများကြောင့် အရေးပါပါသည်။"</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g> ကို <xliff:g id="ACCOUNT">%2$s</xliff:g> ဖြင့်အသုံးပြုသူအသစ်ဖန်တီးခွင့်ပြုမလား။"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g> ကို <xliff:g id="ACCOUNT">%2$s</xliff:g> ဖြင့်အသုံးပြုသူအသစ် ဖန်တီးခွင့်ပြုမလား (ဤအကောင့်ဖြင့် အသုံးပြုသူ ရှိနှင့်ပြီးဖြစ်သည်)။"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g> ဖြင့်အသုံးပြုသူအသစ်ကို <xliff:g id="APP">%1$s</xliff:g> အား ဖန်တီးခွင့်ပြုလိုပါသလား (ဤအကောင့်ဖြင့် အသုံးပြုသူ ရှိနှင့်ပြီးဖြစ်သည်) ။"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> ဖြင့်အသုံးပြုသူအသစ်ကို <xliff:g id="APP">%1$s</xliff:g> အား ဖန်တီးခွင့်ပြုလိုပါသလား ။"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"ဘာသာစကားတစ်ခု ထည့်ပါ"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"ဒေသရွေးချယ်မှု"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"ဘာသာစကားအမည် ထည့်ပါ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index c6d1698..f6f7bf4 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -226,7 +226,7 @@
     <string name="global_actions" product="default" msgid="2406416831541615258">"Telefoninnstillinger"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"Lås skjermen"</string>
     <string name="global_action_power_off" msgid="4471879440839879722">"Slå av"</string>
-    <string name="global_action_emergency" msgid="7112311161137421166">"Nødsituasjon"</string>
+    <string name="global_action_emergency" msgid="7112311161137421166">"Nødssituasjon"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"Feilrapport"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Avslutt økten"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Skjermdump"</string>
@@ -291,7 +291,7 @@
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Vil du gi &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tilgang til kalenderen din?"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"sende og lese SMS-meldinger"</string>
-    <string name="permgrouprequest_sms" msgid="7168124215838204719">"Vil du la &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; sende og se SMS-meldinger?"</string>
+    <string name="permgrouprequest_sms" msgid="7168124215838204719">"Vil du la &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; sende og se tekstmeldinger?"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Lagring"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"åpne bilder, medieinnhold og filer på enheten din"</string>
     <string name="permgrouprequest_storage" msgid="7885942926944299560">"Vil du gi &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tilgang til bilder, medier og filer på enheten din?"</string>
@@ -812,7 +812,7 @@
     <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Trykk på menyknappen for å låse opp eller ringe et nødnummer."</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Trykk på menyknappen for å låse opp."</string>
     <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Tegn mønster for å låse opp"</string>
-    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Nødsituasjon"</string>
+    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Nødssituasjon"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Tilbake til samtale"</string>
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Riktig!"</string>
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Prøv på nytt"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Trykk for å se alle nettverkene"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Koble til"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alle nettverk"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Vil du koble til Wi-Fi-nettverk?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Foreslått av <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nei"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Vil du tillate foreslåtte Wi-Fi nettverk?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g>-foreslåtte nettverk. Enheten kan koble til automatisk."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Tillat"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nei takk"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi slås på automatisk"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Når du er i nærheten av et lagret nettverk av høy kvalitet"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ikke slå på igjen"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Uten kategori"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Du angir viktigheten for disse varslene."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Dette er viktig på grunn av folkene som er involvert."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Vil du la <xliff:g id="APP">%1$s</xliff:g> opprette en ny bruker med <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Vil du la <xliff:g id="APP">%1$s</xliff:g> opprette en ny bruker med <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Det finnes allerede en bruker med denne kontoen.)"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Vil du la <xliff:g id="APP">%1$s</xliff:g> opprette en ny bruker med <xliff:g id="ACCOUNT">%2$s</xliff:g> (en bruker med denne kontoen eksisterer allerede)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Vil du la <xliff:g id="APP">%1$s</xliff:g> opprette en ny bruker med <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Legg til et språk"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Regionsinnstilling"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Skriv inn språknavn"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 4739232..ff0eade 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1261,10 +1261,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सबै नेटवर्कहरू हेर्न ट्याप गर्नुहोस्"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"जडान गर्नुहोस्"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"सबै नेटवर्कहरू"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi-Fi नेटवर्कसँग जोड्ने हो?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> ले सुझाव दिएको"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"हो"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"होइन"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"सिफारिस गरिएका Wi‑Fi नेटवर्कहरूलाई अनुमति दिनुहोस्?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> ले सिफारिस गरेका नेटवर्कहरू। यन्त्र स्वतः जडान हुन सक्छ।"</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"अनुमति दिनुहोस्"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"पर्दैन, धन्यवाद"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi स्वतः सक्रिय हुनेछ"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"तपाईं कुनै सुरक्षित गरिएको उच्च गुणस्तरीय नेटवर्कको नजिक हुनुभएको अवस्थामा"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"फेरि सक्रिय नगर्नुहोला"</string>
@@ -1894,8 +1894,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"वर्गीकरण नगरिएको"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"तपाईंले यी सूचनाहरूको महत्त्व सेट गर्नुहोस् ।"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"यसमा सङ्लग्न भएका मानिसहरूको कारणले गर्दा यो महत्वपूर्ण छ।"</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="ACCOUNT">%2$s</xliff:g> सँगै नयाँ प्रयोगकर्ता सिर्जना गर्न <xliff:g id="APP">%1$s</xliff:g> लाई अनुमति दिने हो?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="ACCOUNT">%2$s</xliff:g> सँगै नयाँ प्रयोगकर्ता सिर्जना गर्न <xliff:g id="APP">%1$s</xliff:g> लाई अनुमति दिने (यस खाताको प्रयोगकर्ता पहिले नै अवस्थित छ) ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g> (यस खाताको प्रयोगकर्ता पहिले नै अवस्थित छ) मा नयाँ प्रयोगकर्ता सिर्जना गर्न <xliff:g id="APP">%1$s</xliff:g> लाई अनुमति दिने हो?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> मा नयाँ प्रयोगकर्ता सिर्जना गर्न <xliff:g id="APP">%1$s</xliff:g> लाई अनुमति दिने हो?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"भाषा थप्नुहोस्"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"क्षेत्रको प्राथमिकता"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"भाषाको नाम टाइप गर्नुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index fe53b23..e27ad0d 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tik om alle netwerken te bekijken"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Verbinding maken"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alle netwerken"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Verbinding maken met wifi-netwerken?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Voorgesteld door <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nee"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Voorgestelde wifi-netwerken toestaan?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> heeft netwerken voorgesteld. Apparaat kan automatisch verbinding maken."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Toestaan"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nee, bedankt"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wifi wordt automatisch ingeschakeld"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Wanneer je in de buurt van een opgeslagen netwerk van hoge kwaliteit bent"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Niet weer inschakelen"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Geen categorie"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Je stelt het belang van deze meldingen in."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Dit is belangrijk vanwege de betrokken mensen."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Toestaan dat <xliff:g id="APP">%1$s</xliff:g> een nieuwe gebruiker met <xliff:g id="ACCOUNT">%2$s</xliff:g> maakt?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Toestaan dat <xliff:g id="APP">%1$s</xliff:g> een nieuwe gebruiker met <xliff:g id="ACCOUNT">%2$s</xliff:g> maakt (er is al een gebruiker met dit account)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Toestaan dat <xliff:g id="APP">%1$s</xliff:g> een nieuwe gebruiker met <xliff:g id="ACCOUNT">%2$s</xliff:g> maakt (er is al een gebruiker met dit account)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Toestaan dat <xliff:g id="APP">%1$s</xliff:g> een nieuwe gebruiker met <xliff:g id="ACCOUNT">%2$s</xliff:g> maakt?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Een taal toevoegen"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Regiovoorkeur"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Typ een taalnaam"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 949de6e..5192adb 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ସମସ୍ତ ନେଟ୍‌ୱର୍କ ଦେଖିବାକୁ ଟାପ୍‍ କରନ୍ତୁ"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"କନେକ୍ଟ କରନ୍ତୁ"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ସମସ୍ତ ନେଟ୍‌ୱର୍କ"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"ୱାଇ-ଫାଇ ନେଟ୍‍ୱର୍କଗୁଡ଼ିକୁ ସଂଯୁକ୍ତ କରିବେ?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g>ଙ୍କ ଦ୍ୱାରା ପ୍ରସ୍ତାବିତ"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ହଁ"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ନାହିଁ"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"ପ୍ରସ୍ତାବିତ ୱାଇ-ଫାଇ ନେଟ୍‌ୱାର୍କଗୁଡ଼ିକୁ ଅନୁମତି ଦେବେ?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> ପ୍ରସ୍ତାବିତ ନେଟ୍‌ୱାର୍କଗୁଡ଼ିକ। ଡିଭାଇସ୍ ହୁଏତ ସ୍ୱଚାଳିତ ଭାବେ ସଂଯୋଗ ହୋଇପାରେ।"</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"ନାହିଁ, ଥାଉ"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"ୱାଇ-ଫାଇ ସ୍ୱଚାଳିତ ଭାବେ ଅନ୍ ହେବ"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"ଆପଣ ଏକ ଉଚ୍ଚ-କ୍ୱାଲିଟୀ ବିଶିଷ୍ଟ ସେଭ୍‌ କରାଯାଇଥିବା ନେଟ୍‌ୱର୍କ ପାଖରେ ଥିବା ସମୟରେ"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ପୁଣି ଅନ୍‍ କରନ୍ତୁ ନାହିଁ"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"ଅବର୍ଗୀକୃତ"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ପ୍ରମୁଖତା ଆପଣ ସେଟ୍‍ କରନ୍ତି।"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"ସମ୍ପୃକ୍ତ ଲୋକଙ୍କ କାରଣରୁ ଏହା ଗୁରୁତ୍ୱପୂର୍ଣ୍ଣ ଅଟେ।"</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="ACCOUNT">%2$s</xliff:g> ସହ ଏକ ନୂଆ ୟୁଜର୍‌ ତିଆରି କରିବା ପାଇଁ <xliff:g id="APP">%1$s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="ACCOUNT">%2$s</xliff:g> ସହ ଏକ ନୂଆ ୟୁଜର୍‌ ତିଆରି କରିବାକୁ <xliff:g id="APP">%1$s</xliff:g>କୁ ଅନୁମତି ଦେବେ (ଏହି ଆକାଉଣ୍ଟରେ ଜଣେ ୟୁଜର୍‌ ପୂର୍ବରୁ ରହିଛନ୍ତି)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g>ରେ ଏକ ନୂଆ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରିବା ପାଇଁ <xliff:g id="ACCOUNT">%2$s</xliff:g>କୁ (ପୂର୍ବରୁ ଏହି ଆକାଉଣ୍ଟ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ନାମରେ ଅଛି) ଅନୁମତି ଦେବେ?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g>ରେ ଏକ ନୂଆ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରିବା ପାଇଁ <xliff:g id="ACCOUNT">%2$s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"ଏକ ଭାଷା ଯୋଡ଼ନ୍ତୁ"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"ପସନ୍ଦର ଅଞ୍ଚଳ"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"ଭାଷାର ନାମ ଟାଇପ୍‍ କରନ୍ତୁ"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 4fc980b..fe0fada 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ਸਾਰੇ ਨੈੱਟਵਰਕਾਂ ਨੂੰ ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"ਕਨੈਕਟ ਕਰੋ"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ਸਾਰੇ ਨੈੱਟਵਰਕ"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"ਕੀ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕਾਂ ਨਾਲ ਕਨੈਕਟ ਕਰਨਾ ਹੈ?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> ਵਲੋਂ ਸੁਝਾਇਆ ਗਿਆ"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ਹਾਂ"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ਨਹੀਂ"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"ਕੀ ਸੁਝਾਏ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਵਰਤਣੇ ਹਨ?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> ਦੇ ਸੁਝਾਏ ਨੈੱਟਵਰਕ। ਸ਼ਾਇਦ ਡੀਵਾਈਸ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਕਨੈਕਟ ਹੋਵੇ।"</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"ਵਰਤਣ ਦਿਓ"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"ਨਹੀਂ ਧੰਨਵਾਦ"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"ਵਾਈ‑ਫਾਈ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਚੱਲ ਪਵੇਗਾ"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"ਜਦੋਂ ਤੁਸੀਂ ਕਿਸੇ ਰੱਖਿਅਤ ਕੀਤੇ ਉੱਚ-ਗੁਣਵੱਤਾ ਵਾਲੇ ਨੈੱਟਵਰਕ ਦੇ ਨੇੜੇ ਹੋਵੋ"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ਵਾਪਸ ਚਾਲੂ ਨਾ ਕਰੋ"</string>
@@ -1889,8 +1889,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"ਗੈਰ-ਸ਼੍ਰੇਣੀਕਿਰਤ"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"ਤੁਸੀਂ ਇਹਨਾਂ ਸੂਚਨਾਵਾਂ ਦੀ ਮਹੱਤਤਾ ਸੈੱਟ ਕੀਤੀ।"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"ਇਹ ਸ਼ਾਮਲ ਲੋਕਾਂ ਦੇ ਕਾਰਨ ਮਹੱਤਵਪੂਰਨ ਹੈ।"</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"ਕੀ <xliff:g id="APP">%1$s</xliff:g> ਨੂੰ <xliff:g id="ACCOUNT">%2$s</xliff:g> ਨਾਲ ਇੱਕ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਬਣਾਉਣ ਦੀ ਮਨਜ਼ੂਰੀ ਦੇਣੀ ਹੈ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"ਕੀ <xliff:g id="APP">%1$s</xliff:g> ਨੂੰ <xliff:g id="ACCOUNT">%2$s</xliff:g> ਨਾਲ ਇੱਕ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਬਣਾਉਣ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ (ਇਸ ਖਾਤੇ ਨਾਲ ਇੱਕ ਵਰਤੋਂਕਾਰ ਪਹਿਲਾਂ ਤੋਂ ਹੀ ਮੌਜੂਦ ਹੈ) ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"ਕੀ <xliff:g id="APP">%1$s</xliff:g> ਨੂੰ <xliff:g id="ACCOUNT">%2$s</xliff:g> ਨਾਲ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਬਣਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣੀ ਹੈ (ਇਸ ਖਾਤੇ ਨਾਲ ਇੱਕ ਵਰਤੋਂਕਾਰ ਪਹਿਲਾਂ ਤੋਂ ਹੀ ਮੌਜੂਦ ਹੈ)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"ਕੀ <xliff:g id="APP">%1$s</xliff:g> ਨੂੰ <xliff:g id="ACCOUNT">%2$s</xliff:g> ਨਾਲ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਬਣਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣੀ ਹੈ?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"ਇੱਕ ਭਾਸ਼ਾ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"ਖੇਤਰ ਤਰਜੀਹ"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"ਭਾਸ਼ਾ ਨਾਮ ਟਾਈਪ ਕਰੋ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 302f541..c4d3217 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1299,10 +1299,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Kliknij, by zobaczyć wszystkie sieci"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Połącz"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Wszystkie sieci"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Nawiązywać połączenia z sieciami Wi-Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Sugestia: <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Tak"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nie"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Zezwalać na sugerowane sieci Wi‑Fi?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Sugerowane sieci: <xliff:g id="NAME">%s</xliff:g>. Urządzenie może łączyć się automatycznie."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Zezwól"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nie, dziękuję"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi włączy się automatycznie"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Gdy znajdziesz się w pobliżu zapisanej sieci o mocnym sygnale"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Nie włączaj ponownie"</string>
@@ -1956,8 +1956,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Bez kategorii"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Ustawiłeś ważność tych powiadomień."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ta wiadomość jest ważna ze względu na osoby uczestniczące w wątku."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Zezwalasz aplikacji <xliff:g id="APP">%1$s</xliff:g> na utworzenie nowego użytkownika dla konta <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Zezwalasz aplikacji <xliff:g id="APP">%1$s</xliff:g> na utworzenie nowego użytkownika dla konta <xliff:g id="ACCOUNT">%2$s</xliff:g>)? Użytkownik z tym kontem już istnieje."</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Zezwolić aplikacji <xliff:g id="APP">%1$s</xliff:g> na utworzenie nowego użytkownika dla konta <xliff:g id="ACCOUNT">%2$s</xliff:g> (użytkownik dla tego konta już istnieje)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Zezwolić aplikacji <xliff:g id="APP">%1$s</xliff:g> na utworzenie nowego użytkownika dla konta <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Dodaj język"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Ustawienie regionu"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Wpisz nazwę języka"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index d0e1bc9..d239d76 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas as redes"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Conectar a redes Wi-Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Sugerido por <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sim"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Não"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Permitir redes Wi-Fi sugeridas?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Redes sugeridas pelo app <xliff:g id="NAME">%s</xliff:g>. O dispositivo pode se conectar automaticamente."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Permitir"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Não"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"O Wi‑Fi será ativado automaticamente"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Quando você estiver perto de uma rede salva de alta qualidade"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Não ativar novamente"</string>
@@ -1476,7 +1476,7 @@
     <string name="submit" msgid="1602335572089911941">"Enviar"</string>
     <string name="car_mode_disable_notification_title" msgid="5704265646471239078">"O app para carro está sendo usado"</string>
     <string name="car_mode_disable_notification_message" msgid="7647248420931129377">"Toque para sair do app para carro."</string>
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Vínculo ou ponto de acesso ativo"</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"Ponto de acesso ou tethering ativo"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string>
     <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering desativado"</string>
     <string name="disable_tether_notification_message" msgid="2913366428516852495">"Fale com seu administrador para saber detalhes"</string>
@@ -1670,8 +1670,8 @@
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"O atalho de acessibilidade desativou o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Toque nos dois botões de volume e os mantenha pressionados por três segundo para usar o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Escolha um serviço a ser usado quando você toca no botão Acessibilidade:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Escolha um serviço a ser usado com o gesto de acessibilidade (deslizar de baixo para cima na tela com dois dedos):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Escolha um serviço a ser usado com o gesto de acessibilidade (deslizar de baixo para cima na tela com três dedos):"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Escolha um serviço para usar com o gesto de acessibilidade (deslizar de baixo para cima na tela com dois dedos):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Escolha um serviço para usar com o gesto de acessibilidade (deslizar de baixo para cima na tela com três dedos):"</string>
     <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Para alternar entre serviços, toque no botão de acessibilidade e mantenha-o pressionado."</string>
     <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Para alternar entre serviços, deslize de baixo para cima na tela com dois dedos sem soltar."</string>
     <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Para alternar entre serviços, deslize de baixo para cima na tela com três dedos sem soltar."</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Sem classificação"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Você definiu a importância dessas notificações."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Isso é importante por causa das pessoas envolvidas."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Permitir que <xliff:g id="APP">%1$s</xliff:g> crie um novo usuário com <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Permitir que <xliff:g id="APP">%1$s</xliff:g> crie um novo usuário com <xliff:g id="ACCOUNT">%2$s</xliff:g> (já existe um usuário com essa conta)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Permitir que o app <xliff:g id="APP">%1$s</xliff:g> crie um novo usuário com <xliff:g id="ACCOUNT">%2$s</xliff:g> (já existe um usuário com essa conta)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Permitir que o app <xliff:g id="APP">%1$s</xliff:g> crie um novo usuário com <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Adicionar um idioma"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Preferência de região"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Digitar nome do idioma"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index a4cbc3e..edcf3c7 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -229,7 +229,7 @@
     <string name="global_action_emergency" msgid="7112311161137421166">"Emergência"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"Relatório de erros"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Terminar sessão"</string>
-    <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de ecrã"</string>
+    <string name="global_action_screenshot" msgid="8329831278085426283">"Capt. ecrã"</string>
     <string name="bugreport_title" msgid="5981047024855257269">"Relatório de erro"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Será recolhida informação sobre o estado atual do seu dispositivo a enviar através de uma mensagem de email. Demorará algum tempo até que o relatório de erro esteja pronto para ser enviado. Aguarde um pouco."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Relatório interativo"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ligar"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas as redes"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Pretende estabelecer ligação a redes Wi-Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Sugerida por <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sim"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Não"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Pretende permitir redes Wi-Fi sugeridas?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Redes sugeridas por <xliff:g id="NAME">%s</xliff:g>. O dispositivo pode estabelecer ligação automaticamente."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Permitir"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Não, obrigado"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"O Wi‑Fi será ativado automaticamente"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Quando estiver próximo de uma rede de alta qualidade guardada."</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Não reativar"</string>
@@ -1355,7 +1355,7 @@
     <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Acessório de áudio analógico detetado"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"O dispositivo ligado não é compatível com este telemóvel. Toque para saber mais."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB ligada"</string>
-    <string name="adb_active_notification_message" msgid="7463062450474107752">"Toque para desativar a depuração USB."</string>
+    <string name="adb_active_notification_message" msgid="7463062450474107752">"Toque para desativar a depuração USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração por USB."</string>
     <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Modo de estrutura de teste ativado"</string>
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Efetue uma reposição de dados de fábrica para desativar o Modo de estrutura de teste."</string>
@@ -1506,7 +1506,7 @@
     <string name="sync_really_delete" msgid="2572600103122596243">"Eliminar os itens"</string>
     <string name="sync_undo_deletes" msgid="2941317360600338602">"Anular as eliminações"</string>
     <string name="sync_do_nothing" msgid="3743764740430821845">"Não fazer nada por agora"</string>
-    <string name="choose_account_label" msgid="5655203089746423927">"Selecionar uma conta"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"Selecione uma conta"</string>
     <string name="add_account_label" msgid="2935267344849993553">"Adicionar uma conta"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"Adicionar conta"</string>
     <string name="number_picker_increment_button" msgid="2412072272832284313">"Aumentar"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Sem categoria"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Definiu a importância destas notificações."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"É importante devido às pessoas envolvidas."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Pretende permitir que o <xliff:g id="APP">%1$s</xliff:g> crie um novo utilizador com <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Pretende permitir que o <xliff:g id="APP">%1$s</xliff:g> crie um novo utilizador com <xliff:g id="ACCOUNT">%2$s</xliff:g> (já existe um utilizador com esta conta)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Pretende permitir que a aplicação <xliff:g id="APP">%1$s</xliff:g> crie um novo utilizador com a conta <xliff:g id="ACCOUNT">%2$s</xliff:g> (já existe um utilizador com esta conta)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Pretende permitir que a aplicação <xliff:g id="APP">%1$s</xliff:g> crie um novo utilizador com a conta <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Adicionar um idioma"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Preferência de região"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Intr. nome do idioma"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index d0e1bc9..d239d76 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas as redes"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Conectar a redes Wi-Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Sugerido por <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sim"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Não"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Permitir redes Wi-Fi sugeridas?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Redes sugeridas pelo app <xliff:g id="NAME">%s</xliff:g>. O dispositivo pode se conectar automaticamente."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Permitir"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Não"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"O Wi‑Fi será ativado automaticamente"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Quando você estiver perto de uma rede salva de alta qualidade"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Não ativar novamente"</string>
@@ -1476,7 +1476,7 @@
     <string name="submit" msgid="1602335572089911941">"Enviar"</string>
     <string name="car_mode_disable_notification_title" msgid="5704265646471239078">"O app para carro está sendo usado"</string>
     <string name="car_mode_disable_notification_message" msgid="7647248420931129377">"Toque para sair do app para carro."</string>
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Vínculo ou ponto de acesso ativo"</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"Ponto de acesso ou tethering ativo"</string>
     <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string>
     <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering desativado"</string>
     <string name="disable_tether_notification_message" msgid="2913366428516852495">"Fale com seu administrador para saber detalhes"</string>
@@ -1670,8 +1670,8 @@
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"O atalho de acessibilidade desativou o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Toque nos dois botões de volume e os mantenha pressionados por três segundo para usar o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Escolha um serviço a ser usado quando você toca no botão Acessibilidade:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Escolha um serviço a ser usado com o gesto de acessibilidade (deslizar de baixo para cima na tela com dois dedos):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Escolha um serviço a ser usado com o gesto de acessibilidade (deslizar de baixo para cima na tela com três dedos):"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Escolha um serviço para usar com o gesto de acessibilidade (deslizar de baixo para cima na tela com dois dedos):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Escolha um serviço para usar com o gesto de acessibilidade (deslizar de baixo para cima na tela com três dedos):"</string>
     <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Para alternar entre serviços, toque no botão de acessibilidade e mantenha-o pressionado."</string>
     <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Para alternar entre serviços, deslize de baixo para cima na tela com dois dedos sem soltar."</string>
     <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Para alternar entre serviços, deslize de baixo para cima na tela com três dedos sem soltar."</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Sem classificação"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Você definiu a importância dessas notificações."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Isso é importante por causa das pessoas envolvidas."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Permitir que <xliff:g id="APP">%1$s</xliff:g> crie um novo usuário com <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Permitir que <xliff:g id="APP">%1$s</xliff:g> crie um novo usuário com <xliff:g id="ACCOUNT">%2$s</xliff:g> (já existe um usuário com essa conta)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Permitir que o app <xliff:g id="APP">%1$s</xliff:g> crie um novo usuário com <xliff:g id="ACCOUNT">%2$s</xliff:g> (já existe um usuário com essa conta)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Permitir que o app <xliff:g id="APP">%1$s</xliff:g> crie um novo usuário com <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Adicionar um idioma"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Preferência de região"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Digitar nome do idioma"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 245864c..1fdf162 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1277,10 +1277,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Atingeți pentru a vedea toate rețelele"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectați-vă"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Toate rețelele"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Vă conectați la rețele Wi-Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Sugerat de <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Da"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nu"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Permiteți rețelele Wi-Fi sugerate?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> a sugerat rețele. Dispozitivul se poate conecta automat."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Permiteți"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nu, mulțumesc"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi se va activa automat"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Când vă aflați lângă o rețea salvată, de înaltă calitate"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Nu reactivați"</string>
@@ -1922,8 +1922,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Neclasificate"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Dvs. setați importanța acestor notificări."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Notificarea este importantă având în vedere persoanele implicate."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Permiteți ca <xliff:g id="APP">%1$s</xliff:g> să creeze un nou utilizator folosind <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Permiteți ca <xliff:g id="APP">%1$s</xliff:g> să creeze un nou utilizator folosind <xliff:g id="ACCOUNT">%2$s</xliff:g>? (există deja un utilizator cu acest cont)"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Permiteți ca <xliff:g id="APP">%1$s</xliff:g> să creeze un nou utilizator folosind <xliff:g id="ACCOUNT">%2$s</xliff:g>? (există deja un utilizator cu acest cont)"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Permiteți ca <xliff:g id="APP">%1$s</xliff:g> să creeze un nou utilizator folosind <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Adăugați o limbă"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Regiunea preferată"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Numele limbii"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 29c2e12..7cba3df 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1299,10 +1299,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Нажмите, чтобы увидеть список сетей"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Подключиться"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Все сети"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Подключиться к сети Wi-Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Предложено приложением \"<xliff:g id="NAME">%s</xliff:g>\""</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Да"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Нет"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Подключаться к предложенным сетям Wi‑Fi?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Приложение \"<xliff:g id="NAME">%s</xliff:g>\" рекомендует сети, к которым устройство может подключаться автоматически."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Разрешить"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Нет, спасибо"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi включится автоматически"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Когда вы будете в зоне действия сохраненной сети с хорошим сигналом."</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Не включать снова"</string>
@@ -1718,8 +1718,8 @@
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Сервис <xliff:g id="SERVICE_NAME">%1$s</xliff:g> отключен"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Чтобы использовать сервис \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\", нажмите и удерживайте обе клавиши громкости в течение трех секунд."</string>
     <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Выберите сервис, который будет запускаться при нажатии кнопки специальных возможностей:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Выберите сервис, который будет запускаться жестом для доступа к специальным возможностям (провести по экрану снизу вверх двумя пальцами):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Выберите сервис, который будет запускаться жестом для доступа к специальным возможностям (провести по экрану снизу вверх тремя пальцами):"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Выберите сервис, который будет запускаться жестом (провести по экрану снизу вверх двумя пальцами):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Выберите сервис, который будет запускаться жестом (провести по экрану снизу вверх тремя пальцами):"</string>
     <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Для переключения между сервисами нажмите и удерживайте кнопку специальных возможностей."</string>
     <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Для переключения между сервисами проведите по экрану снизу вверх двумя пальцами и задержите их."</string>
     <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Для переключения между сервисами проведите по экрану снизу вверх тремя пальцами и задержите их."</string>
@@ -1956,8 +1956,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Без категории"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Вы определяете важность этих уведомлений."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Важное (люди)"</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Разрешить приложению \"<xliff:g id="APP">%1$s</xliff:g>\" создать пользователя для аккаунта <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Разрешить приложению \"<xliff:g id="APP">%1$s</xliff:g>\" создать нового пользователя для аккаунта <xliff:g id="ACCOUNT">%2$s</xliff:g> (пользователь c таким аккаунтом уже есть)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Разрешить приложению \"<xliff:g id="APP">%1$s</xliff:g>\" создать нового пользователя с аккаунтом <xliff:g id="ACCOUNT">%2$s</xliff:g> (пользователь с этим аккаунтом уже существует)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Разрешить приложению \"<xliff:g id="APP">%1$s</xliff:g>\" создать нового пользователя с аккаунтом <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Добавьте язык"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Региональные настройки"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Введите язык"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 65b899c..4d9c143 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1257,10 +1257,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"සියලු ජාල බැලීමට තට්ටු කරන්න"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"සම්බන්ධ කරන්න"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"සියලු ජාල"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi-Fi ජාල වෙත සම්බන්ධ කරන්නේද?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> විසින් යෝජනා කරන ලදි"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ඔව්"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"නැත"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"යෝජිත Wi-Fi ජාල ඉඩ දෙන්නද?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> යෝජිත ජාල. උපාංගය ස්වයංක්‍රියව සම්බන්ධ වනු ඇත."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"ඉඩ දෙන්න"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"එපා, ස්තූතියි"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi ස්වයංක්‍රියව ක්‍රියාත්මක වනු ඇත"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"ඔබ උසස් තත්ත්වයේ සුරැකි ජාලයක් අවට සිටින විට"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"නැවත ක්‍රියාත්මක නොකරන්න"</string>
@@ -1890,8 +1890,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"වර්ගීකරණය නොකළ"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"ඔබ මෙම දැනුම්දීම්වල වැදගත්කම සකසා ඇත."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"සම්බන්ධ වූ පුද්ගලයන් නිසා මෙය වැදගත් වේ."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g> හට <xliff:g id="ACCOUNT">%2$s</xliff:g> සමගින් නව පරිශීලකයෙකු සෑදීමට ඉඩ දෙන්නද?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g> හට <xliff:g id="ACCOUNT">%2$s</xliff:g> සමගින් නව පරිශීලකයෙකු සෑදීමට ඉඩ දෙන්නද (මෙම ගිණුම සහිත පරිශීලකයෙකු දැනටමත් සිටී) ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> හට <xliff:g id="ACCOUNT">%2$s</xliff:g> සමගින් නව පරිශීලකයෙකු සෑදීමට ඉඩ දෙන්නද (මෙම ගිණුම සහිත පරිශීලකයෙකු දැනටමත් සිටී) ?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> හට <xliff:g id="ACCOUNT">%2$s</xliff:g> සමගින් නව පරිශීලකයෙකු සෑදීමට ඉඩ දෙන්නද ?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"භාෂාවක් එක් කරන්න"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"ප්‍රදේශ මනාපය"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"භාෂා නම ටයිප් කරන්න"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index ee04eff..102b0d1 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1299,10 +1299,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Klepnutím zobrazíte všetky siete"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Pripojiť"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Všetky siete"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Chcete sa pripojiť k sieťam Wi‑Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Navrhuje <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Áno"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nie"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Chcete povoliť navrhované siete Wi‑Fi?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Siete navrhuje aplikácia <xliff:g id="NAME">%s</xliff:g>. Zariadenie sa môže pripájať automaticky."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Povoliť"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nie, ďakujem"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi sa zapne automaticky"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Keď budete v blízkosti kvalitnej uloženej siete"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Znova nezapínať"</string>
@@ -1956,8 +1956,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Nekategorizované"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Nastavili ste dôležitosť týchto upozornení."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Táto správa je dôležitá vzhľadom na osoby, ktorých sa to týka."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Povoliť aplikácii <xliff:g id="APP">%1$s</xliff:g> vytvoriť nového používateľa pomocou účtu <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Povoliť aplikácii <xliff:g id="APP">%1$s</xliff:g> vytvoriť nového používateľa pomocou účtu <xliff:g id="ACCOUNT">%2$s</xliff:g> (používateľ s týmto účtom už existuje)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Chcete povoliť aplikácii <xliff:g id="APP">%1$s</xliff:g> vytvoriť nového používateľa pomocou účtu <xliff:g id="ACCOUNT">%2$s</xliff:g> (používateľ s týmto účtom už existuje)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Chcete povoliť aplikácii <xliff:g id="APP">%1$s</xliff:g> vytvoriť nového používateľa pomocou účtu <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Pridať jazyk"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Preferovaný región"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Zadajte názov jazyka"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 3f1668c..252ab4c 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1060,10 +1060,10 @@
       <item quantity="other">pred <xliff:g id="COUNT_1">%d</xliff:g> minutami</item>
     </plurals>
     <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
-      <item quantity="one">pred <xliff:g id="COUNT_1">%d</xliff:g> uro</item>
-      <item quantity="two">pred <xliff:g id="COUNT_1">%d</xliff:g> urama</item>
-      <item quantity="few">pred <xliff:g id="COUNT_1">%d</xliff:g> urami</item>
-      <item quantity="other">pred <xliff:g id="COUNT_1">%d</xliff:g> urami</item>
+      <item quantity="one">pred <xliff:g id="COUNT_1">%d</xliff:g> h</item>
+      <item quantity="two">pred <xliff:g id="COUNT_1">%d</xliff:g> h</item>
+      <item quantity="few">pred <xliff:g id="COUNT_1">%d</xliff:g> h</item>
+      <item quantity="other">pred <xliff:g id="COUNT_1">%d</xliff:g> h</item>
     </plurals>
     <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
       <item quantity="one">pred <xliff:g id="COUNT_1">%d</xliff:g> dnevom</item>
@@ -1299,10 +1299,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dotaknite se, če si želite ogledati vsa omrežja"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Vzpostavi povezavo"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Vsa omrežja"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Želite vzpostaviti povezavo z omrežji Wi-Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Predlagala aplikacija <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Da"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Želite dovoliti predlagana omrežja Wi-Fi?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> – predlagana omrežja. Naprava se lahko poveže samodejno."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Dovoli"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ne, hvala"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Povezava Wi‑Fi se bo samodejno vklopila"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Ko ste v bližini zanesljivega shranjenega omrežja"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ne vklopi znova"</string>
@@ -1537,7 +1537,7 @@
     </plurals>
     <string name="action_mode_done" msgid="7217581640461922289">"Končano"</string>
     <string name="progress_erasing" msgid="2569962663843586562">"Brisanje skupne shrambe …"</string>
-    <string name="share" msgid="1778686618230011964">"Deli z dr."</string>
+    <string name="share" msgid="1778686618230011964">"Deli"</string>
     <string name="find" msgid="4808270900322985960">"Najdi"</string>
     <string name="websearch" msgid="4337157977400211589">"Spletno iskanje"</string>
     <string name="find_next" msgid="5742124618942193978">"Najdi naslednje"</string>
@@ -1956,8 +1956,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Nekategorizirano"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Vi določite raven pomembnosti teh obvestil."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Pomembno zaradi udeleženih ljudi."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Dovolite, da aplikacija <xliff:g id="APP">%1$s</xliff:g> ustvari novega uporabnika za račun <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Dovolite aplikaciji <xliff:g id="APP">%1$s</xliff:g>, da ustvari novega uporabnika za račun <xliff:g id="ACCOUNT">%2$s</xliff:g> (uporabnik s tem računom že obstaja)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Ali aplikaciji <xliff:g id="APP">%1$s</xliff:g> dovolite, da ustvari novega uporabnika za račun <xliff:g id="ACCOUNT">%2$s</xliff:g> (uporabnik s tem računom že obstaja)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Ali aplikaciji <xliff:g id="APP">%1$s</xliff:g> dovolite, da ustvari novega uporabnika za račun <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Dodajanje jezika"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Nastavitev območja"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Vnesite ime jezika"</string>
@@ -2051,7 +2051,7 @@
     <string name="shortcut_restore_signature_mismatch" msgid="2406209324521327518">"Bližnjice ni bilo mogoče obnoviti zaradi neujemanja podpisa aplikacije"</string>
     <string name="shortcut_restore_unknown_issue" msgid="8703738064603262597">"Bližnjice ni bilo mogoče obnoviti"</string>
     <string name="shortcut_disabled_reason_unknown" msgid="5276016910284687075">"Bližnjica je onemogočena"</string>
-    <string name="harmful_app_warning_uninstall" msgid="4837672735619532931">"ODSTRANI"</string>
+    <string name="harmful_app_warning_uninstall" msgid="4837672735619532931">"ODMESTI"</string>
     <string name="harmful_app_warning_open_anyway" msgid="596432803680914321">"VSEENO ODPRI"</string>
     <string name="harmful_app_warning_title" msgid="8982527462829423432">"Zaznana je bila škodljiva aplikacija"</string>
     <string name="slices_permission_request" msgid="8484943441501672932">"Aplikacija <xliff:g id="APP_0">%1$s</xliff:g> želi prikazati izreze aplikacije <xliff:g id="APP_2">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 49b6dcf..089c6b9 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -546,7 +546,7 @@
     <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Shumë përpjekje. Sensori i gjurmës së gishtit u çaktivizua."</string>
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Provo përsëri."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="7654382120628334248">"Nuk ka asnjë gjurmë gishti të regjistruar."</string>
-    <string name="fingerprint_error_hw_not_present" msgid="409523969613176352">"Kjo pajisje nuk ka një sensor të gjurmës së gishtit."</string>
+    <string name="fingerprint_error_hw_not_present" msgid="409523969613176352">"Kjo pajisje nuk ka sensor të gjurmës së gishtit."</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"Gishti <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Trokit për të parë të gjitha rrjetet"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Lidhu"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Të gjitha rrjetet"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Do të lidhesh me rrjetet Wi-Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Sugjeruar nga <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Po"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Jo"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Të lejohen rrjetet e sugjeruara Wi‑Fi?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Rrjet e sugjeruara të <xliff:g id="NAME">%s</xliff:g>. Pajisja mund të lidhet automatikisht."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Lejo"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Jo, faleminderit"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi do të aktivizohet automatikisht"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kur ndodhesh pranë një rrjeti të ruajtur me cilësi të lartë"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Mos e aktivizo përsëri"</string>
@@ -1355,7 +1355,7 @@
     <string name="usb_power_notification_message" msgid="4647527153291917218">"Pajisja e lidhur po karikohet. Trokit për opsione të tjera."</string>
     <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"U zbulua aksesor i audios analoge"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Pajisja e bashkuar nuk është e pajtueshme me këtë telefon. Trokit për të mësuar më shumë."</string>
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"Korrigjuesi i USB-së i lidhur"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"Korrigjuesi i USB-së është i lidhur"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Trokit për të çaktivizuar korrigjimin e USB-së"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Përzgjidhe për të çaktivizuar korrigjimin e gabimeve të USB-së"</string>
     <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Modaliteti i lidhjes së testimit është aktivizuar"</string>
@@ -1578,8 +1578,8 @@
     <string name="expires_on" msgid="3676242949915959821">"Skadon më:"</string>
     <string name="serial_number" msgid="758814067660862493">"Numri serik:"</string>
     <string name="fingerprints" msgid="4516019619850763049">"Shenjat e gishtave:"</string>
-    <string name="sha256_fingerprint" msgid="4391271286477279263">"Shenja e gishtit SHA-256:"</string>
-    <string name="sha1_fingerprint" msgid="7930330235269404581">"Shenja e gishtit SHA-1:"</string>
+    <string name="sha256_fingerprint" msgid="4391271286477279263">"Gjurma e gishtit SHA-256:"</string>
+    <string name="sha1_fingerprint" msgid="7930330235269404581">"Gjurma e gishtit SHA-1:"</string>
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Shikoji të gjitha"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Zgjidh aktivitetin"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Shpërnda publikisht me"</string>
@@ -1889,8 +1889,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"E pakategorizuara"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Ke caktuar rëndësinë e këtyre njoftimeve."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Është i rëndësishëm për shkak të personave të përfshirë."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Të lejohet <xliff:g id="APP">%1$s</xliff:g> që të krijojë një përdorues të ri me <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Të lejohet <xliff:g id="APP">%1$s</xliff:g> që të krijojë një përdorues të ri me <xliff:g id="ACCOUNT">%2$s</xliff:g> (një përdorues me këtë llogari ekziston tashmë) ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Të lejohet <xliff:g id="APP">%1$s</xliff:g> që të krijojë një përdorues të ri me <xliff:g id="ACCOUNT">%2$s</xliff:g> (një përdorues me këtë llogari ekziston tashmë) ?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Të lejohet <xliff:g id="APP">%1$s</xliff:g> që të krijojë një përdorues të ri me <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Shto një gjuhë"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Preferenca e rajonit"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Shkruaj emrin e gjuhës"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index a8a4c5c..3d64668 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -27,7 +27,7 @@
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
-    <string name="untitled" msgid="4638956954852782576">"&lt;Без наслова&gt;"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;Без имена&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Нема броја телефона)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Непознато"</string>
     <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Гласовна пошта"</string>
@@ -1277,10 +1277,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Додирните да бисте видели све мреже"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Повежи"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Све мреже"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Желите ли да се повежете са Wi-Fi мрежама?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> предлаже"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Да"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Не"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Желите да дозволите предложене Wi‑Fi мреже?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Мреже које предлаже <xliff:g id="NAME">%s</xliff:g>. Уређај ће се можда повезати аутоматски."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Дозволи"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Не, хвала"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi ће се аутоматски укључити"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Када сте у близини сачуване мреже високог квалитета"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Не укључуј поново"</string>
@@ -1922,8 +1922,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Некатегоризовано"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Ви подешавате важност ових обавештења."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ово је важно због људи који учествују."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Желите ли да дозволите апликацији <xliff:g id="APP">%1$s</xliff:g> да направи новог корисника за <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Желите ли да дозволите апликацији <xliff:g id="APP">%1$s</xliff:g> да направи новог корисника за <xliff:g id="ACCOUNT">%2$s</xliff:g> (корисник са овим налогом већ постоји)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Желите ли да дозволите да <xliff:g id="APP">%1$s</xliff:g> направи новог корисника са налогом <xliff:g id="ACCOUNT">%2$s</xliff:g> (корисник са тим налогом већ постоји)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Желите ли да дозволите да <xliff:g id="APP">%1$s</xliff:g> направи новог корисника са налогом <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Додајте језик"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Подешавање региона"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Унесите назив језика"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 12143f4..8c0ef5b 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tryck för att visa alla nätverk"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Anslut"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alla nätverk"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Vill du ansluta till Wi-Fi-nätverk?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Förslag från <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nej"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Vill du tillåta föreslagna Wi-Fi-nätverk?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Nätverk som föreslagits av <xliff:g id="NAME">%s</xliff:g>. Enheten kan anslutas automatiskt."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Tillåt"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nej tack"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi aktiveras automatiskt"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"När du är i närheten av ett sparat nätverk av hög kvalitet"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Återaktivera inte"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Okategoriserad"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Du anger hur viktiga aviseringarna är."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Detta är viktigt på grund av personerna som deltar."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Tillåter du att <xliff:g id="APP">%1$s</xliff:g> skapar en ny användare för <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Tillåter du att <xliff:g id="APP">%1$s</xliff:g> skapar en ny användare för <xliff:g id="ACCOUNT">%2$s</xliff:g> (det finns redan en användare med det här kontot)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Tillåter du att <xliff:g id="APP">%1$s</xliff:g> skapar en ny användare för <xliff:g id="ACCOUNT">%2$s</xliff:g> (det finns redan en användare med det här kontot)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Tillåter du att <xliff:g id="APP">%1$s</xliff:g> skapar en ny användare för <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Lägg till ett språk"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Regionsinställningar"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Ange språket"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index eb9ab2f..6320768 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Gusa ili uone mitandao yote"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Unganisha"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Mitandao yote"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Je, ungependa kuunganisha kwenye mitandao ya Wi-Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Imependekezwa na <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ndiyo"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Hapana"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Ungependa kuruhusu mitandao inayopendekezwa ya Wi-Fi?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Mitandao inayopendekezwa kwa ajili ya <xliff:g id="NAME">%s</xliff:g>. Huenda kifaa kikaunganisha kiotomatiki."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Ruhusu"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Hapana, asante"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi itawashwa kiotomatiki"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Unapokuwa karibu na mtandao uliohifadhiwa wenye ubora wa juu"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Usiwashe tena"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Ambazo aina haijabainishwa"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Uliweka mipangilio ya umuhimu wa arifa hizi."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Hii ni muhimu kwa sababu ya watu waliohusika."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Ungependa kuruhusu <xliff:g id="APP">%1$s</xliff:g> iunde Mtumiaji mpya ikitumia <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Ungependa kuruhusu <xliff:g id="APP">%1$s</xliff:g> iunde Mtumiaji mpya ikitumia <xliff:g id="ACCOUNT">%2$s</xliff:g> (Je, akaunti hii tayari ina Mtumiaji)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Ruhusu <xliff:g id="APP">%1$s</xliff:g> iweke Mtumiaji mpya ikitumia <xliff:g id="ACCOUNT">%2$s</xliff:g> (Je, tayari kuna mtumiaji anayetumia akaunti hii)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Ungependa kuruhusu <xliff:g id="APP">%1$s</xliff:g> iweke Mtumiaji mpya ikitumia <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Ongeza lugha"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Mapendeleo ya eneo"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Weka jina la lugha"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index fb815de..a76538b 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -220,7 +220,7 @@
     <string name="reboot_safemode_title" msgid="7054509914500140361">"பாதுகாப்பான பயன்முறைக்கு மீண்டும் தொடங்கவும்"</string>
     <string name="reboot_safemode_confirm" msgid="55293944502784668">"பாதுகாப்பான பயன்முறைக்குச் செல்ல மீண்டும் துவக்க விரும்புகிறீர்களா? நீங்கள் நிறுவிய எல்லா மூன்றாம் தரப்பு பயன்பாடுகளையும் இது முடக்கும். நீங்கள் மீண்டும் மறுதொடக்கம் செய்யும்போது அவை மீட்டமைக்கப்படும்."</string>
     <string name="recent_tasks_title" msgid="3691764623638127888">"சமீபத்தியவை"</string>
-    <string name="no_recent_tasks" msgid="8794906658732193473">"சமீபத்திய பயன்பாடுகள் எதுவுமில்லை."</string>
+    <string name="no_recent_tasks" msgid="8794906658732193473">"சமீபத்திய ஆப்ஸ் எதுவுமில்லை."</string>
     <string name="global_actions" product="tablet" msgid="408477140088053665">"டேப்லெட் விருப்பங்கள்"</string>
     <string name="global_actions" product="tv" msgid="7240386462508182976">"டிவி விருப்பங்கள்"</string>
     <string name="global_actions" product="default" msgid="2406416831541615258">"தொலைபேசி விருப்பங்கள்"</string>
@@ -270,7 +270,7 @@
     <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"ஆப்ஸ் இயங்குகிறது"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"பேட்டரியைப் பயன்படுத்தும் ஆப்ஸ்"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் பேட்டரியைப் பயன்படுத்துகிறது"</string>
-    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> பயன்பாடுகள் பேட்டரியைப் பயன்படுத்துகின்றன"</string>
+    <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ஆப்ஸ் பேட்டரியைப் பயன்படுத்துகின்றன"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"பேட்டரி மற்றும் டேட்டா உபயோக விவரங்களைக் காண, தட்டவும்"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"பாதுகாப்பு பயன்முறை"</string>
@@ -340,33 +340,33 @@
     <string name="permlab_answerPhoneCalls" msgid="4077162841226223337">"ஃபோன் அழைப்புகளுக்குப் பதிலளி"</string>
     <string name="permdesc_answerPhoneCalls" msgid="2901889867993572266">"உள்வரும் ஃபோன் அழைப்பிற்குப் பதிலளிக்க, ஆப்ஸை அனுமதிக்கும்."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"உரைச் செய்திகளை (SMS) பெறுதல்"</string>
-    <string name="permdesc_receiveSms" msgid="6424387754228766939">"SMS செய்திகளைப் பெற, செயற்படுத்தப் ஆப்ஸை அனுமதிக்கிறது. இதற்கு அர்த்தம் உங்கள் சாதனத்திற்கு அனுப்பப்படும் செய்திகளை உங்களுக்குக் காட்டாமல் கண்காணிப்பதற்கு அல்லது நீக்குவதற்குப் பயன்பாட்டால் முடியும் என்பதாகும்."</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"SMS செய்திகளைப் பெற, செயற்படுத்தப் ஆப்ஸை அனுமதிக்கிறது. இதற்கு அர்த்தம் உங்கள் சாதனத்திற்கு அனுப்பப்படும் செய்திகளை உங்களுக்குக் காட்டாமல் கண்காணிப்பதற்கு அல்லது நீக்குவதற்கு ஆப்ஸால் முடியும் என்பதாகும்."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"உரைச் செய்திகளை (MMS) பெறுதல்"</string>
-    <string name="permdesc_receiveMms" msgid="533019437263212260">"MMS செய்திகளைப் பெற, செயற்படுத்தப் ஆப்ஸை அனுமதிக்கிறது. இதற்கு அர்த்தம் உங்கள் சாதனத்திற்கு அனுப்பப்படும் செய்திகளை உங்களுக்குக் காட்டாமல் கண்காணிக்கவோ, நீக்கவோ பயன்பாட்டால் முடியும் என்பதாகும்."</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"MMS செய்திகளைப் பெற, செயற்படுத்தப் ஆப்ஸை அனுமதிக்கிறது. இதற்கு அர்த்தம் உங்கள் சாதனத்திற்கு அனுப்பப்படும் செய்திகளை உங்களுக்குக் காட்டாமல் கண்காணிக்கவோ, நீக்கவோ ஆப்ஸால் முடியும் என்பதாகும்."</string>
     <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"செல் அலைபரப்புச் செய்திகளைப் படித்தல்"</string>
-    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"உங்கள் சாதனத்தில் பெறப்படும் செல் அலைபரப்புச் செய்திகளைப் படிப்பதற்குப் ஆப்ஸை அனுமதிக்கிறது. அவசரநிலை சூழ்நிலைகளை உங்களுக்கு எச்சரிக்கைச் செய்வதற்கு சில இடங்களில் செல் அலைபரப்பு விழிப்பூட்டல்கள் வழங்கப்படும். அவசரநிலை மொபைல் அலைபரப்புப் பெறப்படும்போது உங்கள் சாதனத்தின் செயல்திறன் அல்லது செயல்பாட்டுடன் தீங்கிழைக்கும் பயன்பாடுகள் அதைத் தடுக்கலாம்."</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"உங்கள் சாதனத்தில் பெறப்படும் செல் அலைபரப்புச் செய்திகளைப் படிப்பதற்குப் ஆப்ஸை அனுமதிக்கிறது. அவசரநிலை சூழ்நிலைகளை உங்களுக்கு எச்சரிக்கைச் செய்வதற்கு சில இடங்களில் செல் அலைபரப்பு விழிப்பூட்டல்கள் வழங்கப்படும். அவசரநிலை மொபைல் அலைபரப்புப் பெறப்படும்போது உங்கள் சாதனத்தின் செயல்திறன் அல்லது செயல்பாட்டுடன் தீங்கிழைக்கும் ஆப்ஸ் அதைத் தடுக்கலாம்."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"குழுசேர்ந்த ஊட்டங்களைப் படித்தல்"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"தற்போது ஒத்திசைந்த ஊட்டங்களைப் பற்றிய விவரங்களைப் பெற ஆப்ஸை அனுமதிக்கிறது."</string>
     <string name="permlab_sendSms" msgid="7544599214260982981">"SMS செய்திகளை அனுப்புதல் மற்றும் பார்த்தல்"</string>
-    <string name="permdesc_sendSms" msgid="7094729298204937667">"SMS செய்திகளை அனுப்ப ஆப்ஸை அனுமதிக்கிறது. இதற்கு எதிர்பாராத பேமெண்ட்கள் விதிக்கப்படலாம். தீங்கு விளைவிக்கும் பயன்பாடுகள் உங்களின் உறுதிப்படுத்தல் எதுவுமின்றி செய்திகளை அனுப்பி உங்களுக்குக் கட்டணம் விதிக்கலாம்."</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"SMS செய்திகளை அனுப்ப ஆப்ஸை அனுமதிக்கிறது. இதற்கு எதிர்பாராத பேமெண்ட்கள் விதிக்கப்படலாம். தீங்கு விளைவிக்கும் ஆப்ஸ் உங்களின் உறுதிப்படுத்தல் எதுவுமின்றி செய்திகளை அனுப்பி உங்களுக்குக் கட்டணம் விதிக்கலாம்."</string>
     <string name="permlab_readSms" msgid="8745086572213270480">"உங்கள் உரைச் செய்திகளை (SMS அல்லது MMS) படித்தல்"</string>
     <string name="permdesc_readSms" product="tablet" msgid="4741697454888074891">"இந்த ஆப்ஸ் உங்கள் டேப்லெட்டில் சேமிக்கப்பட்டுள்ள எல்லா SMS (உரை) செய்திகளையும் படிக்கலாம்."</string>
     <string name="permdesc_readSms" product="tv" msgid="5796670395641116592">"இந்த ஆப்ஸ் உங்கள் டிவியில் சேமிக்கப்பட்டுள்ள எல்லா SMS (உரை) செய்திகளையும் படிக்கலாம்."</string>
     <string name="permdesc_readSms" product="default" msgid="6826832415656437652">"இந்த ஆப்ஸ் உங்கள் மொபைலில் சேமிக்கப்பட்டுள்ள எல்லா SMS (உரை) செய்திகளையும் படிக்கலாம்."</string>
     <string name="permlab_receiveWapPush" msgid="5991398711936590410">"உரைச் செய்திகளைப் (WAP) பெறுதல்"</string>
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAP செய்திகளைப் பெற, செயற்படுத்தப் ஆப்ஸை அனுமதிக்கிறது. உங்களுக்கு அனுப்பப்படும் செய்திகளை உங்களுக்குக் காட்டாமல் கண்காணிக்க அல்லது நீக்குவதற்கான திறன் இந்த அனுமதியில் உள்ளடங்கும்."</string>
-    <string name="permlab_getTasks" msgid="6466095396623933906">"இயங்கும் பயன்பாடுகளை மீட்டெடுத்தல்"</string>
-    <string name="permdesc_getTasks" msgid="7454215995847658102">"நடப்பில் மற்றும் சமீபத்தில் இயங்கும் காரியங்களின் தகவலைப் பெற ஆப்ஸை அனுமதிக்கிறது. சாதனத்தில் எந்தப் பயன்பாடுகள் பயன்படுத்தப்படுகின்றன என்பது குறித்த தகவலைக் கண்டறிய ஆப்ஸை இது அனுமதிக்கலாம்."</string>
+    <string name="permlab_getTasks" msgid="6466095396623933906">"இயங்கும் ஆப்ஸை மீட்டெடுத்தல்"</string>
+    <string name="permdesc_getTasks" msgid="7454215995847658102">"நடப்பில் மற்றும் சமீபத்தில் இயங்கும் காரியங்களின் தகவலைப் பெற ஆப்ஸை அனுமதிக்கிறது. சாதனத்தில் எந்த ஆப்ஸ் பயன்படுத்தப்படுகின்றன என்பது குறித்த தகவலைக் கண்டறிய ஆப்ஸை இது அனுமதிக்கலாம்."</string>
     <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"சுயவிவரத்தையும் சாதன உரிமையாளர்களையும் நிர்வகித்தல்"</string>
-    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"சுயவிவர உரிமையாளர்களையும் சாதன உரிமையாளரையும் அமைக்க, பயன்பாடுகளை அனுமதிக்கிறது."</string>
-    <string name="permlab_reorderTasks" msgid="2018575526934422779">"இயங்கும் பயன்பாடுகளை மறுவரிசைப்படுத்தல்"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"சுயவிவர உரிமையாளர்களையும் சாதன உரிமையாளரையும் அமைக்க, ஆப்ஸை அனுமதிக்கிறது."</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"இயங்கும் ஆப்ஸை மறுவரிசைப்படுத்தல்"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"பின்புலத்திலும், முன்புலத்திலும் காரியங்களை நகர்த்த ஆப்ஸை அனுமதிக்கிறது. உங்கள் உள்ளீடு இல்லாமலே ஆப்ஸ் இதைச் செய்யலாம்."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"கார் பயன்முறையை இயக்குதல்"</string>
     <string name="permdesc_enableCarMode" msgid="4853187425751419467">"கார் முறையை இயக்க, ஆப்ஸை அனுமதிக்கிறது."</string>
-    <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"பிற பயன்பாடுகளை மூடுதல்"</string>
-    <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"பிற பயன்பாடுகளின் பின்புலச் செயல்முறைகளை நிறுத்த ஆப்ஸை அனுமதிக்கிறது. இதனால் பிற பயன்பாடுகள் இயங்குவதை நிறுத்தலாம்."</string>
-    <string name="permlab_systemAlertWindow" msgid="7238805243128138690">"இந்த ஆப்ஸ் பிற பயன்பாடுகளின் மேலே தோன்றலாம்"</string>
-    <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"இந்த ஆப்ஸ் பிற பயன்பாடுகளின் மேலே அல்லது திரையின் பிற பகுதிகளில் தோன்றலாம். இது வழக்கமான ஆப்ஸ் உபயோகத்தில் குறுக்கிட்டு, பிற பயன்பாடுகள் தோன்றும் விதத்தை மாற்றக்கூடும்."</string>
+    <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"பிற ஆப்ஸை மூடுதல்"</string>
+    <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"பிற ஆப்ஸின் பின்புலச் செயல்முறைகளை நிறுத்த ஆப்ஸை அனுமதிக்கிறது. இதனால் பிற ஆப்ஸ் இயங்குவதை நிறுத்தலாம்."</string>
+    <string name="permlab_systemAlertWindow" msgid="7238805243128138690">"இந்த ஆப்ஸ் பிற ஆப்ஸின் மேலே தோன்றலாம்"</string>
+    <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"இந்த ஆப்ஸ் பிற ஆப்ஸின் மேலே அல்லது திரையின் பிற பகுதிகளில் தோன்றலாம். இது வழக்கமான ஆப்ஸ் உபயோகத்தில் குறுக்கிட்டு, பிற ஆப்ஸ் தோன்றும் விதத்தை மாற்றக்கூடும்."</string>
     <string name="permlab_runInBackground" msgid="7365290743781858803">"பின்னணியில் இயக்கு"</string>
     <string name="permdesc_runInBackground" msgid="7370142232209999824">"இந்த ஆப்ஸ், பின்னணியில் இயங்கலாம். இதனால் பேட்டரி விரைவாகத் தீர்ந்துவிடக்கூடும்."</string>
     <string name="permlab_useDataInBackground" msgid="8694951340794341809">"பின்னணியில் தரவைப் பயன்படுத்து"</string>
@@ -380,7 +380,7 @@
     <string name="permlab_getPackageSize" msgid="7472921768357981986">"பயன்பாட்டுச் சேமிப்பு இடத்தை அளவிடல்"</string>
     <string name="permdesc_getPackageSize" msgid="3921068154420738296">"ஆப்ஸ், அதன் குறியீடு, தரவு, மற்றும் தற்காலிகச் சேமிப்பு அளவுகளை மீட்டெடுக்க அனுமதிக்கிறது"</string>
     <string name="permlab_writeSettings" msgid="2226195290955224730">"சாதன அமைப்புகளை மாற்றுதல்"</string>
-    <string name="permdesc_writeSettings" msgid="7775723441558907181">"முறைமையின் அமைப்பு தரவைத் திருத்த, ஆப்ஸை அனுமதிக்கிறது. தீங்குவிளைவிக்கும் பயன்பாடுகள், முறைமையின் உள்ளமைவைச் சிதைக்கலாம்."</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"முறைமையின் அமைப்பு தரவைத் திருத்த, ஆப்ஸை அனுமதிக்கிறது. தீங்குவிளைவிக்கும் ஆப்ஸ், முறைமையின் உள்ளமைவைச் சிதைக்கலாம்."</string>
     <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"தொடக்கத்தில் இயக்குதல்"</string>
     <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"மறுஇயக்கம் முடிந்தது, விரைவில் தானாகவே தொடங்க, ஆப்ஸை அனுமதிக்கிறது. இதனால் டேப்லெட் நீண்ட நேரம் கழித்து தொடங்கும் மற்றும் எப்போதும் இயங்குகின்ற டேப்லெட்டின் ஒட்டுமொத்தச் செயல்பாட்டையும் தாமதமாகும்."</string>
     <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"சாதனம் தொடங்குவது முடிந்தவுடன், ஆப்ஸ் தானாகவே விரைவில் தொடங்க அனுமதிக்கிறது. இது டிவி தொடங்குவதற்கான நேரத்தைத் தாமதமாக்குவதோடு, எப்போதும் இயங்கிக்கொண்டிருப்பதன் மூலம் ஒட்டுமொத்த டேப்லெட்டின் வேகத்தைக் குறைக்க, ஆப்ஸை அனுமதிக்கிறது."</string>
@@ -390,21 +390,21 @@
     <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"அலைபரப்பு முடிந்த பின்னரும் தங்கிவிடும் ஸ்டிக்கி அலைபரப்புகளை அனுப்ப, ஆப்ஸை அனுமதிக்கிறது. அளவுக்கதிகமான உபயோகமானது, டிவியின் வேகத்தைக் குறைக்கலாம் அல்லது அதிகமான நினைவகம் பயன்பட்டால் நிலையற்றதாகலாம்."</string>
     <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"அலைபரப்பு முடிந்த பின்னும் இருக்கும், தொடர்ந்து அணுகத்தக்க அலைபரப்பை அனுப்பப் ஆப்ஸை அனுமதிக்கிறது. அதிகமாகப் பயன்படுத்தினால், மொபைலானது நினைவகத்தை மிக அதிகமாகப் பயன்படுத்துவதால் வேகம் குறைந்ததாகவும், நிலையற்றதாகவும் ஆகலாம்."</string>
     <string name="permlab_readContacts" msgid="8348481131899886131">"உங்கள் தொடர்புகளைப் படித்தல்"</string>
-    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"குறிப்பிட்டவர்களுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்டதின் எண்ணிக்கை உட்பட, உங்கள் டேப்லெட்டில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைப் படிக்க ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதி, உங்கள் தொடர்பு தரவைச் சேமிக்க பயன்பாடுகளை அனுமதிக்கிறது, மேலும் தீங்கிழைக்கும் பயன்பாடுகள் உங்களுக்குத் தெரியாமல் தொடர்பு தரவைப் பகிரலாம்."</string>
-    <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"உங்கள் டிவியில் சேமிக்கப்பட்ட தொடர்புகள் பற்றிய தரவைப் படிக்க, ஆப்ஸை அனுமதிக்கிறது, இதில் குறிப்பிட்ட தனிநபர் எண்ணை எத்தனைமுறை அழைத்தீர்கள், மின்னஞ்சல் செய்தீர்கள் அல்லது பிறவழிகளில் தொடர்புகொண்டீர்கள் என்பதும் அடங்கும். இந்த அனுமதியானது உங்கள் தொடர்புத் தரவைச் சேமிக்கப் ஆப்ஸை அனுமதிக்கிறது மற்றும் தீங்குவிளைவிக்கும் பயன்பாடுகள் உங்கள் அனுமதியின்றி தொடர்புத் தரவைப் பகிரலாம்."</string>
-    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"குறிப்பிட்டவர்களுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்ட எண்ணிக்கை உட்பட, உங்கள் மொபைலில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைப் படிக்க ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதி, உங்கள் தொடர்பு தரவைச் சேமிக்க பயன்பாடுகளை அனுமதிக்கிறது, மேலும் தீங்கிழைக்கும் பயன்பாடுகள் உங்களுக்குத் தெரியாமல் தொடர்பு தரவைப் பகிரலாம்."</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"குறிப்பிட்டவர்களுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்டதின் எண்ணிக்கை உட்பட, உங்கள் டேப்லெட்டில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைப் படிக்க ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதி, உங்கள் தொடர்பு தரவைச் சேமிக்க ஆப்ஸை அனுமதிக்கிறது, மேலும் தீங்கிழைக்கும் ஆப்ஸ் உங்களுக்குத் தெரியாமல் தொடர்பு தரவைப் பகிரலாம்."</string>
+    <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"உங்கள் டிவியில் சேமிக்கப்பட்ட தொடர்புகள் பற்றிய தரவைப் படிக்க, ஆப்ஸை அனுமதிக்கிறது, இதில் குறிப்பிட்ட தனிநபர் எண்ணை எத்தனைமுறை அழைத்தீர்கள், மின்னஞ்சல் செய்தீர்கள் அல்லது பிறவழிகளில் தொடர்புகொண்டீர்கள் என்பதும் அடங்கும். இந்த அனுமதியானது உங்கள் தொடர்புத் தரவைச் சேமிக்கப் ஆப்ஸை அனுமதிக்கிறது மற்றும் தீங்குவிளைவிக்கும் ஆப்ஸ் உங்கள் அனுமதியின்றி தொடர்புத் தரவைப் பகிரலாம்."</string>
+    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"குறிப்பிட்டவர்களுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்ட எண்ணிக்கை உட்பட, உங்கள் மொபைலில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைப் படிக்க ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதி, உங்கள் தொடர்பு தரவைச் சேமிக்க ஆப்ஸை அனுமதிக்கிறது, மேலும் தீங்கிழைக்கும் ஆப்ஸ் உங்களுக்குத் தெரியாமல் தொடர்பு தரவைப் பகிரலாம்."</string>
     <string name="permlab_writeContacts" msgid="5107492086416793544">"உங்கள் தொடர்புகளை மாற்றுதல்"</string>
-    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"குறிப்பிட்ட தொடர்புகளுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்டதின் எண்ணிக்கை உள்பட, உங்கள் டேப்லெட்டில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைத் திருத்த ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதியானது தொடர்புத் தரவை நீக்கப் பயன்பாடுகளை அனுமதிக்கிறது."</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"குறிப்பிட்ட தொடர்புகளுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்டதின் எண்ணிக்கை உள்பட, உங்கள் டேப்லெட்டில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைத் திருத்த ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதியானது தொடர்புத் தரவை நீக்க ஆப்ஸை அனுமதிக்கிறது."</string>
     <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"உங்கள் டிவியில் சேமிக்கப்பட்ட தொடர்புகள் பற்றிய தரவை மாற்ற, ஆப்ஸை அனுமதிக்கிறது, இதில் குறிப்பிட்ட தொடர்பை எத்தனைமுறை அழைத்தீர்கள், மின்னஞ்சல் செய்தீர்கள் அல்லது பிறவழிகளில் தொடர்புகொண்டீர்கள் என்பதும் அடங்கும். இது தொடர்புத் தரவை நீக்க, ஆப்ஸை அனுமதிக்கிறது."</string>
-    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"குறிப்பிட்ட தொடர்புகளுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்டதின் எண்ணிக்கை உள்பட, உங்கள் மொபைலில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைத் திருத்த ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதியானது தொடர்புத் தரவை நீக்கப் பயன்பாடுகளை அனுமதிக்கிறது."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"குறிப்பிட்ட தொடர்புகளுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்டதின் எண்ணிக்கை உள்பட, உங்கள் மொபைலில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைத் திருத்த ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதியானது தொடர்புத் தரவை நீக்க ஆப்ஸை அனுமதிக்கிறது."</string>
     <string name="permlab_readCallLog" msgid="3478133184624102739">"அழைப்புப் பதிவைப் படித்தல்"</string>
     <string name="permdesc_readCallLog" msgid="3204122446463552146">"இந்த ஆப்ஸ் உங்கள் அழைப்பு வரலாற்றைப் படிக்கலாம்."</string>
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"அழைப்புப் பதிவை எழுதுதல்"</string>
-    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"உள்வரும் மற்றும் வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உள்பட உங்கள் டேப்லெட்டின் அழைப்புப் பதிவைத் திருத்துவதற்குப் ஆப்ஸை அனுமதிக்கிறது. உங்கள் அழைப்பின் பதிவை அழிக்க அல்லது திருத்த தீங்கு விளைவிக்கும் பயன்பாடுகள் இதைப் பயன்படுத்தலாம்."</string>
-    <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"உள்வரும் மற்றும் வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உள்ளிட்ட உங்கள் டிவியின் அழைப்பு பதிவைத் திருத்த, ஆப்ஸை அனுமதிக்கிறது. உங்கள் அழைப்பு பதிவை அழிக்க அல்லது திருத்த தீங்கு விளைவிக்கும் பயன்பாடுகள் இதைப் பயன்படுத்தலாம்."</string>
-    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"உள்வரும் மற்றும் வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உள்பட உங்கள் மொபைல் அழைப்புப் பதிவைத் திருத்துவதற்குப் ஆப்ஸை அனுமதிக்கிறது. உங்கள் அழைப்பின் பதிவை அழிக்க அல்லது திருத்த தீங்கு விளைவிக்கும் பயன்பாடுகள் இதைப் பயன்படுத்தலாம்."</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"உள்வரும் மற்றும் வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உள்பட உங்கள் டேப்லெட்டின் அழைப்புப் பதிவைத் திருத்துவதற்குப் ஆப்ஸை அனுமதிக்கிறது. உங்கள் அழைப்பின் பதிவை அழிக்க அல்லது திருத்த தீங்கு விளைவிக்கும் ஆப்ஸ் இதைப் பயன்படுத்தலாம்."</string>
+    <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"உள்வரும் மற்றும் வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உள்ளிட்ட உங்கள் டிவியின் அழைப்பு பதிவைத் திருத்த, ஆப்ஸை அனுமதிக்கிறது. உங்கள் அழைப்பு பதிவை அழிக்க அல்லது திருத்த தீங்கு விளைவிக்கும் ஆப்ஸ் இதைப் பயன்படுத்தலாம்."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"உள்வரும் மற்றும் வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உள்பட உங்கள் மொபைல் அழைப்புப் பதிவைத் திருத்துவதற்குப் ஆப்ஸை அனுமதிக்கிறது. உங்கள் அழைப்பின் பதிவை அழிக்க அல்லது திருத்த தீங்கு விளைவிக்கும் ஆப்ஸ் இதைப் பயன்படுத்தலாம்."</string>
     <string name="permlab_bodySensors" msgid="4683341291818520277">"உடல் உணர்விகளை (இதயத் துடிப்பு மானிட்டர்கள் போன்றவை) அணுகுதல்"</string>
-    <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"உங்கள் இதயத்துடிப்பு விகிதம் போன்ற உங்கள் உடல்நிலையைக் கண்காணிக்கும் உணர்விகளில் இருந்து தரவை அணுக பயன்பாடுகளை அனுமதிக்கும்."</string>
+    <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"உங்கள் இதயத்துடிப்பு விகிதம் போன்ற உங்கள் உடல்நிலையைக் கண்காணிக்கும் உணர்விகளில் இருந்து தரவை அணுக ஆப்ஸை அனுமதிக்கும்."</string>
     <string name="permlab_readCalendar" msgid="6716116972752441641">"கேலெண்டர் நிகழ்வுகளையும் விவரங்களையும் படிக்கலாம்"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="4993979255403945892">"இந்த ஆப்ஸ் உங்கள் டேப்லெட்டில் சேமிக்கப்பட்டுள்ள கேலெண்டர் நிகழ்வுகள் அனைத்தையும் படிக்கலாம், உங்கள் கேலெண்டர் தரவைப் பகிரலாம் அல்லது சேமிக்கலாம்."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="8837931557573064315">"இந்த ஆப்ஸ் உங்கள் டிவியில் சேமிக்கப்பட்டுள்ள எல்லா கேலெண்டர் நிகழ்வுகளையும் படிக்கலாம், உங்கள் கேலெண்டர் தரவைப் பகிரலாம் அல்லது சேமிக்கலாம்."</string>
@@ -436,7 +436,7 @@
     <string name="permlab_vibrate" msgid="7696427026057705834">"அதிர்வைக் கட்டுப்படுத்துதல்"</string>
     <string name="permdesc_vibrate" msgid="6284989245902300945">"அதிர்வைக் கட்டுப்படுத்தப் ஆப்ஸை அனுமதிக்கிறது."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"தொலைபேசி எண்களை நேரடியாக அழைத்தல்"</string>
-    <string name="permdesc_callPhone" msgid="3740797576113760827">"உங்கள் தலையீட்டின்றி மொபைல் எண்களை அழைக்கப் ஆப்ஸை அனுமதிக்கிறது. இதன் விளைவாக எதிர்பாராத கட்டணங்களோ அழைப்புகளோ ஏற்படலாம். அவசரகால எண்களை அழைக்க இது ஆப்ஸை அனுமதிக்காது என்பதை நினைவில்கொள்ளவும். தீங்கிழைக்கும் பயன்பாடுகள், உங்கள் உறுதிப்படுத்தல் இன்றி அழைப்புகளைச் செய்வதால் உங்களுக்குச் செலவு ஏற்படக்கூடும்."</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"உங்கள் தலையீட்டின்றி மொபைல் எண்களை அழைக்கப் ஆப்ஸை அனுமதிக்கிறது. இதன் விளைவாக எதிர்பாராத கட்டணங்களோ அழைப்புகளோ ஏற்படலாம். அவசரகால எண்களை அழைக்க இது ஆப்ஸை அனுமதிக்காது என்பதை நினைவில்கொள்ளவும். தீங்கிழைக்கும் ஆப்ஸ், உங்கள் உறுதிப்படுத்தல் இன்றி அழைப்புகளைச் செய்வதால் உங்களுக்குச் செலவு ஏற்படக்கூடும்."</string>
     <string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS அழைப்புச் சேவையை அணுகுதல்"</string>
     <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"உங்கள் குறுக்கீடின்றி IMS சேவையைப் பயன்படுத்தி அழைப்பதற்கு, ஆப்ஸை அனுமதிக்கும்."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"மொபைல் நிலை மற்றும் அடையாளத்தைப் படித்தல்"</string>
@@ -936,15 +936,15 @@
     <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"உங்கள் இணையப் புத்தக்கக்குறிகள் மற்றும் வரலாற்றைப் படித்தல்"</string>
     <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"உலாவி மூலம் பார்வையிட்ட எல்லா URLகளின் வரலாற்றையும், உலாவியில் குறிக்கப்பட்ட எல்லா புத்தகக்குறிகளையும் படிக்கப் ஆப்ஸை அனுமதிக்கிறது. குறிப்பு: மூன்றாம் தரப்பு உலாவிகள் அல்லது இணைய உலாவல் திறன்களுடன் கூடிய பிற பயன்பாடுகளால் இந்த அனுமதி செயற்படுத்தப்படாமல் போகலாம்."</string>
     <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"இணையப் புத்தகக்குறிகளையும், வரலாற்றையும் எழுதுதல்"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"உங்கள் டேப்லெட்டில் சேமிக்கப்பட்ட உலாவியின் வரலாறு அல்லது புத்தகக்குறிகளைத் திருத்த ஆப்ஸை அனுமதிக்கிறது. இது உலாவியின் தரவை அழிக்கவோ, திருத்தவோ ஆப்ஸை அனுமதிக்கலாம். குறிப்பு: இணைய உலாவல் செயல்திறன்கள் மூலம் மூன்றாம் தரப்பு உலாவிகள் அல்லது பிற பயன்பாடுகள் இந்த அனுமதியைச் செயற்படுத்த முடியாது."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"டிவியில் சேமிக்கப்பட்ட உலாவியின் வரலாறு அல்லது புத்தகக்குறிகளைத் திருத்த, ஆப்ஸை அனுமதிக்கிறது. இது உலாவியின் தரவை அழிக்க அல்லது திருத்த ஆப்ஸை அனுமதிக்கலாம். குறிப்பு: இந்த அனுமதி, மூன்றாம் தரப்பு உலாவிகள் அல்லது இணைய உலாவல் திறன்களுடன் கூடிய பிற பயன்பாடுகள் போன்றவற்றில் செயல்படாமல் போகலாம்."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"உங்கள் மொபைலில் சேமிக்கப்பட்ட உலாவியின் வரலாறு அல்லது புத்தகக்குறிகளைத் திருத்த ஆப்ஸை அனுமதிக்கிறது. இது உலாவியின் தரவை அழிக்கவோ, திருத்தவோ ஆப்ஸை அனுமதிக்கலாம். குறிப்பு: இணைய உலாவல் செயல்திறன்கள் மூலம் மூன்றாம் தரப்பு உலாவிகள் அல்லது பிற பயன்பாடுகள் இந்த அனுமதியைச் செயற்படுத்த முடியாது."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"உங்கள் டேப்லெட்டில் சேமிக்கப்பட்ட உலாவியின் வரலாறு அல்லது புத்தகக்குறிகளைத் திருத்த ஆப்ஸை அனுமதிக்கிறது. இது உலாவியின் தரவை அழிக்கவோ, திருத்தவோ ஆப்ஸை அனுமதிக்கலாம். குறிப்பு: இணைய உலாவல் செயல்திறன்கள் மூலம் மூன்றாம் தரப்பு உலாவிகள் அல்லது பிற ஆப்ஸ் இந்த அனுமதியைச் செயற்படுத்த முடியாது."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"டிவியில் சேமிக்கப்பட்ட உலாவியின் வரலாறு அல்லது புத்தகக்குறிகளைத் திருத்த, ஆப்ஸை அனுமதிக்கிறது. இது உலாவியின் தரவை அழிக்க அல்லது திருத்த ஆப்ஸை அனுமதிக்கலாம். குறிப்பு: இந்த அனுமதி, மூன்றாம் தரப்பு உலாவிகள் அல்லது இணைய உலாவல் திறன்களுடன் கூடிய பிற ஆப்ஸ் போன்றவற்றில் செயல்படாமல் போகலாம்."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"உங்கள் மொபைலில் சேமிக்கப்பட்ட உலாவியின் வரலாறு அல்லது புத்தகக்குறிகளைத் திருத்த ஆப்ஸை அனுமதிக்கிறது. இது உலாவியின் தரவை அழிக்கவோ, திருத்தவோ ஆப்ஸை அனுமதிக்கலாம். குறிப்பு: இணைய உலாவல் செயல்திறன்கள் மூலம் மூன்றாம் தரப்பு உலாவிகள் அல்லது பிற ஆப்ஸ் இந்த அனுமதியைச் செயற்படுத்த முடியாது."</string>
     <string name="permlab_setAlarm" msgid="1379294556362091814">"அலாரத்தை அமைத்தல்"</string>
     <string name="permdesc_setAlarm" msgid="316392039157473848">"நிறுவிய அலார கடிகாரப் பயன்பாட்டில் அலாரத்தை அமைக்க, ஆப்ஸை அனுமதிக்கிறது. சில அலார கடிகார பயன்பாடுகளில் இந்த அம்சம் இல்லாமல் இருக்கலாம்."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"குரலஞ்சலைச் சேர்த்தல்"</string>
     <string name="permdesc_addVoicemail" msgid="6604508651428252437">"குரலஞ்சல் இன்பாக்ஸில் செய்திகளைச் சேர்க்க, ஆப்ஸை அனுமதிக்கிறது."</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"உலாவியின் புவியியல் இருப்பிடம் சார்ந்த அனுமதிகளைத் திருத்துதல்"</string>
-    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"உலாவியின் புவியியல் இருப்பிடம் சார்ந்த அனுமதிகளைத் திருத்த, ஆப்ஸை அனுமதிக்கிறது. இடத் தகவலை தன்னிச்சையான இணையதளங்களுக்கு அனுப்புவதை அனுமதிக்க, தீங்குவிளைவிக்கும் பயன்பாடுகள் இதைப் பயன்படுத்தலாம்."</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"உலாவியின் புவியியல் இருப்பிடம் சார்ந்த அனுமதிகளைத் திருத்த, ஆப்ஸை அனுமதிக்கிறது. இடத் தகவலை தன்னிச்சையான இணையதளங்களுக்கு அனுப்புவதை அனுமதிக்க, தீங்குவிளைவிக்கும் ஆப்ஸ் இதைப் பயன்படுத்தலாம்."</string>
     <string name="save_password_message" msgid="767344687139195790">"இந்தக் கடவுச்சொல்லை உலாவி நினைவில்கொள்ள விரும்புகிறீர்களா?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"இப்போது இல்லை"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"நினைவில்கொள்"</string>
@@ -1153,10 +1153,10 @@
     <string name="whichImageCaptureApplicationLabel" msgid="6390303445371527066">"படமெடு"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"இந்தச் செயலுக்கு இயல்பாகப் பயன்படுத்து."</string>
     <string name="use_a_different_app" msgid="8134926230585710243">"வேறு ஆப்ஸைப் பயன்படுத்தவும்"</string>
-    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"முறைமை அமைப்பு &gt; பயன்பாடுகள் &gt; பதிவிறக்கியவை என்பதில் உள்ள இயல்பை அழிக்கவும்."</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"முறைமை அமைப்பு &gt; ஆப்ஸ் &gt; பதிவிறக்கியவை என்பதில் உள்ள இயல்பை அழிக்கவும்."</string>
     <string name="chooseActivity" msgid="7486876147751803333">"செயலைத் தேர்ந்தெடுக்கவும்"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"USB சாதனத்திற்கான பயன்பாட்டைத் தேர்வுசெய்க"</string>
-    <string name="noApplications" msgid="2991814273936504689">"இந்தச் செயலைச் செய்ய பயன்பாடுகள் எதுவுமில்லை."</string>
+    <string name="noApplications" msgid="2991814273936504689">"இந்தச் செயலைச் செய்ய ஆப்ஸ் எதுவுமில்லை."</string>
     <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g> செயலிழந்தது"</string>
     <string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> செயலிழந்தது"</string>
     <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> தொடர்ந்து செயலிழக்கிறது"</string>
@@ -1181,7 +1181,7 @@
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> உண்மையாக வெளியிடப்பட்டது."</string>
     <string name="screen_compat_mode_scale" msgid="3202955667675944499">"அளவு"</string>
     <string name="screen_compat_mode_show" msgid="4013878876486655892">"எப்போதும் காட்டு"</string>
-    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"சிஸ்டம் அமைப்பு &gt; பயன்பாடுகள் &gt; பதிவிறக்கம் என்பதில் இதை மீண்டும் இயக்கவும்."</string>
+    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"சிஸ்டம் அமைப்பு &gt; ஆப்ஸ் &gt; பதிவிறக்கம் என்பதில் இதை மீண்டும் இயக்கவும்."</string>
     <string name="unsupported_display_size_message" msgid="6545327290756295232">"தற்போதைய திரை அளவு அமைப்பை <xliff:g id="APP_NAME">%1$s</xliff:g> ஆதரிக்காததால், அது வழக்கத்திற்கு மாறாகச் செயல்படக்கூடும்."</string>
     <string name="unsupported_display_size_show" msgid="7969129195360353041">"எப்போதும் காட்டு"</string>
     <string name="unsupported_compile_sdk_message" msgid="4253168368781441759">"<xliff:g id="APP_NAME">%1$s</xliff:g> பயன்பாடானது, இந்தச் சாதனத்தின் Android OSக்கு இணக்கமற்ற பதிப்பிற்காக உருவாக்கப்பட்டதால், இதில் சரியாகச் செயல்படாது. இந்த ஆப்ஸின் புதுப்பிக்கப்பட்ட பதிப்பானது தற்போது கிடைக்கக்கூடும்."</string>
@@ -1201,7 +1201,7 @@
     <string name="app_upgrading_toast" msgid="3008139776215597053">"<xliff:g id="APPLICATION">%1$s</xliff:g>ஐ மேம்படுத்துகிறது…"</string>
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g> ஆப்ஸை ஒருங்கிணைக்கிறது."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g>ஐத் தயார்செய்கிறது."</string>
-    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"பயன்பாடுகள் தொடங்கப்படுகின்றன."</string>
+    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"ஆப்ஸ் தொடங்கப்படுகின்றன."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"துவக்குதலை முடிக்கிறது."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> இயங்குகிறது"</string>
     <string name="heavy_weight_notification_detail" msgid="2304833848484424985">"கேமிற்குச் செல்ல, தட்டவும்"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"எல்லா நெட்வொர்க்குகளையும் பார்க்க, தட்டவும்"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"இணை"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"எல்லா நெட்வொர்க்குகளும்"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"வைஃபை நெட்வொக்குகளுடன் இணைக்கவா?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> ஆப்ஸால் பரிந்துரைக்கப்பட்டது"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"சரி"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"வேண்டாம்"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"பரிந்துரைக்கப்பட்ட வைஃபை நெட்வொர்க்குகளை அனுமதிக்க வேண்டுமா?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> பரிந்துரைக்கும் நெட்வொர்க்குகள். சாதனம் தானாக இணைக்கப்படக்கூடும்."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"அனுமதி"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"வேண்டாம்"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"வைஃபை தானாக ஆன் ஆகும்"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"சேமித்த, உயர்தர நெட்வொர்க்கிற்கு அருகில் இருக்கும்போது"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"மீண்டும் ஆன் செய்யாதே"</string>
@@ -1320,7 +1320,7 @@
     <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"அனுப்பு"</string>
     <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"ரத்துசெய்"</string>
     <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"எனது விருப்பத்தேர்வை நினைவில்கொள்"</string>
-    <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"அமைப்பு &gt; பயன்பாடுகள் என்பதில் பிறகு நீங்கள் மாற்றலாம்"</string>
+    <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"அமைப்பு &gt; ஆப்ஸ் என்பதில் பிறகு நீங்கள் மாற்றலாம்"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"எப்போதும் அனுமதி"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"ஒருபோதும் அனுமதிக்காதே"</string>
     <string name="sim_removed_title" msgid="6227712319223226185">"சிம் கார்டு அகற்றப்பட்டது"</string>
@@ -1378,7 +1378,7 @@
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"பிற ஆப்ஸின் மேலே காட்டு"</string>
-    <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> பிற பயன்பாடுகளின் மீது தோன்றுகிறது"</string>
+    <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> பிற ஆப்ஸின் மீது தோன்றுகிறது"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> பிற ஆப்ஸின் மீது தோன்றுகிறது"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> இந்த அம்சத்தைப் பயன்படுத்த வேண்டாம் என நினைத்தால், அமைப்புகளைத் திறந்து அதை முடக்க, தட்டவும்."</string>
     <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"ஆஃப் செய்"</string>
@@ -1444,7 +1444,7 @@
     <string name="ime_action_default" msgid="2840921885558045721">"செயலாக்கு"</string>
     <string name="dial_number_using" msgid="5789176425167573586">"<xliff:g id="NUMBER">%s</xliff:g> ஐப் பயன்படுத்தி\nஅழை"</string>
     <string name="create_contact_using" msgid="4947405226788104538">"<xliff:g id="NUMBER">%s</xliff:g> ஐப்\nபயன்படுத்தி தொடர்பை உருவாக்கு"</string>
-    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"பின்வரும் ஒன்று அல்லது அதற்கு மேற்பட்ட பயன்பாடுகள், இப்போதும் எதிர்காலத்திலும் உங்கள் கணக்கை அணுகுவதற்கான அனுமதியைக் கோருகின்றன."</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"பின்வரும் ஒன்று அல்லது அதற்கு மேற்பட்ட ஆப்ஸ், இப்போதும் எதிர்காலத்திலும் உங்கள் கணக்கை அணுகுவதற்கான அனுமதியைக் கோருகின்றன."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"இந்தக் கோரிக்கையை அனுமதிக்க விரும்புகிறீர்களா?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"‍அணுகல் கோரிக்கை"</string>
     <string name="allow" msgid="7225948811296386551">"அனுமதி"</string>
@@ -1889,8 +1889,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"வகைப்படுத்தப்படாதவை"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"இந்த அறிவிப்புகளின் முக்கியத்துவத்தை அமைத்துள்ளீர்கள்."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"ஈடுபட்டுள்ளவர்களின் காரணமாக, இது முக்கியமானது."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="ACCOUNT">%2$s</xliff:g> மூலம் புதிய பயனரை உருவாக்க <xliff:g id="APP">%1$s</xliff:g>ஐ அனுமதிக்கவா?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="ACCOUNT">%2$s</xliff:g> (இந்தக் கணக்கில் ஏற்கனவே ஒரு பயனர் உள்ளார்) மூலம் புதிய பயனரை உருவாக்க <xliff:g id="APP">%1$s</xliff:g>ஐ அனுமதிக்கவா?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g> மூலம் புதிய பயனரை உருவாக்க <xliff:g id="APP">%1$s</xliff:g> ஆப்ஸை அனுமதிக்கவா (இந்தக் கணக்கில் ஏற்கெனவே ஒரு பயனர் உள்ளார்) ?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> மூலம் புதிய பயனரை உருவாக்க <xliff:g id="APP">%1$s</xliff:g> ஆப்ஸை அனுமதிக்கவா?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"மொழியைச் சேர்"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"மண்டல விருப்பம்"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"மொழி பெயரை உள்ளிடுக"</string>
@@ -1999,7 +1999,7 @@
     <string name="notification_app_name_settings" msgid="7751445616365753381">"அமைப்புகள்"</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"கேமரா"</string>
     <string name="notification_appops_microphone_active" msgid="4335305527588191730">"மைக்ரோஃபோன்"</string>
-    <string name="notification_appops_overlay_active" msgid="633813008357934729">"உங்கள் திரையில் உள்ள பிற பயன்பாடுகளின் மேல் காட்டுகிறது"</string>
+    <string name="notification_appops_overlay_active" msgid="633813008357934729">"உங்கள் திரையில் உள்ள பிற ஆப்ஸின் மேல் காட்டுகிறது"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"வழக்கமான பேட்டரி சேமிப்பானுக்கான விவர அறிவிப்பு"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"வழக்கமாகச் சார்ஜ் செய்வதற்கு முன்பே பேட்டரி தீர்ந்துபோகக்கூடும்"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"பேட்டரி நிலையை நீட்டிக்க பேட்டரி சேமிப்பான் இயக்கப்பட்டுள்ளது"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 5e2b460..6112bc5 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -291,7 +291,7 @@
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"మీ క్యాలెండర్‌ని యాక్సెస్ చేయడానికి &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ని అనుమతించాలా?"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS సందేశాలను పంపడం మరియు వీక్షించడం"</string>
-    <string name="permgrouprequest_sms" msgid="7168124215838204719">"SMS సందేశాలు పంపడానికి మరియు వీక్షించడానికి &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ని అనుమతించాలా?"</string>
+    <string name="permgrouprequest_sms" msgid="7168124215838204719">"SMS సందేశాలు పంపడం, చూడటం చేయగలిగేలా &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ను అనుమతించాలా?"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"నిల్వ"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"మీ పరికరంలోని ఫోటోలు, మీడియా మరియు ఫైల్‌లను యాక్సెస్ చేయడానికి"</string>
     <string name="permgrouprequest_storage" msgid="7885942926944299560">"మీ పరికరంలోని ఫోటోలు, మీడియా మరియు ఫైల్‌లను యాక్సెస్ చేయడానికి &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ను అనుమతించాలా?"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"అన్ని నెట్‌వర్క్‌లు చూడటానికి నొక్కండి"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"కనెక్ట్ చేయి"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"అన్ని నెట్‌వర్క్‌లు"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi‑Fi నెట్‌వర్క్‌లకు కనెక్ట్ చేయాలా?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> ద్వారా సూచించబడింది"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"అవును"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"లేదు"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"సూచించిన Wi‑Fi నెట్‌వర్క్‌లను అనుమతించాలా?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> సూచించిన నెట్‌వర్క్‌లు. పరికరం ఆటోమేటిక్‌గా కనెక్ట్ అవచ్చు."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"అనుమతించు"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"వద్దు"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi స్వయంచాలకంగా ఆన్ అవుతుంది"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"మీరు అధిక నాణ్యత గల సేవ్ చేసిన నెట్‌వర్క్‌కు సమీపంగా ఉన్నప్పుడు"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"తిరిగి ఆన్ చేయవద్దు"</string>
@@ -1328,7 +1328,7 @@
     <string name="sim_done_button" msgid="827949989369963775">"పూర్తయింది"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"సిమ్ కార్డు జోడించబడింది"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"మొబైల్ నెట్‌వర్క్‌ను యాక్సెస్ చేయడానికి మీ పరికరాన్ని పునఃప్రారంభించండి."</string>
-    <string name="sim_restart_button" msgid="4722407842815232347">"పునఃప్రారంభించు"</string>
+    <string name="sim_restart_button" msgid="4722407842815232347">"రీస్టార్ట్ చేయి"</string>
     <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"మొబైల్ సేవను సక్రియం చేయండి"</string>
     <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"మీ కొత్త SIMని సక్రియం చేయడానికి క్యారియర్ యాప్‌ను డౌన్‌లోడ్ చేయండి"</string>
     <string name="install_carrier_app_notification_text_app_name" msgid="1196505084835248137">"మీ కొత్త SIMని సక్రియం చేయడం కోసం <xliff:g id="APP_NAME">%1$s</xliff:g> యాప్‌ని డౌన్‌లోడ్ చేయండి"</string>
@@ -1671,7 +1671,7 @@
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"యాక్సెస్ సామర్థ్య షార్ట్‌కట్ ద్వారా <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆఫ్ చేయబడింది"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>ని ఉపయోగించడానికి వాల్యూమ్ కీలు రెండింటినీ 3 సెకన్లు నొక్కి ఉంచండి"</string>
     <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"యాక్సెసిబిలిటీ బటన్‌ను మీరు నొక్కినప్పుడు ఉపయోగించాల్సిన ఒక ఫీచర్‌ను ఎంచుకోండి:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"యాక్సెసిబిలిటీ సంజ్ఞతో ఉపయోగించడానికి ఒక సేవను ఎంచుకోండి (రెండు చేతి వేళ్లతో స్క్రీన్‌ను కింద నుండి పైకి స్వైప్ చేయండి):"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"యాక్సెసిబిలిటీ సంజ్ఞతో ఉపయోగించడానికి ఒక సేవను ఎంచుకోండి (రెండు వేళ్లతో స్క్రీన్‌ను కింద నుండి పైకి స్వైప్ చేయండి):"</string>
     <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"యాక్సెసిబిలిటీ సంజ్ఞతో ఉపయోగించడానికి ఒక సేవను ఎంచుకోండి (మూడు చేతి వేళ్లతో స్క్రీన్‌ను కింద నుండి పైకి స్వైప్ చేయండి):"</string>
     <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"సేవల మధ్య మారడానికి, యాక్సెసిబిలిటీ బటన్‌ను నొక్కి &amp; పట్టుకోండి."</string>
     <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"సేవల మధ్య మారడానికి, రెండు చేతి వేళ్ళతో పైకి స్వైప్ చేసి పట్టుకోండి."</string>
@@ -1889,8 +1889,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"వర్గీకరించబడలేదు"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"మీరు ఈ నోటిఫికేషన్‌ల ప్రాముఖ్యతను సెట్ చేసారు."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"ఇందులో పేర్కొనబడిన వ్యక్తులను బట్టి ఇది చాలా ముఖ్యమైనది."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="ACCOUNT">%2$s</xliff:g>తో కొత్త వినియోగదారుని సృష్టించడానికి <xliff:g id="APP">%1$s</xliff:g>ని అనుమతించాలా ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="ACCOUNT">%2$s</xliff:g>తో (ఈ ఖాతాతో ఇప్పటికే ఒక వినియోగదారు ఉన్నారు) కొత్త వినియోగదారుని సృష్టించడానికి <xliff:g id="APP">%1$s</xliff:g>ని అనుమతించాలా?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g>తో కొత్త వినియోగదారుని సృష్టించడానికి <xliff:g id="APP">%1$s</xliff:g>ను అనుమతించాలా (ఈ ఖాతాతో ఇప్పటికే ఒక వినియోగదారు ఉన్నారు) ?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g>తో కొత్త వినియోగదారుని సృష్టించడానికి <xliff:g id="APP">%1$s</xliff:g>ను అనుమతించాలా?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"భాషను జోడించండి"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"ప్రాంతం ప్రాధాన్యత"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"భాష పేరును టైప్ చేయండి"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index fdedffa..5f11ee7 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -282,7 +282,7 @@
     <string name="permgrouprequest_contacts" msgid="6032805601881764300">"อนุญาตให้ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; เข้าถึงรายชื่อติดต่อไหม"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"ตำแหน่ง"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"เข้าถึงตำแหน่งของอุปกรณ์นี้"</string>
-    <string name="permgrouprequest_location" msgid="3788275734953323491">"อนุญาตให้ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; เข้าถึงตำแหน่งของอุปกรณ์นี้ไหม"</string>
+    <string name="permgrouprequest_location" msgid="3788275734953323491">"อนุญาตให้&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;เข้าถึงตำแหน่งของอุปกรณ์นี้ไหม"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"แอปจะมีสิทธิ์เข้าถึงตำแหน่งในขณะที่คุณใช้แอปเท่านั้น"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"อนุญาตให้ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; เข้าถึงตำแหน่งของอุปกรณ์นี้&lt;b&gt;ตลอดเวลา&lt;/b&gt;ไหม"</string>
     <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"ปัจจุบันแอปมีสิทธิ์เข้าถึงตำแหน่งในขณะที่คุณใช้แอปเท่านั้น"</string>
@@ -297,8 +297,8 @@
     <string name="permgrouprequest_storage" msgid="7885942926944299560">"อนุญาตให้ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; เข้าถึงรูปภาพ สื่อ และไฟล์ในอุปกรณ์ไหม"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"ไมโครโฟน"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"บันทึกเสียง"</string>
-    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"อนุญาตให้ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; บันทึกเสียงไหม"</string>
-    <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"กิจกรรมการเคลื่อนไหวร่างกาย"</string>
+    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"อนุญาตให้&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;บันทึกเสียงไหม"</string>
+    <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"การเคลื่อนไหวร่างกาย"</string>
     <string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"เข้าถึงกิจกรรมการเคลื่อนไหวร่างกายของคุณ"</string>
     <string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"อนุญาตให้ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; เข้าถึงกิจกรรมการเคลื่อนไหวร่างกายของคุณไหม"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"กล้องถ่ายรูป"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"แตะเพื่อดูเครือข่ายทั้งหมด"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"เชื่อมต่อ"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"เครือข่ายทั้งหมด"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"เชื่อมต่อเครือข่าย Wi-Fi ไหม"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"แนะนำโดย <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ใช่"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ไม่"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"อนุญาตให้เชื่อมต่อเครือข่าย Wi-Fi ที่แนะนำไหม"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"เครือข่ายที่แนะนำโดย <xliff:g id="NAME">%s</xliff:g> และอุปกรณ์อาจเชื่อมต่อโดยอัตโนมัติ"</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"อนุญาต"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"ไม่เป็นไร"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi จะเปิดโดยอัตโนมัติ"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"เมื่อคุณอยู่ใกล้เครือข่ายคุณภาพสูงที่บันทึกไว้"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ไม่ต้องเปิดอีกครั้ง"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"ไม่จัดอยู่ในหมวดหมู่ใดๆ"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"คุณตั้งค่าความสำคัญของการแจ้งเตือนเหล่านี้"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"ข้อความนี้สำคัญเนื่องจากบุคคลที่เกี่ยวข้อง"</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"อนุญาตให้ <xliff:g id="APP">%1$s</xliff:g> สร้างผู้ใช้ใหม่ด้วย <xliff:g id="ACCOUNT">%2$s</xliff:g> ไหม"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"อนุญาตให้ <xliff:g id="APP">%1$s</xliff:g> สร้างผู้ใช้ใหม่ด้วย <xliff:g id="ACCOUNT">%2$s</xliff:g> (มีผู้ใช้ที่มีบัญชีนี้อยู่แล้ว) ไหม"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"อนุญาตให้ <xliff:g id="APP">%1$s</xliff:g> สร้างผู้ใช้ใหม่ด้วย <xliff:g id="ACCOUNT">%2$s</xliff:g> ไหม (มีผู้ใช้ที่มีบัญชีนี้อยู่แล้ว)"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"อนุญาตให้ <xliff:g id="APP">%1$s</xliff:g> สร้างผู้ใช้ใหม่ด้วย <xliff:g id="ACCOUNT">%2$s</xliff:g> ไหม"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"เพิ่มภาษา"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"ค่ากำหนดภูมิภาค"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"พิมพ์ชื่อภาษา"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index c33e561..3caa9cc 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"I-tap upang makita ang lahat ng network"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kumonekta"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Lahat ng network"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Kumonekta sa mga Wi-Fi network?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Iminumungkahi ng <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Oo"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Hindi"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Payagan ang mga iminumungkahing Wi‑Fi network?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Mga iminumungkahing network ng <xliff:g id="NAME">%s</xliff:g>. Posibleng awtomatikong kumonekta ang device."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Payagan"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Hindi, salamat na lang"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Awtomatikong mag-o-on ang Wi‑Fi"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kapag malapit ka sa naka-save na network na mataas ang kalidad"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Huwag i-on muli"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Di-nakategorya"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Ikaw ang magtatakda sa kahalagahan ng mga notification na ito."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Mahalaga ito dahil sa mga taong kasangkot."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Payagan ang <xliff:g id="APP">%1$s</xliff:g> na gumawa ng bagong User sa <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Payagan ang <xliff:g id="APP">%1$s</xliff:g> na gumawa ng bagong User sa <xliff:g id="ACCOUNT">%2$s</xliff:g> (mayroon nang User sa account na ito) ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Payagan ang <xliff:g id="APP">%1$s</xliff:g> na gumawa ng bagong User sa <xliff:g id="ACCOUNT">%2$s</xliff:g> (mayroon nang User sa account na ito) ?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Payagan ang <xliff:g id="APP">%1$s</xliff:g> na gumawa ng bagong User sa <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Magdagdag ng wika"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Kagustuhan sa rehiyon"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"I-type ang wika"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 7d69213..1f110d6 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tüm ağları görmek için dokunun"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Bağlan"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Tüm ağlar"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Kablosuz ağlara bağlanılsın mı?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Öneren: <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Evet"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Hayır"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Önerilen kablosuz ağlara izin verilsin mi?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> tarafından önerilen ağlar. Cihaz otomatik olarak bağlanabilir."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"İzin ver"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Hayır, teşekkürler"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Kablosuz özelliği otomatik olarak açılacak"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Daha önce kaydedilmiş yüksek kaliteli bir ağın yakınında olduğunuzda"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Tekrar açılmasın"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Kategorize edilmemiş"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Bu bildirimlerin önem derecesini ayarladınız."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Bu, dahil olan kişiler nedeniyle önemlidir."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g> uygulamasının <xliff:g id="ACCOUNT">%2$s</xliff:g> hesabına sahip yeni bir Kullanıcı eklemesine izin verilsin mi?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g> uygulamasının <xliff:g id="ACCOUNT">%2$s</xliff:g> hesabına sahip yeni bir Kullanıcı eklemesine izin verilsin mi (bu hesaba sahip bir kullanıcı zaten var)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> uygulamasının <xliff:g id="ACCOUNT">%2$s</xliff:g> hesabına sahip yeni bir Kullanıcı eklemesine izin verilsin mi (bu hesaba sahip bir kullanıcı zaten var)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> uygulamasının <xliff:g id="ACCOUNT">%2$s</xliff:g> hesabına sahip yeni bir Kullanıcı eklemesine izin verilsin mi?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Dil ekleyin"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Bölge tercihi"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Dil adını yazın"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index f6ce4eb..49e1de1 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1299,10 +1299,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Торкніться, щоб побачити всі мережі"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Під’єднатися"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Усі мережі"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Підключатися до мереж Wi-Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Запропоновано додатком <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Так"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ні"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Дозволити пропоновані мережі Wi‑Fi?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Мережі, пропоновані додатком <xliff:g id="NAME">%s</xliff:g>. Пристрій може підключитися автоматично."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Дозволити"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ні, дякую"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi вмикатиметься автоматично"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Коли ви поблизу збереженої мережі високої якості"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Не вмикати знову"</string>
@@ -1956,8 +1956,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Без категорії"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Ви вказуєте пріоритет цих сповіщень."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Важливе з огляду на учасників."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Дозволити додатку <xliff:g id="APP">%1$s</xliff:g> створити нового користувача з обліковим записом <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Дозволити додатку <xliff:g id="APP">%1$s</xliff:g> створити нового користувача з обліковим записом <xliff:g id="ACCOUNT">%2$s</xliff:g> (користувач із таким обліковим записом уже існує)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Дозволити додатку <xliff:g id="APP">%1$s</xliff:g> створити нового користувача з обліковим записом <xliff:g id="ACCOUNT">%2$s</xliff:g> (користувач із таким обліковим записом уже існує)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Дозволити додатку <xliff:g id="APP">%1$s</xliff:g> створити нового користувача з обліковим записом <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Додати мову"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Вибір регіону"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Введіть назву мови"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index dba7f8f..10aaef3 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -323,7 +323,7 @@
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ڈسپلے کے زوم کی سطح اور پوزیشن کو کنٹرول کریں۔"</string>
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"اشارے انجام دینے کی"</string>
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"تھپتھپانا، سوائپ کرنا، چٹکی بھرنا اور دیگر اشارے انجام دے سکتی ہے"</string>
-    <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"فنگرپرنٹ کے اشارے"</string>
+    <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"فنگر پرنٹ کے اشارے"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="4386487962402228670">"آلہ کے فنگر پرنٹ سینسر پر کیے گئے اشاروں کو کیپچر کر سکتا ہے۔"</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"اسٹیٹس بار کو غیر فعال یا اس میں ترمیم کریں"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"ایپ کو اسٹیٹس بار غیر فعال کرنے یا سسٹم آئیکنز شامل کرنے اور ہٹانے کی اجازت دیتا ہے۔"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"تمام نیٹ ورکس دیکھنے کیلئے تھپتھپائيں"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"منسلک کریں"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"سبھی نیٹ ورکس"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"‏Wi-Fi نیٹ ورکس سے منسلک کریں؟"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> کی طرف سے تجویز کردہ"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ہاں"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"نہیں"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"‏تجویز کردہ Wi‑Fi نیٹ ورکس کو اجازت دیں؟"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> تجویز کردہ نیٹ ورکس۔ آلہ خودکار طور پر منسلک ہو سکتا ہے۔"</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"اجازت ہیں"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"نہیں شکریہ"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"‏Wi‑Fi از خود آن ہو جائے گا"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"جب آپ اعلی معیار کے محفوظ کردہ نیٹ ورک کے قریب ہوں"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"دوبارہ آن نہ کریں"</string>
@@ -1889,8 +1889,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"غیر زمرہ بند"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"ان اطلاعات کی اہمیت آپ مقرر کرتے ہیں۔"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"اس میں موجود لوگوں کی وجہ سے یہ اہم ہے۔"</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g> کو <xliff:g id="ACCOUNT">%2$s</xliff:g> کے ساتھ ایک نیا صارف بنانے کی اجازت دیں؟"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g> کو <xliff:g id="ACCOUNT">%2$s</xliff:g> کے ساتھ ایک نیا صارف بنانے کی اجازت دیں (اس اکاؤنٹ کے ساتھ ایک صارف پہلے سے موجود ہے) ؟"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> کو <xliff:g id="ACCOUNT">%2$s</xliff:g> کے ساتھ ایک نیا صارف بنانے کی اجازت دیں (اس اکاؤنٹ کے ساتھ ایک صارف پہلے سے موجود ہے) ؟"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> کے ساتھ نئے صارف کو تخلیق کرنے کے لیے <xliff:g id="APP">%1$s</xliff:g> کو اجازت دیں ؟"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"ایک زبان شامل کریں"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"علاقہ کی ترجیح"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"زبان کا نام ٹائپ کریں"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 7a9a72a..b17b84b 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1224,12 +1224,12 @@
     <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Ovozsiz rejim tanlandi"</string>
     <string name="volume_call" msgid="3941680041282788711">"Suhbat vaqtidagi tovush balandligi"</string>
     <string name="volume_bluetooth_call" msgid="2002891926351151534">"Kiruvchi bluetooth tovushi"</string>
-    <string name="volume_alarm" msgid="1985191616042689100">"Signal tovushi balandligi"</string>
+    <string name="volume_alarm" msgid="1985191616042689100">"Signal tovushi"</string>
     <string name="volume_notification" msgid="2422265656744276715">"Eslatma tovushi"</string>
     <string name="volume_unknown" msgid="1400219669770445902">"Tovush balandligi"</string>
     <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Bluetooth tovushi"</string>
     <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Rington balandligi"</string>
-    <string name="volume_icon_description_incall" msgid="8890073218154543397">"Qo‘ng‘iroq tovushi balandligi"</string>
+    <string name="volume_icon_description_incall" msgid="8890073218154543397">"Suhbat tovushi"</string>
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Multimedia tovushi"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Eslatma tovushi"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Standart rington"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Barcha tarmoqlarni ko‘rish uchun bosing"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ulanish"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Barcha tarmoqlar"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi-Fi tarmoqlarga ulanilsinmi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> tomonidan taklif etilgan"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ha"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Yoʻq"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Tavsiya qilingan Wi‑Fi tarmoqlarga ruxsat berilsinmi?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> tavsiya qilgan tarmoqlar. Qurilma avtomatik ulanishi mumkin."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Ruxsat"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Kerak emas"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi avtomatik ravishda yoqiladi"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Saqlangan tarmoqlar ichidan signali yaxshisi hududida ekaningizda"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Qayta yoqilmasin"</string>
@@ -1889,8 +1889,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Turkumlanmagan"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Siz ushbu bildirishnomalarning muhimligini belgilagansiz."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Bu odamlar siz uchun muhim."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g> ilovasiga <xliff:g id="ACCOUNT">%2$s</xliff:g> hisobi bilan yangi foydalanuvchi yaratishiga ruxsat berilsinmi ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g> ilovasiga <xliff:g id="ACCOUNT">%2$s</xliff:g> hisobi bilan yangi foydalanuvchi yaratishiga ruxsat berilsinmi (bunday hisobdagi foydalanuvchi allaqachon mavjud) ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> ilovasiga <xliff:g id="ACCOUNT">%2$s</xliff:g> hisobi bilan yangi foydalanuvchi yaratishiga ruxsat berilsinmi (bunday hisobdagi foydalanuvchi allaqachon mavjud) ?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> ilovasiga <xliff:g id="ACCOUNT">%2$s</xliff:g> hisobi bilan yangi foydalanuvchi yaratishiga ruxsat berilsinmi ?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Til qoʻshish"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Hudud sozlamalari"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Til nomini kiriting"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index f7da3ed..72bfecd 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Nhấn để xem tất cả các mạng"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kết nối"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Tất cả các mạng"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Bạn muốn kết nối với mạng Wi‑Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Do <xliff:g id="NAME">%s</xliff:g> đề xuất"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Có"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Không"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Cho phép các mạng Wi‑Fi được đề xuất?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"Các mạng do <xliff:g id="NAME">%s</xliff:g> đề xuất. Thiết bị có thể kết nối tự động."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Cho phép"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Không, cảm ơn"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi sẽ tự động bật"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Khi bạn ở gần mạng đã lưu chất lượng cao"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Không bật lại"</string>
@@ -1577,8 +1577,8 @@
     <string name="expires_on" msgid="3676242949915959821">"Hết hạn vào:"</string>
     <string name="serial_number" msgid="758814067660862493">"Số sê-ri:"</string>
     <string name="fingerprints" msgid="4516019619850763049">"Tệp tham chiếu:"</string>
-    <string name="sha256_fingerprint" msgid="4391271286477279263">"Tệp tham chiếu SHA-256:"</string>
-    <string name="sha1_fingerprint" msgid="7930330235269404581">"Tệp tham chiếu SHA-1:"</string>
+    <string name="sha256_fingerprint" msgid="4391271286477279263">"Vân tay SHA-256:"</string>
+    <string name="sha1_fingerprint" msgid="7930330235269404581">"Vân tay SHA-1:"</string>
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Xem tất cả"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Chọn hoạt động"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Chia sẻ với"</string>
@@ -1670,8 +1670,8 @@
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Đã tắt phím tắt trợ năng <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Nhấn và giữ đồng thời cả hai phím âm lượng trong 3 giây để sử dụng <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Chọn dịch vụ sẽ sử dụng khi bạn nhấn vào nút hỗ trợ tiếp cận:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Chọn dịch vụ sẽ sử dụng với cử chỉ hỗ trợ tiếp cận (vuốt lên từ cuối màn hình bằng 2 ngón tay):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Chọn dịch vụ sẽ sử dụng với cử chỉ hỗ trợ tiếp cận (vuốt lên từ cuối màn hình bằng 3 ngón tay):"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Chọn dịch vụ sẽ sử dụng với cử chỉ hỗ trợ tiếp cận này (vuốt lên từ cuối màn hình bằng 2 ngón tay):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Chọn dịch vụ sẽ sử dụng với cử chỉ hỗ trợ tiếp cận này (vuốt lên từ cuối màn hình bằng 3 ngón tay):"</string>
     <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Để chuyển đổi giữa các dịch vụ, hãy chạm và giữ nút hỗ trợ tiếp cận."</string>
     <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Để chuyển đổi giữa các dịch vụ, hãy vuốt lên và giữ bằng 2 ngón tay."</string>
     <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Để chuyển đổi giữa các dịch vụ, hãy vuốt lên và giữ bằng 3 ngón tay."</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Chưa được phân loại"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Bạn đặt tầm quan trọng của các thông báo này."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Thông báo này quan trọng vì những người có liên quan."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Cho phép <xliff:g id="APP">%1$s</xliff:g> tạo người dùng mới bằng <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Cho phép <xliff:g id="APP">%1$s</xliff:g> tạo người dùng mới bằng <xliff:g id="ACCOUNT">%2$s</xliff:g> (người dùng có tài khoản này đã tồn tại)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Cho phép <xliff:g id="APP">%1$s</xliff:g> tạo người dùng mới bằng <xliff:g id="ACCOUNT">%2$s</xliff:g> (đã tồn tại người dùng có tài khoản này)?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Cho phép <xliff:g id="APP">%1$s</xliff:g> tạo người dùng mới bằng <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Thêm ngôn ngữ"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Tùy chọn khu vực"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Nhập tên ngôn ngữ"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 487e4a0..4f21cc2 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -282,7 +282,7 @@
     <string name="permgrouprequest_contacts" msgid="6032805601881764300">"允许&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;访问您的通讯录吗?"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"位置信息"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"获取此设备的位置信息"</string>
-    <string name="permgrouprequest_location" msgid="3788275734953323491">"允许“<xliff:g id="APP_NAME">%1$s</xliff:g>”获取此设备的位置信息吗?"</string>
+    <string name="permgrouprequest_location" msgid="3788275734953323491">"要允许“<xliff:g id="APP_NAME">%1$s</xliff:g>”获取此设备的位置信息吗?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"只有当您使用该应用时,该应用才有权访问位置信息"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"要&lt;b&gt;一律允许&lt;/b&gt;允许&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;访问此设备的位置信息吗?"</string>
     <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"目前只有当您使用该应用时,该应用才能访问位置信息"</string>
@@ -291,7 +291,7 @@
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"允许&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;访问您的日历吗?"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"短信"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"发送和查看短信"</string>
-    <string name="permgrouprequest_sms" msgid="7168124215838204719">"允许&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;发送和查看短信吗?"</string>
+    <string name="permgrouprequest_sms" msgid="7168124215838204719">"要允许&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;发送和查看短信吗?"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"存储空间"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"访问您设备上的照片、媒体内容和文件"</string>
     <string name="permgrouprequest_storage" msgid="7885942926944299560">"允许“<xliff:g id="APP_NAME">%1$s</xliff:g>”&lt;b&gt;&lt;/b&gt;访问您设备上的照片、媒体内容和文件吗?"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"点按即可查看所有网络"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"连接"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"所有网络"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"要连接到 WLAN 网络吗?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"由<xliff:g id="NAME">%s</xliff:g>推荐"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"是"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"否"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"是否允许系统连接到建议的 WLAN 网络?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g>建议的网络。设备可能会自动连接到这些网络。"</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"允许"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"不用了"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"WLAN 将自动开启"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"当您位于已保存的高品质网络信号范围内时"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"不要重新开启"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"未分类"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"这些通知的重要程度由您来设置。"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"这条通知涉及特定的人,因此被归为重要通知。"</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"允许<xliff:g id="APP">%1$s</xliff:g>使用 <xliff:g id="ACCOUNT">%2$s</xliff:g> 创建新用户吗?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"允许<xliff:g id="APP">%1$s</xliff:g>使用 <xliff:g id="ACCOUNT">%2$s</xliff:g>(目前已有用户使用此帐号)创建新用户吗?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"允许<xliff:g id="APP">%1$s</xliff:g>使用 <xliff:g id="ACCOUNT">%2$s</xliff:g>(目前已有用户使用此帐号)创建新用户吗?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"允许<xliff:g id="APP">%1$s</xliff:g>使用 <xliff:g id="ACCOUNT">%2$s</xliff:g> 创建新用户吗?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"添加语言"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"区域偏好设置"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"输入语言名称"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index c634c68..e01ad3b 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -201,7 +201,7 @@
     <string name="turn_on_radio" msgid="3912793092339962371">"開啟無線網絡"</string>
     <string name="turn_off_radio" msgid="8198784949987062346">"關閉無線網絡"</string>
     <string name="screen_lock" msgid="799094655496098153">"螢幕鎖定"</string>
-    <string name="power_off" msgid="4266614107412865048">"關閉"</string>
+    <string name="power_off" msgid="4266614107412865048">"關機"</string>
     <string name="silent_mode_silent" msgid="319298163018473078">"鈴聲關閉"</string>
     <string name="silent_mode_vibrate" msgid="7072043388581551395">"鈴聲震動"</string>
     <string name="silent_mode_ring" msgid="8592241816194074353">"鈴聲開啟"</string>
@@ -225,7 +225,7 @@
     <string name="global_actions" product="tv" msgid="7240386462508182976">"電視選項"</string>
     <string name="global_actions" product="default" msgid="2406416831541615258">"手機選項"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"螢幕鎖定"</string>
-    <string name="global_action_power_off" msgid="4471879440839879722">"關閉"</string>
+    <string name="global_action_power_off" msgid="4471879440839879722">"關機"</string>
     <string name="global_action_emergency" msgid="7112311161137421166">"緊急"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"錯誤報告"</string>
     <string name="global_action_logout" msgid="935179188218826050">"結束工作階段"</string>
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"輕按即可查看所有網絡"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"連線"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"所有網絡"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"要連線至 Wi-Fi 網絡嗎?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"由 <xliff:g id="NAME">%s</xliff:g> 推薦"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"是"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"否"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"要允許連線至建議的 Wi-Fi 網絡嗎?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"「<xliff:g id="NAME">%s</xliff:g>」已建議網絡連線,裝置可能會自動連接網絡。"</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"允許"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"不用了,謝謝"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi 將會自動開啟"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"當您位於已儲存的高品質網絡信號範圍內時"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"不要重新開啟"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"未分類"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"您可以設定這些通知的重要性。"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"列為重要的原因:涉及的人。"</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"要允許 <xliff:g id="APP">%1$s</xliff:g> 使用 <xliff:g id="ACCOUNT">%2$s</xliff:g> 建立新使用者嗎?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"要允許 <xliff:g id="APP">%1$s</xliff:g> 使用 <xliff:g id="ACCOUNT">%2$s</xliff:g> 建立新使用者 (此帳戶目前已有此使用者) 嗎?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"要允許 <xliff:g id="APP">%1$s</xliff:g> 使用 <xliff:g id="ACCOUNT">%2$s</xliff:g> 建立新使用者 (此帳戶目前已有此使用者) 嗎?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"要允許 <xliff:g id="APP">%1$s</xliff:g> 使用 <xliff:g id="ACCOUNT">%2$s</xliff:g> 建立新使用者嗎?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"新增語言"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"地區偏好設定"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"輸入語言名稱"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 70fcd0c..cf86a1c 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"輕觸即可查看所有網路"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"連線"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"所有網路"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"要連線到 Wi-Fi 網路嗎?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"「<xliff:g id="NAME">%s</xliff:g>」建議的無線網路"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"是"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"否"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"是否允許系統連線到建議的 Wi‑Fi 網路?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"「<xliff:g id="NAME">%s</xliff:g>」建議的網路。裝置可能會自動連線到這些網路。"</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"允許"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"不用了,謝謝"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi 將自動開啟"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"當你位於已儲存的高品質網路範圍內時"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"不要重新開啟"</string>
@@ -1362,7 +1362,7 @@
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 連接埠中有液體或灰塵"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"系統已自動停用 USB 連接埠。輕觸即可瞭解詳情。"</string>
     <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"現在可以使用 USB 連接埠"</string>
-    <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"手機目前無法偵測液體或灰塵。"</string>
+    <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"手機目前沒有偵測到液體或灰塵。"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"正在接收錯誤報告…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"要分享錯誤報告嗎?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"正在分享錯誤報告…"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"未分類"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"這些通知的重要性由你決定。"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"這則通知涉及特定人士,因此被歸為重要通知。"</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"要允許 <xliff:g id="APP">%1$s</xliff:g> 為 <xliff:g id="ACCOUNT">%2$s</xliff:g> 建立新使用者嗎?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"要允許 <xliff:g id="APP">%1$s</xliff:g> 為 <xliff:g id="ACCOUNT">%2$s</xliff:g> 建立新使用者嗎 (這個帳戶目前已有使用者)?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"要允許「<xliff:g id="APP">%1$s</xliff:g>」替 <xliff:g id="ACCOUNT">%2$s</xliff:g> (這個帳戶目前已有使用者) 建立新使用者嗎?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"要允許「<xliff:g id="APP">%1$s</xliff:g>」替 <xliff:g id="ACCOUNT">%2$s</xliff:g> 建立新使用者嗎?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"新增語言"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"地區偏好設定"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"請輸入語言名稱"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 9d19775..aa6bdac 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1255,10 +1255,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Thepha ukuze ubone onke amanethiwekhi"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Xhuma"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Onke amanethiwekhi"</string>
-    <string name="wifi_suggestion_title" msgid="9099832833531486167">"Xhumeka kumanethiwekhi e-Wi-Fi?"</string>
-    <string name="wifi_suggestion_content" msgid="5883181205841582873">"Kuphakanyiswe ngu-<xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yebo"</string>
-    <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Cha"</string>
+    <string name="wifi_suggestion_title" msgid="6396033039578436801">"Vumela amanethiwekhi e-Wi-Fi aphakanyisiwe?"</string>
+    <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> amanethiwekhi aphakanyisiwe. Idivayisi ingaxhumeka ngokuzenzakalela."</string>
+    <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Vumela"</string>
+    <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Cha ngiyabonga"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"I-Wi-Fi izovuleka ngokuzenzakalela"</string>
     <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Uma useduze kwenethiwekhi yekhwalithi ephezulu elondoloziwe"</string>
     <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ungaphindi uvule"</string>
@@ -1888,8 +1888,8 @@
     <string name="default_notification_channel_label" msgid="5929663562028088222">"Akufakwanga esigabeni"</string>
     <string name="importance_from_user" msgid="7318955817386549931">"Usethe ukubaluleka kwalezi zaziso."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Lokhu kubalulekile ngenxa yabantu ababandakanyekayo."</string>
-    <string name="user_creation_account_exists" msgid="1942606193570143289">"Vumela i-<xliff:g id="APP">%1$s</xliff:g> ukudala umsebenzisi omusha nge-<xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
-    <string name="user_creation_adding" msgid="4482658054622099197">"Vumela i-<xliff:g id="APP">%1$s</xliff:g> ukudala umsebenzisi omusha nge-<xliff:g id="ACCOUNT">%2$s</xliff:g> (umsebenzisi onale akhawunti usuvel ukhona) ?"</string>
+    <string name="user_creation_account_exists" msgid="6559477114648176531">"Vumela i-<xliff:g id="APP">%1$s</xliff:g> ukuthi idale umsebenzisi omusha nge-<xliff:g id="ACCOUNT">%2$s</xliff:g> (Umsebenzisi onale akhawunti usevele ukhona) ?"</string>
+    <string name="user_creation_adding" msgid="9089159170398841763">"Vumela i-<xliff:g id="APP">%1$s</xliff:g> ukuthi idale umsebenzisi omusha nge-<xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Engeza ulwimi"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Okuncamelayo kwesifunda"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"Thayipha igama lolimi"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 1577a22..bfcc8d4 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4255,4 +4255,9 @@
     <!-- The list of packages to automatically opt out of refresh rates higher than 60hz because
          of known compatibility issues. -->
     <string-array name="config_highRefreshRateBlacklist"></string-array>
+
+    <!-- Whether or not to hide the navigation bar when the soft keyboard is visible in order to
+         create additional screen real estate outside beyond the keyboard. Note that the user needs
+         to have a confirmed way to dismiss the keyboard when desired. -->
+    <bool name="config_automotiveHideNavBarForKeyboard">false</bool>
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index b4edc4d..71bd802 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3390,13 +3390,13 @@
     <string name="wifi_available_action_all_networks">All networks</string>
 
     <!-- Notification title for a connection to a app suggested wireless network.-->
-    <string name="wifi_suggestion_title">Connect to Wi\u2011Fi networks?</string>
+    <string name="wifi_suggestion_title">Allow suggested Wi\u2011Fi networks?</string>
     <!-- Notification content for a connection to a app suggested wireless network.-->
-    <string name="wifi_suggestion_content">Suggested by <xliff:g id="name" example="App123">%s</xliff:g></string>
+    <string name="wifi_suggestion_content"><xliff:g id="name" example="App123">%s</xliff:g> suggested networks. Device may connect automatically. </string>
     <!-- Notification action for allowing app specified in the notification body.-->
-    <string name="wifi_suggestion_action_allow_app">Yes</string>
+    <string name="wifi_suggestion_action_allow_app">Allow</string>
     <!-- Notification action for disallowing app specified in the notification body.-->
-    <string name="wifi_suggestion_action_disallow_app">No</string>
+    <string name="wifi_suggestion_action_disallow_app">No thanks</string>
 
     <!--Notification title for Wi-Fi Wake onboarding. This is displayed the first time a user disables Wi-Fi with the feature enabled. -->
     <string name="wifi_wakeup_onboarding_title">Wi\u2011Fi will turn on automatically</string>
@@ -5009,9 +5009,9 @@
     <string name="importance_from_person">This is important because of the people involved.</string>
 
     <!-- Message to user that app trying to create user for an account that already exists. [CHAR LIMIT=none] -->
-    <string name="user_creation_account_exists">Allow <xliff:g id="app" example="Gmail">%1$s</xliff:g> to create a new User with <xliff:g id="account" example="foobar@gmail.com">%2$s</xliff:g> ?</string>
+    <string name="user_creation_account_exists">Allow <xliff:g id="app" example="Gmail">%1$s</xliff:g> to create a new User with <xliff:g id="account" example="foobar@gmail.com">%2$s</xliff:g> (a User with this account already exists) ?</string>
     <!-- Message to user that app is trying to create user for a specified account. [CHAR LIMIT=none] -->
-    <string name="user_creation_adding">Allow <xliff:g id="app" example="Gmail">%1$s</xliff:g> to create a new User with <xliff:g id="account" example="foobar">%2$s</xliff:g> (a User with this account already exists) ?</string>
+    <string name="user_creation_adding">Allow <xliff:g id="app" example="Gmail">%1$s</xliff:g> to create a new User with <xliff:g id="account" example="foobar@gmail.com">%2$s</xliff:g> ?</string>
 
     <!-- Locale picker strings -->
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 0d9c4b3..f06b17e 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3835,4 +3835,5 @@
   <java-symbol type="drawable" name="android_logotype" />
   <java-symbol type="layout" name="platlogo_layout" />
 
+  <java-symbol type="bool" name="config_automotiveHideNavBarForKeyboard" />
 </resources>
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 79c93ce..bdb58f6 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -595,7 +595,10 @@
                  Settings.Secure.ANR_SHOW_BACKGROUND,
                  Settings.Secure.ASSISTANT,
                  Settings.Secure.ASSIST_DISCLOSURE_ENABLED,
+                 Settings.Secure.ASSIST_GESTURE_ENABLED,
                  Settings.Secure.ASSIST_GESTURE_SENSITIVITY,
+                 Settings.Secure.ASSIST_GESTURE_WAKE_ENABLED,
+                 Settings.Secure.ASSIST_GESTURE_SILENCE_ALERTS_ENABLED,
                  Settings.Secure.ASSIST_GESTURE_SETUP_COMPLETE,
                  Settings.Secure.ASSIST_SCREENSHOT_ENABLED,
                  Settings.Secure.ASSIST_STRUCTURE_ENABLED,
@@ -722,7 +725,13 @@
                  Settings.Secure.LOCATION_ACCESS_CHECK_DELAY_MILLIS,
                  Settings.Secure.BIOMETRIC_DEBUG_ENABLED,
                  Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED,
-                 Settings.Secure.FACE_UNLOCK_DIVERSITY_REQUIRED);
+                 Settings.Secure.FACE_UNLOCK_DIVERSITY_REQUIRED,
+                 Settings.Secure.AWARE_ENABLED,
+                 Settings.Secure.SKIP_GESTURE,
+                 Settings.Secure.SILENCE_GESTURE,
+                 Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE,
+                 Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE,
+                 Settings.Secure.FACE_UNLOCK_RE_ENROLL);
 
     @Test
     public void systemSettingsBackedUpOrBlacklisted() {
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index 767ec0e..c44b7d8 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -24,12 +24,19 @@
 import static androidx.test.espresso.matcher.ViewMatchers.withId;
 import static androidx.test.espresso.matcher.ViewMatchers.withText;
 
+import static com.android.internal.app.ChooserActivity.CALLER_TARGET_SCORE_BOOST;
+import static com.android.internal.app.ChooserActivity.SHORTCUT_TARGET_SCORE_BOOST;
+import static com.android.internal.app.ChooserActivity.TARGET_TYPE_CHOOSER_TARGET;
+import static com.android.internal.app.ChooserActivity.TARGET_TYPE_DEFAULT;
+import static com.android.internal.app.ChooserActivity.TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE;
+import static com.android.internal.app.ChooserActivity.TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER;
 import static com.android.internal.app.ChooserWrapperActivity.sOverrides;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.CoreMatchers.notNullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
@@ -45,6 +52,8 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.content.pm.ShortcutInfo;
+import android.content.pm.ShortcutManager.ShareShortcutInfo;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
@@ -770,6 +779,139 @@
         onView(withId(R.id.content_preview_file_icon)).check(matches(isDisplayed()));
     }
 
+    @Test
+    public void testGetBaseScore() {
+        final float testBaseScore = 0.89f;
+
+        Intent sendIntent = createSendTextIntent();
+        List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+
+        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+        when(sOverrides.resolverListController.getScore(Mockito.isA(
+                ResolverActivity.DisplayResolveInfo.class))).thenReturn(testBaseScore);
+
+        final ChooserWrapperActivity activity = mActivityRule
+                .launchActivity(Intent.createChooser(sendIntent, null));
+        waitForIdle();
+
+        final ResolverActivity.DisplayResolveInfo testDri =
+                activity.createTestDisplayResolveInfo(sendIntent,
+                ResolverDataProvider.createResolveInfo(3, 0), "testLabel", "testInfo", sendIntent);
+        final ChooserActivity.ChooserListAdapter adapter = activity.getAdapter();
+
+        assertThat(adapter.getBaseScore(null, 0), is(CALLER_TARGET_SCORE_BOOST));
+        assertThat(adapter.getBaseScore(testDri, TARGET_TYPE_DEFAULT), is(testBaseScore));
+        assertThat(adapter.getBaseScore(testDri, TARGET_TYPE_CHOOSER_TARGET), is(testBaseScore));
+        assertThat(adapter.getBaseScore(testDri, TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE),
+                is(SHORTCUT_TARGET_SCORE_BOOST));
+        assertThat(adapter.getBaseScore(testDri, TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER),
+                is(testBaseScore * SHORTCUT_TARGET_SCORE_BOOST));
+    }
+
+    /**
+     * The case when AppPrediction service is not defined in PackageManager is already covered
+     * as a test parameter {@link ChooserActivityTest#packageManagers}. This test is checking the
+     * case when the prediction service is defined but the component is not available on the device.
+     */
+    @Test
+    public void testIsAppPredictionServiceAvailable() {
+        Intent sendIntent = createSendTextIntent();
+        List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+
+        final ChooserWrapperActivity activity = mActivityRule
+                .launchActivity(Intent.createChooser(sendIntent, null));
+        waitForIdle();
+
+        if (activity.getPackageManager().getAppPredictionServicePackageName() == null) {
+            assertThat(activity.isAppPredictionServiceAvailable(), is(false));
+        } else {
+            assertThat(activity.isAppPredictionServiceAvailable(), is(true));
+
+            sOverrides.resources = Mockito.spy(activity.getResources());
+            when(sOverrides.resources.getString(R.string.config_defaultAppPredictionService))
+                    .thenReturn("ComponentNameThatDoesNotExist");
+
+            assertThat(activity.isAppPredictionServiceAvailable(), is(false));
+        }
+    }
+
+    @Test
+    public void testConvertToChooserTarget_predictionService() {
+        Intent sendIntent = createSendTextIntent();
+        List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+
+        final ChooserWrapperActivity activity = mActivityRule
+                .launchActivity(Intent.createChooser(sendIntent, null));
+        waitForIdle();
+
+        List<ShareShortcutInfo> shortcuts = createShortcuts(activity);
+
+        int[] expectedOrderAllShortcuts = {0, 1, 2, 3};
+        float[] expectedScoreAllShortcuts = {1.0f, 0.99f, 0.98f, 0.97f};
+
+        List<ChooserTarget> chooserTargets = activity.convertToChooserTarget(shortcuts, shortcuts,
+                null, TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE);
+        assertCorrectShortcutToChooserTargetConversion(shortcuts, chooserTargets,
+                expectedOrderAllShortcuts, expectedScoreAllShortcuts);
+
+        List<ShareShortcutInfo> subset = new ArrayList<>();
+        subset.add(shortcuts.get(1));
+        subset.add(shortcuts.get(2));
+        subset.add(shortcuts.get(3));
+
+        int[] expectedOrderSubset = {1, 2, 3};
+        float[] expectedScoreSubset = {0.99f, 0.98f, 0.97f};
+
+        chooserTargets = activity.convertToChooserTarget(subset, shortcuts, null,
+                TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE);
+        assertCorrectShortcutToChooserTargetConversion(shortcuts, chooserTargets,
+                expectedOrderSubset, expectedScoreSubset);
+    }
+
+    @Test
+    public void testConvertToChooserTarget_shortcutManager() {
+        Intent sendIntent = createSendTextIntent();
+        List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+
+        final ChooserWrapperActivity activity = mActivityRule
+                .launchActivity(Intent.createChooser(sendIntent, null));
+        waitForIdle();
+
+        List<ShareShortcutInfo> shortcuts = createShortcuts(activity);
+
+        int[] expectedOrderAllShortcuts = {2, 0, 3, 1};
+        float[] expectedScoreAllShortcuts = {1.0f, 0.99f, 0.99f, 0.98f};
+
+        List<ChooserTarget> chooserTargets = activity.convertToChooserTarget(shortcuts, shortcuts,
+                null, TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER);
+        assertCorrectShortcutToChooserTargetConversion(shortcuts, chooserTargets,
+                expectedOrderAllShortcuts, expectedScoreAllShortcuts);
+
+        List<ShareShortcutInfo> subset = new ArrayList<>();
+        subset.add(shortcuts.get(1));
+        subset.add(shortcuts.get(2));
+        subset.add(shortcuts.get(3));
+
+        int[] expectedOrderSubset = {2, 3, 1};
+        float[] expectedScoreSubset = {1.0f, 0.99f, 0.98f};
+
+        chooserTargets = activity.convertToChooserTarget(subset, shortcuts, null,
+                TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER);
+        assertCorrectShortcutToChooserTargetConversion(shortcuts, chooserTargets,
+                expectedOrderSubset, expectedScoreSubset);
+    }
+
     // This test is too long and too slow and should not be taken as an example for future tests.
     @Test
     public void testDirectTargetSelectionLogging() throws InterruptedException {
@@ -800,7 +942,7 @@
                                 "testInfo",
                                 sendIntent),
                         serviceTargets,
-                        false)
+                        TARGET_TYPE_CHOOSER_TARGET)
         );
         // Thread.sleep shouldn't be a thing in an integration test but it's
         // necessary here because of the way the code is structured
@@ -866,7 +1008,7 @@
                                 "testInfo",
                                 sendIntent),
                         serviceTargets,
-                        false)
+                        TARGET_TYPE_CHOOSER_TARGET)
         );
         // Thread.sleep shouldn't be a thing in an integration test but it's
         // necessary here because of the way the code is structured
@@ -927,7 +1069,7 @@
                                 "testInfo",
                                 sendIntent),
                         serviceTargets,
-                        false)
+                        TARGET_TYPE_CHOOSER_TARGET)
         );
         // Thread.sleep shouldn't be a thing in an integration test but it's
         // necessary here because of the way the code is structured
@@ -1066,4 +1208,43 @@
 
         return bitmap;
     }
+
+    private List<ShareShortcutInfo> createShortcuts(Context context) {
+        Intent testIntent = new Intent("TestIntent");
+
+        List<ShareShortcutInfo> shortcuts = new ArrayList<>();
+        shortcuts.add(new ShareShortcutInfo(
+                new ShortcutInfo.Builder(context, "shortcut1")
+                        .setIntent(testIntent).setShortLabel("label1").setRank(3).build(), // 0  2
+                new ComponentName("package1", "class1")));
+        shortcuts.add(new ShareShortcutInfo(
+                new ShortcutInfo.Builder(context, "shortcut2")
+                        .setIntent(testIntent).setShortLabel("label2").setRank(7).build(), // 1  3
+                new ComponentName("package2", "class2")));
+        shortcuts.add(new ShareShortcutInfo(
+                new ShortcutInfo.Builder(context, "shortcut3")
+                        .setIntent(testIntent).setShortLabel("label3").setRank(1).build(), // 2  0
+                new ComponentName("package3", "class3")));
+        shortcuts.add(new ShareShortcutInfo(
+                new ShortcutInfo.Builder(context, "shortcut4")
+                        .setIntent(testIntent).setShortLabel("label4").setRank(3).build(), // 3  2
+                new ComponentName("package4", "class4")));
+
+        return shortcuts;
+    }
+
+    private void assertCorrectShortcutToChooserTargetConversion(List<ShareShortcutInfo> shortcuts,
+            List<ChooserTarget> chooserTargets, int[] expectedOrder, float[] expectedScores) {
+        assertEquals(expectedOrder.length, chooserTargets.size());
+        for (int i = 0; i < chooserTargets.size(); i++) {
+            ChooserTarget ct = chooserTargets.get(i);
+            ShortcutInfo si = shortcuts.get(expectedOrder[i]).getShortcutInfo();
+            ComponentName cn = shortcuts.get(expectedOrder[i]).getTargetComponent();
+
+            assertEquals(si.getId(), ct.getIntentExtras().getString(Intent.EXTRA_SHORTCUT_ID));
+            assertEquals(si.getShortLabel(), ct.getTitle());
+            assertThat(Math.abs(expectedScores[i] - ct.getScore()) < 0.000001, is(true));
+            assertEquals(cn.flattenToString(), ct.getComponentName().flattenToString());
+        }
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
index 44e56ea..1d567c7 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
@@ -24,6 +24,7 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.net.Uri;
@@ -85,6 +86,14 @@
     }
 
     @Override
+    public Resources getResources() {
+        if (sOverrides.resources != null) {
+            return sOverrides.resources;
+        }
+        return super.getResources();
+    }
+
+    @Override
     protected Bitmap loadThumbnail(Uri uri, Size size) {
         if (sOverrides.previewThumbnail != null) {
             return sOverrides.previewThumbnail;
@@ -145,6 +154,7 @@
         public Bitmap previewThumbnail;
         public MetricsLogger metricsLogger;
         public int alternateProfileSetting;
+        public Resources resources;
 
         public void reset() {
             onSafelyStartCallback = null;
@@ -157,6 +167,7 @@
             resolverListController = mock(ResolverListController.class);
             metricsLogger = mock(MetricsLogger.class);
             alternateProfileSetting = 0;
+            resources = null;
         }
     }
 }
diff --git a/core/tests/screenshothelpertests/Android.bp b/core/tests/screenshothelpertests/Android.bp
new file mode 100644
index 0000000..3d54b68
--- /dev/null
+++ b/core/tests/screenshothelpertests/Android.bp
@@ -0,0 +1,28 @@
+android_test {
+    name: "ScreenshotHelperTests",
+
+    srcs: [
+        "src/**/*.java",
+    ],
+    
+    static_libs: [
+        "frameworks-base-testutils",
+        "androidx.test.runner",
+        "androidx.test.rules",
+        "androidx.test.ext.junit",
+        "mockito-target-minus-junit4",
+        "platform-test-annotations",
+    ],
+
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+        "android.test.mock",
+    ],
+
+    platform_apis: true,
+    test_suites: ["device-tests"],
+
+    certificate: "platform",
+}
+
diff --git a/core/tests/screenshothelpertests/AndroidManifest.xml b/core/tests/screenshothelpertests/AndroidManifest.xml
new file mode 100644
index 0000000..2e12ef4
--- /dev/null
+++ b/core/tests/screenshothelpertests/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          android:installLocation="internalOnly"
+          package="com.android.internal.util"
+          android:sharedUserId="android.uid.systemui" >
+
+    <application >
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+            android:targetPackage="com.android.internal.util"
+            android:label="Screenshot Helper Tests" />
+
+            <protected-broadcast android:name="android.intent.action.USER_PRESENT" />
+
+</manifest>
diff --git a/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java b/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java
new file mode 100644
index 0000000..8483645
--- /dev/null
+++ b/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
+import static android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.fail;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public final class ScreenshotHelperTest {
+    private Context mContext;
+    private ScreenshotHelper mScreenshotHelper;
+    private Handler mHandler;
+
+
+    @Before
+    public void setUp() {
+        // `ScreenshotHelper.notifyScreenshotError()` calls `Context.sendBroadcastAsUser()` and
+        // `Context.bindServiceAsUser`.
+        //
+        // This raises a `SecurityException` if the device is locked. Calling either `Context`
+        // method results in a broadcast of `android.intent.action. USER_PRESENT`. Only the system
+        // process is allowed to broadcast that `Intent`.
+        mContext = Mockito.spy(Context.class);
+        Mockito.doNothing().when(mContext).sendBroadcastAsUser(any(), any());
+        Mockito.doReturn(true).when(mContext).bindServiceAsUser(any(), any(), anyInt(), any());
+
+        mHandler = new Handler(Looper.getMainLooper());
+        mScreenshotHelper = new ScreenshotHelper(mContext);
+    }
+
+    @Test
+    public void testFullscreenScreenshot() {
+        mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN, false, false, mHandler, null);
+    }
+
+    @Test
+    public void testSelectedRegionScreenshot() {
+        mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_SELECTED_REGION, false, false, mHandler,
+                null);
+    }
+
+    @Test
+    public void testScreenshotTimesOut() {
+        long timeoutMs = 10;
+
+        CountDownLatch lock = new CountDownLatch(1);
+        mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN, false, false, timeoutMs,
+                mHandler,
+                worked -> {
+                    assertFalse(worked);
+                    lock.countDown();
+                });
+
+        try {
+            // Add tolerance for delay to prevent flakes.
+            long awaitDurationMs = timeoutMs + 100;
+            if (!lock.await(awaitDurationMs, TimeUnit.MILLISECONDS)) {
+                fail("lock never freed");
+            }
+        } catch (InterruptedException e) {
+            fail("lock interrupted");
+        }
+    }
+}
diff --git a/core/tests/utiltests/src/com/android/internal/util/XmlUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/XmlUtilsTest.java
index 2596ece..27f3596 100644
--- a/core/tests/utiltests/src/com/android/internal/util/XmlUtilsTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/XmlUtilsTest.java
@@ -16,13 +16,22 @@
 
 package com.android.internal.util;
 
+import static org.junit.Assert.assertArrayEquals;
+
+import android.util.Xml;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 import java.util.Map;
+
 import junit.framework.TestCase;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlSerializer;
+
 public class XmlUtilsTest extends TestCase {
 
     // https://code.google.com/p/android/issues/detail?id=63717
@@ -38,4 +47,23 @@
         assertEquals("nullValue", deserialized.get(null));
         assertEquals("fooValue", deserialized.get("foo"));
     }
+
+    public void testreadWriteXmlByteArrayValue() throws Exception {
+        byte[] testByteArray = {0x1 , 0xa, 0xb, 0x9, 0x34, (byte) 0xaa, (byte) 0xba, (byte) 0x99};
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+        XmlSerializer serializer = new FastXmlSerializer();
+        serializer.setOutput(baos, StandardCharsets.UTF_8.name());
+        serializer.startDocument(null, true);
+        XmlUtils.writeValueXml(testByteArray,  "testByteArray", serializer);
+        serializer.endDocument();
+
+        InputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        XmlPullParser pullParser = Xml.newPullParser();
+        pullParser.setInput(bais, StandardCharsets.UTF_8.name());
+        String[] name = new String[1];
+        byte[] testByteArrayDeserialized = (byte[]) XmlUtils.readValueXml(pullParser, name);
+        assertEquals("testByteArray", name[0]);
+        assertArrayEquals(testByteArray, testByteArrayDeserialized);
+    }
 }
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 233f826..65f784d 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -205,6 +205,10 @@
                       targetSdk="29">
         <new-permission name="android.permission.ACCESS_BACKGROUND_LOCATION" />
     </split-permission>
+    <split-permission name="android.permission.READ_EXTERNAL_STORAGE"
+                      targetSdk="29">
+        <new-permission name="android.permission.ACCESS_MEDIA_LOCATION" />
+    </split-permission>
 
     <!-- This is a list of all the libraries available for application
          code to link against. -->
diff --git a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
index 7823971..b6a24e4 100644
--- a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
+++ b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
@@ -31,7 +31,9 @@
 import com.android.internal.location.nano.GnssLogsProto.GnssLog;
 import com.android.internal.location.nano.GnssLogsProto.PowerMetrics;
 
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 
 /**
  * GnssMetrics: Is used for logging GNSS metrics
@@ -60,13 +62,20 @@
   /** Default time between location fixes (in millisecs) */
   private static final int DEFAULT_TIME_BETWEEN_FIXES_MILLISECS = 1000;
 
+  /** The number of hertz in one MHz */
+  private static final double HZ_PER_MHZ = 1e6;
+
   /* The time since boot when logging started */
   private String logStartInElapsedRealTime;
 
   /* GNSS power metrics */
   private GnssPowerMetrics mGnssPowerMetrics;
 
-    /**
+  /** Frequency range of GPS L5, Galileo E5a, QZSS J5 frequency band */
+  private static final double L5_CARRIER_FREQ_RANGE_LOW_HZ = 1164 * HZ_PER_MHZ;
+  private static final double L5_CARRIER_FREQ_RANGE_HIGH_HZ = 1189 * HZ_PER_MHZ;
+
+  /**
      * A boolean array indicating whether the constellation types have been used in fix.
      */
     private boolean[] mConstellationTypes;
@@ -78,6 +87,11 @@
     timeToFirstFixSecStatistics = new Statistics();
     positionAccuracyMeterStatistics = new Statistics();
     topFourAverageCn0Statistics = new Statistics();
+    mTopFourAverageCn0StatisticsL5 = new Statistics();
+    mNumSvStatus = 0;
+    mNumL5SvStatus = 0;
+    mNumSvStatusUsedInFix = 0;
+    mNumL5SvStatusUsedInFix = 0;
     reset();
   }
 
@@ -133,11 +147,16 @@
     return;
   }
 
-  /*
+  /**
   * Logs CN0 when at least 4 SVs are available
   *
+  * @param cn0s
+  * @param numSv
+  * @param svCarrierFreqs
   */
-  public void logCn0(float[] cn0s, int numSv) {
+  public void logCn0(float[] cn0s, int numSv, float[] svCarrierFreqs) {
+    // Calculate L5 Cn0
+    logCn0L5(numSv, cn0s, svCarrierFreqs);
     if (numSv == 0 || cn0s == null || cn0s.length == 0 || cn0s.length < numSv) {
       if (numSv == 0) {
          mGnssPowerMetrics.reportSignalQuality(null, 0);
@@ -161,6 +180,76 @@
     return;
   }
 
+  /* Helper function to check if a SV is L5 */
+  private static boolean isL5Sv(float carrierFreq) {
+    return (carrierFreq >= L5_CARRIER_FREQ_RANGE_LOW_HZ
+            && carrierFreq <= L5_CARRIER_FREQ_RANGE_HIGH_HZ);
+  }
+
+  /**
+   * Logs sv status data
+   *
+   * @param svCount
+   * @param svidWithFlags
+   * @param svCarrierFreqs
+   */
+  public void logSvStatus(int svCount, int[] svidWithFlags, float[] svCarrierFreqs) {
+    boolean isL5 = false;
+    // Calculate SvStatus Information
+    for (int i = 0; i < svCount; i++) {
+      if ((svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) != 0) {
+        mNumSvStatus++;
+        isL5 = isL5Sv(svCarrierFreqs[i]);
+        if (isL5) {
+          mNumL5SvStatus++;
+        }
+        if ((svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
+          mNumSvStatusUsedInFix++;
+          if (isL5) {
+            mNumL5SvStatusUsedInFix++;
+          }
+        }
+      }
+    }
+    return;
+  }
+
+  /**
+   * Logs CN0 when at least 4 SVs are available L5 Only
+   *
+   * @param svCount
+   * @param cn0s
+   * @param svCarrierFreqs
+   */
+  private void logCn0L5(int svCount, float[] cn0s, float[] svCarrierFreqs) {
+    if (svCount == 0 || cn0s == null || cn0s.length == 0 || cn0s.length < svCount
+            || svCarrierFreqs == null || svCarrierFreqs.length == 0
+            || svCarrierFreqs.length < svCount) {
+      return;
+    }
+    // Create array list of all L5 satellites in report.
+    ArrayList<Float> CnoL5Array = new ArrayList();
+    for (int i = 0; i < svCount; i++) {
+      if (isL5Sv(svCarrierFreqs[i])) {
+        CnoL5Array.add(cn0s[i]);
+      }
+    }
+    if (CnoL5Array.size() == 0 || CnoL5Array.size() < 4) {
+      return;
+    }
+    int numSvL5 = CnoL5Array.size();
+    Collections.sort(CnoL5Array);
+    if (CnoL5Array.get(numSvL5 - 4) > 0.0) {
+      double top4AvgCn0 = 0.0;
+      for (int i = numSvL5 - 4; i < numSvL5; i++) {
+        top4AvgCn0 += (double) CnoL5Array.get(i);
+      }
+      top4AvgCn0 /= 4;
+      mTopFourAverageCn0StatisticsL5.addItem(top4AvgCn0);
+    }
+    return;
+  }
+
 
     /**
      * Logs that a constellation type has been observed.
@@ -201,6 +290,24 @@
       msg.standardDeviationTopFourAverageCn0DbHz
           = topFourAverageCn0Statistics.getStandardDeviation();
     }
+    if (mNumSvStatus > 0) {
+      msg.numSvStatusProcessed = mNumSvStatus;
+    }
+    if (mNumL5SvStatus > 0) {
+      msg.numL5SvStatusProcessed = mNumL5SvStatus;
+    }
+    if (mNumSvStatusUsedInFix > 0) {
+      msg.numSvStatusUsedInFix = mNumSvStatusUsedInFix;
+    }
+    if (mNumL5SvStatusUsedInFix > 0) {
+      msg.numL5SvStatusUsedInFix = mNumL5SvStatusUsedInFix;
+    }
+    if (mTopFourAverageCn0StatisticsL5.getCount() > 0) {
+      msg.numL5TopFourAverageCn0Processed = mTopFourAverageCn0StatisticsL5.getCount();
+      msg.meanL5TopFourAverageCn0DbHz = mTopFourAverageCn0StatisticsL5.getMean();
+      msg.standardDeviationL5TopFourAverageCn0DbHz =
+              mTopFourAverageCn0StatisticsL5.getStandardDeviation();
+    }
     msg.powerMetrics = mGnssPowerMetrics.buildProto();
     msg.hardwareRevision = SystemProperties.get("ro.boot.revision", "");
     String s = Base64.encodeToString(GnssLog.toByteArray(msg), Base64.DEFAULT);
@@ -249,6 +356,22 @@
       s.append("  Top 4 Avg CN0 standard deviation (dB-Hz): ").append(
           topFourAverageCn0Statistics.getStandardDeviation()).append("\n");
     }
+    s.append("  Total number of sv status messages processed: ").append(
+            mNumSvStatus).append("\n");
+    s.append("  Total number of L5 sv status messages processed: ").append(
+            mNumL5SvStatus).append("\n");
+    s.append("  Total number of sv status messages processed, where sv is used in fix: ").append(
+            mNumSvStatusUsedInFix).append("\n");
+    s.append("  Total number of L5 sv status messages processed, where sv is used in fix: ").append(
+            mNumL5SvStatusUsedInFix).append("\n");
+    s.append("  Number of L5 CN0 reports: ").append(
+            mTopFourAverageCn0StatisticsL5.getCount()).append("\n");
+    if (mTopFourAverageCn0StatisticsL5.getCount() > 0) {
+      s.append("  L5 Top 4 Avg CN0 mean (dB-Hz): ").append(
+              mTopFourAverageCn0StatisticsL5.getMean()).append("\n");
+      s.append("  L5 Top 4 Avg CN0 standard deviation (dB-Hz): ").append(
+              mTopFourAverageCn0StatisticsL5.getStandardDeviation()).append("\n");
+    }
         s.append("  Used-in-fix constellation types: ");
         for (int i = 0; i < mConstellationTypes.length; i++) {
             if (mConstellationTypes[i]) {
@@ -333,6 +456,21 @@
   /** Top 4 average CN0 statistics */
   private Statistics topFourAverageCn0Statistics;
 
+  /** Top 4 average CN0 statistics L5 */
+  private Statistics mTopFourAverageCn0StatisticsL5;
+
+  /** Total number of sv status messages processed */
+  private int mNumSvStatus;
+
+  /** Total number of L5 sv status messages processed */
+  private int mNumL5SvStatus;
+
+  /** Total number of sv status messages processed, where sv is used in fix */
+  private int mNumSvStatusUsedInFix;
+
+  /** Total number of L5 sv status messages processed, where sv is used in fix */
+  private int mNumL5SvStatusUsedInFix;
+
   /**
    * Resets GNSS metrics
    */
@@ -344,6 +482,11 @@
     timeToFirstFixSecStatistics.reset();
     positionAccuracyMeterStatistics.reset();
     topFourAverageCn0Statistics.reset();
+    mTopFourAverageCn0StatisticsL5.reset();
+    mNumSvStatus = 0;
+    mNumL5SvStatus = 0;
+    mNumSvStatusUsedInFix = 0;
+    mNumL5SvStatusUsedInFix = 0;
         resetConstellationTypes();
     return;
   }
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index e29e569..7cd09de 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -1184,8 +1184,15 @@
             int bufferSizeInBytes, int mode) {
         // If no attributes, OK
         // otherwise check attributes for USAGE_MEDIA and CONTENT_UNKNOWN, MUSIC, or MOVIE.
+        // Only consider flags that are not compatible with FLAG_DEEP_BUFFER. We include
+        // FLAG_DEEP_BUFFER because if set the request is explicit and
+        // shouldEnablePowerSaving() should return false.
+        final int flags = attributes.getAllFlags()
+                & (AudioAttributes.FLAG_DEEP_BUFFER | AudioAttributes.FLAG_LOW_LATENCY
+                    | AudioAttributes.FLAG_HW_AV_SYNC | AudioAttributes.FLAG_BEACON);
+
         if (attributes != null &&
-                (attributes.getAllFlags() != 0  // cannot have any special flags
+                (flags != 0  // cannot have any special flags
                 || attributes.getUsage() != AudioAttributes.USAGE_MEDIA
                 || (attributes.getContentType() != AudioAttributes.CONTENT_TYPE_UNKNOWN
                     && attributes.getContentType() != AudioAttributes.CONTENT_TYPE_MUSIC
diff --git a/media/jni/android_media_ImageWriter.cpp b/media/jni/android_media_ImageWriter.cpp
index cfcba76..7a0eeee 100644
--- a/media/jni/android_media_ImageWriter.cpp
+++ b/media/jni/android_media_ImageWriter.cpp
@@ -26,6 +26,7 @@
 
 #include <gui/IProducerListener.h>
 #include <gui/Surface.h>
+#include <ui/PublicFormat.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/android_view_Surface.h>
 #include <android_runtime/android_hardware_HardwareBuffer.h>
@@ -126,7 +127,7 @@
             Condition mCondition;
             std::deque<wp<Surface>> mQueue;
 
-            static const nsecs_t kWaitDuration = 20000000; // 20 ms
+            static const nsecs_t kWaitDuration = 500000000; // 500 ms
         };
         sp<DetachThread> mThread;
 
@@ -401,8 +402,28 @@
             return 0;
         }
     } else {
+        // Set consumer buffer format to user specified format
+        PublicFormat publicFormat = static_cast<PublicFormat>(userFormat);
+        int nativeFormat = mapPublicFormatToHalFormat(publicFormat);
+        android_dataspace nativeDataspace = mapPublicFormatToHalDataspace(publicFormat);
+        res = native_window_set_buffers_format(anw.get(), nativeFormat);
+        if (res != OK) {
+            ALOGE("%s: Unable to configure consumer native buffer format to %#x",
+                    __FUNCTION__, nativeFormat);
+            jniThrowRuntimeException(env, "Failed to set Surface format");
+            return 0;
+        }
+
+        res = native_window_set_buffers_data_space(anw.get(), nativeDataspace);
+        if (res != OK) {
+            ALOGE("%s: Unable to configure consumer dataspace %#x",
+                    __FUNCTION__, nativeDataspace);
+            jniThrowRuntimeException(env, "Failed to set Surface dataspace");
+            return 0;
+        }
         surfaceFormat = userFormat;
     }
+
     ctx->setBufferFormat(surfaceFormat);
     env->SetIntField(thiz,
             gImageWriterClassInfo.mWriterFormat, reinterpret_cast<jint>(surfaceFormat));
diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp
index 4906695..102bbf0 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/jni/soundpool/SoundPool.cpp
@@ -951,6 +951,8 @@
         ALOGV("process %p channel %d event %s",
               this, mChannelID, (event == AudioTrack::EVENT_UNDERRUN) ? "UNDERRUN" :
                       "BUFFER_END");
+        // Only BUFFER_END should happen as we use static tracks.
+        setVolume_l(0.f, 0.f);  // set volume to 0 to indicate no need to ramp volume down.
         mSoundPool->addToStopList(this);
     } else if (event == AudioTrack::EVENT_LOOP_END) {
         ALOGV("End loop %p channel %d", this, mChannelID);
@@ -966,14 +968,18 @@
 bool SoundChannel::doStop_l()
 {
     if (mState != IDLE) {
-        setVolume_l(0, 0);
         ALOGV("stop");
-        // Since we're forcibly halting the previously playing content,
-        // we sleep here to ensure the volume is ramped down before we stop the track.
-        // Ideally the sleep time is the mixer period, or an approximation thereof
-        // (Fast vs Normal tracks are different).
-        // TODO: consider pausing instead of stop here.
-        std::this_thread::sleep_for(std::chrono::milliseconds(20));
+        if (mLeftVolume != 0.f || mRightVolume != 0.f) {
+            setVolume_l(0.f, 0.f);
+            if (mSoundPool->attributes()->usage != AUDIO_USAGE_GAME) {
+                // Since we're forcibly halting the previously playing content,
+                // we sleep here to ensure the volume is ramped down before we stop the track.
+                // Ideally the sleep time is the mixer period, or an approximation thereof
+                // (Fast vs Normal tracks are different).
+                ALOGV("sleeping: ChannelID:%d  SampleID:%d", mChannelID, mSample->sampleID());
+                std::this_thread::sleep_for(std::chrono::milliseconds(20));
+            }
+        }
         mAudioTrack->stop();
         mPrevSampleID = mSample->sampleID();
         mSample.clear();
diff --git a/packages/BackupRestoreConfirmation/res/values-in/strings.xml b/packages/BackupRestoreConfirmation/res/values-in/strings.xml
index 63a3772..5c82adf 100644
--- a/packages/BackupRestoreConfirmation/res/values-in/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-in/strings.xml
@@ -16,9 +16,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Backup sepenuhnya"</string>
+    <string name="backup_confirm_title" msgid="827563724209303345">"Pencadangan lengkap"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Pemulihan sepenuhnya"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Backup lengkap semua data ke komputer yang tersambung telah diminta. Apakah Anda ingin mengizinkan hal ini dilakukan?\n\nJika Anda tidak meminta backup ini, jangan izinkan operasi dilanjutkan."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Pencadangan semua data ke komputer yang tersambung telah diminta. Apakah Anda ingin mengizinkan hal ini dilakukan?\n\nJika Anda tidak meminta pencadangan ini, jangan izinkan operasi dilanjutkan."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Cadangkan data saya"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Jangan mencadangkan"</string>
     <string name="restore_confirm_text" msgid="7499866728030461776">"Pemulihan lengkap semua data dari komputer desktop yang tersambung telah diminta. Apakah Anda ingin mengizinkan hal ini?\n\nJika Anda tidak meminta pemulihan ini, jangan izinkan operasi dilanjutkan. Operasi ini akan mengganti data apa pun yang saat ini ada dalam perangkat!"</string>
@@ -31,8 +31,8 @@
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Jika Anda ingin mengenkripsi data cadangan lengkap, masukkan sandi di bawah:"</string>
     <string name="backup_enc_password_required" msgid="7889652203371654149">"Karena perangkat Anda dienkripsi, Anda perlu mengenkripsi cadangan. Masukkan sandi di bawah:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Jika data pemulihan dienkripsi, masukkan sandi di bawah:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Backup dimulai..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Backup selesai"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"Pencadangan dimulai..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"Pencadangan selesai"</string>
     <string name="toast_restore_started" msgid="7881679218971277385">"Pemulihan dimulai..."</string>
     <string name="toast_restore_ended" msgid="1764041639199696132">"Pemulihan berakhir"</string>
     <string name="toast_timeout" msgid="5276598587087626877">"Waktu tunggu operasi habis"</string>
diff --git a/packages/CarSystemUI/Android.bp b/packages/CarSystemUI/Android.bp
index 589623b..672879a 100644
--- a/packages/CarSystemUI/Android.bp
+++ b/packages/CarSystemUI/Android.bp
@@ -13,21 +13,22 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 //
-android_app {
-    name: "CarSystemUI",
-
-    overrides: [
-        "SystemUI",
-    ],
+android_library {
+    name: "CarSystemUI-core",
 
     srcs: [
         "src/**/*.java",
         "src/**/I*.aidl",
     ],
 
+    resource_dirs: [
+        "res-keyguard",
+        "res",
+    ],
+
     static_libs: [
-        "CarNotificationLib",
         "SystemUI-core",
+        "CarNotificationLib",
         "SystemUIPluginLib",
         "SystemUISharedLib",
         "SettingsLib",
@@ -47,6 +48,8 @@
         "androidx.lifecycle_lifecycle-extensions",
         "SystemUI-tags",
         "SystemUI-proto",
+        "dagger2-2.19",
+        "//external/kotlinc:kotlin-annotations",
     ],
 
     libs: [
@@ -56,6 +59,28 @@
 
     manifest: "AndroidManifest.xml",
 
+    plugins: ["dagger2-compiler-2.19"],
+
+}
+
+android_app {
+    name: "CarSystemUI",
+
+    static_libs: [
+        "CarSystemUI-core",
+    ],
+
+    libs: [
+        "telephony-common",
+        "android.car",
+    ],
+
+    resource_dirs: [],
+
+     overrides: [
+        "SystemUI",
+    ],
+
     platform_apis: true,
     product_specific: true,
     certificate: "platform",
@@ -66,12 +91,6 @@
             "proguard.flags",
         ],
     },
-    resource_dirs: [
-        "res-keyguard",
-        "res",
-    ],
-
-
     dxflags: ["--multi-dex"],
 
     aaptflags: [
@@ -79,6 +98,8 @@
         "com.android.keyguard",
     ],
 
+    kotlincflags: ["-Xjvm-default=enable"],
+
     plugins: ["dagger2-compiler-2.19"],
 
     required: ["privapp_whitelist_com.android.systemui"],
diff --git a/packages/CarSystemUI/AndroidManifest.xml b/packages/CarSystemUI/AndroidManifest.xml
index 195d4fe..261b9f5 100644
--- a/packages/CarSystemUI/AndroidManifest.xml
+++ b/packages/CarSystemUI/AndroidManifest.xml
@@ -21,4 +21,8 @@
         coreApp="true">
     <!-- This permission is required to monitor car power state. -->
     <uses-permission android:name="android.car.permission.CAR_POWER" />
+    <!-- This permission is required to get the trusted device list of a user. -->
+    <uses-permission android:name="android.car.permission.CAR_ENROLL_TRUST"/>
+    <!-- This permission is required to get bluetooth broadcast. -->
+    <uses-permission android:name="android.permission.BLUETOOTH" />
 </manifest>
diff --git a/packages/CarSystemUI/res/drawable/unlock_dialog_background.xml b/packages/CarSystemUI/res/drawable/unlock_dialog_background.xml
new file mode 100644
index 0000000..bec6ba7
--- /dev/null
+++ b/packages/CarSystemUI/res/drawable/unlock_dialog_background.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 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">
+  <solid android:color="@color/unlock_dialog_background_color"/>
+  <padding
+      android:bottom="@*android:dimen/car_padding_2"
+      android:left="@*android:dimen/car_padding_2"
+      android:right="@*android:dimen/car_padding_2"
+      android:top="@*android:dimen/car_padding_2"/>
+  <corners
+      android:radius="@dimen/unlock_dialog_radius"/>
+</shape>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml
new file mode 100644
index 0000000..8247211
--- /dev/null
+++ b/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<com.android.systemui.statusbar.car.CarNavigationBarView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:systemui="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/car_top_bar"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@drawable/system_bar_background"
+    android:orientation="vertical">
+
+  <RelativeLayout
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:layout_weight="1">
+
+    <FrameLayout
+        android:id="@+id/left_hvac_container"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_alignParentStart="true"
+        >
+
+      <com.android.systemui.statusbar.car.CarNavigationButton
+          android:id="@+id/hvacleft"
+          android:layout_width="match_parent"
+          android:layout_height="match_parent"
+          android:background="@null"
+          systemui:broadcast="true"
+          systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
+          />
+
+      <com.android.systemui.statusbar.hvac.AnimatedTemperatureView
+          android:id="@+id/lefttext"
+          android:layout_width="wrap_content"
+          android:layout_height="match_parent"
+          android:paddingStart="@*android:dimen/car_padding_4"
+          android:paddingEnd="16dp"
+          android:gravity="center_vertical|start"
+          android:minEms="4"
+          android:textAppearance="@style/TextAppearance.CarStatus"
+          systemui:hvacAreaId="49"
+          systemui:hvacMaxText="@string/hvac_max_text"
+          systemui:hvacMaxValue="@dimen/hvac_max_value"
+          systemui:hvacMinText="@string/hvac_min_text"
+          systemui:hvacMinValue="@dimen/hvac_min_value"
+          systemui:hvacPivotOffset="60dp"
+          systemui:hvacPropertyId="358614275"
+          systemui:hvacTempFormat="%.0f\u00B0"
+          />
+    </FrameLayout>
+
+    <FrameLayout
+        android:id="@+id/clock_container"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_centerInParent="true">
+      <com.android.systemui.statusbar.car.CarNavigationButton
+          android:id="@+id/qs"
+          android:layout_width="match_parent"
+          android:layout_height="match_parent"
+          android:background="@null"/>
+      <com.android.systemui.statusbar.policy.Clock
+          android:id="@+id/clock"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:layout_gravity="center"
+          android:elevation="5dp"
+          android:singleLine="true"
+          android:textAppearance="@style/TextAppearance.StatusBar.Clock"/>
+    </FrameLayout>
+
+    <LinearLayout
+        android:id="@+id/system_icon_area"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_centerHorizontal="true"
+        android:layout_centerVertical="true"
+        android:layout_toEndOf="@+id/clock_container"
+        android:paddingStart="@*android:dimen/car_padding_1"
+        android:gravity="center_vertical"
+        android:orientation="horizontal"
+        >
+
+      <include
+          layout="@layout/system_icons"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:layout_weight="1"
+          android:paddingStart="4dp"
+          android:gravity="center_vertical"
+          />
+    </LinearLayout>
+
+    <FrameLayout
+        android:id="@+id/right_hvac_container"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_alignParentEnd="true"
+        >
+
+      <com.android.systemui.statusbar.car.CarNavigationButton
+          android:id="@+id/hvacright"
+          android:layout_width="match_parent"
+          android:layout_height="match_parent"
+          android:background="@null"
+          systemui:broadcast="true"
+          systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
+          />
+
+      <com.android.systemui.statusbar.hvac.AnimatedTemperatureView
+          android:id="@+id/righttext"
+          android:layout_width="wrap_content"
+          android:layout_height="match_parent"
+          android:paddingStart="16dp"
+          android:paddingEnd="@*android:dimen/car_padding_4"
+          android:gravity="center_vertical|end"
+          android:minEms="4"
+          android:textAppearance="@style/TextAppearance.CarStatus"
+          systemui:hvacAreaId="68"
+          systemui:hvacMaxText="@string/hvac_max_text"
+          systemui:hvacMaxValue="@dimen/hvac_max_value"
+          systemui:hvacMinText="@string/hvac_min_text"
+          systemui:hvacMinValue="@dimen/hvac_min_value"
+          systemui:hvacPivotOffset="60dp"
+          systemui:hvacPropertyId="358614275"
+          systemui:hvacTempFormat="%.0f\u00B0"
+          />
+    </FrameLayout>
+  </RelativeLayout>
+
+</com.android.systemui.statusbar.car.CarNavigationBarView>
diff --git a/packages/CarSystemUI/res/layout/super_status_bar.xml b/packages/CarSystemUI/res/layout/super_status_bar.xml
index 728a239..0b34626 100644
--- a/packages/CarSystemUI/res/layout/super_status_bar.xml
+++ b/packages/CarSystemUI/res/layout/super_status_bar.xml
@@ -42,6 +42,14 @@
     </com.android.systemui.statusbar.BackDropView>
 
     <com.android.systemui.statusbar.ScrimView
+        android:id="@+id/scrim_for_bubble"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:importantForAccessibility="no"
+        sysui:ignoreRightInset="true"
+    />
+
+    <com.android.systemui.statusbar.ScrimView
         android:id="@+id/scrim_behind"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
@@ -61,10 +69,10 @@
             android:visibility="gone"
         />
 
-        <include layout="@layout/car_top_navigation_bar"
+        <FrameLayout
+            android:id="@+id/car_top_navigation_bar_container"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-        />
+            android:layout_height="wrap_content"/>
     </LinearLayout>
 
     <include layout="@layout/brightness_mirror"/>
diff --git a/packages/CarSystemUI/res/layout/trust_agent_unlock_dialog.xml b/packages/CarSystemUI/res/layout/trust_agent_unlock_dialog.xml
new file mode 100644
index 0000000..9df78f1
--- /dev/null
+++ b/packages/CarSystemUI/res/layout/trust_agent_unlock_dialog.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 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
+  -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/unlock_dialog_parent"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:gravity="center">
+
+    <LinearLayout
+        android:id="@+id/unlock_dialog"
+        android:layout_width="@dimen/unlock_dialog_width"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:layout_gravity="center"
+        android:orientation="vertical"
+        android:background="@drawable/unlock_dialog_background"
+        android:padding="@*android:dimen/car_padding_2">
+        <FrameLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content">
+            <ProgressBar
+                android:layout_gravity="center"
+                android:layout_width="@dimen/unlock_dialog_progress_bar_size"
+                android:layout_height="@dimen/unlock_dialog_progress_bar_size" />
+            <ImageView
+                android:id="@+id/avatar"
+                android:layout_gravity="center"
+                android:layout_width="@dimen/unlock_dialog_avatar_size"
+                android:layout_height="@dimen/unlock_dialog_avatar_size"
+                android:scaleType="fitCenter"/>
+        </FrameLayout>
+
+        <TextView
+            android:id="@+id/user_name"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:text="@string/unlock_dialog_default_user_name"
+            android:textSize="@*android:dimen/car_body1_size"
+            android:textColor="@android:color/white"/>
+
+        <TextView
+            android:id="@+id/unlocking_text"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:layout_marginTop="@*android:dimen/car_padding_1"
+            android:text="@string/unlock_dialog_message_default"
+            android:textSize="@*android:dimen/car_body4_size"
+            android:textColor="@color/unlock_dialog_message_text_default"/>
+
+        <Button
+            android:id="@+id/enter_pin_button"
+            android:layout_marginTop="@*android:dimen/car_padding_1"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:text="@string/unlock_dialog_button_text_pin"
+            style="@style/UnlockDialogButton"/>
+    </LinearLayout>
+</FrameLayout>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/values/colors.xml b/packages/CarSystemUI/res/values/colors.xml
index e13c940..b818962 100644
--- a/packages/CarSystemUI/res/values/colors.xml
+++ b/packages/CarSystemUI/res/values/colors.xml
@@ -32,7 +32,7 @@
     <color name="system_bar_background_opaque">#ff172026</color>
 
     <color name="status_bar_background_color">#33000000</color>
-    <drawable name="system_bar_background">@android:color/transparent</drawable>
+    <drawable name="system_bar_background">@color/status_bar_background_color</drawable>
 
     <!-- The background color of the notification shade -->
     <color name="notification_shade_background_color">#DD000000</color>
diff --git a/packages/CarSystemUI/res/values/colors_car.xml b/packages/CarSystemUI/res/values/colors_car.xml
index 69ab3f3..0a3f7aa 100644
--- a/packages/CarSystemUI/res/values/colors_car.xml
+++ b/packages/CarSystemUI/res/values/colors_car.xml
@@ -26,4 +26,9 @@
     <color name="car_user_switcher_add_user_background_color">@*android:color/car_dark_blue_grey_600</color>
     <color name="car_user_switcher_add_user_add_sign_color">@*android:color/car_body1_light</color>
 
+    <!-- colors for unlock dialog -->
+    <color name="unlock_dialog_background_color">#ff282a2d</color>
+    <color name="unlock_dialog_message_text_default">@*android:color/car_grey_400</color>
+    <color name="unlock_dialog_enter_pin_text_color">#ff66b5ff</color>
+
 </resources>
diff --git a/packages/CarSystemUI/res/values/dimens_car.xml b/packages/CarSystemUI/res/values/dimens_car.xml
index 42a7649..9cb09c9 100644
--- a/packages/CarSystemUI/res/values/dimens_car.xml
+++ b/packages/CarSystemUI/res/values/dimens_car.xml
@@ -43,4 +43,10 @@
     <!-- This must be the negative of car_user_switcher_container_height for the animation. -->
     <dimen name="car_user_switcher_container_anim_height">-420dp</dimen>
 
+    <!-- dimensions for the unlock dialog -->
+    <dimen name="unlock_dialog_width">500dp</dimen>
+    <dimen name="unlock_dialog_radius">16dp</dimen>
+    <dimen name="unlock_dialog_avatar_size">100dp</dimen>
+    <dimen name="unlock_dialog_progress_bar_size">140dp</dimen>
+
 </resources>
diff --git a/packages/CarSystemUI/res/values/integers_car.xml b/packages/CarSystemUI/res/values/integers_car.xml
index be2cb0d..fb67b30 100644
--- a/packages/CarSystemUI/res/values/integers_car.xml
+++ b/packages/CarSystemUI/res/values/integers_car.xml
@@ -31,5 +31,7 @@
     <!--Percentage of the screen height, from the bottom, that a notification panel being peeked
     at will result in remaining closed the panel if released-->
     <integer name="notification_settle_close_percentage">80</integer>
+    <!-- The delay before the unlock dialog pops up -->
+    <integer name="unlock_dialog_delay_ms">0</integer>
 
 </resources>
diff --git a/packages/CarSystemUI/res/values/strings_car.xml b/packages/CarSystemUI/res/values/strings_car.xml
index 83e91c5..717692e 100644
--- a/packages/CarSystemUI/res/values/strings_car.xml
+++ b/packages/CarSystemUI/res/values/strings_car.xml
@@ -29,4 +29,19 @@
     <string name="user_add_user_message_setup">When you add a new user, that person needs to set up their space.</string>
     <!-- Message to inform user that the newly created user will have permissions to update apps for all other users. [CHAR LIMIT=100] -->
     <string name="user_add_user_message_update">Any user can update apps for all other users.</string>
+    <!-- Default messages displayed on the unlock dialog before unlock advertising started. [CHAR LIMIT=30]-->
+    <string name="unlock_dialog_message_default">Waiting\u2026</string>
+    <!-- Message to inform user that the IHU is looking for trusted device. [CHAR LIMIT=30] -->
+    <string name="unlock_dialog_message_start">Looking for trusted device\u2026</string>
+
+    <!-- Cancel Button text for user who has PIN as security lock. [CHAR LIMIT=30] -->
+    <string name="unlock_dialog_button_text_pin">Enter PIN instead</string>
+    <!-- Cancel Button text for user who has Pattern as security lock. [CHAR LIMIT=30] -->
+    <string name="unlock_dialog_button_text_pattern">Enter Pattern instead</string>
+    <!-- Cancel Button text for user who has Password as security lock. [CHAR LIMIT=30] -->
+    <string name="unlock_dialog_button_text_password">Enter Password instead</string>
+    <!-- Default user name shows on unlock dialog -->
+    <string name="unlock_dialog_default_user_name">Default Name</string>
+    <!-- Default title for unlock dialog -->
+    <string name="unlock_dialog_title">Unlock Dialogue</string>
 </resources>
diff --git a/packages/CarSystemUI/res/values/styles.xml b/packages/CarSystemUI/res/values/styles.xml
index 371bebd..a9423bf 100644
--- a/packages/CarSystemUI/res/values/styles.xml
+++ b/packages/CarSystemUI/res/values/styles.xml
@@ -46,4 +46,12 @@
         <item name="android:layout_width">96dp</item>
         <item name="android:background">@drawable/nav_button_background</item>
     </style>
+
+    <style name="UnlockDialogButton">
+        <item name="android:background">?android:attr/selectableItemBackground</item>
+        <item name="android:textAlignment">center</item>
+        <item name="android:textColor">@color/unlock_dialog_enter_pin_text_color</item>
+        <item name="android:paddingHorizontal">16dp</item>
+        <item name="android:textAllCaps">false</item>
+    </style>
 </resources>
\ No newline at end of file
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
index 3b278b4..c7654e8 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
@@ -20,12 +20,8 @@
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.ViewMediatorCallback;
-import com.android.systemui.car.CarNotificationEntryManager;
-import com.android.systemui.car.CarNotificationInterruptionStateProvider;
 import com.android.systemui.statusbar.car.CarFacetButtonController;
 import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.volume.CarVolumeDialogComponent;
 import com.android.systemui.volume.VolumeDialogComponent;
@@ -33,8 +29,6 @@
 import javax.inject.Singleton;
 
 import dagger.Component;
-import dagger.Module;
-import dagger.Provides;
 
 /**
  * Class factory to provide car specific SystemUI components.
@@ -44,11 +38,14 @@
     private CarDependencyComponent mCarDependencyComponent;
 
     @Override
-    protected void init(Context context) {
-        super.init(context);
+    protected SystemUIRootComponent buildSystemUIRootComponent(Context context) {
         mCarDependencyComponent = DaggerCarSystemUIFactory_CarDependencyComponent.builder()
                 .contextHolder(new ContextHolder(context))
                 .build();
+        return DaggerCarSystemUIRootComponent.builder()
+                .dependencyProvider(new com.android.systemui.DependencyProvider())
+                .contextHolder(new ContextHolder(context))
+                .build();
     }
 
     public CarDependencyComponent getCarDependencyComponent() {
@@ -64,42 +61,9 @@
         return new CarVolumeDialogComponent(systemUi, context);
     }
 
-    @Override
-    public NotificationInterruptionStateProvider provideNotificationInterruptionStateProvider(
-            Context context) {
-        return new CarNotificationInterruptionStateProvider(context);
-    }
-
-    @Override
-    public boolean provideAllowNotificationLongPress() {
-        return false;
-    }
-
-    @Module
-    protected static class ContextHolder {
-        private Context mContext;
-
-        public ContextHolder(Context context) {
-            mContext = context;
-        }
-
-        @Provides
-        public Context provideContext() {
-            return mContext;
-        }
-    }
-
     @Singleton
     @Component(modules = ContextHolder.class)
     public interface CarDependencyComponent {
         CarFacetButtonController getCarFacetButtonController();
     }
-
-    /**
-     * Use {@link CarNotificationEntryManager}, which does nothing when adding a notification.
-     */
-    @Singleton
-    public NotificationEntryManager provideNotificationEntryManager(Context context) {
-        return new CarNotificationEntryManager(context);
-    }
 }
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
new file mode 100644
index 0000000..9a063aa
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2019 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;
+
+import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
+import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME;
+
+import android.content.Context;
+
+import com.android.systemui.car.CarNotificationEntryManager;
+import com.android.systemui.car.CarNotificationInterruptionStateProvider;
+import com.android.systemui.dock.DockManager;
+import com.android.systemui.dock.DockManagerImpl;
+import com.android.systemui.power.EnhancedEstimates;
+import com.android.systemui.power.EnhancedEstimatesImpl;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
+import com.android.systemui.statusbar.notification.collection.NotificationData;
+import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl;
+import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.StatusBar;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import dagger.Binds;
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+abstract class CarSystemUIModule {
+
+    @Binds
+    abstract NotificationInterruptionStateProvider bindNotificationInterruptionStateProvider(
+            CarNotificationInterruptionStateProvider notificationInterruptionStateProvider);
+
+    @Singleton
+    @Provides
+    @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME)
+    static boolean provideAllowNotificationLongPress() {
+        return false;
+    }
+
+    /**
+     * Use {@link CarNotificationEntryManager}, which does nothing when adding a notification.
+     */
+    @Binds
+    abstract NotificationEntryManager bindNotificationEntryManager(
+            CarNotificationEntryManager notificationEntryManager);
+
+    @Singleton
+    @Provides
+    @Named(LEAK_REPORT_EMAIL_NAME)
+    static String provideLeakReportEmail() {
+        return "buganizer-system+181579@google.com";
+    }
+
+    @Binds
+    abstract EnhancedEstimates bindEnhancedEstimates(EnhancedEstimatesImpl enhancedEstimates);
+
+    @Binds
+    abstract NotificationLockscreenUserManager bindNotificationLockscreenUserManager(
+            NotificationLockscreenUserManagerImpl notificationLockscreenUserManager);
+
+    @Binds
+    abstract DockManager bindDockManager(DockManagerImpl dockManager);
+
+    @Binds
+    abstract NotificationData.KeyguardEnvironment bindKeyguardEnvironment(
+            KeyguardEnvironmentImpl keyguardEnvironment);
+
+    @Singleton
+    @Provides
+    static ShadeController provideShadeController(Context context) {
+        return SysUiServiceProvider.getComponent(context, StatusBar.class);
+    }
+
+    @Binds
+    abstract SystemUIRootComponent bindSystemUIRootComponent(
+            CarSystemUIRootComponent systemUIRootComponent);
+}
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIRootComponent.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIRootComponent.java
new file mode 100644
index 0000000..d6b766b
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIRootComponent.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019 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;
+
+import javax.inject.Singleton;
+
+import dagger.Component;
+
+@Singleton
+@Component(
+        modules = {
+                DependencyProvider.class,
+                DependencyBinder.class,
+                ServiceBinder.class,
+                SystemUIFactory.ContextHolder.class,
+                SystemUIModule.class,
+                CarSystemUIModule.class
+        })
+interface CarSystemUIRootComponent extends SystemUIRootComponent {
+
+}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
index 6d9c7ba..a107dd7 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
@@ -21,13 +21,19 @@
 
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
 /**
  * Car specific notification entry manager that does nothing when adding a notification.
  *
  * <p> This is because system UI notifications are disabled and we have a different implementation.
  * Please see {@link com.android.car.notification}.
  */
+@Singleton
 public class CarNotificationEntryManager extends NotificationEntryManager {
+
+    @Inject
     public CarNotificationEntryManager(Context context) {
         super(context);
     }
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationInterruptionStateProvider.java b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationInterruptionStateProvider.java
index 6d960d7..447e579 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationInterruptionStateProvider.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationInterruptionStateProvider.java
@@ -18,14 +18,26 @@
 
 import android.content.Context;
 
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.notification.NotificationFilter;
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.policy.BatteryController;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
 
 /** Auto-specific implementation of {@link NotificationInterruptionStateProvider}. */
+@Singleton
 public class CarNotificationInterruptionStateProvider extends
         NotificationInterruptionStateProvider {
-    public CarNotificationInterruptionStateProvider(Context context) {
-        super(context);
+
+    @Inject
+    public CarNotificationInterruptionStateProvider(Context context,
+            NotificationFilter filter,
+            StatusBarStateController stateController,
+            BatteryController batteryController) {
+        super(context, filter, stateController, batteryController);
     }
 
     @Override
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
index 58f80a4..d79849c 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
@@ -257,6 +257,11 @@
         return false;
     }
 
+    @Override
+    public boolean isAodPowerSave() {
+        return false;
+    }
+
     private void notifyBatteryLevelChanged() {
         for (int i = 0, size = mChangeCallbacks.size(); i < size; i++) {
             mChangeCallbacks.get(i)
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 2874ce6..b7aa496 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -26,11 +26,15 @@
 import android.car.drivingstate.CarDrivingStateEvent;
 import android.car.drivingstate.CarUxRestrictionsManager;
 import android.car.hardware.power.CarPowerManager.CarPowerStateListener;
+import android.car.trust.CarTrustAgentEnrollmentManager;
 import android.content.Context;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.inputmethodservice.InputMethodService;
+import android.os.IBinder;
 import android.util.Log;
+import android.view.Display;
 import android.view.GestureDetector;
 import android.view.Gravity;
 import android.view.MotionEvent;
@@ -61,9 +65,9 @@
 import com.android.systemui.R;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.classifier.FalsingLog;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.qs.car.CarQSFragment;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -85,8 +89,7 @@
 /**
  * A status bar (and navigation bar) tailored for the automotive use case.
  */
-public class CarStatusBar extends StatusBar implements
-        CarBatteryController.BatteryViewHandler {
+public class CarStatusBar extends StatusBar implements CarBatteryController.BatteryViewHandler {
     private static final String TAG = "CarStatusBar";
     // used to calculate how fast to open or close the window
     private static final float DEFAULT_FLING_VELOCITY = 0;
@@ -106,9 +109,11 @@
     private BatteryMeterView mBatteryMeterView;
     private Drawable mNotificationPanelBackground;
 
+    private ViewGroup mTopNavigationBarContainer;
     private ViewGroup mNavigationBarWindow;
     private ViewGroup mLeftNavigationBarWindow;
     private ViewGroup mRightNavigationBarWindow;
+    private CarNavigationBarView mTopNavigationBarView;
     private CarNavigationBarView mNavigationBarView;
     private CarNavigationBarView mLeftNavigationBarView;
     private CarNavigationBarView mRightNavigationBarView;
@@ -120,7 +125,7 @@
     private CarFacetButtonController mCarFacetButtonController;
     private ActivityManagerWrapper mActivityManagerWrapper;
     private DeviceProvisionedController mDeviceProvisionedController;
-    private boolean mDeviceIsProvisioned = true;
+    private boolean mDeviceIsSetUpForUser = true;
     private HvacController mHvacController;
     private DrivingStateHelper mDrivingStateHelper;
     private PowerManagerHelper mPowerManagerHelper;
@@ -141,6 +146,9 @@
     private boolean mNotificationListAtBottom;
     // Was the notification list at the bottom when the user first touched the screen
     private boolean mNotificationListAtBottomAtTimeOfTouch;
+    // To be attached to the top navigation bar (i.e. status bar) to pull down the notification
+    // panel.
+    private View.OnTouchListener mTopNavBarNotificationTouchListener;
     // To be attached to the navigation bars such that they can close the notification panel if
     // it's open.
     private View.OnTouchListener mNavBarNotificationTouchListener;
@@ -167,6 +175,9 @@
     private boolean mIsSwipingVerticallyToClose;
     // Whether heads-up notifications should be shown when shade is open.
     private boolean mEnableHeadsUpNotificationWhenNotificationShadeOpen;
+    // If the nav bar should be hidden when the soft keyboard is visible.
+    private boolean mHideNavBarForKeyboard;
+    private boolean mBottomNavBarVisible;
 
     private final CarPowerStateListener mCarPowerStateListener =
             (int state) -> {
@@ -187,7 +198,22 @@
         // get the provisioned state before calling the parent class since it's that flow that
         // builds the nav bar
         mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
-        mDeviceIsProvisioned = mDeviceProvisionedController.isDeviceProvisioned();
+        mDeviceIsSetUpForUser = mDeviceProvisionedController.isCurrentUserSetup();
+
+        // Keyboard related setup, before nav bars are created.
+        mHideNavBarForKeyboard = mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard);
+        mBottomNavBarVisible = false;
+
+        // Need to initialize screen lifecycle before calling super.start - before switcher is
+        // created.
+        mScreenLifecycle = Dependency.get(ScreenLifecycle.class);
+        mScreenLifecycle.addObserver(mScreenObserver);
+
+        // Need to initialize HVAC controller before calling super.start - before system bars are
+        // created.
+        mHvacController = new HvacController(mContext);
+
         super.start();
         mTaskStackListener = new TaskStackListenerImpl();
         mActivityManagerWrapper = ActivityManagerWrapper.getInstance();
@@ -206,25 +232,18 @@
 
         mHvacController.connectToCarService();
 
-        CarSystemUIFactory factory = SystemUIFactory.getInstance();
-        if (!mDeviceIsProvisioned) {
-            mDeviceProvisionedController.addCallback(
-                    new DeviceProvisionedController.DeviceProvisionedListener() {
-                        @Override
-                        public void onDeviceProvisionedChanged() {
-                            mHandler.post(() -> {
-                                // on initial boot we are getting a call even though the value
-                                // is the same so we are confirming the reset is needed
-                                boolean deviceProvisioned =
-                                        mDeviceProvisionedController.isDeviceProvisioned();
-                                if (mDeviceIsProvisioned != deviceProvisioned) {
-                                    mDeviceIsProvisioned = deviceProvisioned;
-                                    restartNavBars();
-                                }
-                            });
-                        }
-                    });
-        }
+        mDeviceProvisionedController.addCallback(
+                new DeviceProvisionedController.DeviceProvisionedListener() {
+                    @Override
+                    public void onUserSetupChanged() {
+                        mHandler.post(() -> restartNavBarsIfNecessary());
+                    }
+
+                    @Override
+                    public void onUserSwitched() {
+                        mHandler.post(() -> restartNavBarsIfNecessary());
+                    }
+                });
 
         // Register a listener for driving state changes.
         mDrivingStateHelper = new DrivingStateHelper(mContext, this::onDrivingStateChanged);
@@ -234,9 +253,14 @@
         mPowerManagerHelper.connectToCarService();
 
         mSwitchToGuestTimer = new SwitchToGuestTimer(mContext);
+    }
 
-        mScreenLifecycle = Dependency.get(ScreenLifecycle.class);
-        mScreenLifecycle.addObserver(mScreenObserver);
+    private void restartNavBarsIfNecessary() {
+        boolean currentUserSetup = mDeviceProvisionedController.isCurrentUserSetup();
+        if (mDeviceIsSetUpForUser != currentUserSetup) {
+            mDeviceIsSetUpForUser = currentUserSetup;
+            restartNavBars();
+        }
     }
 
     /**
@@ -247,8 +271,8 @@
         // remove and reattach all hvac components such that we don't keep a reference to unused
         // ui elements
         mHvacController.removeAllComponents();
-        addTemperatureViewToController(mStatusBarWindow);
         mCarFacetButtonController.removeAll();
+
         if (mNavigationBarWindow != null) {
             mNavigationBarWindow.removeAllViews();
             mNavigationBarView = null;
@@ -342,7 +366,6 @@
     @Override
     protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
         super.makeStatusBarView(result);
-        mHvacController = new HvacController(mContext);
 
         CarSystemUIFactory factory = SystemUIFactory.getInstance();
         mCarFacetButtonController = factory.getCarDependencyComponent()
@@ -367,7 +390,8 @@
      * touch listeners needed for opening and closing the notification panel
      */
     private void connectNotificationsUI() {
-        // Attached to the status bar to detect pull down of the notification shade.
+        // Attached to the top navigation bar (i.e. status bar) to detect pull down of the
+        // notification shade.
         GestureDetector openGestureDetector = new GestureDetector(mContext,
                 new OpenNotificationGestureListener() {
                     @Override
@@ -400,6 +424,18 @@
         GestureDetector handleBarCloseNotificationGestureDetector = new GestureDetector(mContext,
                 new HandleBarCloseNotificationGestureListener());
 
+        mTopNavBarNotificationTouchListener = (v, event) -> {
+            if (!mDeviceIsSetUpForUser) {
+                return true;
+            }
+            boolean consumed = openGestureDetector.onTouchEvent(event);
+            if (consumed) {
+                return true;
+            }
+            maybeCompleteAnimation(event);
+            return true;
+        };
+
         mNavBarNotificationTouchListener =
                 (v, event) -> {
                     boolean consumed = navBarCloseNotificationGestureDetector.onTouchEvent(event);
@@ -410,21 +446,6 @@
                     return true;
                 };
 
-        // The following are the ui elements that the user would call the status bar.
-        // This will set the status bar so it they can make call backs.
-        CarNavigationBarView topBar = mStatusBarWindow.findViewById(R.id.car_top_bar);
-        topBar.setStatusBar(this);
-        topBar.setStatusBarWindowTouchListener((v1, event1) -> {
-
-                    boolean consumed = openGestureDetector.onTouchEvent(event1);
-                    if (consumed) {
-                        return true;
-                    }
-                    maybeCompleteAnimation(event1);
-                    return true;
-                }
-        );
-
         mNotificationClickHandlerFactory = new NotificationClickHandlerFactory(
                 mBarService,
                 launchResult -> {
@@ -718,29 +739,43 @@
         buildNavBarContent();
         attachNavBarWindows();
 
+        // Try setting up the initial state of the nav bar if applicable.
+        if (result != null) {
+            setImeWindowStatus(Display.DEFAULT_DISPLAY, result.mImeToken,
+                    result.mImeWindowVis, result.mImeBackDisposition,
+                    result.mShowImeSwitcher);
+        }
+
         // There has been a car customized nav bar on the default display, so just create nav bars
         // on external displays.
         mNavigationBarController.createNavigationBars(false /* includeDefaultDisplay */, result);
     }
 
     private void buildNavBarContent() {
+        // Always build top bar.
+        buildTopBar((mDeviceIsSetUpForUser) ? R.layout.car_top_navigation_bar :
+                R.layout.car_top_navigation_bar_unprovisioned);
+
         if (mShowBottom) {
-            buildBottomBar((mDeviceIsProvisioned) ? R.layout.car_navigation_bar :
+            buildBottomBar((mDeviceIsSetUpForUser) ? R.layout.car_navigation_bar :
                     R.layout.car_navigation_bar_unprovisioned);
         }
 
         if (mShowLeft) {
-            buildLeft((mDeviceIsProvisioned) ? R.layout.car_left_navigation_bar :
+            buildLeft((mDeviceIsSetUpForUser) ? R.layout.car_left_navigation_bar :
                     R.layout.car_left_navigation_bar_unprovisioned);
         }
 
         if (mShowRight) {
-            buildRight((mDeviceIsProvisioned) ? R.layout.car_right_navigation_bar :
+            buildRight((mDeviceIsSetUpForUser) ? R.layout.car_right_navigation_bar :
                     R.layout.car_right_navigation_bar_unprovisioned);
         }
     }
 
     private void buildNavBarWindows() {
+        mTopNavigationBarContainer = mStatusBarWindow
+            .findViewById(R.id.car_top_navigation_bar_container);
+
         if (mShowBottom) {
             mNavigationBarWindow = (ViewGroup) View.inflate(mContext,
                     R.layout.navigation_bar_window, null);
@@ -756,9 +791,30 @@
 
     }
 
-    private void attachNavBarWindows() {
+    /**
+     * We register for soft keyboard visibility events such that we can hide the navigation bar
+     * giving more screen space to the IME. Note: this is optional and controlled by
+     * {@code com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard}.
+     */
+    @Override
+    public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,
+            boolean showImeSwitcher) {
+        if (!mHideNavBarForKeyboard) {
+            return;
+        }
 
-        if (mShowBottom) {
+        if (mContext.getDisplay().getDisplayId() != displayId) {
+            return;
+        }
+
+        boolean isKeyboardVisible = (vis & InputMethodService.IME_VISIBLE) != 0;
+        showBottomNavBarWindow(isKeyboardVisible);
+    }
+
+    private void attachNavBarWindows() {
+        if (mShowBottom && !mBottomNavBarVisible) {
+            mBottomNavBarVisible = true;
+
             WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                     LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
                     WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
@@ -806,7 +862,34 @@
             rightlp.gravity = Gravity.RIGHT;
             mWindowManager.addView(mRightNavigationBarWindow, rightlp);
         }
+    }
 
+    private void showBottomNavBarWindow(boolean isKeyboardVisible) {
+        if (!mShowBottom) {
+            return;
+        }
+
+        // If keyboard is visible and bottom nav bar not visible, this is the correct state, so do
+        // nothing. Same with if keyboard is not visible and bottom nav bar is visible.
+        if (isKeyboardVisible ^ mBottomNavBarVisible) {
+            return;
+        }
+
+        mNavigationBarWindow.setVisibility(isKeyboardVisible ? View.GONE : View.VISIBLE);
+        mBottomNavBarVisible = !isKeyboardVisible;
+    }
+
+    private void buildTopBar(int layout) {
+        mTopNavigationBarContainer.removeAllViews();
+        View.inflate(mContext, layout, mTopNavigationBarContainer);
+        mTopNavigationBarView = (CarNavigationBarView) mTopNavigationBarContainer.getChildAt(0);
+        if (mTopNavigationBarView == null) {
+            Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_top_navigation_bar");
+            throw new RuntimeException("Unable to build top nav bar due to missing layout");
+        }
+        mTopNavigationBarView.setStatusBar(this);
+        addTemperatureViewToController(mTopNavigationBarView);
+        mTopNavigationBarView.setStatusBarWindowTouchListener(mTopNavBarNotificationTouchListener);
     }
 
     private void buildBottomBar(int layout) {
@@ -817,7 +900,7 @@
         mNavigationBarView = (CarNavigationBarView) mNavigationBarWindow.getChildAt(0);
         if (mNavigationBarView == null) {
             Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_navigation_bar");
-            throw new RuntimeException("Unable to build botom nav bar due to missing layout");
+            throw new RuntimeException("Unable to build bottom nav bar due to missing layout");
         }
         mNavigationBarView.setStatusBar(this);
         addTemperatureViewToController(mNavigationBarView);
@@ -828,7 +911,7 @@
         View.inflate(mContext, layout, mLeftNavigationBarWindow);
         mLeftNavigationBarView = (CarNavigationBarView) mLeftNavigationBarWindow.getChildAt(0);
         if (mLeftNavigationBarView == null) {
-            Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_navigation_bar");
+            Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_left_navigation_bar");
             throw new RuntimeException("Unable to build left nav bar due to missing layout");
         }
         mLeftNavigationBarView.setStatusBar(this);
@@ -841,7 +924,7 @@
         View.inflate(mContext, layout, mRightNavigationBarWindow);
         mRightNavigationBarView = (CarNavigationBarView) mRightNavigationBarWindow.getChildAt(0);
         if (mRightNavigationBarView == null) {
-            Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_navigation_bar");
+            Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_right_navigation_bar");
             throw new RuntimeException("Unable to build right nav bar due to missing layout");
         }
         mRightNavigationBarView.setStatusBar(this);
@@ -877,7 +960,7 @@
             KeyguardUpdateMonitor.getInstance(mContext).dump(fd, pw, args);
         }
 
-        FalsingManagerFactory.getInstance(mContext).dump(pw);
+        Dependency.get(FalsingManager.class).dump(pw);
         FalsingLog.dump(pw);
 
         pw.println("SharedPreferences:");
@@ -956,8 +1039,12 @@
         UserSwitcherController userSwitcherController =
                 Dependency.get(UserSwitcherController.class);
         if (userSwitcherController.useFullscreenUserSwitcher()) {
+            Car car = Car.createCar(mContext);
+            CarTrustAgentEnrollmentManager enrollmentManager = (CarTrustAgentEnrollmentManager) car
+                    .getCarManager(Car.CAR_TRUST_AGENT_ENROLLMENT_SERVICE);
             mFullscreenUserSwitcher = new FullscreenUserSwitcher(this,
-                    mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub), mContext);
+                    mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub),
+                    enrollmentManager, mContext);
         } else {
             super.createUserSwitcher();
         }
@@ -1072,9 +1159,10 @@
             // shade is visible to the user. When the notification shade is completely open then
             // alpha value will be 1.
             float alpha = (float) height / mNotificationView.getHeight();
-            Drawable background = mNotificationView.getBackground();
+            Drawable background = mNotificationView.getBackground().mutate();
 
             background.setAlpha((int) (alpha * 255));
+            mNotificationView.setBackground(background);
         }
     }
 
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarTrustAgentUnlockDialogHelper.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarTrustAgentUnlockDialogHelper.java
new file mode 100644
index 0000000..ec72ee7
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarTrustAgentUnlockDialogHelper.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2019 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.statusbar.car;
+
+import android.app.admin.DevicePolicyManager;
+import android.bluetooth.BluetoothAdapter;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.PixelFormat;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.R;
+
+/**
+ * A helper class displays an unlock dialog and receives broadcast about detecting trusted device
+ * & unlocking state to show the appropriate message on the dialog.
+ */
+class CarTrustAgentUnlockDialogHelper extends BroadcastReceiver{
+    private static final String TAG = CarTrustAgentUnlockDialogHelper.class.getSimpleName();
+
+    private final Context mContext;
+    private final WindowManager mWindowManager;
+    private final UserManager mUserManager;
+    private final WindowManager.LayoutParams mParams;
+    /**
+     * Not using Dialog because context passed from {@link FullscreenUserSwitcher} is not an
+     * activity.
+     */
+    private final View mUnlockDialogLayout;
+    private final TextView mUnlockingText;
+    private final Button mButton;
+    private final IntentFilter mFilter;
+    private int mUid;
+    private boolean mIsDialogShowing;
+    private OnHideListener mOnHideListener;
+
+    CarTrustAgentUnlockDialogHelper(Context context) {
+        mContext = context;
+        mUserManager = mContext.getSystemService(UserManager.class);
+        mWindowManager = mContext.getSystemService(WindowManager.class);
+        mParams = createLayoutParams();
+        mFilter = getIntentFilter();
+
+        mParams.packageName = mContext.getPackageName();
+        mParams.setTitle(mContext.getString(R.string.unlock_dialog_title));
+
+        mUnlockDialogLayout = LayoutInflater.from(mContext).inflate(
+            R.layout.trust_agent_unlock_dialog, null);
+        mUnlockDialogLayout.setLayoutParams(mParams);
+
+        View dialogParent = mUnlockDialogLayout.findViewById(R.id.unlock_dialog_parent);
+        dialogParent.setOnTouchListener((v, event)-> {
+            hideUnlockDialog(/* dismissUserSwitcher= */ false);
+            return true;
+        });
+        View unlockDialog = mUnlockDialogLayout.findViewById(R.id.unlock_dialog);
+        unlockDialog.setOnTouchListener((v, event) -> {
+            // If the person taps inside the unlock dialog, the touch event will be intercepted here
+            // and the dialog will not exit
+            return true;
+        });
+        mUnlockingText = mUnlockDialogLayout.findViewById(R.id.unlocking_text);
+        mButton = mUnlockDialogLayout.findViewById(R.id.enter_pin_button);
+        mButton.setOnClickListener(v -> {
+            hideUnlockDialog(/* dismissUserSwitcher= */true);
+            // TODO(b/138250105) Stop unlock advertising
+        });
+
+        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+        if (bluetoothAdapter != null
+                && bluetoothAdapter.getLeState() == BluetoothAdapter.STATE_BLE_ON) {
+            mUnlockingText.setText(R.string.unlock_dialog_message_start);
+        }
+    }
+
+    /**
+     * This filter is listening on:
+     * {@link BluetoothAdapter#ACTION_BLE_STATE_CHANGED} for starting unlock advertising;
+     * {@link Intent#ACTION_USER_UNLOCKED} for IHU unlocked
+     */
+    private IntentFilter getIntentFilter() {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(BluetoothAdapter.ACTION_BLE_STATE_CHANGED);
+        filter.addAction(Intent.ACTION_USER_UNLOCKED);
+        return filter;
+    }
+
+    /**
+     * Show dialog for the given user
+     */
+    void showUnlockDialog(int uid, OnHideListener listener) {
+        showUnlockDialogAfterDelay(uid, 0, listener);
+    }
+
+    /**
+     * Show dialog for the given user after the certain time of delay has elapsed
+     *
+     * @param uid the user to unlock
+     * @param listener listener that listens to dialog hide
+     */
+    void showUnlockDialogAfterDelay(int uid, OnHideListener listener) {
+        long delayMillis = mContext.getResources().getInteger(R.integer.unlock_dialog_delay_ms);
+        showUnlockDialogAfterDelay(uid, delayMillis, listener);
+    }
+
+    /**
+     * Show dialog for the given user after the supplied delay has elapsed
+     */
+    private void showUnlockDialogAfterDelay(int uid, long delayMillis, OnHideListener listener) {
+        setUid(uid);
+        mOnHideListener = listener;
+        if (!mIsDialogShowing) {
+            logd("Receiver registered");
+            mContext.registerReceiverAsUser(this, UserHandle.ALL, mFilter,
+                    /* broadcastPermission= */ null,
+                    /* scheduler= */ null);
+            new Handler().postDelayed(() -> {
+                if (!mUserManager.isUserUnlocked(uid)) {
+                    logd("Showed unlock dialog for user: " + uid + " after " + delayMillis
+                            + " delay.");
+                    mWindowManager.addView(mUnlockDialogLayout, mParams);
+                }
+            }, delayMillis);
+        }
+        mIsDialogShowing = true;
+    }
+
+    private void setUid(int uid) {
+        mUid = uid;
+        TextView userName = mUnlockDialogLayout.findViewById(R.id.user_name);
+        userName.setText(mUserManager.getUserInfo(mUid).name);
+        ImageView avatar = mUnlockDialogLayout.findViewById(R.id.avatar);
+        avatar.setImageBitmap(mUserManager.getUserIcon(mUid));
+        setButtonText();
+    }
+
+    private void hideUnlockDialog(boolean dismissUserSwitcher) {
+        if (!mIsDialogShowing) {
+            return;
+        }
+        mWindowManager.removeView(mUnlockDialogLayout);
+        logd("Receiver unregistered");
+        mContext.unregisterReceiver(this);
+        if (mOnHideListener != null) {
+            mOnHideListener.onHide(dismissUserSwitcher);
+        }
+        mIsDialogShowing = false;
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        String action = intent.getAction();
+        if (action == null) {
+            return;
+        }
+        switch (action) {
+            case BluetoothAdapter.ACTION_BLE_STATE_CHANGED:
+                logd("Received ACTION_BLE_STATE_CHANGED");
+                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
+                if (state == BluetoothAdapter.STATE_BLE_ON) {
+                    logd("Received BLE_ON");
+                    mUnlockingText.setText(R.string.unlock_dialog_message_start);
+                }
+                break;
+            case Intent.ACTION_USER_UNLOCKED:
+                int uid = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+                if (uid == mUid) {
+                    logd("IHU unlocked");
+                    hideUnlockDialog(/* notifyOnHideListener= */false);
+                } else {
+                    Log.e(TAG, "Received ACTION_USER_UNLOCKED for unexpected uid: " + uid);
+                }
+                break;
+            default:
+                Log.e(TAG, "Encountered unexpected action when attempting to set "
+                        + "unlock state message: " + action);
+        }
+    }
+
+    // Set button text based on screen lock type
+    private void setButtonText() {
+        LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext);
+        int passwordQuality = lockPatternUtils.getActivePasswordQuality(mUid);
+        switch (passwordQuality) {
+            // PIN
+            case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
+            case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
+                mButton.setText(R.string.unlock_dialog_button_text_pin);
+                break;
+            // Pattern
+            case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
+                mButton.setText(R.string.unlock_dialog_button_text_pattern);
+                break;
+            // Password
+            case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
+            case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
+            case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
+                mButton.setText(R.string.unlock_dialog_button_text_password);
+                break;
+            default:
+                Log.e(TAG, "Encountered unexpected screen lock type when attempting to set "
+                        + "button text:" + passwordQuality);
+        }
+    }
+
+    private WindowManager.LayoutParams createLayoutParams() {
+        return new WindowManager.LayoutParams(
+                WindowManager.LayoutParams.MATCH_PARENT,
+                WindowManager.LayoutParams.MATCH_PARENT,
+                WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG,
+                WindowManager.LayoutParams.FLAG_FULLSCREEN
+                        | WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
+                        | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
+                PixelFormat.TRANSLUCENT
+        );
+    }
+
+    private void logd(String message) {
+        if (Log.isLoggable(TAG, Log.DEBUG)) {
+            Log.d(TAG, message);
+        }
+    }
+
+    /**
+     * Listener used to notify when the dialog is hidden
+     */
+    interface OnHideListener {
+        void onHide(boolean dismissUserSwitcher);
+    }
+}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
index 0a167d9..0f7c1ee 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
@@ -18,29 +18,61 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
+import android.car.trust.CarTrustAgentEnrollmentManager;
+import android.car.userlib.CarUserManagerHelper;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.UserInfo;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Log;
 import android.view.View;
 import android.view.ViewStub;
 
 import androidx.recyclerview.widget.GridLayoutManager;
 
 import com.android.systemui.R;
+import com.android.systemui.statusbar.car.CarTrustAgentUnlockDialogHelper.OnHideListener;
+import com.android.systemui.statusbar.car.UserGridRecyclerView.UserRecord;
 
 /**
  * Manages the fullscreen user switcher.
  */
 public class FullscreenUserSwitcher {
+    private static final String TAG = FullscreenUserSwitcher.class.getSimpleName();
+    // Because user 0 is headless, user count for single user is 2
+    private static final int NUMBER_OF_BACKGROUND_USERS = 1;
     private final UserGridRecyclerView mUserGridView;
     private final View mParent;
     private final int mShortAnimDuration;
     private final CarStatusBar mStatusBar;
+    private final Context mContext;
+    private final UserManager mUserManager;
+    private final CarTrustAgentEnrollmentManager mEnrollmentManager;
+    private CarTrustAgentUnlockDialogHelper mUnlockDialogHelper;
+    private UserGridRecyclerView.UserRecord mSelectedUser;
+    private CarUserManagerHelper mCarUserManagerHelper;
+    private final BroadcastReceiver mUserUnlockReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                Log.d(TAG, "user 0 is unlocked, SharedPreference is accessible.");
+            }
+            showDialogForInitialUser();
+            mContext.unregisterReceiver(mUserUnlockReceiver);
+        }
+    };
 
-    public FullscreenUserSwitcher(CarStatusBar statusBar, ViewStub containerStub, Context context) {
+
+    public FullscreenUserSwitcher(CarStatusBar statusBar, ViewStub containerStub,
+            CarTrustAgentEnrollmentManager enrollmentManager, Context context) {
         mStatusBar = statusBar;
         mParent = containerStub.inflate();
-        // Hide the user grid by default. It will only be made visible by clicking on a cancel
-        // button in a bouncer.
-        hide();
+        mEnrollmentManager = enrollmentManager;
+        mContext = context;
+
         View container = mParent.findViewById(R.id.container);
 
         // Initialize user grid.
@@ -50,9 +82,51 @@
         mUserGridView.setLayoutManager(layoutManager);
         mUserGridView.buildAdapter();
         mUserGridView.setUserSelectionListener(this::onUserSelected);
+        mCarUserManagerHelper = new CarUserManagerHelper(context);
+        mUnlockDialogHelper = new CarTrustAgentUnlockDialogHelper(mContext);
+        mUserManager = mContext.getSystemService(UserManager.class);
 
         mShortAnimDuration = container.getResources()
                 .getInteger(android.R.integer.config_shortAnimTime);
+        IntentFilter filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED);
+        if (mUserManager.isUserUnlocked(UserHandle.USER_SYSTEM)) {
+            // User0 is unlocked, switched to the initial user
+            showDialogForInitialUser();
+        } else {
+            // listen to USER_UNLOCKED
+            mContext.registerReceiverAsUser(mUserUnlockReceiver,
+                    UserHandle.getUserHandleForUid(UserHandle.USER_SYSTEM),
+                    filter,
+                    /* broadcastPermission= */ null,
+                    /* scheduler */ null);
+        }
+    }
+
+    private void showDialogForInitialUser() {
+        int initialUser = mCarUserManagerHelper.getInitialUser();
+        UserInfo initialUserInfo = mUserManager.getUserInfo(initialUser);
+        mSelectedUser = new UserRecord(initialUserInfo,
+                /* isStartGuestSession= */ false,
+                /* isAddUser= */ false,
+                /* isForeground= */ true);
+        // For single user without trusted device, hide the user switcher.
+        if (!hasMultipleUsers() && !hasTrustedDevice(initialUser)) {
+            dismissUserSwitcher();
+            return;
+        }
+        // Show unlock dialog for initial user
+        if (hasTrustedDevice(initialUser)) {
+            mUnlockDialogHelper.showUnlockDialogAfterDelay(initialUser,
+                    mOnHideListener);
+        }
+    }
+
+    /**
+     * Check if there is only one possible user to login in.
+     * In a Multi-User system there is always one background user (user 0)
+     */
+    private boolean hasMultipleUsers() {
+        return mUserManager.getUserCount() > NUMBER_OF_BACKGROUND_USERS + 1;
     }
 
     /**
@@ -77,14 +151,33 @@
     }
 
     /**
-     * Every time user clicks on an item in the switcher, we hide the switcher, either
-     * gradually or immediately.
+     * Every time user clicks on an item in the switcher, if the clicked user has no trusted device,
+     * we hide the switcher, either gradually or immediately.
      *
-     * We dismiss the entire keyguard if user clicked on the foreground user (user we're already
-     * logged in as).
+     * If the user has trusted device, we show an unlock dialog to notify user the unlock state.
+     * When the unlock dialog is dismissed by user, we hide the unlock dialog and the switcher.
+     *
+     * We dismiss the entire keyguard when we hide the switcher if user clicked on the foreground
+     * user (user we're already logged in as).
      */
     private void onUserSelected(UserGridRecyclerView.UserRecord record) {
-        if (record.mIsForeground) {
+        mSelectedUser = record;
+        if (hasTrustedDevice(record.mInfo.id)) {
+            mUnlockDialogHelper.showUnlockDialog(record.mInfo.id, mOnHideListener);
+            return;
+        }
+        if (Log.isLoggable(TAG, Log.DEBUG)) {
+            Log.d(TAG, "no trusted device enrolled for uid: " + record.mInfo.id);
+        }
+        dismissUserSwitcher();
+    }
+
+    private void dismissUserSwitcher() {
+        if (mSelectedUser == null) {
+            Log.e(TAG, "Request to dismiss user switcher, but no user selected");
+            return;
+        }
+        if (mSelectedUser.mIsForeground) {
             hide();
             mStatusBar.dismissKeyguard();
             return;
@@ -106,4 +199,22 @@
                 });
 
     }
+
+    private boolean hasTrustedDevice(int uid) {
+        return !mEnrollmentManager.getEnrolledDeviceInfoForUser(uid).isEmpty();
+    }
+
+    private OnHideListener mOnHideListener = new OnHideListener() {
+        @Override
+        public void onHide(boolean dismissUserSwitcher) {
+            if (dismissUserSwitcher) {
+                dismissUserSwitcher();
+            } else {
+                // Re-draw the parent view, otherwise the unlock dialog will not be removed from
+                // the screen immediately.
+                mParent.invalidate();
+            }
+
+        }
+    };
 }
diff --git a/packages/SettingsLib/HelpUtils/AndroidManifest.xml b/packages/SettingsLib/HelpUtils/AndroidManifest.xml
index 5240ce4..ccad6e4 100644
--- a/packages/SettingsLib/HelpUtils/AndroidManifest.xml
+++ b/packages/SettingsLib/HelpUtils/AndroidManifest.xml
@@ -16,6 +16,6 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.settingslib.helputils">
+    package="com.android.settingslib.widget">
 
 </manifest>
diff --git a/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java b/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java
index e407d72..2d13b73 100644
--- a/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java
+++ b/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java
@@ -33,11 +33,11 @@
 import android.view.MenuItem;
 import android.view.MenuItem.OnMenuItemClickListener;
 
+import com.android.settingslib.widget.R;
+
 import java.net.URISyntaxException;
 import java.util.Locale;
 
-import com.android.settingslib.helputils.R;
-
 /**
  * Functions to easily prepare contextual help menu option items with an intent that opens up the
  * browser to a particular URL, while taking into account the preferred language and app version.
diff --git a/packages/SettingsLib/RestrictedLockUtils/AndroidManifest.xml b/packages/SettingsLib/RestrictedLockUtils/AndroidManifest.xml
index d19a022..0975640 100644
--- a/packages/SettingsLib/RestrictedLockUtils/AndroidManifest.xml
+++ b/packages/SettingsLib/RestrictedLockUtils/AndroidManifest.xml
@@ -16,6 +16,6 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.restrictedlockutils">
+          package="com.android.settingslib.widget">
 
 </manifest>
\ No newline at end of file
diff --git a/packages/SettingsLib/SearchWidget/res/values-km/strings.xml b/packages/SettingsLib/SearchWidget/res/values-km/strings.xml
index f012e3a..7ac9cb1 100644
--- a/packages/SettingsLib/SearchWidget/res/values-km/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-km/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="search_menu" msgid="1604061903696928905">"ការកំណត់ការ​ស្វែងរក"</string>
+    <string name="search_menu" msgid="1604061903696928905">"​ស្វែងរកការកំណត់"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index afdb105..2649544 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -385,10 +385,10 @@
     <string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"Temps restant aproximat segons l\'ús que en fas: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <!-- no translation found for power_remaining_duration_only_short (9183070574408359726) -->
     <skip />
-    <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"La bateria hauria de durar aproximadament fins a les <xliff:g id="TIME">%1$s</xliff:g> segons l\'ús que en fas (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"La bateria hauria de durar aproximadament fins a les <xliff:g id="TIME">%1$s</xliff:g> segons l\'ús que en fas"</string>
-    <string name="power_discharge_by" msgid="6453537733650125582">"La bateria hauria de durar aproximadament fins a les <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_discharge_by_only" msgid="107616694963545745">"La bateria hauria de durar aproximadament fins a les <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Hauria de durar aproximadament fins a les <xliff:g id="TIME">%1$s</xliff:g> segons l\'ús que en facis (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Hauria de durar aproximadament fins a les <xliff:g id="TIME">%1$s</xliff:g> segons l\'ús que en facis"</string>
+    <string name="power_discharge_by" msgid="6453537733650125582">"Hauria de durar aproximadament fins a les <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_discharge_by_only" msgid="107616694963545745">"Hauria de durar aproximadament fins a les <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Fins a les <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_suggestion_extend_battery" msgid="4401408879069551485">"Allarga la durada de la bateria després de les <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Temps restant inferior a <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index a74b4ae..16d7ea4 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -169,7 +169,7 @@
     <string name="tts_engine_security_warning" msgid="8786238102020223650">"Այս խոսքային սինթեզի գործիքը կարող է հավաքել այն ամենը, ինչ արտասանված է, այդ թվում` անձնական տվյալներ, ինչպիսիք են գաղտնաբառն ու բանկային քարտի համարները: Սկզբնաբյուրը <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> շարժիչն է: Միացնե՞լ խոսքի սինթեզի շարժիչի օգտագործումը:"</string>
     <string name="tts_engine_network_required" msgid="1190837151485314743">"Այս լեզուն պահանջում է աշխատող ցանցային կապ գրվածքից խոսք ելքի համար:"</string>
     <string name="tts_default_sample_string" msgid="4040835213373086322">"Սա խոսքային սինթեզի մի նմուշ է:"</string>
-    <string name="tts_status_title" msgid="7268566550242584413">"Լռելյայն լեզվի կարգավիճակը"</string>
+    <string name="tts_status_title" msgid="7268566550242584413">"Կանխադրված լեզվի կարգավիճակը"</string>
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g>-ը լիովին աջակցվում է"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g>-ը պահանջում է ցանցային կապ"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g>-ը չի աջակցվում"</string>
@@ -201,9 +201,9 @@
     <string name="vpn_settings_not_available" msgid="956841430176985598">"VPN-ի կարգավորումները հասանելի չեն այս օգտատիրոջը"</string>
     <string name="tethering_settings_not_available" msgid="6765770438438291012">"Այս օգտատերը չի կարող փոխել մոդեմի ռեժիմի կարգավորումները"</string>
     <string name="apn_settings_not_available" msgid="7873729032165324000">"Մուտքի կետի անվան կարգավորումները հասանելի չեն այս օգտատիրոջը"</string>
-    <string name="enable_adb" msgid="7982306934419797485">"USB վրիպազերծում"</string>
+    <string name="enable_adb" msgid="7982306934419797485">"USB-ով վրիպազերծում"</string>
     <string name="enable_adb_summary" msgid="4881186971746056635">"Միացնել վրիպազերծման ռեժիմը, երբ USB-ն միացված է"</string>
-    <string name="clear_adb_keys" msgid="4038889221503122743">"Չեղարկել USB վրիպազերծման լիազորումները"</string>
+    <string name="clear_adb_keys" msgid="4038889221503122743">"Չեղարկել USB-ով վրիպազերծման թույլտվությունները"</string>
     <string name="bugreport_in_power" msgid="7923901846375587241">"Սխալի հաղորդման դյուրանցում"</string>
     <string name="bugreport_in_power_summary" msgid="1778455732762984579">"Գործարկման ցանկում ցույց տալ կոճակը՝ վրիպակների հաղորդման համար"</string>
     <string name="keep_screen_on" msgid="1146389631208760344">"Մնալ արթուն"</string>
@@ -263,9 +263,9 @@
     <string name="debug_view_attributes" msgid="6485448367803310384">"Միացնել ցուցադրման հատկանիշների ստուգումը"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Միշտ ակտիվացրած պահել բջջային տվյալները, նույնիսկ Wi‑Fi-ը միացրած ժամանակ (ցանցերի միջև արագ փոխարկման համար):"</string>
     <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Օգտագործել սարքակազմի արագացման միացումը, եթե հասանելի է"</string>
-    <string name="adb_warning_title" msgid="6234463310896563253">"Թույլատրե՞լ USB վրիպազերծումը:"</string>
-    <string name="adb_warning_message" msgid="7316799925425402244">"USB վրիպազերծումը միայն ծրագրավորման նպատակների համար է: Օգտագործեք այն ձեր համակարգչից տվյալները ձեր սարք պատճենելու համար, առանց ծանուցման ձեր սարքի վրա ծրագրեր տեղադրելու և տվյալների մատյանը ընթերցելու համար:"</string>
-    <string name="adb_keys_warning_message" msgid="5659849457135841625">"Փակե՞լ USB-ի վրիպազերծման մուտքը` անջատելով այն բոլոր համակարգիչներից, որտեղ նախկինում թույլատրել էիք:"</string>
+    <string name="adb_warning_title" msgid="6234463310896563253">"Թույլատրե՞լ USB-ով վրիպազերծումը:"</string>
+    <string name="adb_warning_message" msgid="7316799925425402244">"USB-ով վրիպազերծումը միայն ծրագրավորման նպատակների համար է: Օգտագործեք այն ձեր համակարգչից տվյալները ձեր սարք պատճենելու համար, առանց ծանուցման ձեր սարքի վրա ծրագրեր տեղադրելու և տվյալների մատյանը ընթերցելու համար:"</string>
+    <string name="adb_keys_warning_message" msgid="5659849457135841625">"Չեղարկե՞լ USB-ով վրիպազերծման հասանելիությունը` անջատելով այն բոլոր համակարգիչներից, որտեղ նախկինում թույլատրել էիք:"</string>
     <string name="dev_settings_warning_title" msgid="7244607768088540165">"Ընդունե՞լ ծրագրավորման կարգավորումներ:"</string>
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Այս կարգավորումները միայն ծրագրավորման նպատակների համար են նախատեսված: Դրանք կարող են խանգարել ձեր սարքի կամ ծրագրի աշխատանքին:"</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Ստուգել հավելվածները USB-ի նկատմամբ"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 7fe1ef9..02c4c8c 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -336,8 +336,8 @@
     <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Buat semua aktivitas dapat diubah ukurannya untuk banyak jendela, terlepas dari nilai manifes."</string>
     <string name="enable_freeform_support" msgid="1461893351278940416">"Aktifkan jendela berformat bebas"</string>
     <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Aktifkan dukungan untuk jendela eksperimental berformat bebas."</string>
-    <string name="local_backup_password_title" msgid="3860471654439418822">"Sandi backup desktop"</string>
-    <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Saat ini backup desktop sepenuhnya tidak dilindungi"</string>
+    <string name="local_backup_password_title" msgid="3860471654439418822">"Sandi cadangan desktop"</string>
+    <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Saat ini cadangan desktop penuh tidak dilindungi"</string>
     <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Ketuk guna mengubah atau menghapus sandi untuk cadangan lengkap desktop"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Sandi cadangan baru telah disetel"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Sandi baru dan konfirmasinya tidak cocok."</string>
@@ -387,8 +387,8 @@
     <skip />
     <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Akan bertahan kira-kira sampai <xliff:g id="TIME">%1$s</xliff:g> berdasarkan penggunaan Anda (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Akan bertahan kira-kira sampai <xliff:g id="TIME">%1$s</xliff:g> berdasarkan penggunaan Anda"</string>
-    <string name="power_discharge_by" msgid="6453537733650125582">"Akan bertahan kira-kira sampai <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_discharge_by_only" msgid="107616694963545745">"Akan bertahan kira-kira sampai <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_discharge_by" msgid="6453537733650125582">"Akan bertahan kira-kira sampai pukul <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_discharge_by_only" msgid="107616694963545745">"Akan bertahan kira-kira sampai pukul <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Hingga <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_suggestion_extend_battery" msgid="4401408879069551485">"Perpanjang masa pakai baterai hingga <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Tersisa kurang dari <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 68c0f17..a43e8d6 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -240,7 +240,7 @@
     <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
     <string name="select_private_dns_configuration_title" msgid="3700456559305263922">"DNS privato"</string>
     <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"Seleziona modalità DNS privato"</string>
-    <string name="private_dns_mode_off" msgid="8236575187318721684">"Non attivo"</string>
+    <string name="private_dns_mode_off" msgid="8236575187318721684">"Off"</string>
     <string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"Automatico"</string>
     <string name="private_dns_mode_provider" msgid="8354935160639360804">"Nome host del provider DNS privato"</string>
     <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Inserisci il nome host del provider DNS"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index ead0bfb..a3e049c 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -342,7 +342,7 @@
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"הוגדרה סיסמת גיבוי חדשה"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"הסיסמה החדשה והאישור אינם תואמים"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"הגדרת סיסמת גיבוי נכשלה"</string>
-    <string name="loading_injected_setting_summary" msgid="4095178591461231376">"טוען…"</string>
+    <string name="loading_injected_setting_summary" msgid="4095178591461231376">"בטעינה…"</string>
   <string-array name="color_mode_names">
     <item msgid="2425514299220523812">"דינמי (ברירת מחדל)"</item>
     <item msgid="8446070607501413455">"טבעי"</item>
@@ -405,7 +405,7 @@
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> עד לטעינה מלאה"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד לטעינה מלאה"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"לא ידוע"</string>
-    <string name="battery_info_status_charging" msgid="1705179948350365604">"טוען"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"בטעינה"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"בטעינה"</string>
     <string name="battery_info_status_discharging" msgid="310932812698268588">"לא בטעינה"</string>
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"המכשיר מחובר, אבל לא ניתן לטעון עכשיו"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index e5d29bf..50543d8 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -385,10 +385,10 @@
     <string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"残り時間: 約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>(使用状況に基づく)(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <!-- no translation found for power_remaining_duration_only_short (9183070574408359726) -->
     <skip />
-    <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"電池切れの推定時間: <xliff:g id="TIME">%1$s</xliff:g>(使用状況に基づく)(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"電池切れの推定時間: <xliff:g id="TIME">%1$s</xliff:g>(使用状況に基づく)"</string>
-    <string name="power_discharge_by" msgid="6453537733650125582">"電池切れの推定時間: <xliff:g id="TIME">%1$s</xliff:g>(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_discharge_by_only" msgid="107616694963545745">"電池切れの推定時間: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"電池切れの推定時刻: <xliff:g id="TIME">%1$s</xliff:g>(使用状況に基づく)(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"電池切れの推定時刻: <xliff:g id="TIME">%1$s</xliff:g>(使用状況に基づく)"</string>
+    <string name="power_discharge_by" msgid="6453537733650125582">"電池切れの推定時刻: <xliff:g id="TIME">%1$s</xliff:g>(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_discharge_by_only" msgid="107616694963545745">"電池切れの推定時刻: <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> まで"</string>
     <string name="power_suggestion_extend_battery" msgid="4401408879069551485">"<xliff:g id="TIME">%1$s</xliff:g>まで電池消費量を抑える"</string>
     <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"残り時間: <xliff:g id="THRESHOLD">%1$s</xliff:g>未満"</string>
diff --git a/packages/SettingsLib/res/values-ko/arrays.xml b/packages/SettingsLib/res/values-ko/arrays.xml
index e2d8e02..15e11db 100644
--- a/packages/SettingsLib/res/values-ko/arrays.xml
+++ b/packages/SettingsLib/res/values-ko/arrays.xml
@@ -226,7 +226,7 @@
   </string-array>
   <string-array name="enable_opengl_traces_entries">
     <item msgid="3191973083884253830">"없음"</item>
-    <item msgid="9089630089455370183">"로그캣"</item>
+    <item msgid="9089630089455370183">"Logcat"</item>
     <item msgid="5397807424362304288">"Systrace(그래픽)"</item>
     <item msgid="1340692776955662664">"glGetError의 스택 호출"</item>
   </string-array>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index ed88bc5..1cee8fb 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -385,10 +385,10 @@
     <string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"ເຫຼືອອີກປະມານ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ອ້າງອີງຈາກການນຳໃຊ້ຂອງທ່ານ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <!-- no translation found for power_remaining_duration_only_short (9183070574408359726) -->
     <skip />
-    <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Should last until about <xliff:g id="TIME">%1$s</xliff:g> based on your usage (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Should last until about <xliff:g id="TIME">%1$s</xliff:g> based on your usage"</string>
-    <string name="power_discharge_by" msgid="6453537733650125582">"Should last until about <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_discharge_by_only" msgid="107616694963545745">"Should last until about <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"ໜ້າຈະໃຊ້ໄດ້ຈົນຮອດປະມານ <xliff:g id="TIME">%1$s</xliff:g> ໂດຍອ້າງອີງຈາກການນຳໃຊ້ຂອງທ່ານ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"ໜ້າຈະໃຊ້ໄດ້ຈົນຮອດປະມານ <xliff:g id="TIME">%1$s</xliff:g> ໂດຍອ້າງອີງຈາກການນຳໃຊ້ຂອງທ່ານ"</string>
+    <string name="power_discharge_by" msgid="6453537733650125582">"ໜ້າຈະໃຊ້ໄດ້ຈົນຮອດປະມານ <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_discharge_by_only" msgid="107616694963545745">"ໜ້າຈະໃຊ້ໄດ້ຈົນຮອດປະມານ <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharge_by_only_short" msgid="1372817269546888804">"ຈົນກວ່າຈະຮອດ <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_suggestion_extend_battery" msgid="4401408879069551485">"ຂະຫຍາຍອາຍຸແບັດເຕີຣີກາຍ <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"ຍັງເຫຼືອໜ້ອຍກວ່າ <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 8feb5ab..96aebc5 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -403,7 +403,7 @@
     <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Iespējams, ierīce drīz izslēgsies (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Atlikušais laiks līdz pilnai uzlādei: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>, kamēr pilnībā uzlādēts"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> līdz pilnīgai uzlādei"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Nezināms"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Uzlāde"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"notiek uzlāde"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index dda3462..d93304f 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -153,7 +153,7 @@
     <string name="launch_defaults_some" msgid="313159469856372621">"Поставени се некои стандардни вредности"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"Нема поставено стандардни вредности"</string>
     <string name="tts_settings" msgid="8186971894801348327">"Поставки на текст-во-говор"</string>
-    <string name="tts_settings_title" msgid="1237820681016639683">"Излез текст-во-говор"</string>
+    <string name="tts_settings_title" msgid="1237820681016639683">"Претворање текст во говор"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"Брзина на говор"</string>
     <string name="tts_default_rate_summary" msgid="4061815292287182801">"Брзина со која се кажува текстот"</string>
     <string name="tts_default_pitch_title" msgid="6135942113172488671">"Интензитет"</string>
@@ -167,7 +167,7 @@
     <string name="tts_install_data_title" msgid="4264378440508149986">"Инсталирај гласовни податоци"</string>
     <string name="tts_install_data_summary" msgid="5742135732511822589">"Инсталирај ги гласовните податоци потребни за синтеза на говор"</string>
     <string name="tts_engine_security_warning" msgid="8786238102020223650">"Овој софтвер за синтеза на говор може да го собере сиот текст што ќе се говори, вклучувајќи и лични податоци како што се лозинки и броеви на кредитни картички. Тоа го прави апликацијата <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Употреби го овој софтвер за синтеза на говор?"</string>
-    <string name="tts_engine_network_required" msgid="1190837151485314743">"За овој јазик е потребно поврување со мрежа што функционира на излез за текст-во-говор."</string>
+    <string name="tts_engine_network_required" msgid="1190837151485314743">"За претворање текст во говор на овој јазик, потребна е активна мрежна врска."</string>
     <string name="tts_default_sample_string" msgid="4040835213373086322">"Ова е пример на синтеза на говор"</string>
     <string name="tts_status_title" msgid="7268566550242584413">"Статус на стандарден јазик"</string>
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> е целосно поддржан"</string>
@@ -375,7 +375,7 @@
     <string name="daltonizer_mode_deuteranomaly" msgid="5475532989673586329">"Девтераномалија (слепило за црвена и зелена)"</string>
     <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"Протаномалија (слепило за црвена и зелена)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"Тританомалија (слепило за сина и жолта)"</string>
-    <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Корекција на боја"</string>
+    <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Корекција на бои"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Функцијата е експериментална и може да влијае на изведбата."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Прескокнато според <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4845022416859002011">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index f1934c3..b2e1cd6 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -153,7 +153,7 @@
     <string name="launch_defaults_some" msgid="313159469856372621">"केही पूर्वनिर्धारितहरू सेट गरिएका छन्"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"कुनै पूर्वनिर्धारित सेट गरिएको छैन"</string>
     <string name="tts_settings" msgid="8186971894801348327">"पाठ-वाचन सेटिङहरू"</string>
-    <string name="tts_settings_title" msgid="1237820681016639683">"पाठवाचकको उत्पादन"</string>
+    <string name="tts_settings_title" msgid="1237820681016639683">"पाठवाचकको आउटपुट"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"वाणी दर"</string>
     <string name="tts_default_rate_summary" msgid="4061815292287182801">"पाठ वाचन हुने गति"</string>
     <string name="tts_default_pitch_title" msgid="6135942113172488671">"पिच"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 5725c22..f9e0d39 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -402,7 +402,7 @@
     <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"ଖୁବ୍ ଶୀଘ୍ର ଟାବଲେଟ୍‌ଟି ବନ୍ଦ ହୋଇଯାଇପାରେ (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
     <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"ଖୁବ୍ ଶୀଘ୍ର ଡିଭାଇସ୍‌ଟି ବନ୍ଦ ହୋଇଯାଇପାରେ(<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"ସମ୍ପୂର୍ଣ୍ଣ ଚାର୍ଜ ହେବାପାଇଁ <xliff:g id="TIME">%1$s</xliff:g> ଅବଶିଷ୍ଟ ଅଛି"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"ସମ୍ପୂର୍ଣ୍ଣ ଚାର୍ଜ ହେବାପାଇଁ <xliff:g id="TIME">%1$s</xliff:g> ବାକି ଅଛି"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ପୂର୍ଣ୍ଣ ଚାର୍ଜ ହେବା ପର୍ଯ୍ୟନ୍ତ"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"ଅଜ୍ଞାତ"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"ଚାର୍ଜ ହେଉଛି"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index faccda7..b5acd8e 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -388,7 +388,7 @@
     <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"ਤੁਹਾਡੀ ਵਰਤੋਂ ਦੇ ਆਧਾਰ \'ਤੇ ਲਗਭਗ <xliff:g id="TIME">%1$s</xliff:g> ਚੱਲੇਗਾ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"ਤੁਹਾਡੀ ਵਰਤੋਂ ਦੇ ਆਧਾਰ \'ਤੇ ਲਗਭਗ <xliff:g id="TIME">%1$s</xliff:g> ਚੱਲੇਗਾ"</string>
     <string name="power_discharge_by" msgid="6453537733650125582">"ਲਗਭਗ <xliff:g id="TIME">%1$s</xliff:g> ਚੱਲੇਗਾ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_discharge_by_only" msgid="107616694963545745">"ਲਗਭਗ <xliff:g id="TIME">%1$s</xliff:g> ਚੱਲੇਗਾ"</string>
+    <string name="power_discharge_by_only" msgid="107616694963545745">"ਲਗਭਗ <xliff:g id="TIME">%1$s</xliff:g> ਤੱਕ ਚੱਲੇਗੀ"</string>
     <string name="power_discharge_by_only_short" msgid="1372817269546888804">"<xliff:g id="TIME">%1$s</xliff:g> ਤੱਕ"</string>
     <string name="power_suggestion_extend_battery" msgid="4401408879069551485">"ਬੈਟਰੀ ਲਾਈਫ਼ <xliff:g id="TIME">%1$s</xliff:g> ਤੋਂ ਬਾਅਦ ਤੱਕ ਵਧਾਓ"</string>
     <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"<xliff:g id="THRESHOLD">%1$s</xliff:g> ਤੋਂ ਘੱਟ ਸਮਾਂ ਬਾਕੀ"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 501cf50..c076d32 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -387,8 +387,8 @@
     <skip />
     <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Deve durar até cerca da(s) <xliff:g id="TIME">%1$s</xliff:g> com base na sua utilização (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string>
     <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Deve durar até cerca da(s) <xliff:g id="TIME">%1$s</xliff:g> com base na sua utilização."</string>
-    <string name="power_discharge_by" msgid="6453537733650125582">"Deve durar até cerca da(s) <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string>
-    <string name="power_discharge_by_only" msgid="107616694963545745">"Deve durar até cerca da(s) <xliff:g id="TIME">%1$s</xliff:g>."</string>
+    <string name="power_discharge_by" msgid="6453537733650125582">"Deve durar até cerca da(s) <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_discharge_by_only" msgid="107616694963545745">"Deve durar até cerca da(s) <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Até à(s) <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_suggestion_extend_battery" msgid="4401408879069551485">"Prolongar a autonomia da bateria após <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Resta(m) menos de <xliff:g id="THRESHOLD">%1$s</xliff:g>."</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index e28825c..d77e1eb 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -385,10 +385,10 @@
     <string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"Zostáva približne <xliff:g id="TIME_REMAINING">%1$s</xliff:g> – závisí to od intenzity využitia (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <!-- no translation found for power_remaining_duration_only_short (9183070574408359726) -->
     <skip />
-    <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Mal by vydržať približne do <xliff:g id="TIME">%1$s</xliff:g> v závislosti od využitia (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Mal by vydržať približne do <xliff:g id="TIME">%1$s</xliff:g> v závislosti od využitia"</string>
-    <string name="power_discharge_by" msgid="6453537733650125582">"Mal by vydržať približne <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_discharge_by_only" msgid="107616694963545745">"Mal by vydržať približne do <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Podľa vášho využitia (<xliff:g id="LEVEL">%2$s</xliff:g>) vydrží asi do <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Podľa vášho využitia vydrží asi do <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_discharge_by" msgid="6453537733650125582">"Vydrží asi do <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_discharge_by_only" msgid="107616694963545745">"Vydrží asi do <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_suggestion_extend_battery" msgid="4401408879069551485">"Predĺžiť výdrž batérie minimálne do <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Zostáva menej ako <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
@@ -402,8 +402,8 @@
     <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet sa môže čoskoro vypnúť (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
     <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Zariadenie sa môže čoskoro vypnúť (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Zostávajúci čas do úplného nabitia: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> do úplného nabitia"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Neznáme"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Nabíja sa"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"nabíja sa"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index b16d5d9..263b4d0 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -388,7 +388,7 @@
     <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Naprava bi morala glede na način uporabe (<xliff:g id="LEVEL">%2$s</xliff:g>) delovati do približno <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Naprava bi morala glede na način uporabe delovati do približno <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharge_by" msgid="6453537733650125582">"Naprava bi morala delovati do približno <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_discharge_by_only" msgid="107616694963545745">"Naprava bi morala delovati do približno <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_discharge_by_only" msgid="107616694963545745">"Moralo bi zadostovati do približno <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Do <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_suggestion_extend_battery" msgid="4401408879069551485">"Podaljšanje časa delovanja akumulatorja za dlje kot <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Preostalo manj kot <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 57e690d..a0f2ede 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -138,8 +138,8 @@
     <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"கடவுச்சொல் தேவைப்படாத திறந்த நெட்வொர்க்"</string>
     <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"கடவுச்சொல் தேவைப்படும் பாதுகாப்பான நெட்வொர்க்"</string>
     <string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
-    <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"அகற்றப்பட்ட பயன்பாடுகள்"</string>
-    <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"அகற்றப்பட்ட பயன்பாடுகள் மற்றும் பயனர்கள்"</string>
+    <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"அகற்றப்பட்ட ஆப்ஸ்"</string>
+    <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"அகற்றப்பட்ட ஆப்ஸ் மற்றும் பயனர்கள்"</string>
     <string name="data_usage_ota" msgid="5377889154805560860">"சிஸ்டம் புதுப்பிப்புகள்"</string>
     <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB டெதெரிங்"</string>
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"போர்ட்டபிள் ஹாட்ஸ்பாட்"</string>
@@ -264,7 +264,7 @@
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"வைஃபை இயங்கும் போதும் (வேகமான நெட்வொர்க் மாற்றத்திற்கு), மொபைல் டேட்டாவை எப்போதும் இயக்கத்தில் வைக்கும்."</string>
     <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"வன்பொருள் விரைவுப்படுத்துதல் இணைப்பு முறை கிடைக்கும் போது, அதைப் பயன்படுத்தும்"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB பிழைதிருத்தத்தை அனுமதிக்கவா?"</string>
-    <string name="adb_warning_message" msgid="7316799925425402244">"USB பிழைதிருத்தம் மேம்படுத்தல் நோக்கங்களுக்காக மட்டுமே. அதை உங்கள் கணினி மற்றும் சாதனத்திற்கு இடையில் தரவை நகலெடுக்கவும், அறிவிப்பு இல்லாமல் உங்கள் சாதனத்தில் பயன்பாடுகளை நிறுவவும், பதிவு தரவைப் படிக்கவும் பயன்படுத்தவும்."</string>
+    <string name="adb_warning_message" msgid="7316799925425402244">"USB பிழைதிருத்தம் மேம்படுத்தல் நோக்கங்களுக்காக மட்டுமே. அதை உங்கள் கணினி மற்றும் சாதனத்திற்கு இடையில் தரவை நகலெடுக்கவும், அறிவிப்பு இல்லாமல் உங்கள் சாதனத்தில் ஆப்ஸை நிறுவவும், பதிவு தரவைப் படிக்கவும் பயன்படுத்தவும்."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"நீங்கள் ஏற்கனவே அனுமதித்த எல்லா கணினிகளிலிருந்தும் USB பிழைத்திருத்தத்திற்கான அணுகலைத் திரும்பப்பெற வேண்டுமா?"</string>
     <string name="dev_settings_warning_title" msgid="7244607768088540165">"மேம்பட்ட அமைப்புகளை அனுமதிக்கவா?"</string>
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"இந்த அமைப்பு மேம்பட்டப் பயன்பாட்டிற்காக மட்டுமே. உங்கள் சாதனம் மற்றும் அதில் உள்ள பயன்பாடுகளைச் சிதைக்கும் அல்லது தவறாகச் செயல்படும் வகையில் பாதிப்பை ஏற்படுத்தும்."</string>
@@ -402,7 +402,7 @@
     <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"டேப்லெட் விரைவில் ஆஃப் ஆகக்கூடும் (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
     <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"சாதனம் விரைவில் ஆஃப் ஆகக்கூடும் (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"முழு சார்ஜாக <xliff:g id="TIME">%1$s</xliff:g> ஆகும்"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"முழு சார்ஜாக <xliff:g id="TIME">%1$s</xliff:g>ம் ஆகும்"</string>
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - முழு சார்ஜாக <xliff:g id="TIME">%2$s</xliff:g> ஆகும்"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"அறியப்படாத"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"சார்ஜ் ஆகிறது"</string>
@@ -437,7 +437,7 @@
     <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"சாதன மொழிகளைப் பயன்படுத்து"</string>
     <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> க்கான அமைப்புகளைத் திறப்பதில் தோல்வி"</string>
     <string name="ime_security_warning" msgid="4135828934735934248">"இந்த உள்ளீட்டு முறையானது, கடவுச்சொற்கள் மற்றும் கிரெடிட் கார்டு எண்கள் போன்ற தனிப்பட்ட தகவல் உள்பட நீங்கள் உள்ளிடும் எல்லா உரையையும் சேகரிக்கக்கூடும். இது <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> பயன்பாட்டிலிருந்து வந்துள்ளது. இந்த உள்ளீட்டு முறையைப் பயன்படுத்தவா?"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"குறிப்பு: மறுதொடக்கம் செய்த பிறகு, மொபைலைத் திறக்கும் வரை இந்தப் பயன்பாட்டால் தொடங்க முடியாது"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"குறிப்பு: மறுதொடக்கம் செய்த பிறகு, மொபைலைத் திறக்கும் வரை இந்த ஆப்ஸால் தொடங்க முடியாது"</string>
     <string name="ims_reg_title" msgid="7609782759207241443">"IMS பதிவின் நிலை"</string>
     <string name="ims_reg_status_registered" msgid="933003316932739188">"பதிவு செய்யப்பட்டது"</string>
     <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"பதிவு செய்யப்படவில்லை"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 83636dc..e591121 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -143,7 +143,7 @@
     <string name="data_usage_ota" msgid="5377889154805560860">"సిస్టమ్ అప్‌డేట్‌లు"</string>
     <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB టీథరింగ్"</string>
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"పోర్టబుల్ హాట్‌స్పాట్"</string>
-    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"బ్లూటూత్ టీథరింగ్"</string>
+    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"బ్లూటూత్ టెథెరింగ్"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"టీథరింగ్"</string>
     <string name="tether_settings_title_all" msgid="8356136101061143841">"టీథరింగ్ &amp; పోర్టబుల్ హాట్‌స్పాట్"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"అన్ని కార్యాలయ అనువర్తనాలు"</string>
@@ -376,7 +376,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"ప్రొటానోమలీ (ఎరుపు-ఆకుపచ్చ రంగు)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"ట్రైటనోమలీ (నీలం-పసుపు రంగు)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"రంగు సవరణ"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ఈ లక్షణం ప్రయోగాత్మకమైనది మరియు పనితీరుపై ప్రభావం చూపవచ్చు."</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ఈ ఫీచ‌ర్‌ ప్రయోగాత్మకమైనది, పనితీరుపై ప్రభావం చూపవచ్చు."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ద్వారా భర్తీ చేయబడింది"</string>
     <string name="power_remaining_settings_home_page" msgid="4845022416859002011">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="6123167166221295462">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> సమయం మిగిలి ఉంది"</string>
@@ -414,7 +414,7 @@
     <string name="disabled" msgid="9206776641295849915">"నిలిపివేయబడింది"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"అనుమతించినవి"</string>
     <string name="external_source_untrusted" msgid="2677442511837596726">"అనుమతించబడలేదు"</string>
-    <string name="install_other_apps" msgid="6986686991775883017">"తెలియని యాప్‌లను ఇన్‌స్టాల్ చేయండి"</string>
+    <string name="install_other_apps" msgid="6986686991775883017">"తెలియని యాప్‌లను ఇన్‌స్టాల్ చేయడం"</string>
     <string name="home" msgid="3256884684164448244">"సెట్టింగ్‌ల హోమ్"</string>
   <string-array name="battery_labels">
     <item msgid="8494684293649631252">"0%"</item>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 0b184d2..b3bef9d 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -403,7 +403,7 @@
     <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"อุปกรณ์อาจปิดเครื่องในไม่ช้า (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"อีก <xliff:g id="TIME">%1$s</xliff:g> จึงจะชาร์จเต็ม"</string>
-    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะชาร์จเต็ม"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>จนกว่าจะชาร์จเต็ม"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"ไม่ทราบ"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"กำลังชาร์จ"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"กำลังชาร์จ"</string>
diff --git a/packages/SettingsLib/res/values-uz/arrays.xml b/packages/SettingsLib/res/values-uz/arrays.xml
index 164aa93..4bc995f 100644
--- a/packages/SettingsLib/res/values-uz/arrays.xml
+++ b/packages/SettingsLib/res/values-uz/arrays.xml
@@ -241,7 +241,7 @@
     <item msgid="2355151170975410323">"“<xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g>” buyrug‘ida"</item>
   </string-array>
   <string-array name="debug_hw_overdraw_entries">
-    <item msgid="8190572633763871652">"YOQILMAGAN"</item>
+    <item msgid="8190572633763871652">"Yoqilmagan"</item>
     <item msgid="7688197031296835369">"Ortiqcha chizilgan joylarni ko‘rsatish"</item>
     <item msgid="2290859360633824369">"Muayyan rangdagi hududlarni ajratib belgilash"</item>
   </string-array>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 5dca475..0d3e8de 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -201,7 +201,7 @@
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Ushbu foydalanuvchi uchun VPN sozlamalari mavjud emas"</string>
     <string name="tethering_settings_not_available" msgid="6765770438438291012">"Ushbu foydalanuvchi uchun Modem rejimi sozlamalari mavjud emas"</string>
     <string name="apn_settings_not_available" msgid="7873729032165324000">"Ushbu foydalanuvchi uchun Internetga kirish nuqtasi (APN) sozlamalari mavjud emas"</string>
-    <string name="enable_adb" msgid="7982306934419797485">"USB orqali nosozliklarni tuzatish"</string>
+    <string name="enable_adb" msgid="7982306934419797485">"USB orqali nosozliklarni aniqlash"</string>
     <string name="enable_adb_summary" msgid="4881186971746056635">"USB orqali kompyuterga ulanganda tuzatish rejimi yoqilsin"</string>
     <string name="clear_adb_keys" msgid="4038889221503122743">"USB orqali nosozliklarni tuzatishni taqiqlash"</string>
     <string name="bugreport_in_power" msgid="7923901846375587241">"Xatoliklar hisoboti"</string>
@@ -264,7 +264,7 @@
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mobil internet har doim yoniq tursin, hatto Wi-Fi yoniq bo‘lsa ham (bir tarmoqdan ikkinchisiga tezroq o‘tish uchun)."</string>
     <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Modem rejimida apparatli tezlashtirishdan foydalanish (agar mavjud bo‘lsa)"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB orqali nosozliklarni tuzatishga ruxsat berilsinmi?"</string>
-    <string name="adb_warning_message" msgid="7316799925425402244">"USB orqali nosozliklarni tuzatish faqat dasturlash maqsadlarida yoqiladi. Undan ma‘lumotlarni qurilmangiz va kompyuter o‘rtasida ko‘chirish, ilovalarni xabarnomasiz o‘rnatish va jurnal ma‘lumotlarini o‘qish uchun foydalaniladi."</string>
+    <string name="adb_warning_message" msgid="7316799925425402244">"USB orqali nosozliklarni aniqlash faqat dasturlash maqsadlarida yoqiladi. Undan maʼlumotlarni qurilmangiz va kompyuter o‘rtasida ko‘chirish, ilovalarni xabarnomasiz o‘rnatish va jurnal maʼlumotlarini o‘qish uchun foydalaniladi."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"USB orqali nosozliklarni tuzatishga berilgan ruxsat siz hisobingizga kirgan barcha kompyuterlar uchun bekor qilinsinmi?"</string>
     <string name="dev_settings_warning_title" msgid="7244607768088540165">"Dasturlash sozlamalariga ruxsat berilsinmi?"</string>
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Bu sozlamalar faqat dasturlash maqsadlariga mo‘ljallangan. Shuning uchun, ular qurilmangizga va undagi ilovalariga shikast yetkazib, noto‘g‘ri ishlashiga sabab bo‘lishi mumkin."</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 5c06c80..003c457 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -402,8 +402,8 @@
     <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Máy tính bảng có thể sắp tắt (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
     <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Thiết bị có thể sắp tắt (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Còn <xliff:g id="TIME">%1$s</xliff:g> cho tới khi được sạc đầy"</string>
-    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho tới khi được sạc đầy"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> nữa sẽ được sạc đầy"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> nữa sẽ được sạc đầy"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Không xác định"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Đang sạc"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"đang sạc"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 460142c..bcf1f2d 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -60,7 +60,7 @@
     <string name="speed_label_medium" msgid="3175763313268941953">"适中"</string>
     <string name="speed_label_fast" msgid="7715732164050975057">"快"</string>
     <string name="speed_label_very_fast" msgid="2265363430784523409">"很快"</string>
-    <string name="preference_summary_default_combination" msgid="8532964268242666060">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
+    <string name="preference_summary_default_combination" msgid="8532964268242666060">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"已断开连接"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"正在断开连接..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"正在连接..."</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index e85199f..c641302 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -329,7 +329,7 @@
     <string name="show_all_anrs" msgid="4924885492787069007">"顯示背景 ANR"</string>
     <string name="show_all_anrs_summary" msgid="6636514318275139826">"為背景應用程式顯示「應用程式無回應」對話方塊"</string>
     <string name="show_notification_channel_warnings" msgid="1399948193466922683">"顯示通知管道警告"</string>
-    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"當應用程式未經有效管道發佈通知時,在畫面上顯示警告"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"當應用程式未經有效管道發布通知時,在畫面上顯示警告"</string>
     <string name="force_allow_on_external" msgid="3215759785081916381">"強制允許將應用程式寫入外部儲存空間"</string>
     <string name="force_allow_on_external_summary" msgid="3640752408258034689">"允許將任何應用程式寫入外部儲存空間 (無論資訊清單值為何)"</string>
     <string name="force_resizable_activities" msgid="8615764378147824985">"將活動強制設為可調整大小"</string>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index b2c10ec..f8c9bcc 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1057,6 +1057,9 @@
                 Settings.Global.NOTIFICATION_SNOOZE_OPTIONS,
                 GlobalSettingsProto.Notification.SNOOZE_OPTIONS);
         dumpSetting(s, p,
+                Settings.Global.NOTIFICATION_BUBBLES,
+                GlobalSettingsProto.Notification.BUBBLES);
+        dumpSetting(s, p,
                 Settings.Global.SMART_REPLIES_IN_NOTIFICATIONS_FLAGS,
                 GlobalSettingsProto.Notification.SMART_REPLIES_IN_NOTIFICATIONS_FLAGS);
         dumpSetting(s, p,
@@ -2150,7 +2153,7 @@
                 Settings.Secure.NOTIFICATION_BADGING,
                 SecureSettingsProto.Notification.BADGING);
         dumpSetting(s, p,
-                Settings.Secure.NOTIFICATION_BUBBLES,
+                Settings.Global.NOTIFICATION_BUBBLES,
                 SecureSettingsProto.Notification.BUBBLES);
         dumpSetting(s, p,
                 Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 5cd29b7..fbfbe7f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -3238,7 +3238,7 @@
         }
 
         private final class UpgradeController {
-            private static final int SETTINGS_VERSION = 182;
+            private static final int SETTINGS_VERSION = 183;
 
             private final int mUserId;
 
@@ -4255,19 +4255,7 @@
 
                 if (currentVersion == 173) {
                     // Version 173: Set the default value for Secure Settings: NOTIFICATION_BUBBLES
-
-                    final SettingsState secureSettings = getSecureSettingsLocked(userId);
-
-                    final Setting bubblesSetting = secureSettings.getSettingLocked(
-                            Secure.NOTIFICATION_BUBBLES);
-
-                    if (bubblesSetting.isNull()) {
-                        secureSettings.insertSettingLocked(Secure.NOTIFICATION_BUBBLES,
-                                getContext().getResources().getBoolean(
-                                        R.bool.def_notification_bubbles) ? "1" : "0", null,
-                                true, SettingsState.SYSTEM_PACKAGE_NAME);
-                    }
-
+                    // Removed. Moved NOTIFICATION_BUBBLES to Global Settings.
                     currentVersion = 174;
                 }
 
@@ -4391,14 +4379,9 @@
                 if (currentVersion == 179) {
                     // Version 178: Reset the default for Secure Settings: NOTIFICATION_BUBBLES
                     // This is originally set in version 173, however, the default value changed
-                    // so this step is to ensure the value is updated to the correct defaulte
-                    final SettingsState secureSettings = getSecureSettingsLocked(userId);
+                    // so this step is to ensure the value is updated to the correct default.
 
-                    secureSettings.insertSettingLocked(Secure.NOTIFICATION_BUBBLES,
-                            getContext().getResources().getBoolean(
-                                    R.bool.def_notification_bubbles) ? "1" : "0", null,
-                                    true, SettingsState.SYSTEM_PACKAGE_NAME);
-
+                    // Removed. Moved NOTIFICATION_BUBBLES to Global Settings.
                     currentVersion = 180;
                 }
 
@@ -4452,6 +4435,20 @@
                     currentVersion = 182;
                 }
 
+                if (currentVersion == 182) {
+                    // Remove secure bubble settings.
+                    getSecureSettingsLocked(userId).deleteSettingLocked(
+                            Secure.NOTIFICATION_BUBBLES);
+
+                    // Add global bubble settings.
+                    getGlobalSettingsLocked().insertSettingLocked(Global.NOTIFICATION_BUBBLES,
+                            getContext().getResources().getBoolean(
+                                    R.bool.def_notification_bubbles) ? "1" : "0", null /* tag */,
+                            true /* makeDefault */, SettingsState.SYSTEM_PACKAGE_NAME);
+
+                    currentVersion = 183;
+                }
+
                 // vXXX: Add new settings above this point.
 
                 if (currentVersion != newVersion) {
diff --git a/packages/Shell/res/values-zh-rTW/strings.xml b/packages/Shell/res/values-zh-rTW/strings.xml
index fc6397d..96671c8 100644
--- a/packages/Shell/res/values-zh-rTW/strings.xml
+++ b/packages/Shell/res/values-zh-rTW/strings.xml
@@ -25,9 +25,9 @@
     <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"系統即將在手機上顯示錯誤報告"</string>
     <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"選取即可分享錯誤報告"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"輕觸即可分享錯誤報告"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"選取即可分享不包含螢幕擷取畫面的錯誤報告;你也可以等候螢幕畫面擷取完畢"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"輕觸即可分享無螢幕擷圖的錯誤報告;你也可以等候螢幕畫面擷取完畢"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"輕觸即可分享無螢幕擷圖的錯誤報告;你也可以等候螢幕畫面擷取完畢"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"選取即可分享不包含螢幕截圖的錯誤報告;你也可以等候螢幕畫面擷取完畢"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"輕觸即可分享無螢幕截圖的錯誤報告;你也可以等候螢幕畫面擷取完畢"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"輕觸即可分享無螢幕截圖的錯誤報告;你也可以等候螢幕畫面擷取完畢"</string>
     <string name="bugreport_confirm" msgid="5917407234515812495">"錯誤報告的資料來自系統的各種記錄檔,當中可能包含敏感資料 (例如應用程式使用情形和位置資料)。請務必只與你信任的使用者和應用程式分享錯誤報告。"</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"不要再顯示"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"錯誤報告"</string>
@@ -35,9 +35,9 @@
     <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"無法在 ZIP 檔案中加入錯誤報告"</string>
     <string name="bugreport_unnamed" msgid="2800582406842092709">"未命名"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"詳細資料"</string>
-    <string name="bugreport_screenshot_action" msgid="8677781721940614995">"螢幕擷取畫面"</string>
-    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"已成功拍攝螢幕擷取畫面。"</string>
-    <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"無法拍攝螢幕擷取畫面。"</string>
+    <string name="bugreport_screenshot_action" msgid="8677781721940614995">"螢幕截圖"</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"已成功拍攝螢幕截圖。"</string>
+    <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"無法拍攝螢幕截圖。"</string>
     <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"錯誤報告 <xliff:g id="ID">#%d</xliff:g> 的詳細資料"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"檔案名稱"</string>
     <string name="bugreport_info_title" msgid="2306030793918239804">"錯誤標題"</string>
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 4c52b132..d674be4 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -71,10 +71,6 @@
         "telephony-common",
     ],
 
-    aaptflags: [
-        "--extra-packages",
-        "com.android.keyguard",
-    ],
     kotlincflags: ["-Xjvm-default=enable"],
 
     plugins: ["dagger2-compiler-2.19"],
@@ -114,6 +110,7 @@
         "androidx.lifecycle_lifecycle-extensions",
         "androidx.dynamicanimation_dynamicanimation",
         "androidx-constraintlayout_constraintlayout",
+        "iconloader_base",
         "SystemUI-tags",
         "SystemUI-proto",
         "metrics-helper-lib",
@@ -132,7 +129,7 @@
     kotlincflags: ["-Xjvm-default=enable"],
     aaptflags: [
         "--extra-packages",
-        "com.android.keyguard:com.android.systemui",
+        "com.android.systemui",
     ],
     plugins: ["dagger2-compiler-2.19"],
 }
@@ -160,10 +157,6 @@
     kotlincflags: ["-Xjvm-default=enable"],
 
     dxflags: ["--multi-dex"],
-    aaptflags: [
-        "--extra-packages",
-        "com.android.keyguard",
-    ],
     required: ["privapp_whitelist_com.android.systemui"],
 
 }
@@ -180,10 +173,6 @@
     privileged: true,
 
     dxflags: ["--multi-dex"],
-    aaptflags: [
-        "--extra-packages",
-        "com.android.keyguard",
-    ],
     optimize: {
         proguard_flags_files: ["proguard.flags", "legacy/recents/proguard.flags"],
     },
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 17274f4..403e894 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -20,6 +20,7 @@
         xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
         package="com.android.systemui"
         android:sharedUserId="android.uid.systemui"
+        xmlns:tools="http://schemas.android.com/tools"
         coreApp="true">
 
     <!-- Using OpenGL ES 2.0 -->
@@ -259,7 +260,8 @@
         android:theme="@style/Theme.SystemUI"
         android:defaultToDeviceProtectedStorage="true"
         android:directBootAware="true"
-        android:appComponentFactory="androidx.core.app.CoreComponentFactory">
+        tools:replace="android:appComponentFactory"
+        android:appComponentFactory=".SystemUIAppComponentFactory">
         <!-- Keep theme in sync with SystemUIApplication.onCreate().
              Setting the theme on the application does not affect views inflated by services.
              The application theme is set again from onCreate to take effect for those views. -->
@@ -607,6 +609,10 @@
                 android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden"
                 android:process=":ui"
                 android:visibleToInstantApps="true">
+            <intent-filter>
+                <action android:name="android.intent.action.CHOOSER" />
+                <category android:name="android.intent.category.VOICE" />
+            </intent-filter>
         </activity>
 
         <!-- Doze with notifications, run in main sysui process for every user  -->
diff --git a/packages/SystemUI/docs/dagger.md b/packages/SystemUI/docs/dagger.md
index c2159df..c440fba 100644
--- a/packages/SystemUI/docs/dagger.md
+++ b/packages/SystemUI/docs/dagger.md
@@ -53,7 +53,7 @@
 ### Adding injection to a new SystemUI object
 
 Anything that depends on any `@Singleton` provider from SystemUIRootComponent
-should be declared as an `@Subcomponent` of the root component, this requires
+should be declared as a `@Subcomponent` of the root component. This requires
 declaring your own interface for generating your own modules or just the
 object you need injected. The subcomponent also needs to be added to
 SystemUIRootComponent in SystemUIFactory so it can be acquired.
@@ -204,6 +204,13 @@
 }
 ```
 
+## Updating Dagger2
+
+Binaries can be downloaded from https://repo1.maven.org/maven2/com/google/dagger/ and then loaded
+into
+[/prebuilts/tools/common/m2/repository/com/google/dagger/](http://cs/android/prebuilts/tools/common/m2/repository/com/google/dagger/)
+
+
 ## TODO List
 
  - Eliminate usages of Dependency#get
diff --git a/packages/SystemUI/docs/physics-animation-layout.md b/packages/SystemUI/docs/physics-animation-layout.md
index 488c465..de2ee9e 100644
--- a/packages/SystemUI/docs/physics-animation-layout.md
+++ b/packages/SystemUI/docs/physics-animation-layout.md
@@ -1,7 +1,11 @@
 # Physics Animation Layout
 
 ## Overview
-**PhysicsAnimationLayout** works with an implementation of **PhysicsAnimationController** to construct and maintain physics animations for each of its child views. During the initial construction of the animations, the layout queries the controller for configuration settings such as which properties to animate, which animations to chain together, and what stiffness or bounciness to use. Once the animations are built to the controller’s specifications, the controller can then ask the layout to start, stop and manipulate them arbitrarily to achieve any desired animation effect. The controller is notified whenever children are added or removed from the layout, so that it can animate their entrance or exit, respectively.
+**PhysicsAnimationLayout** works with implementations of **PhysicsAnimationController** to configure and run physics-based animations for each of its child views. During the initial construction of the animations, the layout queries the controller for basic configuration settings such as which properties to animate, which animations to chain together, and the default physics parameters to use.
+
+Once the animations are built, the controller can access **PhysicsPropertyAnimator** instances to run them. The animator behaves similarly to the familiar `ViewPropertyAnimator`, with the ability to animate `alpha`, `translation`, and `scale` values. It also supports additional functionality such as `followAnimatedTargetAlongPath` for more advanced motion.
+
+The controller is notified whenever children are added or removed from the layout, so that it can animate their entrance or exit, respectively.
 
 An example usage is Bubbles, which uses a PhysicsAnimationLayout for its stack of bubbles. Bubbles has controller subclasses including StackAnimationController and ExpansionAnimationController. StackAnimationController tells the layout to configure the translation animations to be chained (for the ‘following’ drag effect), and has methods such as ```moveStack(x, y)``` to animate the stack to a given point. ExpansionAnimationController asks for no animations to be chained, and exposes methods like ```expandStack()``` and ```collapseStack()```, which animate the bubbles to positions along the bottom of the screen.
 
@@ -27,7 +31,7 @@
 ### Animation Control Methods
 Once the layout has used the controller’s configuration properties to build the animations, the controller can use them to actually run animations. This is done for two reasons - reacting to a view being added or removed, or responding to another class (such as a touch handler or broadcast receiver) requesting an animation. ```onChildAdded```, ```onChildRemoved```, and ```setChildVisibility``` are called automatically by the layout, giving the controller the opportunity to animate the child in/out/visible/gone. Custom methods are called by anyone with access to the controller instance to do things like expand, collapse, or move the child views.
 
-In either case, the controller can use `super.animationForChild` to retrieve a `PhysicsPropertyAnimator` instance. This object behaves similarly to the `ViewPropertyAnimator` object you would receive from `View.animate()`. 
+In either case, the controller can use `super.animationForChild` to retrieve a `PhysicsPropertyAnimator` instance. This object behaves similarly to the `ViewPropertyAnimator` object you would receive from `View.animate()`.
 
 #### PhysicsPropertyAnimator
 
@@ -36,9 +40,14 @@
 - `translationX/Y/Z(float)`
 - `scaleX/Y(float)`
 
+...as well as shortcut methods to reduce the amount of boilerplate code needed for common use cases:
+- `position(float, float, Runnable…)`, which starts translationX and translationY animations, and calls the provided callbacks only when both animations have completed.
+- `followAnimatedTargetAlongPath(Path, int, TimeInterpolator)`, which animates a ‘target’ point along the given path using a traditional Animator. As the target moves, the translationX/Y physics animations are updated to follow the target, similarly to how they might follow a touch event location. This results in the view roughly following the path, but with natural motion that takes momentum into account. For example, if a path makes a 90 degree turn to the right, the physics animations will cause the view to curve naturally towards the new trajectory.
+
 It also provides the following configuration methods:
 - `withStartDelay(int)`, for starting the animation after a given delay.
 - `withStartVelocity(float)`, for starting the animation with the given start velocity.
+- `withStiffness(float)` and `withDampingRatio(float)`, for overriding the default physics param values returned by the controller’s getSpringForce method.
 - `withPositionStartVelocities(float, float)`, for setting specific start velocities for TRANSLATION_X and TRANSLATION_Y, since these typically differ.
 - `start(Runnable)`, to start the animation, with an optional end action to call when the animations for every property (including chained animations) have completed.
 
@@ -61,8 +70,7 @@
 
 - Often, animations will set starting values for properties before the animation begins. Property methods like `translationX` have an overloaded variant: `translationX(from, to)`. When `start()` is called, the animation will set the view's translationX property to `from` before beginning the animation to `to`.
 - We may want to use different end actions for each property. For example, if we're animating a view to the bottom of the screen, and also fading it out, we might want to perform an action as soon as the fade out is complete. We can use `alpha(to, endAction)`, which will call endAction as soon as the alpha animation is finished. A special case is `position(x, y, endAction)`, where the endAction is called when both translationX and translationY animations have completed.
-
-`PhysicsAnimationController` also provides `animationsForChildrenFromIndex(int, ChildAnimationConfigurator)`. This is a convenience method for starting animations on multiple child views, starting at the given index. The `ChildAnimationConfigurator` is called with a `PhysicsPropertyAnimator` for each child, where calls to methods like `translationX` and `withStartVelocity` can be made. `animationsForChildrenFromIndex` returns a `MultiAnimationStarter` with a single method, `startAll(endAction)`, which starts all of the animations and calls the end action when they have all completed.
+- `PhysicsAnimationController` also provides `animationsForChildrenFromIndex(int, ChildAnimationConfigurator)`. This is a convenience method for starting animations on multiple child views, starting at the given index. The `ChildAnimationConfigurator` is called with a `PhysicsPropertyAnimator` for each child, where calls to methods like `translationX` and `withStartVelocity` can be made. `animationsForChildrenFromIndex` returns a `MultiAnimationStarter` with a single method, `startAll(endAction)`, which starts all of the animations and calls the end action when they have all completed.
 
 ##### Examples
 Spring the stack of bubbles (whose animations are chained) to the bottom of the screen, shrinking them to 50% size. Once the first bubble is done shrinking, begin fading them out, and then remove them all from the parent once all bubbles have faded out:
@@ -93,16 +101,22 @@
     .startAll(removeFirstView);
 ```
 
+Move a view up along the left side of the screen, and then to the top right of the screen (assume a view that is currently halfway down the left side of the screen). When the translation animations have finished following the target, call a callback:
+
+```
+Path path = new Path();
+path.moveTo(view.getTranslationX(), view.getTranslationY());
+path.lineTo(view.getTranslationX(), 0);
+path.lineTo(mScreenWidth, 0);
+animationForChild(view)
+    .followAnimatedTargetAlongPath(path, 100, new LinearInterpolator())
+    .start(callbackAfterFollowingFinished);
+```
+
 ## PhysicsAnimationLayout
 The layout itself is a FrameLayout descendant with a few extra methods:
 
-```setController(PhysicsAnimationController controller)```
-Attaches the layout to the controller, so that the controller can access the layout’s protected methods. It also constructs or reconfigures the physics animations according to the new controller’s configuration methods.
+```setActiveController(PhysicsAnimationController controller)```
+Sets the given controller as the active controller for the layout. This causes the layout to construct or reconfigure the physics animations according to the new controller’s configuration methods, and halt any in-progress animations.
 
-```setEndListenerForProperty(ViewProperty property, AnimationEndListener endListener)```
-Sets an end listener that is called when all animations on the given property have ended.
-
-```setMaxRenderedChildren(int max)```
-Child views beyond this limit will be set to GONE, and won't be animated, for performance reasons. Defaults to **5**.
-
-It has one protected method, ```animateValueForChildAtIndex(ViewProperty property, int index, float value)```, which is visible to PhysicsAnimationController descendants. This method dispatches the given value to the appropriate animation.
\ No newline at end of file
+Only the currently active controller is allowed to start animations. If a different controller is set as the active controller, the previous controller will no longer be able to start animations. Attempts to do so will have no effect. This is to ensure that multiple controllers aren’t updating animations at the same time, which can cause undefined behavior.
\ No newline at end of file
diff --git a/packages/SystemUI/legacy/recents/res/values-vi/strings.xml b/packages/SystemUI/legacy/recents/res/values-vi/strings.xml
index f672a3d..aefeae9 100644
--- a/packages/SystemUI/legacy/recents/res/values-vi/strings.xml
+++ b/packages/SystemUI/legacy/recents/res/values-vi/strings.xml
@@ -34,7 +34,7 @@
     <string name="recents_launch_disabled_message" msgid="826461671965217243">"<xliff:g id="APP">%s</xliff:g> bị tắt ở chế độ an toàn."</string>
     <string name="recents_stack_action_button_label" msgid="1974273390109881497">"Xóa tất cả"</string>
     <string name="recents_drag_hint_message" msgid="610417221848280136">"Kéo vào đây để sử dụng chế độ chia đôi màn hình"</string>
-    <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="488987777874979435">"Phân tách ngang"</string>
+    <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="488987777874979435">"Chia ngang"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="2498375296906391117">"Phân tách dọc"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="7368405969130304811">"Tùy chỉnh phân tách"</string>
     <string name="recents_accessibility_split_screen_top" msgid="8773505308411722524">"Chia đôi màn hình lên trên"</string>
diff --git a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackView.java
index 14fd149..b89218c 100644
--- a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackView.java
@@ -41,8 +41,10 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.recents.LegacyRecentsImpl;
 import com.android.systemui.recents.RecentsActivity;
 import com.android.systemui.recents.RecentsActivityLaunchState;
@@ -86,15 +88,15 @@
 import com.android.systemui.recents.misc.DozeTrigger;
 import com.android.systemui.recents.misc.ReferenceCountedTrigger;
 import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.recents.model.TaskStack;
 import com.android.systemui.recents.utilities.AnimationProps;
 import com.android.systemui.recents.utilities.Utilities;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.recents.model.TaskStack;
 import com.android.systemui.recents.views.grid.GridTaskView;
 import com.android.systemui.recents.views.grid.TaskGridLayoutAlgorithm;
 import com.android.systemui.recents.views.grid.TaskViewFocusFrame;
-
+import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
+
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -256,7 +258,8 @@
         mLayoutAlgorithm = new TaskStackLayoutAlgorithm(context, this);
         mStableLayoutAlgorithm = new TaskStackLayoutAlgorithm(context, null);
         mStackScroller = new TaskStackViewScroller(context, this, mLayoutAlgorithm);
-        mTouchHandler = new TaskStackViewTouchHandler(context, this, mStackScroller);
+        mTouchHandler = new TaskStackViewTouchHandler(
+                context, this, mStackScroller, Dependency.get(FalsingManager.class));
         mAnimationHelper = new TaskStackAnimationHelper(context, this);
         mTaskCornerRadiusPx = LegacyRecentsImpl.getConfiguration().isGridEnabled ?
                 res.getDimensionPixelSize(R.dimen.recents_grid_task_view_rounded_corners_radius) :
diff --git a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index dd6926c..a7fb4fa 100644
--- a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -37,6 +37,7 @@
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.LegacyRecentsImpl;
 import com.android.systemui.recents.events.EventBus;
@@ -107,7 +108,7 @@
     boolean mInterceptedBySwipeHelper;
 
     public TaskStackViewTouchHandler(Context context, TaskStackView sv,
-            TaskStackViewScroller scroller) {
+            TaskStackViewScroller scroller, FalsingManager falsingManager) {
         Resources res = context.getResources();
         ViewConfiguration configuration = ViewConfiguration.get(context);
         mContext = context;
@@ -119,7 +120,7 @@
         mWindowTouchSlop = configuration.getScaledWindowTouchSlop();
         mFlingAnimUtils = new FlingAnimationUtils(context, 0.2f);
         mOverscrollSize = res.getDimensionPixelSize(R.dimen.recents_fling_overscroll_distance);
-        mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, context) {
+        mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, context, falsingManager) {
             @Override
             protected float getSize(View v) {
                 return getScaledDismissSize();
diff --git a/packages/SystemUI/res-keyguard/values-et/strings.xml b/packages/SystemUI/res-keyguard/values-et/strings.xml
index 7e03a5c..b6cac13 100644
--- a/packages/SystemUI/res-keyguard/values-et/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-et/strings.xml
@@ -117,7 +117,7 @@
     <string name="kg_pin_accepted" msgid="7637293533973802143">"Kood on õige."</string>
     <string name="keyguard_carrier_default" msgid="4274828292998453695">"Teenus puudub."</string>
     <string name="accessibility_ime_switch_button" msgid="2695096475319405612">"Vaheta sisestusmeetodit"</string>
-    <string name="airplane_mode" msgid="3807209033737676010">"Lennurežiim"</string>
+    <string name="airplane_mode" msgid="3807209033737676010">"Lennukirežiim"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="7246972020562621506">"Pärast seadme taaskäivitamist tuleb sisestada muster"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"Pärast seadme taaskäivitamist tuleb sisestada PIN-kood"</string>
     <string name="kg_prompt_reason_restart_password" msgid="6984641181515902406">"Pärast seadme taaskäivitamist tuleb sisestada parool"</string>
diff --git a/packages/SystemUI/res/drawable/bubble_dismiss_circle.xml b/packages/SystemUI/res/drawable/bubble_dismiss_circle.xml
index 1661bb2..8c7e82f 100644
--- a/packages/SystemUI/res/drawable/bubble_dismiss_circle.xml
+++ b/packages/SystemUI/res/drawable/bubble_dismiss_circle.xml
@@ -24,4 +24,5 @@
         android:width="1dp"
         android:color="#66FFFFFF" />
 
+    <solid android:color="#B3000000" />
 </shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/bubble_dismiss_target.xml b/packages/SystemUI/res/layout/bubble_dismiss_target.xml
index 245177c..ca085b6 100644
--- a/packages/SystemUI/res/layout/bubble_dismiss_target.xml
+++ b/packages/SystemUI/res/layout/bubble_dismiss_target.xml
@@ -20,6 +20,13 @@
     android:layout_height="@dimen/pip_dismiss_gradient_height"
     android:layout_gravity="bottom|center_horizontal">
 
+    <FrameLayout
+        android:id="@+id/bubble_dismiss_circle"
+        android:layout_width="@dimen/bubble_dismiss_encircle_size"
+        android:layout_height="@dimen/bubble_dismiss_encircle_size"
+        android:layout_gravity="center"
+        android:background="@drawable/bubble_dismiss_circle" />
+
     <LinearLayout
         android:id="@+id/bubble_dismiss_icon_container"
         android:layout_width="wrap_content"
@@ -38,29 +45,5 @@
             android:layout_width="24dp"
             android:layout_height="24dp"
             android:src="@drawable/bubble_dismiss_icon" />
-
-        <TextView
-            android:id="@+id/bubble_dismiss_text"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="9dp"
-            android:layout_marginBottom="9dp"
-            android:layout_marginLeft="8dp"
-            android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
-            android:textColor="@android:color/white"
-            android:shadowColor="@android:color/black"
-            android:shadowDx="-1"
-            android:shadowDy="1"
-            android:shadowRadius="0.01"
-            android:text="@string/bubble_dismiss_text" />
-
     </LinearLayout>
-
-    <FrameLayout
-        android:id="@+id/bubble_dismiss_circle"
-        android:layout_width="@dimen/bubble_dismiss_encircle_size"
-        android:layout_height="@dimen/bubble_dismiss_encircle_size"
-        android:layout_gravity="center"
-        android:alpha="0"
-        android:background="@drawable/bubble_dismiss_circle" />
 </FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/bubble_view.xml b/packages/SystemUI/res/layout/bubble_view.xml
index a8eb2914..e2dea45 100644
--- a/packages/SystemUI/res/layout/bubble_view.xml
+++ b/packages/SystemUI/res/layout/bubble_view.xml
@@ -24,7 +24,6 @@
         android:id="@+id/bubble_image"
         android:layout_width="@dimen/individual_bubble_size"
         android:layout_height="@dimen/individual_bubble_size"
-        android:padding="@dimen/bubble_view_padding"
         android:clipToPadding="false"/>
 
 </com.android.systemui.bubbles.BubbleView>
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index 21c2c6b..1bfc4c0 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -24,48 +24,7 @@
     android:outlineProvider="none"
     android:elevation="5dp" > <!-- Put it above the status bar header -->
 
-    <LinearLayout
-        android:id="@+id/keyguard_indication_area"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginBottom="@dimen/keyguard_indication_margin_bottom"
-        android:layout_gravity="bottom|center_horizontal"
-        android:orientation="horizontal">
-
-        <include layout="@layout/left_docked_overlay" />
-
-        <LinearLayout
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:layout_gravity="center_vertical|center_horizontal"
-            android:orientation="vertical">
-
-            <com.android.systemui.statusbar.phone.KeyguardIndicationTextView
-                android:id="@+id/keyguard_indication_enterprise_disclosure"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:gravity="center"
-                android:paddingStart="@dimen/keyguard_indication_text_padding"
-                android:paddingEnd="@dimen/keyguard_indication_text_padding"
-                android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"
-                android:visibility="gone" />
-
-            <com.android.systemui.statusbar.phone.KeyguardIndicationTextView
-                android:id="@+id/keyguard_indication_text"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:gravity="center"
-                android:paddingStart="@dimen/keyguard_indication_text_padding"
-                android:paddingEnd="@dimen/keyguard_indication_text_padding"
-                android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"
-                android:accessibilityLiveRegion="polite" />
-
-        </LinearLayout>
-
-        <include layout="@layout/right_docked_overlay" />
-
-    </LinearLayout>
+    <include layout="@layout/keyguard_indication_area_overlay" />
 
     <FrameLayout
         android:id="@+id/preview_container"
diff --git a/packages/SystemUI/res/layout/keyguard_indication_area_overlay.xml b/packages/SystemUI/res/layout/keyguard_indication_area_overlay.xml
new file mode 100644
index 0000000..cc30a68
--- /dev/null
+++ b/packages/SystemUI/res/layout/keyguard_indication_area_overlay.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/keyguard_indication_area"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_marginBottom="@dimen/keyguard_indication_margin_bottom"
+    android:layout_gravity="bottom|center_horizontal"
+    android:orientation="vertical">
+
+  <include layout="@layout/keyguard_indication_text_view" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/keyguard_indication_text_view.xml b/packages/SystemUI/res/layout/keyguard_indication_text_view.xml
new file mode 100644
index 0000000..2b2100c
--- /dev/null
+++ b/packages/SystemUI/res/layout/keyguard_indication_text_view.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <com.android.systemui.statusbar.phone.KeyguardIndicationTextView
+        android:id="@+id/keyguard_indication_enterprise_disclosure"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:paddingStart="@dimen/keyguard_indication_text_padding"
+        android:paddingEnd="@dimen/keyguard_indication_text_padding"
+        android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"
+        android:visibility="gone"/>
+
+    <com.android.systemui.statusbar.phone.KeyguardIndicationTextView
+        android:id="@+id/keyguard_indication_text"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:paddingStart="@dimen/keyguard_indication_text_padding"
+        android:paddingEnd="@dimen/keyguard_indication_text_padding"
+        android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"
+        android:accessibilityLiveRegion="polite"/>
+</merge>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/left_docked_overlay.xml b/packages/SystemUI/res/layout/left_docked_overlay.xml
deleted file mode 100644
index 430143c..0000000
--- a/packages/SystemUI/res/layout/left_docked_overlay.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2019 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.
-  -->
-
-<!-- empty stub -->
-<merge />
diff --git a/packages/SystemUI/res/layout/qs_carrier_group.xml b/packages/SystemUI/res/layout/qs_carrier_group.xml
index 36f382b..56efb49 100644
--- a/packages/SystemUI/res/layout/qs_carrier_group.xml
+++ b/packages/SystemUI/res/layout/qs_carrier_group.xml
@@ -25,6 +25,17 @@
     android:orientation="horizontal">
 
 
+    <com.android.systemui.util.AutoMarqueeTextView
+        android:id="@+id/no_carrier_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="@style/TextAppearance.QS.Status"
+        android:textDirection="locale"
+        android:marqueeRepeatLimit="marquee_forever"
+        android:singleLine="true"
+        android:maxEms="7"
+        android:visibility="gone"/>
+
     <include
         layout="@layout/qs_carrier"
         android:id="@+id/carrier1"
diff --git a/packages/SystemUI/res/layout/right_docked_overlay.xml b/packages/SystemUI/res/layout/right_docked_overlay.xml
deleted file mode 100644
index 430143c..0000000
--- a/packages/SystemUI/res/layout/right_docked_overlay.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2019 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.
-  -->
-
-<!-- empty stub -->
-<merge />
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index a914930..9716a00 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -44,7 +44,7 @@
     </com.android.systemui.statusbar.BackDropView>
 
     <com.android.systemui.statusbar.ScrimView
-        android:id="@+id/scrim_behind"
+        android:id="@+id/scrim_for_bubble"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:importantForAccessibility="no"
@@ -56,6 +56,14 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content" />
 
+    <com.android.systemui.statusbar.ScrimView
+        android:id="@+id/scrim_behind"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:importantForAccessibility="no"
+        sysui:ignoreRightInset="true"
+        />
+
     <include layout="@layout/status_bar_expanded"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index e0907ae..538fdce 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Minder dringende kennisgewings hieronder"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Tik weer om oop te maak"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Swiep op om oop te maak"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Swiep op om weer te probeer"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Jou organisasie bestuur hierdie toestel"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Hierdie toestel word deur <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> bestuur"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Swiep vanaf ikoon vir foon"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Dit hou dit in sig totdat jy dit ontspeld. Raak en hou Tuis om dit te ontspeld."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Raak en hou die Terug- en Oorsig-knoppie om hierdie skerm te ontspeld"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Raak en hou die Terug- en Tuis-knoppie om hierdie skerm te ontspeld"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Swiep na bo en hou om hierdie skerm te ontspeld"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Het dit"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nee, dankie"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Skerm is vasgespeld"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index a1067af..82339f4 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"በጣም አስቸካይ ያልሆኑ ማሳወቂያዎች ከታች"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"ለመክፈት ዳግም መታ ያድርጉ"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"ለመክፈት በጣት ወደ ላይ ጠረግ ያድርጉ"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"እንደገና ለመሞከር ወደ ላይ ይጥረጉ"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ይህ መሣሪያ በእርስዎ ድርጅት የሚተዳደር ነው"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"ይህ መሣሪያ በ<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> የሚተዳደር ነው"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ለስልክ ከአዶ ላይ ጠረግ ያድርጉ"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"ይሄ እስኪነቅሉት ድረስ በእይታ ውስጥ ያስቀምጠዋል። ለመንቀል መነሻ የሚለውን ይንኩ እና ይያዙ።"</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"ይህን ማያ ገጽ ለመንቀል ተመለስ እና አጠቃላይ ዕይታ አዝራሮችን ይንኩ እና ይያዙ"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ይህን ማያ ገጽ ለመንቀል ተመለስ እና መነሻ የሚለውን ይንኩ እና ይያዙ"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"ይህን ማያ ገጽ ለመንቀል ወደ ላይ ጠርገው ይያዙ"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"ገባኝ"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"አይ፣ አመሰግናለሁ"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"ማያ ገጽ ተሰክቷል"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index d67359c..2792c3b 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -409,6 +409,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"الإشعارات الأقل إلحاحًا أدناه"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"انقر مرة أخرى للفتح"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"يمكنك الفتح بالتمرير سريعًا لأعلى."</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"مرِّر سريعًا للأعلى لإعادة المحاولة."</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"تتولى مؤسستك إدارة هذا الجهاز."</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"تتم إدارة هذا الجهاز بواسطة <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"يمكنك التمرير سريعًا من الرمز لتشغيل الهاتف"</string>
@@ -556,6 +557,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"يؤدي هذا إلى استمرار عرض الشاشة المُختارة إلى أن تتم إزالة تثبيتها. المس مع الاستمرار زر \"الشاشة الرئيسية\" لإزالة التثبيت."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"لإزالة تثبيت هذه الشاشة، يمكنك النقر مع الاستمرار على زرّي \"الرجوع\" و\"النظرة العامة\"."</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"لإزالة تثبيت هذه الشاشة، يمكنك النقر مع الاستمرار على زرّي \"الرجوع\" و\"الشاشة الرئيسية\"."</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"مرّر الشاشة بسرعة للأعلى مع الاستمرار لإزالة تثبيت الشاشة."</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"حسنًا"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"لا، شكرًا"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"تمّ تثبيت الشاشة."</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index c7b5f08..7d8ba64 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"কম জৰুৰী জাননীসমূহ তলত"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"খুলিবলৈ পুনৰাই টিপক"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"খুলিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"পুনৰ চেষ্টা কৰিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"আপোনাৰ প্ৰতিষ্ঠানে এই ডিভাইচটো পৰিচালনা কৰে"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"এই ডিভাইচটো <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>ৰ দ্বাৰা পৰিচালিত।"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ফ\'নৰ বাবে আইকনৰপৰা ছোৱাইপ কৰক"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"এই কাৰ্যই আপুনি আনপিন নকৰালৈকে ইয়াক দেখা পোৱা অৱস্থাত ৰাখে। আনপিন কৰিবলৈ পিছলৈ যাওক আৰু হ\'মত স্পৰ্শ কৰি সেঁচি ধৰক।"</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"এই স্ক্ৰীণখন আনপিন কৰিবলৈ পিছলৈ যাওক আৰু অৱলোকন বুটামত স্পৰ্শ কৰি হেঁচি ধৰক।"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"এই স্ক্ৰীণখন আনপিন কৰিবলৈ পিছলৈ যাওক আৰু হ\'ম বুটামত স্পৰ্শ কৰি হেঁচি ধৰক।"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"এই স্ক্রীণখন আনপিন কৰিবলৈ ওপৰলৈ ছোৱাইপ কৰি ধৰি ৰাখক"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"বুজি পালোঁ"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"নালাগে, ধন্যবাদ"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"স্ক্ৰীণ পিন কৰা হ’ল"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 847d10d..5ae4d2d 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Daha az təcili bildirişlər aşağıdadır"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Açmaq üçün yenidən tıklayın"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Açmaq üçün yuxarı sürüşdürün"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Yenidən cəhd etmək üçün yuxarı sürüşdürün"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Bu cihaz təşkilatınız tərəfindən idarə olunur"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tərəfindən idarə olunur"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Telefon üçün ikonadan sürüşdürün"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Sancaq götürülənə qədər bu görünəcək. Sancağı götürmək üçün Əsas səhifə düyməsinə basıb saxlayın."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Bu ekrandan sancağı götürmək üçün Geri və İcmal düymələrinə basıb saxlayın"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Bu ekrandan sancağı götürmək üçün Geri və Əsas səhifə düymələrinə basıb saxlayın"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Bu ekranı sancaqdan çıxarmaq üçün sürüşdürüb saxlayın"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Anladım!"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Yox, çox sağ olun"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Ekran sancılıb"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 78e9d04..95346e4 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -403,6 +403,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Manje hitna obaveštenja su u nastavku"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Dodirnite ponovo da biste otvorili"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Prevucite nagore da biste otvorili"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Prevucite nagore da biste probali ponovo"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Ovim uređajem upravlja organizacija"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Prevucite od ikone za telefon"</string>
@@ -547,6 +548,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Na ovaj način se ovo stalno prikazuje dok ga ne otkačite. Dodirnite i zadržite Početna da biste ga otkačili."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Da biste otkačili ovaj ekran, dodirnite i zadržite dugmad Nazad i Pregled"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Da biste otkačili ovaj ekran, dodirnite i zadržite dugmad Nazad i Početna"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Da biste otkačili ovaj ekran, prevucite nagore i zadržite"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Važi"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, hvala"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Ekran je zakačen"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index a6b46697..3674564 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -407,6 +407,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Менш тэрміновыя апавяшчэнні ніжэй"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Дакраніцеся яшчэ раз, каб адкрыць"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Каб адкрыць, прагарніце ўверх"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Прагартайце ўверх, каб паўтарыць спробу"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Гэта прылада знаходзіцца пад кіраваннем вашай арганізацыі"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Гэта прылада знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Тэлефон: правядзіце пальцам ад значка"</string>
@@ -552,6 +553,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Будзе паказвацца, пакуль не адмацуеце. Каб адмацаваць, націсніце і ўтрымлівайце кнопку \"Галоўны экран\"."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Каб адмацаваць гэты экран, націсніце і ўтрымлівайце кнопкі \"Назад\" і \"Агляд\""</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Каб адмацаваць гэты экран, націсніце і ўтрымлівайце кнопкі \"Назад\" і \"Галоўны экран\""</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Каб адмацаваць экран, правядзіце пальцам, утрымліваючы яго на экране"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Зразумела"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Не, дзякуй"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Экран замацаваны"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index a0128eb..eadb19b 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Ппоказване на по-малко спешните известия по-долу"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Докоснете отново, за да отворите"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Прекарайте пръст нагоре, за да отключите"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Плъзнете бързо нагоре, за да опитате отново"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Това устройство се управлява от организацията ви"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Това устройство се управлява от <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Плъзнете с пръст от иконата, за да използвате телефона"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Екранът ще се показва, докато не го освободите с докосване и задържане на бутона „Начало“."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"За да освободите този екран, докоснете и задръжте бутона за връщане назад и този за общ преглед"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"За да освободите този екран, докоснете и задръжте бутона за връщане назад и „Начало“"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"За да освободите този екран, прекарайте пръст нагоре и задръжте"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Разбрах"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Не, благодаря"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Екранът е фиксиран"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index bf55d52..6b7561b 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"নিচে অপেক্ষাকৃত কম জরুরী বিজ্ঞপ্তিগুলি"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"খোলার জন্য আবার আলতো চাপুন"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"খোলার জন্য উপরে সোয়াইপ করুন"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"আবার চেষ্টা করতে উপরের দিকে সোয়াইপ করুন"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"আপনার সংস্থা এই ডিভাইসটি পরিচালনা করছে"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"এই ডিভাইসটি <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> এর দ্বারা পরিচালিত"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ফোনের জন্য আইকন থেকে সোয়াইপ করুন"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"এর ফলে আপনি এটি আনপিন না করা পর্যন্ত এটি দেখানো হতে থাকবে। আনপিন করতে \"হোম\" বোতামটি ট্যাপ করে ধরে রাখুন।"</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"এই স্ক্রিনটি আনপিন করতে \"ফিরে যান\" এবং \"এক নজরে\" বোতামদুটি ট্যাপ করে ধরে রাখুন"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"এই স্ক্রিনটি আনপিন করতে \"ফিরে যান\" এবং \"হোম\" বোতামদুটি ট্যাপ করে ধরে রাখুন"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"আনপিন করতে এই স্ক্রিনটি উপরের দিকে সোয়াইপ করে ধরে রাখুন"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"বুঝেছি"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"না থাক"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"স্ক্রিন পিন করা হয়েছে"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index d7e5c23..c22ddfd 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -403,6 +403,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Prikaži manje važna obavještenja ispod"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Dodirnite ponovo da otvorite"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Prevucite da otvorite"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Prevucite prema gore da pokušate ponovo"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Ovim uređajem upravlja vaša organizacija"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Prevucite preko ikone da otvorite telefon"</string>
@@ -547,6 +548,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Na ovaj način ekran ostaje prikazan dok ga ne otkačite. Da okačite ekran, dodirnite ili držite dugme Početna."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Dodirnite i držite dugmad Nazad i Pregled da otkačite ekran"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Dodirnite i držite dugmad Nazad i Početna da otkačite ekran."</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Da otkačite ovaj ekran, prevucite prema gore i zadržite"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Razumijem"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, hvala"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Ekran je zakačen"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 23d5d5c..d4147ba 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificacions menys urgents a continuació"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Torna a tocar per obrir-la."</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Llisca cap amunt per obrir"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Llisca cap a dalt per tornar-ho a provar"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"La teva organització gestiona aquest dispositiu"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> gestiona aquest dispositiu"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Llisca des de la icona per obrir el telèfon"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Aquest element es continuarà mostrant fins que deixis de fixar-lo. Per fer-ho, mantén premut el botó d\'inici."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Per deixar de fixar aquesta pantalla, mantén premuts els botons Enrere i Aplicacions recents"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Per deixar de fixar aquesta pantalla, mantén premuts els botons Enrere i Inici"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Per deixar de fixar aquesta pantalla, fes-la lliscar cap a dalt i mantén-la premuda"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Entesos"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"No, gràcies"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"S\'ha fitxat la pantalla"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 9c765d9..87aaa94 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -405,6 +405,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Méně urgentní oznámení níže"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Oznámení otevřete opětovným klepnutím"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Otevřete přejetím prstem nahoru"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Přejetím nahoru to zkusíte znovu"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Toto zařízení spravuje vaše organizace"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Toto zařízení je spravováno organizací <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Telefon otevřete přejetím prstem od ikony"</string>
@@ -550,6 +551,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Obsah bude připnut v zobrazení, dokud ho neuvolníte. Uvolníte ho podržením tlačítka Plocha."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Chcete-li tuto obrazovku uvolnit, podržte tlačítka Zpět a Přehled"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Chcete-li tuto obrazovku uvolnit, podržte tlačítka Zpět a Plocha"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Chcete-li tuto obrazovku odepnout, přejeďte prstem nahoru a podržte"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Rozumím"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, děkuji"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Obrazovka připnuta"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index b0d3d66..e6d98ca 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Mindre presserende notifikationer nedenfor"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Tryk igen for at åbne"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Stryg opad for at åbne"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Stryg opad for at prøve igen"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Denne enhed administreres af din organisation"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Denne enhed administreres af <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Stryg fra telefonikonet"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Dette fastholder skærmen i visningen, indtil du frigør den. Hold Startskærm nede for at frigøre skærmen."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Hold knapperne Tilbage og Oversigt nede for at frigøre skærmen"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Hold knapperne Tilbage og Hjem nede for at frigøre skærmen"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Stryg opad, og hold fingeren nede for at frigøre denne skærm"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"OK, det er forstået"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nej tak"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Skærmen blev fastgjort"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 9b3974b..e1fd8db 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -405,6 +405,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Weniger dringende Benachrichtigungen unten"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Erneut tippen, um Benachrichtigung zu öffnen"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Zum Öffnen nach oben wischen"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Zum Wiederholen nach oben wischen"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Dieses Gerät wird von deiner Organisation verwaltet"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Dieses Gerät wird von <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> verwaltet"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Zum Öffnen des Telefons vom Symbol wegwischen"</string>
@@ -548,6 +549,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Der Bildschirm wird so lange angezeigt, bis du die Fixierung aufhebst. Berühre und halte dazu \"Startbildschirm\"."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Um die Fixierung für diesen Bildschirm aufzuheben, berühre und halte \"Zurück\" und \"Übersicht\""</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Um die Fixierung für diesen Bildschirm aufzuheben, berühre und halte \"Zurück\" und \"Startbildschirm\""</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Zum Loslösen des Bildschirms nach oben wischen und halten"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Ok"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nein danke"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Der Bildschirm ist angepinnt"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 0ceef42..dfb5edf 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Λιγότερο επείγουσες ειδοποιήσεις παρακάτω"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Πατήστε ξανά για να ανοίξετε"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Σύρετε προς τα επάνω για άνοιγμα"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Σύρετε προς τα πάνω για να δοκιμάσετε ξανά"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Αυτή η συσκευή είναι διαχειριζόμενη από τον οργανισμό σας"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Τη συσκευή διαχειρίζεται ο οργανισμός <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Σύρετε προς τα έξω για τηλέφωνο"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Με αυτόν τον τρόπο, παραμένει σε προβολή μέχρι να το ξεκαρφιτσώσετε. Αγγίξτε παρατεταμένα το στοιχείο \"Αρχική οθόνη\" για ξεκαρφίτσωμα."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Για να ξεκαρφιτσώσετε αυτήν την οθόνη, αγγίξτε παρατεταμένα τα κουμπιά \"Πίσω\" και \"Επισκόπηση\""</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Για να ξεκαρφιτσώσετε αυτήν την οθόνη, αγγίξτε παρατεταμένα τα κουμπιά \"Πίσω\" και \"Αρχική οθόνη\""</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Για να ξεκαρφιτσώσετε αυτήν την οθόνη, σύρετε προς τα πάνω και κρατήστε παρατεταμένα"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Το κατάλαβα"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Όχι"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Η οθόνη καρφιτσώθηκε"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index eacceb2..562338c 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Tap again to open"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Swipe up to open"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Swipe up to try again"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"This device is managed by your organisation"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"This device is managed by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Swipe from icon for phone"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"This keeps it in view until you unpin. Touch &amp; hold Home to unpin."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"To unpin this screen, touch &amp; hold Back and Overview buttons"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"To unpin this screen, touch and hold Back and Home buttons"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"To unpin this screen, swipe up &amp; hold"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Got it"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"No, thanks"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Screen pinned"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 7161dde..4bf9f54 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Tap again to open"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Swipe up to open"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Swipe up to try again"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"This device is managed by your organisation"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"This device is managed by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Swipe from icon for phone"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"This keeps it in view until you unpin. Touch &amp; hold Home to unpin."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"To unpin this screen, touch &amp; hold Back and Overview buttons"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"To unpin this screen, touch and hold Back and Home buttons"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"To unpin this screen, swipe up &amp; hold"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Got it"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"No, thanks"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Screen pinned"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index eacceb2..562338c 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Tap again to open"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Swipe up to open"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Swipe up to try again"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"This device is managed by your organisation"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"This device is managed by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Swipe from icon for phone"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"This keeps it in view until you unpin. Touch &amp; hold Home to unpin."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"To unpin this screen, touch &amp; hold Back and Overview buttons"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"To unpin this screen, touch and hold Back and Home buttons"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"To unpin this screen, swipe up &amp; hold"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Got it"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"No, thanks"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Screen pinned"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index eacceb2..562338c 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Tap again to open"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Swipe up to open"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Swipe up to try again"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"This device is managed by your organisation"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"This device is managed by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Swipe from icon for phone"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"This keeps it in view until you unpin. Touch &amp; hold Home to unpin."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"To unpin this screen, touch &amp; hold Back and Overview buttons"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"To unpin this screen, touch and hold Back and Home buttons"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"To unpin this screen, swipe up &amp; hold"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Got it"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"No, thanks"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Screen pinned"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index d8c862a..139215aa 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‏‏‏‏‎‏‎‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‎‎‎‏‎‎‎‏‎‏‎‏‎‏‏‎Less urgent notifications below‎‏‎‎‏‎"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‏‎‏‏‏‎‎‏‎‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‎‎‎‎‏‏‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‏‎‎Tap again to open‎‏‎‎‏‎"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‏‏‏‎‎‎‎‏‏‎‎‏‎‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎Swipe up to open‎‏‎‎‏‎"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‏‏‎‏‏‎‏‎‎‏‎‏‎‏‎‏‏‎‏‏‎‏‎‎‎‏‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‏‎‎‏‎‏‎Swipe up to try again‎‏‎‎‏‎"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‎‎‎‎‎‏‏‎‎‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎This device is managed by your organization‎‏‎‎‏‎"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎‏‏‎‏‎‏‎‎‎‏‏‏‏‏‏‎‏‎This device is managed by ‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="phone_hint" msgid="4872890986869209950">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‏‎‏‏‎‏‎‏‏‏‏‎‎Swipe from icon for phone‎‏‎‎‏‎"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎‏‏‎‏‎‎‏‏‏‎‏‎‏‏‏‎‏‏‎‎‏‎‏‎‎‎‎‏‎‏‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‏‎This keeps it in view until you unpin. Touch &amp; hold Home to unpin.‎‏‎‎‏‎"</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‎‏‏‎‎‎‎‎‎‎‎‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‎‎To unpin this screen, touch &amp; hold Back and Overview buttons‎‏‎‎‏‎"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‏‏‎‎‏‏‎‏‏‎‎‎‎‏‎‏‏‎‏‎‏‏‎‏‎‎‏‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‏‎‎‎‎‎‏‎To unpin this screen, touch &amp; hold Back and Home buttons‎‏‎‎‏‎"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‏‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‏‏‏‏‎‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‏‎‏‎‏‎‏‏‏‎‏‏‏‏‏‎‎To unpin this screen, swipe up &amp; hold‎‏‎‎‏‎"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‎‎‎‎‎‏‎‏‏‎‎‎‏‎‏‏‏‏‎‏‎‎‏‏‏‏‏‏‎‏‎‎Got it‎‏‎‎‏‎"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎‏‎‎‏‎‎‏‏‎‎‎No thanks‎‏‎‎‏‎"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‏‏‏‎‏‎‎‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎‏‎‎‎‏‏‎‏‎‏‎‏‏‎‏‏‎‏‎‏‏‎‏‏‎‏‏‎‏‎Screen pinned‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index d6c8d09..6adf6d5 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificaciones menos urgentes abajo"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Presionar de nuevo para abrir"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Desliza el dedo hacia arriba para abrir"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Desliza el dedo hacia arriba para volver a intentarlo"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Tu organización administra este dispositivo"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> administra este dispositivo"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Desliza el dedo para desbloquear el teléfono."</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Esta función mantiene la pantalla visible hasta que dejes de fijarla. Para ello, mantén presionado el botón de inicio."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Para dejar de fijar esta pantalla, mantén presionados los botones Atrás y Recientes"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Para dejar de fijar esta pantalla, mantén presionados los botones de inicio y Atrás"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Para no fijar esta pantalla, desliza el dedo hacia arriba y mantén presionado"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Entendido"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"No, gracias"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Pantalla fija"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 9007835..9810eb4 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificaciones menos urgente abajo"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Toca de nuevo para abrir"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Desliza el dedo hacia arriba para abrir"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Desliza el dedo hacia arriba para volverlo a intentar"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Este dispositivo está administrado por tu organización"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Este dispositivo está administrado por <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Desliza desde el icono para abrir el teléfono"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"La pantalla se mantiene visible hasta que dejas de fijarla. Para ello, mantén pulsado el botón Inicio."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Mantén pulsado el botón Atrás y el de aplicaciones recientes para dejar de fijar esta pantalla"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Mantén pulsados los botones Atrás e Inicio para dejar de fijar esta pantalla"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Para dejar de fijar esta pantalla, desliza el dedo hacia arriba y mantenla pulsada"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Entendido"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"No, gracias"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Pantalla fijada"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index dc8b85f..8a64692 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Vähem kiireloomulised märguanded on allpool"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Avamiseks puudutage uuesti"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Pühkige avamiseks üles"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Uuesti proovimiseks pühkige üles"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Seda seadet haldab teie organisatsioon"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Seda seadet haldab <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Telefoni kasutamiseks pühkige ikoonilt eemale"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"See hoitakse kuval, kuni selle vabastate. Vabastamiseks puudutage pikalt nuppu Avakuva."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Ekraanikuva vabastamiseks puudutage pikalt nuppe Tagasi ja Ülevaade"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Ekraanikuva vabastamiseks puudutage pikalt nuppe Tagasi ja Avakuva"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Ekraanikuva vabastamiseks pühkige üles ja hoidke sõrme ekraanil"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Selge"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Tänan, ei"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Ekraanikuva on kinnitatud"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 714af29..f88d676 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Horren premiazkoak ez diren jakinarazpenak daude behean"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Irekitzeko, ukitu berriro"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Pasatu hatza gora irekitzeko"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Berriro saiatzeko, pasatu hatza gora"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Zure erakundeak kudeatzen du gailua"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> erakundeak kudeatzen du gailu hau"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Pasatu hatza ikonotik, telefonoa irekitzeko"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Horrela, ikusgai egongo da aingura kendu arte. Aingura kentzeko, eduki sakatuta Hasiera botoia."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Pantailari aingura kentzeko, eduki sakatuta Atzera eta Ikuspegi orokorra botoiak"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Pantailari aingura kentzeko, eduki sakatuta Atzera eta Hasiera botoiak"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Pantailari aingura kentzeko, pasatu hatza gora eta eduki sakatuta"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Ados"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Ez, eskerrik asko"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Ainguratu da pantaila"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index bcdeccc..e478626 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"اعلان‌های کمتر فوری در زیر"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"دوباره ضربه بزنید تا باز شود"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"برای باز کردن، انگشتتان را تند به بالا بکشید"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"برای امتحان مجدد، انگشتتان را تند به بالا بکشید"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"سازمان شما این دستگاه را مدیریت می‌کند"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"این دستگاه توسط <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> مدیریت می‌شود"</string>
     <string name="phone_hint" msgid="4872890986869209950">"انگشتتان را از نماد تلفن تند بکشید"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"تا برداشتن پین، در نما نگه‌داشته می‌شود. برای برداشتن پین، «صفحه اصلی» را لمس کنید و نگه‌دارید."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"برای برداشتن پین این صفحه، دکمه‌های «برگشت» و «نمای کلی» را لمس کنید و نگه‌دارید"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"برای برداشتن پین این صفحه، دکمه‌های «برگشت» و «صفحه اصلی» را لمس کنید و نگه‌دارید"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"برای برداشتن پین این صفحه‌نمایش، صفحه را تند بالا بکشید و نگه‌دارید"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"متوجه شدم"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"نه متشکرم"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"صفحه پین شد"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 2a4f70e..7be438a 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Vähemmän kiireelliset ilmoitukset ovat alla"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Avaa napauttamalla uudelleen"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Avaa pyyhkäisemällä ylös"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Yritä uudelleen pyyhkäisemällä ylös"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Organisaatiosi hallinnoi laitetta"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Tätä laitetta hallinnoi <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>."</string>
     <string name="phone_hint" msgid="4872890986869209950">"Avaa puhelu pyyhkäisemällä."</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Pysyy näkyvissä, kunnes irrotat sen. Irrota painamalla pitkään Aloitusnäyttö."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Irrota näyttö koskettamalla pitkään Takaisin- ja Viimeisimmät-painikkeita"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Irrota näyttö koskettamalla pitkään Takaisin- ja Aloitusnäyttö-painikkeita"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Irrota näyttö pyyhkäisemällä ylös ja painamalla pitkään"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Selvä"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Ei kiitos"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Näyttö kiinnitetty"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index b45a523..5340263 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notifications moins urgentes affichées ci-dessous"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Touchez à nouveau pour ouvrir"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Balayez l\'écran vers le haut pour ouvrir"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Balayez l\'écran vers le haut pour réessayer"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Cet appareil est géré par votre organisation"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Cet appareil est géré par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Balayez à partir de l\'icône pour accéder au téléphone"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'opération. Pour annuler l\'épinglage, maintenez le doigt sur la touche Accueil."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Pour annuler l\'épinglage de cet écran, maintenez le doigt sur les touches Retour et Aperçu."</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Pour annuler l\'épinglage de cet écran, maintenez le doigt sur les touches Retour et Accueil."</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Pour annuler l\'épinglage de cet écran, balayez-le vers le haut et gardez le doigt dessus"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Non, merci"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Écran épinglé"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 75a76ae..3bc9378 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notifications moins urgentes ci-dessous"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Appuyer à nouveau pour ouvrir"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Balayer vers le haut pour ouvrir"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Balayez l\'écran vers le haut pour réessayer"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Cet appareil est géré par votre entreprise"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Cet appareil est géré par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Balayer pour téléphoner"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Cet écran est épinglé jusqu\'à l\'annulation de l\'opération. Pour annuler l\'épinglage, appuyez de manière prolongée sur le bouton \"Accueil\"."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Pour annuler l\'épinglage de l\'écran, appuyez de manière prolongée sur les boutons \"Retour\" et \"Aperçu\""</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Pour annuler l\'épinglage de l\'écran, appuyez de manière prolongée sur les boutons \"Retour\" et \"Accueil\""</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Pour retirer cet écran, balayez vers le haut et continuez d\'appuyer"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Non, merci"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Écran épinglé"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index d2836df..5480eab 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificacións menos urxentes abaixo"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Toca de novo para abrir"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Pasa o dedo cara arriba para abrir"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Pasa o dedo cara arriba para tentalo de novo"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Este dispositivo está xestionado pola túa organización"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Este dispositivo está xestionado por <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Pasa o dedo desde a icona para acceder ao teléfono"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"A pantalla manterase visible ata que deixes de fixala. Para facelo, mantén premido Inicio."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Para deixar de fixar a pantalla, mantén premidos os botóns Volver e Visión xeral"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Para deixar de fixar a pantalla, mantén premidos os botóns Atrás e Inicio"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Para soltar esta pantalla, pasa o dedo cara arriba e mantena premida"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"De acordo"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Non, grazas"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Fixouse a pantalla"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index bd68c96..6ab1c35 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"નીચે ઓછી તાકીદની સૂચનાઓ"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"ખોલવા માટે ફરીથી ટૅપ કરો"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"ખોલવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"ફરી પ્રયાસ કરવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"આ ઉપકરણ તમારી સંસ્થા દ્વારા સંચાલિત છે"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"આ ઉપકરણ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> દ્વારા સંચાલિત થાય છે"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ફોન માટે આયકનમાંથી સ્વાઇપ કરો"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"તમે જ્યાં સુધી અનપિન કરશો નહીં ત્યાં સુધી આ તેને દૃશ્યક્ષમ રાખે છે. અનપિન કરવા માટે હોમને સ્પર્શ કરી રાખો."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"આ સ્ક્રીનને અનપિન કરવા માટે, પાછળ અને ઝલક બટનને સ્પર્શ કરી રાખો"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"આ સ્ક્રીનને અનપિન કરવા માટે, પાછળ અને હોમ બટનને સ્પર્શ કરી રાખો"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"આ સ્ક્રીનને અનપિન કરવા માટે, ઉપર સ્વાઇપ કરીને બટન દબાવી રાખો"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"સમજાઈ ગયું"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"ના, આભાર"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"સ્ક્રીન પિન કરી"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 3fa2a48..bdf317c 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"कम अत्यावश्यक सूचनाएं नीचे दी गई हैं"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"खोलने के लिए फिर से टैप करें"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"खोलने के लिए ऊपर स्वाइप करें"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"फिर से कोशिश करने के लिए ऊपर की ओर स्वाइप करें"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"इस डिवाइस का प्रबंधन आपका संगठन करता है"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"इस डिवाइस के प्रबंधक <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> हैं"</string>
     <string name="phone_hint" msgid="4872890986869209950">"फ़ोन के लिए आइकॉन से स्वाइप करें"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"इससे वह तब तक दिखाई देती है जब तक आप उसे अनपिन नहीं कर देते. अनपिन करने के लिए, होम बटन को दबाकर रखें."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"इस स्क्रीन को अनपिन करने के लिए, खास जानकारी और वापस जाएं वाले बटन को दबाकर रखें"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"इस स्क्रीन को अनपिन करने के लिए, होम और वापस जाएं वाले बटन को दबाकर रखें"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"इस स्क्रीन को अनपिन करने के लिए, ऊपर की ओर स्वाइप करें और बटन को दबाकर रखें"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"ठीक है"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"नहीं, रहने दें"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"स्‍क्रीन पिन की गई"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 2954de2..052a0d2 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -403,6 +403,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Manje hitne obavijesti pri dnu"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Dodirnite opet za otvaranje"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Prijeđite prstom prema gore da biste otvorili"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Prijeđite prstom prema gore za ponovni pokušaj"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Ovim uređajem upravlja vaša organizacija"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Prijeđite prstom od ikone za telefon"</string>
@@ -547,6 +548,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Zaslon će tako ostati u prvom planu dok ga ne otkvačite. Dodirnite gumb Početna i zadržite pritisak da biste ga otkvačili."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Da biste otkvačili ovaj zaslon, dodirnite gumbe Natrag i Pregled i zadržite pritisak"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Da biste otkvačili ovaj zaslon, dodirnite gumbe Natrag i Početna i zadržite pritisak"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Da biste otkvačili ovaj zaslon, prijeđite prstom i zadržite pritisak"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Shvaćam"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, hvala"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Zaslon je pričvršćen"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 11a0b06..3e3696b 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"A kevésbé sürgős értesítések lentebb vannak"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Koppintson ismét a megnyitáshoz"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Csúsztasson felfelé a megnyitáshoz"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Az újrapróbálkozáshoz csúsztassa felfelé az ujját"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Az eszközt az Ön szervezete kezeli"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Az eszközt a(z) <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> felügyeli."</string>
     <string name="phone_hint" msgid="4872890986869209950">"A telefonhoz csúsztasson az ikonról"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Megjelenítve tartja addig, amíg Ön fel nem oldja a rögzítést. A feloldáshoz tartsa lenyomva a Kezdőképernyő elemet."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"A képernyő rögzítésének feloldásához tartsa lenyomva a Vissza és az Áttekintés gombot"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"A képernyő rögzítésének feloldásához tartsa lenyomva a Vissza és a Kezdőképernyő gombot"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"A képernyő rögzítésének feloldásához csúsztassa felfelé ujját, majd tartsa lenyomva"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Értem"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nem, köszönöm"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Képernyő rögzítve"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 38c7abd..2397f88 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Պակաս հրատապ ծանուցումները ստորև"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Կրկին հպեք՝ բացելու համար"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Բացելու համար սահեցրեք վերև"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Սահեցրեք վերև՝ նորից փորձելու համար"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Այս սարքը կառավարում է ձեր կազմակերպությունը"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Այս սարքը կառավարվում է <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>-ի կողմից"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Սահահարվածեք հեռախոսի պատկերակից"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Էկրանը կցուցադրվի այնքան ժամանակ, մինչև որ չապամրացնեք այն: Ապամրացնելու համար հպեք և պահեք գլխավոր էկրանի կոճակը:"</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Էկրանն ապամրացնելու համար հպեք և պահեք Հետ և Համատեսք կոճակները"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Էկրանն ապամրացնելու համար հպեք և պահեք «Հետ» և «Գլխավոր էկրան» կոճակները"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Էկրանն ապամրացնելու համար մատը սահեցրեք վերև և պահեք"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Եղավ"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Ոչ"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Էկրանն ամրացված է"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 19b2b99..b18beed 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notifikasi kurang darurat di bawah"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Ketuk lagi untuk membuka"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Geser ke atas untuk membuka"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Geser ke atas untuk mencoba lagi"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Perangkat ini dikelola oleh organisasi"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Perangkat ini dikelola oleh <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Geser dari ikon untuk telepon"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ini akan terus ditampilkan sampai Anda melepas pin. Sentuh lama tombol Beranda untuk melepas pin."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Untuk melepas pin layar ini, sentuh lama tombol Kembali dan Ringkasan"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Untuk melepas pin layar ini, sentuh lama tombol Kembali dan Beranda"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Untuk melepas pin layar ini, geser ke atas &amp; tahan"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Mengerti"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Lain kali"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Layar dipasangi pin"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 0076add..129319d 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Minna áríðandi tilkynningar fyrir neðan"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Ýttu aftur til að opna"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Strjúktu upp til að opna"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Strjúktu upp til að reyna aftur"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Þessu tæki er stýrt af fyrirtækinu þínu"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Þessu tæki er stýrt af <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Strjúktu frá tákninu fyrir síma"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Þetta heldur þessu opnu þangað til það er losað. Haltu heimahnappinum inni til að losa."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Til að losa þessa skjámynd skaltu halda inni bakkhnappinum og yfirlitshnappinum"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Til að losa þessa skjámynd skaltu halda inni bakkhnappinum og heimahnappinum"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Til að losa þennan skjá skaltu strjúka upp og halda"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Ég skil"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nei, takk"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Skjámynd fest"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 699cb72..c4effdd 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notifiche meno urgenti in basso"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Tocca ancora per aprire"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Scorri verso l\'alto per aprire"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Scorri verso l\'alto per riprovare"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Questo dispositivo è gestito dalla tua organizzazione"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Questo dispositivo è gestito da <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Scorri per accedere al telefono"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"La schermata rimane visibile finché non viene disattivato il blocco su schermo. Per disattivarlo, tocca e tieni premuto Home."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Per disattivare il blocco su schermo, tocca e tieni premuti i pulsanti Indietro e Panoramica"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Per disattivare il blocco su schermo, tocca e tieni premuti i pulsanti Indietro e Home"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Per sbloccare questa schermata, scorri verso l\'alto e tieni premuto"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"No, grazie"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Blocco su schermo attivato"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 12b2cee..7a7cfa4 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -405,6 +405,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"התראות בדחיפות נמוכה יותר בהמשך"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"הקש שוב כדי לפתוח"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"צריך להחליק כדי לפתוח"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"יש להחליק למעלה כדי לנסות שוב"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"מכשיר זה מנוהל על ידי הארגון שלך"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"המכשיר הזה מנוהל על ידי <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"החלק מהסמל כדי להפעיל את הטלפון"</string>
@@ -550,6 +551,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"נשאר בתצוגה עד לביטול ההצמדה. יש ללחוץ לחיצה ארוכה על הלחצן \'דף הבית\' כדי לבטל את ההצמדה."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"כדי לבטל את ההצמדה של מסך זה, יש ללחוץ לחיצה ארוכה על הלחצנים \'הקודם\' ו\'סקירה\'"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"כדי לבטל את ההצמדה של מסך זה, יש ללחוץ לחיצה ארוכה על הלחצנים \'הקודם\' ו\'דף הבית\'"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"לביטול ההצמדה של המסך הזה יש להחליק מעלה ולהחזיק"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"הבנתי"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"לא, תודה"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"המסך מוצמד"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 51e19a2..05f254f 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"緊急度の低い通知を下に表示"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"開くにはもう一度タップしてください"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"開くには上にスワイプします"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"上にスワイプしてもう一度お試しください"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"このデバイスは組織によって管理されています"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"このデバイスは <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> が管理しています"</string>
     <string name="phone_hint" msgid="4872890986869209950">"右にスワイプして通話"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"固定を解除するまで画面が常に表示されるようになります。[ホーム] を押し続けると固定が解除されます。"</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"この画面の固定を解除するには [戻る] ボタンと [最近] ボタンを押し続けます"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"この画面の固定を解除するには [戻る] ボタンと [ホーム] ボタンを押し続けます"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"この画面の固定を解除するには、上にスワイプして長押しします"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"はい"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"いいえ"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"画面を固定しました"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 058f233..6a7460d 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"ქვემოთ მითითებულია ნაკლებად სასწრაფო შეტყობინებები"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"შეეხეთ ისევ გასახსნელად"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"გასახსნელად გადაფურცლეთ ზემოთ"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"ხელახლა საცდელად გადაფურცლეთ ზემოთ"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ამ მოწყობილობას მართავს თქვენი ორგანიზაცია"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"ამ მოწყობილობას მართავს <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ტელეფონისთვის გადაფურცლეთ ხატულადან"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"ამით ის დარჩება ხედში ჩამაგრების მოხსნამდე. ჩამაგრების მოსახსნელად, ხანგრძლივად შეეხეთ „მთავარ გვერდს“."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"ამ ეკრანის ჩამაგრების მოსახსნელად, ხანგრძლივად შეეხეთ ღილაკებს „უკან“ და „მიმოხილვა“"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ამ ეკრანის ჩამაგრების მოსახსნელად, ხანგრძლივად შეეხეთ ღილაკებს „უკან“ და „მთავარი გვერდი“"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"ამ ეკრანის ჩამაგრების მოსახსნელად გადაფურცლეთ ზემოთ და არ აუშვათ"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"გასაგებია"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"არა, გმადლობთ"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"ეკრანი ჩამაგრებულია"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 1b201dd..6e0fca7 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Шұғылдығы азырақ хабарландырулар төменде"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Ашу үшін қайта түртіңіз"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Ашу үшін жоғары қарай сырғытыңыз."</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Әрекетті қайталау үшін жоғары сырғытыңыз."</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Бұл құрылғыны ұйым басқарады"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Бұл құрылғыны <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> басқарады"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Телефонды ашу үшін белгішеден әрі қарай сырғытыңыз"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Экран босатылғанға дейін көрсетіліп тұрады. Оны босату үшін \"Негізгі бет\" түймесін түртіп, ұстап тұрыңыз."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Бұл экранды босату үшін \"Артқа\" және \"Шолу\" түймелерін түртіп, ұстап тұрыңыз"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Бұл экранды босату үшін \"Артқа\" және \"Негізгі бет\" түймелерін түртіп, ұстап тұрыңыз"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Бұл экранды босату үшін жоғары сырғытып, ұстап тұрыңыз."</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Түсінікті"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Жоқ, рақмет"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Экран бекітілді"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 60c13e1..f4ef491 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"ការ​ជូន​ដំណឹង​​មិន​សូវ​បន្ទាន់​ខាង​ក្រោម"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"ប៉ះ​ម្ដង​ទៀត ដើម្បី​បើក"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"អូសឡើងលើ​ដើម្បីបើក"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"អូសឡើងលើ ដើម្បី​ព្យាយាម​ម្ដងទៀត"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ឧបករណ៍​នេះ​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​​របស់ស្ថាប័ន​​អ្នក"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"ឧបករណ៍នេះស្ថិតក្រោមការគ្រប់គ្រងរបស់ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"អូសចេញពីរូបតំណាងដើម្បីប្រើទូរស័ព្ទ"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"វា​នឹង​នៅតែ​បង្ហាញ រហូត​ទាល់​តែ​អ្នក​ដក​ការដៅ។ សូម​ចុច​ប៊ូតុង​ទំព័រដើម​ឱ្យ​ជាប់ ដើម្បី​ដក​ការ​ដៅ។"</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"ដើម្បី​ដកខ្ទាស់​អេក្រង់​នេះ សូម​ចុច​ប៊ូតុង​ថយ​ក្រោយ និង​ប៊ូតុង​ទិដ្ឋភាពរួម​ឱ្យ​ជាប់"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ដើម្បី​ដកខ្ទាស់​អេក្រង់​នេះ សូម​ចុច​ប៊ូតុង​ថយ​ក្រោយ និង​ប៊ូតុងទំព័រដើម​ឱ្យ​ជាប់"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"អូសឡើងលើ​ឱ្យជាប់ ដើម្បី​ដកការដៅ​អេក្រង់​នេះ"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"យល់​ហើយ"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"ទេ អរគុណ"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"បាន​ដៅ​អេក្រង់"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 1eafd86..4f0462c 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"ಕೆಳಗೆ ಕಡಿಮೆ ಅವಸರದ ಅಧಿಸೂಚನೆಗಳು"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"ತೆರೆಯಲು ಮತ್ತೆ ಟ್ಯಾಪ್‌ ಮಾಡಿ"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"ತೆರೆಯಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ಈ ಸಾಧನವನ್ನು ನಿಮ್ಮ ಸಂಸ್ಥೆ ನಿರ್ವಹಿಸುತ್ತಿದೆ"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"ಈ ಸಾಧನವನ್ನು <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ರಿಂದ ನಿರ್ವಹಿಸಲಾಗಿದೆ"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ಫೋನ್‌ಗಾಗಿ ಐಕಾನ್‌ನಿಂದ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"ನೀವು ಅನ್‌ಪಿನ್ ಮಾಡುವವರೆಗೆ ಅದನ್ನು ವೀಕ್ಷಣೆಯಲ್ಲಿಡುತ್ತದೆ. ಅನ್‌ಪಿನ್ ಮಾಡಲು ಮುಖಪುಟವನ್ನು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಒತ್ತಿಹಿಡಿಯಿರಿ."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"ಈ ಪರದೆಯನ್ನು ಅನ್‌ಪಿನ್ ಮಾಡಲು, ಹಿಂದಕ್ಕೆ ಮತ್ತು ಸಮಗ್ರ ನೋಟ ಬಟನ್‌ಗಳನ್ನು ಸ್ಪರ್ಶಿಸಿ ಒತ್ತಿಹಿಡಿಯಿರಿ"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ಈ ಪರದೆಯನ್ನು ಅನ್‌ಪಿನ್ ಮಾಡಲು, ಹಿಂದಕ್ಕೆ ಮತ್ತು ಮುಖಪುಟ ಬಟನ್‌ಗಳನ್ನು ಸ್ಪರ್ಶಿಸಿ ಒತ್ತಿಹಿಡಿಯಿರಿ"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"ಈ ಸ್ಕ್ರೀನ್‌ ಅನ್ನು ಅನ್‌ಪಿನ್ ಮಾಡಲು, ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ &amp; ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"ತಿಳಿಯಿತು"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"ಧನ್ಯವಾದಗಳು"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"ಪರದೆಯನ್ನು ಪಿನ್‌ ಮಾಡಲಾಗಿದೆ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index de9b615..f85ba9c 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"아래에 덜 급한 알림 표시"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"다시 탭하여 열기"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"위로 스와이프하여 열기"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"위로 스와이프하여 다시 시도해 주세요"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"조직에서 관리하는 기기입니다."</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>에서 관리하는 기기입니다."</string>
     <string name="phone_hint" msgid="4872890986869209950">"전화 기능을 사용하려면 아이콘에서 스와이프하세요."</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"고정 해제할 때까지 계속 표시됩니다. 고정 해제하려면 홈을 길게 터치하세요."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"이 화면을 고정 해제하려면 뒤로 및 최근 사용 버튼을 길게 터치하세요."</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"이 화면을 고정 해제하려면 뒤로 및 홈 버튼을 길게 터치하세요."</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"이 화면을 고정 해제하려면 위로 스와이프하고 유지하세요."</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"확인"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"거부"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"화면 고정됨"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 063b4fc..f382855 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Анчейин шашылыш эмес эскертмелер төмөндө"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Ачуу үчүн кайра таптап коюңуз"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Ачуу үчүн өйдө сүрүңүз"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Кайталоо үчүн экранды өйдө сүрүңүз"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Бул түзмөк уюмуңуз тарабынан башкарылат"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Бул түзмөк <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> тарабынан башкарылат"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Сүрөтчөнү серпип телефонго өтүңүз"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ал бошотулмайынча көрүнө берет. Бошотуу үчүн, \"Башкы бет\" баскычын басып, кармап туруңуз."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Бул экранды бошотуу үчүн \"Артка\" жана \"Сереп салуу\" баскычтарын басып, кармап туруңуз"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Бул экранды бошотуу үчүн \"Артка\" жана \"Башкы бет\" баскычтарын басып, кармап туруңуз"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Бул экранды бошотуу үчүн аны өйдө сүрүп, кармап туруңуз"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Түшүндүм"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Жок, рахмат"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Экран кадалды"</string>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index 90e78e8..5a8c5dc 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -36,4 +36,8 @@
 
     <dimen name="volume_tool_tip_right_margin">136dp</dimen>
     <dimen name="volume_tool_tip_top_margin">12dp</dimen>
+
+    <!-- Padding between status bar and bubbles when displayed in expanded state, smaller
+         value in landscape since we have limited vertical space-->
+    <dimen name="bubble_padding_top">4dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 7bf95b1..d99db74 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"ການ​ແຈ້ງເຕືອນ​ທີ່​ສຳຄັນ​ໜ້ອຍ​ກວ່າ​ຢູ່​ດ້ານ​ລຸ່ມ"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"ແຕະ​ອີກ​ຄັ້ງ​ເພື່ອ​ເປີດ"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"ປັດຂຶ້ນເພື່ອເປີດ"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"ປັດຂຶ້ນເພື່ອລອງໃໝ່"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ອຸປະກອນນີ້ແມ່ນຈັດການໂດຍອົງກອນຂອງທ່ານ"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"ອຸປະກອນນີ້ຖືກຈັດການໂດຍ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ປັດ​ຈາກ​ໄອ​ຄອນ​ສຳ​ລັບ​ໂທ​ລະ​ສັບ"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"ນີ້ຈະສະແດງມັນໃນໜ້າຈໍຈົນກວ່າທ່ານຈະເຊົາປັກໝຸດ. ໃຫ້ແຕະປຸ່ມພາບຮວມຄ້າງໄວ້ເພື່ອຍົກເລີກການປັກໝຸດ."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"ເພື່ອຍົກເລີກການປັກໝຸດໜ້າຈໍນີ້, ໃຫ້ແຕະປຸ່ມກັບຄືນ ແລະ ປຸ່ມພາບຮວມຄ້າງໄວ້"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ເພື່ອຍົກເລີກການປັກໝຸດໜ້າຈໍນີ້, ໃຫ້ແຕະປຸ່ມກັບຄືນ ແລະ ປຸ່ມພາບຮວມຄ້າງໄວ້"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"ເພື່ອເຊົາປັກໝຸດໜ້າຈໍນີ້, ໃຫ້ປັດຂຶ້ນຄ້າງໄວ້"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"ເຂົ້າໃຈແລ້ວ"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"ບໍ່, ຂອບໃຈ"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"ປັກໝຸດໜ້າຈໍແລ້ວ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index d90238b..9c1f411 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -405,6 +405,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Mažiau skubūs pranešimai toliau"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Palieskite dar kartą, kad atidarytumėte"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Perbraukite aukštyn, kad atidarytumėte"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Jei norite bandyti dar kartą, perbraukite aukštyn"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Šį įrenginį tvarko jūsų organizacija"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Šį įrenginį tvarko <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Perbraukite iš telefono piktogramos"</string>
@@ -550,6 +551,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Tai bus rodoma, kol atsegsite. Palieskite ir palaikykite „Pagrindinis ekranas“, kad atsegtumėte."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Kad atsegtumėte šį ekraną, palieskite ir palaikykite mygtukus „Atgal“ ir „Apžvalga“"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Kad atsegtumėte šį ekraną, palieskite ir palaikykite mygtukus „Atgal“ ir „Pagrindinis ekranas“"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Kad atsegtumėte šį ekraną, perbraukite aukštyn ir palaikykite"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Supratau"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, ačiū"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Ekranas prisegtas"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 581b68a..e6ac235 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -403,6 +403,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Mazāk steidzami paziņojumi tiek rādīti tālāk"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Pieskarieties vēlreiz, lai atvērtu"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Velciet augšup, lai atvērtu"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Velciet augšup, lai mēģinātu vēlreiz"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Šo ierīci pārvalda jūsu organizācija"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Šo ierīci pārvalda <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Lai lietotu tālruni, velciet no ikonas"</string>
@@ -547,6 +548,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Šādi tas būs redzams līdz brīdim, kad to atspraudīsiet. Lai atspraustu, pieskarieties pogai “Sākums” un turiet to."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Lai atspraustu šo ekrānu, pieskarieties pogām “Atpakaļ” un “Pārskats” un turiet tās."</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Lai atspraustu šo ekrānu, pieskarieties pogām “Atpakaļ” un “Sākums” un turiet tās."</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Lai atspraustu šo ekrānu, velciet augšup un turiet."</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Sapratu!"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nē, paldies"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Ekrāns ir piesprausts"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 712443c..e6126e6 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Долу се помалку итни известувања"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Допрете повторно за да се отвори"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Повлечете за да отворите"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Повлечете нагоре за да се обидете повторно"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Вашата организација управува со уредов"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Уредов го управува <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Повлечете од иконата за телефонот"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ќе се гледа сѐ додека не го откачите. Допрете и задржете „Почетен екран“ за откачување."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"За откачување на екранов, допрете и задржете ги копчињата „Назад“ и „Краток преглед“"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"За откачување на екранов, допрете и задржете ги копчињата „Назад“ и „Почетен екран“"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"За да го откачите екранов, повлечете нагоре и задржете"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Сфатив"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Не, фала"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Екранот е прикачен"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index bc4b8ef..67fb73b 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"ആവശ്യം കുറഞ്ഞ അറിയിപ്പുകൾ ചുവടെ നൽകിയിരിക്കുന്നു"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"തുറക്കുന്നതിന് വീണ്ടും ടാപ്പുചെയ്യുക"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"തുറക്കാൻ മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"വീണ്ടും ശ്രമിക്കാൻ മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ഈ ഉപകരണം മാനേജുചെയ്യുന്നത് നിങ്ങളുടെ സ്ഥാപനമാണ്"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> മാനേജുചെയ്യുന്ന ഉപകരണമാണിത്"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ഫോൺ ഐക്കണിൽ നിന്ന് സ്വൈപ്പുചെയ്യുക"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"നിങ്ങൾ അൺപിൻ ചെയ്യുന്നതുവരെ ഇത് കാണുന്ന വിധത്തിൽ നിലനിർത്തും. അൺപിൻ ചെയ്യാൻ \'ഹോം\' ബട്ടൺ സ്‌പർശിച്ച് പിടിക്കുക."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"ഈ സ്‌ക്രീൻ അൺപിൻ ചെയ്യാൻ, \'തിരികെ പോവുക\', \'അവലോകനം\' ബട്ടണുകൾ സ്‌പർശിച്ച് പിടിക്കുക"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ഈ സ്‌ക്രീൻ അൺപിൻ ചെയ്യാൻ, \'തിരികെ പോവുക\', \'ഹോം\' ബട്ടണുകൾ സ്‌പർശിച്ച് പിടിക്കുക"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"ഈ സ്‌ക്രീൻ അൺപിൻ ചെയ്യാൻ മുകളിലേക്ക് സ്വെെപ്പ് ചെയ്‌ത് പിടിക്കുക"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"മനസ്സിലായി"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"വേണ്ട, നന്ദി"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"സ്‌ക്രീൻ പിൻ ചെയ്തു"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index bd733ff..085a0aeeb 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Яаралтай биш мэдэгдлүүдийг доор"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Нээхийн тулд дахин товшино уу"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Нээхийн тулд дээш шударна уу"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Дахин оролдохын тулд дээш шударна уу"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Энэ төхөөрөмжийг таны байгууллага удирдаж байна"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Энэ төхөөрөмжийг <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> удирддаг"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Утсыг гаргахын тулд дүрс тэмдгээс шудрах"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Таныг тогтоосныг болиулах хүртэл үүнийг харуулсан хэвээр байна. Тогтоосныг болиулахын тулд Нүүр хуудас товчлуурыг дараад хүлээнэ үү."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Энэ дэлгэцийг тогтоосныг болиулахын тулд Буцах, Тойм товчлуурыг дараад хүлээнэ үү"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Энэ дэлгэцийг тогтоосныг болиулахын тулд Буцах, Нүүр хуудас товчлуурыг дараад хүлээнэ үү"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Энэ дэлгэцийг тогтоосныг болиулахын тулд дээш шудраад хүлээнэ үү"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Ойлголоо"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Үгүй"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Дэлгэцийг тогтоосон"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 676208b..4722ae9 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"खाली कमी तातडीच्या सूचना"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"उघडण्यासाठी पुन्हा टॅप करा"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"उघडण्यासाठी वर स्वाइप करा"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"पुन्हा प्रयत्न करण्यासाठी वर स्‍वाइप करा"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"हे डिव्हाइस तुमची संस्था व्यवस्थापित करते"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"हे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ने व्यवस्थापित केले आहे"</string>
     <string name="phone_hint" msgid="4872890986869209950">"फोनसाठी चिन्हावरून स्वाइप करा"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"तुम्ही अनपिन करेपर्यंत हे त्यास दृश्यामध्ये ठेवते. अनपिन करण्यासाठी होमला स्पर्श करा आणि धरून ठेवा."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"हा स्क्रीन अनपिन करण्यासाठी, मागे आणि अवलोकन बटणांना स्पर्श करून धरून ठेवा"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"हा स्क्रीन अनपिन करण्यासाठी, मागे आणि होम बटणांना स्पर्श करून धरून ठेवा"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"हा स्क्रीन अनपिन करण्यासाठी, वर स्‍वाइप करा आणि धरून ठेवा"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"समजले"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"नाही, नको"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"स्क्रीन पिन केला"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index f58ea18..1bc7ca9 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Pemberitahuan kurang penting di bawah"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Ketik lagi untuk membuka"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Leret ke atas untuk buka"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Leret ke atas untuk mencuba lagi"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Peranti ini diurus oleh organisasi anda"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Peranti ini diurus oleh <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Leret dari ikon untuk telefon"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Tindakan ini memastikan skrin kelihatan sehingga anda menyahsemat. Sentuh &amp; tahan Skrin Utama untuk menyahsemat."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Untuk menyahsemat skrin ini, sentuh &amp; tahan butang Kembali dan Ikhtisar"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Untuk menyahsemat skrin ini, sentuh &amp; tahan butang Kembali dan Skrin Utama"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Untuk menyahsemat skrin ini, leret ke atas &amp; tahan"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Faham"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Tidak"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Skrin disemat"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 19a9d1c..51aaaa2 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"အရေးပါမှု နည်းသည့် အကြောင်းကြားချက်များ အောက်မှာ"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"ဖွင့်ရန် ထပ်ပြီး ပုတ်ပါ"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"ဖွင့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"ထပ်စမ်းကြည့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ဤစက်ပစ္စည်းကို သင်၏အဖွဲ့အစည်းက စီမံခန့်ခွဲထားပါသည်"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"ဤစက်ပစ္စည်းကို <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> က စီမံခန့်ခွဲထားပါသည်"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ဖုန်းအတွက် သင်္ကေတပုံအား ပွတ်ဆွဲပါ"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"သင်က ပင်မဖြုတ်မချင်း ၎င်းကိုပြသထားပါမည်။ ပင်ဖြုတ်ရန် \'ပင်မ\' ခလုတ်ကို တို့၍ဖိထားပါ။"</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"ဤမျက်နှာပြင်ကို ပင်ဖြုတ်ရန်အတွက် \'နောက်သို့\' နှင့် \'အနှစ်ချုပ်\' ခလုတ်တို့ကို တို့၍ဖိထားပါ"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ဤမျက်နှာပြင်ကို ပင်ဖြုတ်ရန်အတွက် \'နောက်သို့\' နှင့် \'ပင်မ\' ခလုတ်တို့ကို တို့၍ဖိထားပါ"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"ဤမျက်နှာပြင်ကို ပင်ဖြုတ်ရန် အပေါ်သို့ ပွတ်ဆွဲပြီး ဖိထားပါ"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"ရပါပြီ"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"မလိုတော့ပါ"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"မျက်နှာပြင်ကို ပင်ထိုးထားသည်"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 4288f348..ce611e0 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Mindre presserende varsler nedenfor"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Trykk på nytt for å åpne"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Sveip opp for å åpne"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Sveip opp for å prøve igjen"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Denne enheten administreres av organisasjonen din"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Denne enheten administreres av <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Sveip ikonet for å åpne telefon"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"På denne måten blir skjermen synlig frem til du løsner den. Trykk og hold inne Startside for å løsne den."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"For å løsne denne skjermen, trykk på og hold inne Tilbake- og Oversikt-knappene"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"For å løsne denne skjermen, trykk på og hold inne Tilbake- og Startside-knappene"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"For å løsne denne skjermen, sveip opp og hold"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Skjønner"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nei takk"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Skjermen er festet"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 787b04c..a3a3da3 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"तल कम जरुरी सूचनाहरू"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"खोल्न पुनः ट्याप गर्नुहोस्"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"खोल्न माथितिर स्वाइप गर्नुहोस्"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"फेरि प्रयास गर्न माथितिर स्वाइप गर्नुहोस्"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"तपाईंको संगठनले यस यन्त्रलाई व्यवस्थापन गर्दछ"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"यो यन्त्र <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> द्वारा व्यवस्थापन गरिएको छ"</string>
     <string name="phone_hint" msgid="4872890986869209950">"फोनको लागि आइकनबाट स्वाइप गर्नुहोस्"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"तपाईंले अनपिन नगरेसम्म यसले त्यसलाई दृश्यमा कायम राख्छ। अनपिन गर्न गृह नामक बटनलाई छोइराख्नुहोस्।"</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"यस स्क्रिनलाई अनपनि गर्न पछाडि र परिदृश्य नामक बटनहरूलाई छोइराख्नुहोस्"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"यस स्क्रिनलाई अनपिन गर्न पछाडि र गृह नामक बटनहरूलाई छोइराख्नुहोस्"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"यो स्क्रिन अनपिन गर्न माथितिर स्वाइप गरी थिचिराख्नुहोस्"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"बुझेँ"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"धन्यवाद पर्दैन"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"स्क्रिन पिन गरियो"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 88f5bd4..305b46a 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Minder urgente meldingen onderaan"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Tik nog eens om te openen"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Veeg omhoog om te openen"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Veeg omhoog om het opnieuw te proberen"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Dit apparaat wordt beheerd door je organisatie"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Dit apparaat wordt beheerd door <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Vegen voor telefoon"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Het scherm blijft zichtbaar totdat je het losmaakt. Tik op Home en houd dit vast om het scherm los te maken."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Tik op Terug en Overzicht en houd deze knoppen vast om dit scherm los te maken"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Tik op Terug en Home en houd deze knoppen vast om dit scherm los te maken"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Veeg omhoog en houd vast om dit scherm los te maken"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Ik snap het"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nee, bedankt"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Scherm vastgezet"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 83221a6..e9b150c 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"ନିମ୍ନରେ କମ୍‍ ଜରୁରୀ ବିଜ୍ଞପ୍ତି"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"ଖୋଲିବା ପାଇଁ ପୁଣି ଟାପ୍‍ କରନ୍ତୁ"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"ଖୋଲିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"ପୁଣି ଚେଷ୍ଟା କରିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ଏହି ଡିଭାଇସ୍‌ ଆପଣଙ୍କ ସଂସ୍ଥା ଦ୍ୱାରା ପରିଚାଳିତ।"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"ଏହି ଡିଭାଇସ୍‌ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ଦ୍ୱାରା ପରିଚାଳିତ ହେଉଛି"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ଫୋନ୍‍ ପାଇଁ ଆଇକନରୁ ସ୍ୱାଇପ୍‍ କରନ୍ତୁ"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"ଆପଣ ଅନପିନ୍‍ ନକରିବା ପର୍ଯ୍ୟନ୍ତ ଏହା ଦେଖାଉଥିବ। ଅନପିନ୍‍ କରିବା ପର୍ଯ୍ୟନ୍ତ ହୋମ୍‌କୁ ଦାବିଧରନ୍ତୁ।"</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"ଏହି ସ୍କ୍ରୀନ୍‍‍କୁ ଅନପିନ୍‍ କରିବା ପାଇଁ, ବ୍ୟାକ୍ ଏବଂ ଓଭରଭ୍ୟୁ ବଟନ୍‍‌କୁ ଦାବିଧରନ୍ତୁ"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ଏହି ସ୍କ୍ରୀନ୍‍‍କୁ ଅନପିନ୍‍ କରିବା ପାଇଁ, ବ୍ୟାକ୍ ଏବଂ ହୋମ୍ ବଟନ୍‍‌କୁ ଦାବିଧରନ୍ତୁ"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"ଏହି ସ୍କ୍ରୀନ୍‌କୁ ଅନପିନ୍ କରିବା ପାଇଁ, ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ ଏବଂ ଧରି ରଖନ୍ତୁ"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"ବୁଝିଲି"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"ନାହିଁ, ଥାଉ"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"ସ୍କ୍ରୀନ୍‌କୁ ପିନ୍‌ କରାଗଲା"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 64e2d09..fe426c4 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"ਹੇਠਾਂ ਘੱਟ ਲਾਜ਼ਮੀ ਸੂਚਨਾਵਾਂ"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"ਖੋਲ੍ਹਣ ਲਈ ਦੁਬਾਰਾ ਟੈਪ ਕਰੋ"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"ਖੋਲ੍ਹਣ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਲਈ ਉੱਤੇ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੇ ਸੰਗਠਨ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ਫ਼ੋਨ ਲਈ ਪ੍ਰਤੀਕ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਅਨਪਿੰਨ ਨਾ ਕੀਤੇ ਜਾਣ ਤੱਕ ਇਸਨੂੰ ਦਿਖਾਇਆ ਜਾਂਦਾ ਹੈ। ਅਨਪਿੰਨ ਕਰਨ ਲਈ \'ਹੋਮ\' ਨੂੰ ਸਪੱਰਸ਼ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ।"</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"ਇਸ ਸਕ੍ਰੀਨ ਨੂੰ ਅਨਪਿੰਨ ਕਰਨ ਲਈ, \'ਪਿੱਛੇ\' ਅਤੇ \'ਰੂਪ-ਰੇਖਾ\' ਬਟਨਾਂ ਨੂੰ ਸਪੱਰਸ਼ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ਇਸ ਸਕ੍ਰੀਨ ਨੂੰ ਅਨਪਿੰਨ ਕਰਨ ਲਈ, \'ਪਿੱਛੇ\' ਅਤੇ \'ਹੋਮ\' ਬਟਨਾਂ ਨੂੰ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾਈ ਰੱਖੋ"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"ਇਸ ਸਕ੍ਰੀਨ ਨੂੰ ਅਨਪਿੰਨ ਕਰਨ ਲਈ, ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਕੇ ਰੱਖੋ"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"ਸਮਝ ਲਿਆ"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"ਨਹੀਂ ਧੰਨਵਾਦ"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"ਸਕ੍ਰੀਨ ਪਿੰਨ ਕੀਤੀ ਗਈ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 8ca52f3..4be1a0f 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -407,6 +407,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Poniżej widać mniej pilne powiadomienia"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Kliknij ponownie, by otworzyć"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Przesuń w górę, by otworzyć"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Przesuń w górę, by spróbować ponownie"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Tym urządzeniem zarządza Twoja organizacja"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Tym urządzeniem zarządza <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Aby włączyć telefon, przesuń palcem od ikony"</string>
@@ -552,6 +553,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ekran będzie widoczny, dopóki go nie odepniesz. Aby to zrobić, naciśnij i przytrzymaj Ekran główny."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Aby odpiąć ten ekran, naciśnij i przytrzymaj przyciski Wstecz oraz Przegląd"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Aby odpiąć ten ekran, naciśnij i przytrzymaj przyciski Wstecz oraz Ekran główny"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Aby odpiąć ten ekran, przesuń w górę i przytrzymaj"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nie, dziękuję"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Ekran przypięty"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index fb0e271..543571e 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificações menos urgentes abaixo"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Toque novamente para abrir"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Deslize para cima para abrir"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Deslize para cima para tentar novamente"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Este dispositivo é gerenciado pela sua organização"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Este dispositivo é gerenciado por <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Deslize a partir do ícone do telefone"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ela é mantida à vista até que seja liberada. Toque em Início e mantenha essa opção pressionada para liberar."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Para liberar esta tela, mantenha os botões Voltar e Visão geral pressionados"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Para liberar esta tela, mantenha os botões Voltar e Início pressionados"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Para liberar esta tela, deslize para cima e pressione"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Entendi"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Não, obrigado"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Tela fixada"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 0f9d79f..14aaca2 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificações menos urgentes abaixo"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Toque novamente para abrir"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Deslize rapidamente para cima para abrir"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Deslize rapidamente para cima para tentar novamente."</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Este dispositivo é gerido pela sua entidade"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Este dispositivo é gerido por <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Deslize rapid. a partir do ícone para aceder ao telemóvel"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Esta opção mantém o item visível até o soltar. Toque sem soltar em Página inicial para soltar."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Para soltar este ecrã, toque sem soltar nos botões Anterior e Vista geral."</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Para soltar este ecrã, toque sem soltar nos botões Anterior e Página inicial."</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Para soltar este ecrã, deslize rapidamente para cima sem soltar."</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Compreendi"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Não, obrigado"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Ecrã fixo"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index fb0e271..543571e 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificações menos urgentes abaixo"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Toque novamente para abrir"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Deslize para cima para abrir"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Deslize para cima para tentar novamente"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Este dispositivo é gerenciado pela sua organização"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Este dispositivo é gerenciado por <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Deslize a partir do ícone do telefone"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ela é mantida à vista até que seja liberada. Toque em Início e mantenha essa opção pressionada para liberar."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Para liberar esta tela, mantenha os botões Voltar e Visão geral pressionados"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Para liberar esta tela, mantenha os botões Voltar e Início pressionados"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Para liberar esta tela, deslize para cima e pressione"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Entendi"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Não, obrigado"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Tela fixada"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 02e0cc3..6b8c89f 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -403,6 +403,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificările mai puțin urgente mai jos"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Atingeți din nou pentru a deschide"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Glisați în sus pentru a deschide"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Glisați pentru a încerca din nou"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Acest dispozitiv este gestionat de organizația dvs."</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Acest dispozitiv este gestionat de <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Glisați dinspre telefon"</string>
@@ -547,6 +548,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Astfel rămâne afișat până anulați fixarea. Atingeți lung opțiunea Acasă pentru a anula fixarea."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Pentru a anula fixarea acestui ecran, atingeți lung butoanele Înapoi și Recente"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Pentru a anula fixarea acestui ecran, atingeți lung butoanele Înapoi și Acasă"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Pentru a anula fixarea acestui ecran, glisați în sus și mențineți"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Am înțeles"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nu, mulțumesc"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Ecran fixat"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index ec7a879..8fec7f6 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -405,6 +405,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Показать менее важные уведомления"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Нажмите ещё раз, чтобы открыть"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Проведите вверх, чтобы открыть"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Чтобы повторить попытку, проведите вверх"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Этим устройством управляет ваша организация"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Этим устройством управляет компания \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string>
     <string name="phone_hint" msgid="4872890986869209950">"Телефон: проведите от значка"</string>
@@ -550,6 +551,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Приложение останется активным, пока вы не отмените блокировку, нажав и удерживая кнопку \"Главный экран\"."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Чтобы открепить экран, нажмите и удерживайте кнопки \"Назад\" и \"Обзор\"."</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Чтобы открепить экран, нажмите и удерживайте кнопки \"Назад\" и \"Главный экран\"."</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Чтобы открепить этот экран, проведите по нему вверх и задержите руку в крайнем положении."</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"ОК"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Нет, спасибо"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Блокировка включена"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 9e00215..2c54218 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"හදිසිය අඩු දැනුම් දීම් පහත"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"විවෘත කිරීමට නැවත තට්ටු කරන්න"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"විවෘත කිරීමට ස්වයිප් කරන්න"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"නැවත උත්සාහ කිරීමට ඉහළට ස්වයිප් කරන්න"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"මෙම උපාංගය ඔබගේ සංවිධානය විසින් කළමනාකරණය කරනු ලැබේ"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"මෙම උපාංගය <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> මගින් කළමනාකරණය කෙරේ"</string>
     <string name="phone_hint" msgid="4872890986869209950">"දුරකථනය සඳහා නිරූපකය වෙතින් ස්වයිප් කරන්න"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"මෙය ඔබ ගලවන තෙක් එය දසුන තුළ තබයි. ගැලවීමට මුල් පිටුව ස්පර්ශ කර අල්ලාගෙන සිටින්න."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"මෙම තිර ඇමුණුම ගැලවීමට, දළ විශ්ලේෂණය බොත්තම් ස්පර්ශ කර අල්ලා ගෙන සිටින්න"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"මෙම තිරය ඇමුණුම ගැලවීමට, මුල් පිටුව බොත්තම් ස්පර්ශ කර අල්ලා ගෙන සිටින්න"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"මෙම තිරය ගැලවීමට, ඉහළට ස්වයිප් කර අල්ලාගෙන සිටින්න"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"හරි, තේරුණා"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"එපා ස්තූතියි"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"තිරය අමුණා ඇත"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index dabe330..a6a41e1 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -405,6 +405,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Menej naliehavé upozornenia sa nachádzajú nižšie"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Upozornenie otvoríte opätovným klepnutím"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Otvorte potiahnutím prstom nahor"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Potiahnutím nahor to skúste znova"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Toto zariadenie spravuje vaša organizácia"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Toto zariadenie spravuje organizácia <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Telefón otvoríte prejdením prstom od ikony"</string>
@@ -550,6 +551,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Obsah bude pripnutý v zobrazení, dokým ho neuvoľníte. Uvoľníte ho pridržaním tlačidla Domov."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Ak chcete odopnúť túto obrazovku, pridržte tlačidlá Späť a Prehľad"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Ak chcete odopnúť túto obrazovku, pridržte tlačidlá Späť a Prehľad"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Túto obrazovku odopnete potiahnutím prsta nahor a pridržaním"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Dobre"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nie, vďaka"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Obrazovka bola pripnutá"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 2958dc8..63358ba 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -405,6 +405,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Manj nujna obvestila spodaj"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Znova se dotaknite, da odprete"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Povlecite navzgor, da odprete"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Povlecite navzgor za vnovičen poskus"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"To napravo upravlja vaša organizacija"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"To napravo upravlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Povlecite z ikone za telefon"</string>
@@ -550,6 +551,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"S tem ostane zaslon viden, dokler ga ne odpnete. Če ga želite odpeti, pridržite gumb za začetni zaslon."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Če želite odpeti ta zaslon, hkrati pridržite gumba za nazaj in za pregled."</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Če želite odpeti ta zaslon, hkrati pridržite gumba za nazaj in za začetni zaslon."</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Če želite odpeti ta zaslon, povlecite navzgor in pridržite"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Razumem"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, hvala"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Zaslon je pripet"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 69eacd3..6c3162e 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Njoftimet më pak urgjente, më poshtë!"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Trokit përsëri për ta hapur"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Rrëshqit lart për ta hapur"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Rrëshqit lart për të provuar përsëri"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Kjo pajisje menaxhohet nga organizata jote"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Kjo pajisje menaxhohet nga <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Rrëshqit për të hapur telefonin"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Kjo e ruan në pamje deri sa ta heqësh nga gozhdimi. Prek dhe mbaj të shtypur \"Kreu\" për ta hequr nga gozhdimi."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Për të hequr gozhdimin e këtij ekrani, prek dhe mbaj butonat \"Prapa\" dhe \"Përmbledhja\"."</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Për të hequr gozhdimin e këtij ekrani, prek dhe mbaj butonat \"Prapa\" dhe \"Kreu\"."</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Për të hequr gozhdimin e këtij ekrani, rrëshqit shpejt lart dhe mbaje të shtypur"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"E kuptova"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Jo, faleminderit!"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Ekrani u gozhdua"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index f1bf3c9..4d289dc 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -403,6 +403,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Мање хитна обавештења су у наставку"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Додирните поново да бисте отворили"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Превуците нагоре да бисте отворили"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Превуците нагоре да бисте пробали поново"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Овим уређајем управља организација"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Овим уређајем управља <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Превуците од иконе за телефон"</string>
@@ -547,6 +548,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"На овај начин се ово стално приказује док га не откачите. Додирните и задржите Почетна да бисте га откачили."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Да бисте откачили овај екран, додирните и задржите дугмад Назад и Преглед"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Да бисте откачили овај екран, додирните и задржите дугмад Назад и Почетна"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Да бисте откачили овај екран, превуците нагоре и задржите"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Важи"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Не, хвала"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Екран је закачен"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 764ad50..b891b93 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Mindre brådskande aviseringar nedan"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Tryck igen för att öppna"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Öppna genom att svepa uppåt"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Svep uppåt om du vill försöka igen"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Den här enheten hanteras av organisationen"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Den här enheten hanteras av <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Svep från ikonen och öppna telefonen"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Skärmen visas tills du lossar den. Tryck länge på Startsida om du vill lossa skärmen."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Om du vill lossa skärmen trycker du länge på knapparna Tillbaka och Översikt"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Om du vill lossa skärmen trycker du länge på knapparna Tillbaka och Startsida"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Svep uppåt och håll kvar fingret om du vill lossa skärmen"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nej tack"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Skärmen är fäst"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 640bbda..b37405a 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Arifa zisizo za dharura sana ziko hapo chini"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Gusa tena ili ufungue"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Telezesha kidole juu ili ufungue"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Telezesha kidole juu ili ujaribu tena"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Kifaa hiki kinasimamiwa na shirika lako"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Kifaa hiki kinadhibitiwa na <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Telezesha kidole kutoka kwa aikoni ili ufikie simu"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Hali hii huifanya ionekane hadi utakapoibandua. Gusa na ushikilie kitufe cha Mwanzo ili ubandue."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Ili ubandue skrini hii, gusa na ushikilie kitufe cha Nyuma na Muhtasari"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Ili ubandue skrini hii, gusa na ushikilie vitufe vya Nyuma na Mwanzo"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Ili ubandue skrini hii, telezesha kidole juu na ushikilie"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Nimeelewa"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Hapana, asante"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Skrini imebandikwa"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 9efdbe9..27cd17a 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"அவசர நிலைக் குறைவான அறிவிப்புகள் கீழே உள்ளன"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"திறக்க, மீண்டும் தட்டவும்"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"திறப்பதற்கு மேல் நோக்கி ஸ்வைப் செய்யவும்"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"மீண்டும் முயல மேல்நோக்கி ஸ்வைப் செய்யவும்"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"இந்தச் சாதனத்தை உங்கள் நிறுவனம் நிர்வகிக்கிறது"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"இந்தச் சாதனத்தை நிர்வகிப்பது: <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ஃபோனிற்கு ஐகானிலிருந்து ஸ்வைப் செய்யவும்"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"இதற்கான பின்னை அகற்றும் வரை, இந்தப் பயன்முறை செயல்பாட்டிலேயே இருக்கும். அகற்றுவதற்கு, முகப்புப் பொத்தானைத் தொட்டுப் பிடிக்கவும்."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"இந்தத் திரையின் பின்னை அகற்ற, முந்தையது மற்றும் மேலோட்டப் பார்வைப் பொத்தான்களைத் தொட்டுப் பிடிக்கவும்"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"இந்தத் திரையின் பின்னை அகற்ற, முந்தையது மற்றும் முகப்புப் பொத்தான்களைத் தொட்டுப் பிடிக்கவும்"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"இந்தத் திரையை அகற்ற மேல்நோக்கி ஸ்வைப் செய்தவாறு பிடித்திருக்கவும்"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"புரிந்தது"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"வேண்டாம்"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"திரை பின் செய்யப்பட்டது"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 5717e02f..350ccc6 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"తక్కువ అత్యవసర నోటిఫికేషన్‌లు దిగువన"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"తెరవడానికి మళ్లీ నొక్కండి"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"తెరవడానికి, పైకి స్వైప్ చేయండి"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"మళ్ళీ ప్రయత్నించడానికి పైకి స్వైప్ చేయండి"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ఈ పరికరాన్ని మీ సంస్థ నిర్వహిస్తోంది"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"ఈ పరికరం <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> నిర్వహణలో ఉంది"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ఫోన్ కోసం చిహ్నాన్ని స్వైప్ చేయండి"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"దీని వలన మీరు అన్‌పిన్ చేసే వరకు ఇది వీక్షణలో ఉంచబడుతుంది. అన్‌పిన్ చేయడానికి హోమ్‌ని తాకి &amp; అలాగే పట్టుకోండి."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"ఈ స్క్రీన్‌ను అన్‌పిన్ చేయడానికి, వెనుకకు మరియు అవలోకనం బటన్‌లను తాకి &amp; అలాగే పట్టుకోండి"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ఈ స్క్రీన్‌ను అన్‌పిన్ చేయడానికి, వెనుకకు మరియు హోమ్ బటన్‌లను తాకి &amp; అలాగే పట్టుకోండి"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"ఈ స్క్రీన్‌ను అన్‌పిన్ చేయడానికి, పైకి స్వైప్ చేసి &amp; అలాగే పట్టుకోండి"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"అర్థమైంది"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"వద్దు, ధన్యవాదాలు"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"స్క్రీన్ పిన్ చేయబడింది"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index ce123a5..9d39859 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"การแจ้งเตือนที่เร่งด่วนน้อยด้านล่าง"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"แตะอีกครั้งเพื่อเปิด"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"เลื่อนขึ้นเพื่อเปิด"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"เลื่อนขึ้นเพื่อลองอีกครั้ง"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"อุปกรณ์นี้จัดการโดยองค์กรของคุณ"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"อุปกรณ์เครื่องนี้จัดการโดย <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"เลื่อนไอคอนโทรศัพท์"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"การดำเนินการนี้จะแสดงหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกตรึง แตะ \"หน้าแรก\" ค้างไว้เพื่อเลิกตรึง"</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"หากต้องการเลิกตรึงหน้าจอนี้ ให้แตะปุ่ม \"กลับ\" และ \"ภาพรวม\" ค้างไว้"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"หากต้องการเลิกตรึงหน้าจอนี้ ให้แตะปุ่ม \"กลับ\" และ \"หน้าแรก\" ค้างไว้"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"หากต้องการเลิกตรึงหน้าจอนี้ ให้เลื่อนขึ้นค้างไว้"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"รับทราบ"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"ไม่เป็นไร ขอบคุณ"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"ตรึงหน้าจอแล้ว"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 0ab01d8..56da232 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Nasa ibaba ang mga notification na hindi masyadong mahalaga"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"I-tap ulit upang buksan"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Mag-swipe pataas para buksan"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Mag-swipe pataas para subukan ulit"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Ang device na ito ay pinamamahalaan ng iyong organisasyon"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Pinamamahalaan ng <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ang device na ito"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Mag-swipe mula sa icon para sa telepono"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Pinapanatili nitong nakikita ito hanggang sa mag-unpin ka. Pindutin nang matagal ang Home upang mag-unpin."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Upang i-unpin ang screen na ito, pindutin nang matagal ang mga button na Bumalik at Overview"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Upang i-unpin ang screen na ito, pindutin nang matagal ang mga button na Bumalik at Home"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Para i-unpin ang screen na ito, mag-swipe pataas at pumindot nang matagal"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Nakuha ko"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Hindi, salamat na lang"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Na-pin ang screen"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 4e2a891..257b9de 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Daha az acil bildirimler aşağıdadır"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Açmak için tekrar dokunun"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Açmak için yukarı kaydırın"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Tekrar denemek için yukarı kaydırın"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Bu cihaz kuruluşunuz tarafından yönetiliyor"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tarafından yönetilmektedir."</string>
     <string name="phone_hint" msgid="4872890986869209950">"Telefon için, simgeden hızlıca kaydırın"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Bu işlem, siz sabitlemeyi kaldırana kadar ekranı görünür durumda tutar. Sabitlemeyi kaldırmak için Ana sayfaya dokunup basılı tutun."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Bu ekranın sabitlemesini kaldırmak için Geri ve Genel Bakış düğmelerine dokunup basılı tutun"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Bu ekranın sabitlemesini kaldırmak için Geri ve Ana sayfa düğmelerine dokunup basılı tutun"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Bu ekranın sabitlemesini kaldırmak için hızlıca yukarı kaydırıp tutun"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Anladım"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Hayır, teşekkürler"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Ekran sabitlendi"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 56521f6..d82acf7 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -405,6 +405,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Менше термінових сповіщень нижче"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Торкніться знову, щоб відкрити"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Проведіть пальцем угору, щоб відкрити"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Проведіть пальцем угору, щоб повторити спробу"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Цим пристроєм керує адміністратор вашої організації"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Цим пристроєм керує організація <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Телефон: проведіть пальцем від значка"</string>
@@ -550,6 +551,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ви бачитимете цей екран, доки не відкріпите його. Для цього натисніть і утримуйте кнопку \"Головний екран\"."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Щоб відкріпити цей екран, натисніть і утримуйте кнопки \"Назад\" та \"Огляд\""</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Щоб відкріпити цей екран, натисніть і утримуйте кнопки \"Назад\" та \"Головний екран\""</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Щоб відкріпити цей екран, проведіть пальцем вгору й утримуйте"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Зрозуміло"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Ні, дякую"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Екран закріплено"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index b698fe4..7d4f177 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"کم اہم اطلاعات ذیل میں ہیں"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"کھولنے کیلئے دوبارہ تھپتھپائیں"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"کھولنے کے لیے اوپر سوائپ کريں"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"دوبارہ کوشش کرنے کے لیے اوپر سوائپ کريں"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"یہ آلہ آپ کی تنظیم کے زیر انتظام ہے"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"یہ آلہ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> کے زیر انتظام ہے"</string>
     <string name="phone_hint" msgid="4872890986869209950">"فون کیلئے آئیکن سے سوائپ کریں"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"یہ اس کو اس وقت تک مد نظر رکھتا ہے جب تک آپ اس سے پن نہیں ہٹا دیتے۔ پن ہٹانے کیلئے \"ہوم\" بٹن کو ٹچ کریں اور دبائے رکھیں۔"</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"اس اسکرین سے پن ہٹانے کیلئے، \"پیچھے\" اور \"مجموعی جائزہ\" بٹنز کو ٹچ کریں اور دبائے رکھیں"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"اس اسکرین سے پن ہٹانے کیلئے، \"پیچھے\" اور \"ہوم\" بٹنز کو ٹچ کریں اور دبائے رکھیں"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"اس اسکرین سے پن ہٹانے کے لیے، اوپر کی طرف سوائپ کریں: دبائیں رکھیں"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"سمجھ آ گئی"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"نہیں شکریہ"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"اسکرین کو پن کر دیا گیا"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index bb1e062..9bda6e7 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Kam ahamiyatli bildirishnomalarni pastda ko‘rsatish"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Ochish uchun yana bosing"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Ochish uchun tepaga suring"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Qayta urinish uchun tepaga suring"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Bu – tashkilotingiz tomonidan boshqariladigan qurilma"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Bu – <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tomonidan boshqariladigan qurilma"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Telefonni ochish uchun suring"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ekran yechib olinmagunicha u mahkamlangan holatda qoladi. Uni yechish uchun Orqaga va Asosiy tugmlarni birga bosib turing."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Bu ekrandan chiqish uchun Orqaga va Menyu tugmalarini bosib turing"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Bu ekrandan chiqish uchun Orqaga va Boshi tugmalarini bosib turing"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Bu ekrandan chiqish uchun tepaga surib, bosib turing"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Yo‘q, kerakmas"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Ekran mahkamlandi"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 7bbc4b1..c51bab6 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Thông báo ít khẩn cấp hơn bên dưới"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Nhấn lại để mở"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Vuốt lên để mở"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Vuốt lên để thử lại"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Thiết bị này do tổ chức của bạn quản lý"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Thiết bị này được <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> quản lý"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Vuốt từ biểu tượng để mở điện thoại"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Thao tác này sẽ duy trì hiển thị màn hình cho đến khi bạn bỏ ghim. Hãy chạm và giữ nút Màn hình chính để bỏ ghim."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Để bỏ ghim màn hình này, hãy chạm và giữ nút Quay lại và nút Tổng quan"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Để bỏ ghim màn hình này, hãy chạm và giữ nút Quay lại và nút Màn hình chính"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Để bỏ ghim màn hình này, hãy vuốt lên và giữ"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Ok"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Không, cảm ơn"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Đã ghim màn hình"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 3f0ac4f..9b4edaa 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"不太紧急的通知会显示在下方"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"再次点按即可打开"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"向上滑动即可打开"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"向上滑动即可重试"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"此设备由您所属单位管理"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"此设备是由<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>托管"</string>
     <string name="phone_hint" msgid="4872890986869209950">"滑动图标即可拨打电话"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"这将会固定显示此屏幕,直到您取消固定为止。触摸并按住“主屏幕”即可取消固定屏幕。"</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"要取消固定此屏幕,请触摸并按住“返回”和“概览”按钮"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"要取消固定此屏幕,请触摸并按住“返回”和“主屏幕”按钮"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"要取消固定此屏幕,请向上滑动并按住"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"知道了"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"不用了"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"已固定屏幕"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 59480a9..128e1ca 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"不太緊急的通知會在下方顯示"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"再次輕按即可開啟"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"向上滑動即可開啟"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"請向上滑動以再試一次"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"此裝置由您的機構管理"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"此裝置由<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>管理"</string>
     <string name="phone_hint" msgid="4872890986869209950">"從圖示滑動即可使用手機功能"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"畫面將會繼續顯示,直至您取消固定為止。按住主按鈕即可取消固定。"</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"如要取消固定此畫面,請按住 [返回] 按鈕和 [概覽] 按鈕"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"如要取消固定此畫面,請按住 [返回] 按鈕和主按鈕"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"如要取消固定此畫面,請向上滑動然後按住"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"知道了"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"不用了,謝謝"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"已固定畫面"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 1cab7de..457206d 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"較不緊急的通知會顯示在下方"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"再次輕觸即可開啟"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"向上滑動即可開啟"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"向上滑動即可重試"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"這個裝置是由貴機構所管理"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"這個裝置是由 <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> 所管理"</string>
     <string name="phone_hint" msgid="4872890986869209950">"滑動手機圖示即可啟用"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"這會讓應用程式顯示在螢幕上,直到取消固定為止。按住主螢幕按鈕即可取消固定。"</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"如要取消固定這個螢幕畫面,請按住「返回」按鈕和「總覽」按鈕"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"如要取消固定這個螢幕畫面,請按住「返回」按鈕和主螢幕按鈕"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"如要取消固定畫面,請向上滑動並按住"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"知道了"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"不用了,謝謝"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"已固定螢幕畫面"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 74b9143..2306e4a 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -401,6 +401,7 @@
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Izaziso ezingasheshi kakhulu ezingezansi"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Thepha futhi ukuze uvule"</string>
     <string name="keyguard_unlock" msgid="6035822649218712063">"Swayiphela phezulu ukuze uvule"</string>
+    <string name="keyguard_retry" msgid="5221600879614948709">"Swayiphela phezulu ukuze uzame futhi"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Le divayisi iphethwe inhlangano yakho"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Le divayisi iphethwe yi-<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Swayiphela ifoni kusukela kusithonjana"</string>
@@ -544,6 +545,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Lokhu kuyigcina ibukeka uze ususe ukuphina. Thinta uphinde ubambe okuthi Ekhaya ukuze ususe ukuphina."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Ukuze ususe ukuphina lesi sikrini, thinta uphinde ubambe izinkinobho zokubuyela emuva nezokubuka konke"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Ukuze ususe ukuphina lesi sikrini, thinta uphinde ubambe izinkinobho nezithi Emuva nethi Ekhaya"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Ukuze ususe ukuphina lesi sikrini, swayiphela phezulu futhi ubambe"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Ngiyitholile"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Cha ngiyabonga"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Isikrini siphiniwe"</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 6e8e823..78318cb 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -273,7 +273,6 @@
 
     <!-- SystemUI Services: The classes of the stuff to start. -->
     <string-array name="config_systemUIServiceComponents" translatable="false">
-        <item>com.android.systemui.Dependency$DependencyCreator</item>
         <item>com.android.systemui.util.NotificationChannels</item>
         <item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item>
         <item>com.android.systemui.keyguard.KeyguardViewMediator</item>
@@ -304,7 +303,6 @@
 
     <!-- SystemUI Services (per user): The classes of the stuff to start for each user. This is a subset of the config_systemUIServiceComponents -->
     <string-array name="config_systemUIServiceComponentsPerUser" translatable="false">
-        <item>com.android.systemui.Dependency$DependencyCreator</item>
         <item>com.android.systemui.util.NotificationChannels</item>
     </string-array>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index bef1fc2..2e17991 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -385,22 +385,16 @@
     <!-- The width of the panel that holds the quick settings. -->
     <dimen name="qs_panel_width">@dimen/notification_panel_width</dimen>
 
-    <dimen name="volume_dialog_panel_transparent_padding_right">8dp</dimen>
+    <dimen name="volume_dialog_panel_transparent_padding_right">4dp</dimen>
 
     <dimen name="volume_dialog_panel_transparent_padding">20dp</dimen>
 
     <dimen name="volume_dialog_stream_padding">8dp</dimen>
 
-    <!-- the amount the volume panel should be offset at the end from the view next to it (or
-    the screen edge, in portrait-->
-    <dimen name="volume_dialog_base_margin">8dp</dimen>
-
     <dimen name="volume_dialog_panel_width">64dp</dimen>
 
     <dimen name="volume_dialog_slider_height">116dp</dimen>
 
-    <dimen name="volume_dialog_row_height">252dp</dimen>
-
     <dimen name="volume_dialog_ringer_size">64dp</dimen>
 
     <dimen name="volume_dialog_ringer_icon_padding">20dp</dimen>
@@ -417,8 +411,6 @@
 
     <dimen name="volume_dialog_row_margin_bottom">8dp</dimen>
 
-    <dimen name="volume_dialog_settings_icon_size">16dp</dimen>
-
     <dimen name="volume_dialog_elevation">9dp</dimen>
 
     <dimen name="volume_tool_tip_right_margin">76dp</dimen>
@@ -1110,18 +1102,23 @@
     <dimen name="bubble_flyout_pointer_size">6dp</dimen>
     <!-- How much space to leave between the flyout (tip of the arrow) and the bubble stack. -->
     <dimen name="bubble_flyout_space_from_bubble">8dp</dimen>
-    <!-- Padding around a collapsed bubble -->
-    <dimen name="bubble_view_padding">0dp</dimen>
-    <!-- Padding between bubbles when displayed in expanded state -->
-    <dimen name="bubble_padding">8dp</dimen>
+    <!-- Padding between status bar and bubbles when displayed in expanded state -->
+    <dimen name="bubble_padding_top">16dp</dimen>
     <!-- Size of individual bubbles. -->
-    <dimen name="individual_bubble_size">52dp</dimen>
+    <dimen name="individual_bubble_size">60dp</dimen>
+    <!-- Size of bubble icon bitmap. -->
+    <dimen name="bubble_icon_bitmap_size">52dp</dimen>
+    <!-- Extra padding added to the touchable rect for bubbles so they are easier to grab. -->
+    <dimen name="bubble_touch_padding">12dp</dimen>
     <!-- Size of the circle around the bubbles when they're in the dismiss target. -->
-    <dimen name="bubble_dismiss_encircle_size">56dp</dimen>
+    <dimen name="bubble_dismiss_encircle_size">52dp</dimen>
     <!-- How much to inset the icon in the circle -->
     <dimen name="bubble_icon_inset">16dp</dimen>
     <!-- Padding around the view displayed when the bubble is expanded -->
     <dimen name="bubble_expanded_view_padding">4dp</dimen>
+    <!-- This should be at least the size of bubble_expanded_view_padding; it is used to include
+         a slight touch slop around the expanded view. -->
+    <dimen name="bubble_expanded_view_slop">8dp</dimen>
     <!-- Default (and minimum) height of the expanded view shown when the bubble is expanded -->
     <dimen name="bubble_expanded_default_height">180dp</dimen>
     <!-- Height of the triangle that points to the expanded bubble -->
@@ -1130,10 +1127,8 @@
     <dimen name="bubble_pointer_width">6dp</dimen>
     <!-- Extra padding around the dismiss target for bubbles -->
     <dimen name="bubble_dismiss_slop">16dp</dimen>
-    <!-- Height of the header within the expanded view. -->
-    <dimen name="bubble_expanded_header_height">48dp</dimen>
-    <!-- Left and right padding applied to the header. -->
-    <dimen name="bubble_expanded_header_horizontal_padding">24dp</dimen>
+    <!-- Height of button allowing users to adjust settings for bubbles. -->
+    <dimen name="bubble_settings_size">48dp</dimen>
     <!-- How far, horizontally, to animate the expanded view over when animating in/out. -->
     <dimen name="bubble_expanded_animate_x_distance">100dp</dimen>
     <!-- How far, vertically, to animate the expanded view over when animating in/out. -->
@@ -1146,12 +1141,10 @@
     <dimen name="bubble_message_padding">4dp</dimen>
     <!-- Offset between bubbles in their stacked position. -->
     <dimen name="bubble_stack_offset">5dp</dimen>
-    <!-- How far offscreen the bubble stack rests. -->
-    <dimen name="bubble_stack_offscreen">5dp</dimen>
+    <!-- How far offscreen the bubble stack rests. Cuts off padding and part of icon bitmap. -->
+    <dimen name="bubble_stack_offscreen">9dp</dimen>
     <!-- How far down the screen the stack starts. -->
-    <dimen name="bubble_stack_starting_offset_y">100dp</dimen>
-    <!-- Size of image buttons in the bubble header -->
-    <dimen name="bubble_header_icon_size">48dp</dimen>
+    <dimen name="bubble_stack_starting_offset_y">96dp</dimen>
     <!-- Space between the pointer triangle and the bubble expanded view -->
     <dimen name="bubble_pointer_margin">8dp</dimen>
     <!-- Height of the permission prompt shown with bubbles -->
@@ -1160,6 +1153,7 @@
          snap to the dismiss target. -->
     <dimen name="bubble_dismiss_target_padding_x">40dp</dimen>
     <dimen name="bubble_dismiss_target_padding_y">20dp</dimen>
+
     <!-- Size of the RAT type for CellularTile -->
     <dimen name="celltile_rat_type_size">10sp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 66f1949..3727181 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -137,6 +137,7 @@
     <item type="id" name="scale_x_dynamicanimation_tag"/>
     <item type="id" name="scale_y_dynamicanimation_tag"/>
     <item type="id" name="physics_animator_tag"/>
+    <item type="id" name="target_animator_tag" />
 
     <!-- Global Actions Menu -->
     <item type="id" name="global_actions_view" />
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 4b70b97..6ffea1b 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -961,6 +961,9 @@
     <!-- Message shown when lock screen is tapped or face authentication fails. [CHAR LIMIT=60] -->
     <string name="keyguard_unlock">Swipe up to open</string>
 
+    <!-- Message shown when face authentication fails and the pin pad is visible. [CHAR LIMIT=60] -->
+    <string name="keyguard_retry">Swipe up to try again</string>
+
     <!-- Text on keyguard screen and in Quick Settings footer indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=60] -->
     <string name="do_disclosure_generic">This device is managed by your organization</string>
 
@@ -1386,6 +1389,8 @@
         buttons</string>
     <string name="screen_pinning_toast_recents_invisible">To unpin this screen, touch &amp; hold Back
         and Home buttons</string>
+    <!-- Notify (in toast) user how to unpin screen in gesture navigation mode [CHAR LIMIT=NONE] -->
+    <string name="screen_pinning_toast_gesture_nav">To unpin this screen, swipe up &amp; hold</string>
     <!-- Screen pinning positive response. -->
     <string name="screen_pinning_positive">Got it</string>
     <!-- Screen pinning negative response. -->
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
index 328116d..13fc702 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
@@ -236,7 +236,8 @@
 
                     @Override
                     public void onAnimationCanceled(boolean deferredWithScreenshot) {
-                        animationHandler.onAnimationCanceled(deferredWithScreenshot);
+                        animationHandler.onAnimationCanceled(
+                                deferredWithScreenshot ? new ThumbnailData() : null);
                     }
                 };
             }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java
index 5850fda..579858a 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java
@@ -18,6 +18,8 @@
 
 import android.graphics.Rect;
 
+import com.android.systemui.shared.recents.model.ThumbnailData;
+
 public interface RecentsAnimationListener {
 
     /**
@@ -29,5 +31,5 @@
     /**
      * Called when the animation into Recents was canceled. This call is made on the binder thread.
      */
-    void onAnimationCanceled(boolean deferredWithScreenshot);
+    void onAnimationCanceled(ThumbnailData thumbnailData);
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
index c215d0f..4c49494 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
@@ -72,6 +72,13 @@
      */
     public void onSingleTaskDisplayDrawn(int displayId) { }
 
+    /**
+     * Called when the last task is removed from a display which can only contain one task.
+     *
+     * @param displayId the id of the display from which the window is removed.
+     */
+    public void onSingleTaskDisplayEmpty(int displayId) {}
+
     public void onTaskProfileLocked(int taskId, int userId) { }
     public void onTaskCreated(int taskId, ComponentName componentName) { }
     public void onTaskRemoved(int taskId) { }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
index d570a58..4465f04 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
@@ -209,6 +209,12 @@
     }
 
     @Override
+    public void onSingleTaskDisplayEmpty(int displayId) throws RemoteException {
+        mHandler.obtainMessage(H.ON_SINGLE_TASK_DISPLAY_EMPTY, displayId,
+                0 /* unused */).sendToTarget();
+    }
+
+    @Override
     public void onTaskDisplayChanged(int taskId, int newDisplayId) throws RemoteException {
         mHandler.obtainMessage(H.ON_TASK_DISPLAY_CHANGED, taskId, newDisplayId).sendToTarget();
     }
@@ -233,7 +239,8 @@
         private static final int ON_SIZE_COMPAT_MODE_ACTIVITY_CHANGED = 17;
         private static final int ON_BACK_PRESSED_ON_TASK_ROOT = 18;
         private static final int ON_SINGLE_TASK_DISPLAY_DRAWN = 19;
-        private static final int ON_TASK_DISPLAY_CHANGED = 20;
+        private static final int ON_SINGLE_TASK_DISPLAY_EMPTY = 20;
+        private static final int ON_TASK_DISPLAY_CHANGED = 21;
 
 
         public H(Looper looper) {
@@ -376,6 +383,13 @@
                         }
                         break;
                     }
+                    case ON_SINGLE_TASK_DISPLAY_EMPTY: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onSingleTaskDisplayEmpty(
+                                    msg.arg1);
+                        }
+                        break;
+                    }
                     case ON_TASK_DISPLAY_CHANGED: {
                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                             mTaskStackListeners.get(i).onTaskDisplayChanged(msg.arg1, msg.arg2);
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierText.java b/packages/SystemUI/src/com/android/keyguard/CarrierText.java
index adcb7a1..b70d834 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierText.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierText.java
@@ -24,6 +24,8 @@
 import android.view.View;
 import android.widget.TextView;
 
+import com.android.systemui.R;
+
 import java.util.Locale;
 
 public class CarrierText extends TextView {
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
index 10d132a..3f3d8a5 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
@@ -44,6 +44,7 @@
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.settingslib.WirelessUtils;
 import com.android.systemui.Dependency;
+import com.android.systemui.R;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 
 import java.util.ArrayList;
@@ -361,7 +362,9 @@
                 }
             }
         }
-        if (allSimsMissing) {
+        // Only create "No SIM card" if no cards with CarrierName && no wifi when some sim is READY
+        // This condition will also be true always when numSubs == 0
+        if (allSimsMissing && !anySimReadyAndInService) {
             if (numSubs != 0) {
                 // Shows "No SIM card | Emergency calls only" on devices that are voice-capable.
                 // This depends on mPlmn containing the text "Emergency calls only" when the radio
diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyCarrierArea.java b/packages/SystemUI/src/com/android/keyguard/EmergencyCarrierArea.java
index e98ef06..225bebe 100644
--- a/packages/SystemUI/src/com/android/keyguard/EmergencyCarrierArea.java
+++ b/packages/SystemUI/src/com/android/keyguard/EmergencyCarrierArea.java
@@ -21,6 +21,8 @@
 import android.view.MotionEvent;
 import android.view.View;
 
+import com.android.systemui.R;
+
 public class EmergencyCarrierArea extends AlphaOptimizedLinearLayout {
 
     private CarrierText mCarrierText;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index a4b6958..d45603f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -33,6 +33,7 @@
 import com.android.internal.util.LatencyTracker;
 import com.android.internal.widget.LockPatternChecker;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.R;
 
 import java.util.Arrays;
 
@@ -253,6 +254,7 @@
     protected void onUserInput() {
         if (mCallback != null) {
             mCallback.userActivity();
+            mCallback.onUserInput();
         }
         mSecurityMessageDisplay.setMessage("");
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java
index 6a83c71..a78c293 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java
@@ -23,6 +23,8 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.TextView;
 
+import com.android.systemui.R;
+
 /**
  * Replaces fancy colons with regular colons. Only works on TextViews.
  */
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 5097216..df0dc46 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -30,6 +30,7 @@
 import com.android.internal.colorextraction.ColorExtractor.OnColorsChangedListener;
 import com.android.keyguard.clock.ClockManager;
 import com.android.systemui.Interpolators;
+import com.android.systemui.R;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.ClockPlugin;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
index 0ec60e5..9380eb4 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -35,6 +35,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.Dependency;
+import com.android.systemui.R;
 import com.android.systemui.statusbar.NavigationBarController;
 import com.android.systemui.statusbar.phone.NavigationBarView;
 import com.android.systemui.util.InjectionInflationController;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java b/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java
index c2bbfbf..fe64142 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java
@@ -32,6 +32,8 @@
 import android.view.WindowManager;
 import android.widget.Button;
 
+import com.android.systemui.R;
+
 /***
  * This button is used by the device with embedded SIM card to disable current carrier to unlock
  * the device with no cellular service.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
index 14ead04..8e1f6d3 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
@@ -35,6 +35,7 @@
 import com.android.keyguard.KeyguardSecurityContainer.SecurityCallback;
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
 import com.android.settingslib.Utils;
+import com.android.systemui.R;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 
 import java.io.File;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
index 037a8d3..1ff98dd 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
@@ -31,6 +31,7 @@
 import android.view.View;
 import android.widget.TextView;
 
+import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 
 import java.lang.ref.WeakReference;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
index 6808c0f..15d2ea7 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
@@ -24,6 +24,7 @@
 
 import com.android.settingslib.animation.AppearAnimationUtils;
 import com.android.settingslib.animation.DisappearAnimationUtils;
+import com.android.systemui.R;
 
 /**
  * Displays a PIN pad for unlocking.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
index 96392156..e3ac0f6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
@@ -37,6 +37,7 @@
 import android.widget.TextView.OnEditorActionListener;
 
 import com.android.internal.widget.TextViewInputDisabler;
+import com.android.systemui.R;
 
 import java.util.List;
 /**
@@ -85,13 +86,12 @@
             mSecurityMessageDisplay.setMessage("");
         }
         final boolean wasDisabled = mPasswordEntry.isEnabled();
-        // Don't set enabled password entry & showSoftInput when PasswordEntry is invisible or in
-        // pausing stage.
+        setPasswordEntryEnabled(true);
+        setPasswordEntryInputEnabled(true);
+        // Don't call showSoftInput when PasswordEntry is invisible or in pausing stage.
         if (!mResumed || !mPasswordEntry.isVisibleToUser()) {
             return;
         }
-        setPasswordEntryEnabled(true);
-        setPasswordEntryInputEnabled(true);
         if (wasDisabled) {
             mImm.showSoftInput(mPasswordEntry, InputMethodManager.SHOW_IMPLICIT);
         }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
index 55ddfc3..34c15e6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -42,6 +42,7 @@
 import com.android.settingslib.animation.AppearAnimationCreator;
 import com.android.settingslib.animation.AppearAnimationUtils;
 import com.android.settingslib.animation.DisappearAnimationUtils;
+import com.android.systemui.R;
 
 import java.util.List;
 
@@ -274,6 +275,7 @@
         @Override
         public void onPatternCellAdded(List<LockPatternView.Cell> pattern) {
             mCallback.userActivity();
+            mCallback.onUserInput();
         }
 
         @Override
@@ -336,6 +338,7 @@
                     });
             if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) {
                 mCallback.userActivity();
+                mCallback.onUserInput();
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
index ecafc34..274f739 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -23,6 +23,8 @@
 import android.view.MotionEvent;
 import android.view.View;
 
+import com.android.systemui.R;
+
 /**
  * A Pin based Keyguard input view
  */
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java
index cbfbffb..49dcfff 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java
@@ -55,4 +55,9 @@
     default void onCancelClicked() {
         // No-op
     }
+
+    /**
+     * Invoked whenever users are typing their password or drawing a pattern.
+     */
+    void onUserInput();
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 8059dcf..ca7cd0d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -45,6 +45,7 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
 import com.android.systemui.Dependency;
+import com.android.systemui.R;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.statusbar.phone.UnlockMethodCache;
 import com.android.systemui.util.InjectionInflationController;
@@ -596,6 +597,11 @@
             }
         }
 
+        @Override
+        public void onUserInput() {
+            mUpdateMonitor.cancelFaceAuth();
+        }
+
         public void dismiss(boolean authenticated, int targetId) {
             mSecurityCallback.dismiss(authenticated, targetId);
         }
@@ -640,6 +646,8 @@
         @Override
         public void dismiss(boolean securityVerified, int targetUserId) { }
         @Override
+        public void onUserInput() { }
+        @Override
         public void reset() {}
     };
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
index e6a0250..24da3ad 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
@@ -32,6 +32,7 @@
 import android.widget.ViewFlipper;
 
 import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.R;
 
 /**
  * Subclass of the current view flipper that allows us to overload dispatchTouchEvent() so
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
index 69da990..367a7bd 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
@@ -41,6 +41,7 @@
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.IccCardConstants.State;
 import com.android.internal.telephony.PhoneConstants;
+import com.android.systemui.R;
 
 /**
  * Displays a PIN pad for unlocking.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
index 27f71d1..81f8c67 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
@@ -40,6 +40,7 @@
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.IccCardConstants.State;
 import com.android.internal.telephony.PhoneConstants;
+import com.android.systemui.R;
 
 
 /**
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 37e89c0..1dfc5f2 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -40,6 +40,7 @@
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.systemui.Dependency;
+import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 
 import java.io.FileDescriptor;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 109f270..8d858dc 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -94,6 +94,7 @@
 import com.android.internal.util.Preconditions;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.settingslib.WirelessUtils;
+import com.android.systemui.R;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
@@ -844,11 +845,6 @@
                     getCurrentUser());
         }
 
-        // The face timeout message is not very actionable, let's ask the user to
-        // manually retry.
-        if (msgId == FaceManager.FACE_ERROR_TIMEOUT) {
-            errString = mContext.getString(R.string.keyguard_unlock);
-        }
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
@@ -1408,6 +1404,7 @@
     }
 
     protected void handleStartedGoingToSleep(int arg1) {
+        mLockIconPressed = false;
         clearBiometricRecognized();
         final int count = mCallbacks.size();
         for (int i = 0; i < count; i++) {
@@ -1443,7 +1440,6 @@
     }
 
     private void handleScreenTurnedOff() {
-        mLockIconPressed = false;
         mHardwareFingerprintUnavailableRetryCount = 0;
         mHardwareFaceUnavailableRetryCount = 0;
         final int count = mCallbacks.size();
@@ -1646,6 +1642,13 @@
         updateFaceListeningState();
     }
 
+    /**
+     * In case face auth is running, cancel it.
+     */
+    public void cancelFaceAuth() {
+        stopListeningForFace();
+    }
+
     private void updateFaceListeningState() {
         // If this message exists, we should not authenticate again until this message is
         // consumed by the handler
@@ -1685,7 +1688,10 @@
         return shouldListen;
     }
 
-    private boolean shouldListenForFace() {
+    /**
+     * If face auth is allows to scan on this exact moment.
+     */
+    public boolean shouldListenForFace() {
         final boolean awakeKeyguard = mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep;
         final int user = getCurrentUser();
         final int strongAuth = mStrongAuthTracker.getStrongAuthForUser(user);
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
index 08691ec..ebdd8c6 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
@@ -29,6 +29,7 @@
 import android.widget.TextView;
 
 import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.R;
 
 public class NumPadKey extends ViewGroup {
     // list of "ABC", etc per digit, starting with '0'
diff --git a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
index b21bcc9..409ae3f 100644
--- a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
@@ -42,6 +42,8 @@
 import android.view.animation.Interpolator;
 import android.widget.EditText;
 
+import com.android.systemui.R;
+
 import java.util.ArrayList;
 import java.util.Stack;
 
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
index 9c5242c..eba2400 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
@@ -26,7 +26,7 @@
 import android.widget.TextClock;
 
 import com.android.internal.colorextraction.ColorExtractor;
-import com.android.keyguard.R;
+import com.android.systemui.R;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.ClockPlugin;
 
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
index 8e81327..3a2fbe5 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
@@ -26,7 +26,7 @@
 import android.widget.TextClock;
 
 import com.android.internal.colorextraction.ColorExtractor;
-import com.android.keyguard.R;
+import com.android.systemui.R;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.ClockPlugin;
 
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java
index 7485d33..d44d89e 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java
@@ -24,7 +24,7 @@
 import android.view.View;
 import android.widget.FrameLayout;
 
-import com.android.keyguard.R;
+import com.android.systemui.R;
 
 /**
  * Positions clock faces (analog, digital, typographic) and handles pixel shifting
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java
index 98679ade..c81935a 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java
@@ -26,7 +26,7 @@
 import android.widget.TextView;
 
 import com.android.internal.colorextraction.ColorExtractor;
-import com.android.keyguard.R;
+import com.android.systemui.R;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.ClockPlugin;
 
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ImageClock.java b/packages/SystemUI/src/com/android/keyguard/clock/ImageClock.java
index 95f1004..34c041b 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/ImageClock.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ImageClock.java
@@ -21,7 +21,7 @@
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 
-import com.android.keyguard.R;
+import com.android.systemui.R;
 
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java b/packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java
index 60ca945..b304074 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java
@@ -20,6 +20,7 @@
 import android.util.MathUtils;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.R;
 
 /**
  * Computes preferred position of clock by considering height of status bar and lock icon.
@@ -40,10 +41,10 @@
     private float mDarkAmount;
 
     SmallClockPosition(Resources res) {
-        this(res.getDimensionPixelSize(com.android.keyguard.R.dimen.status_bar_height),
-                res.getDimensionPixelSize(com.android.keyguard.R.dimen.keyguard_lock_padding),
-                res.getDimensionPixelSize(com.android.keyguard.R.dimen.keyguard_lock_height),
-                res.getDimensionPixelSize(com.android.keyguard.R.dimen.burn_in_prevention_offset_y)
+        this(res.getDimensionPixelSize(R.dimen.status_bar_height),
+                res.getDimensionPixelSize(R.dimen.keyguard_lock_padding),
+                res.getDimensionPixelSize(R.dimen.keyguard_lock_height),
+                res.getDimensionPixelSize(R.dimen.burn_in_prevention_offset_y)
         );
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/ContextComponentHelper.java b/packages/SystemUI/src/com/android/systemui/ContextComponentHelper.java
new file mode 100644
index 0000000..8fabe7a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/ContextComponentHelper.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2019 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;
+
+/**
+ * Interface necessary to make Dagger happy. See {@link ContextComponentResolver}.
+ */
+public interface ContextComponentHelper {
+    /** Turns a classname into an instance of the class or returns null. */
+    <T> T resolve(String className);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/ContextComponentResolver.java b/packages/SystemUI/src/com/android/systemui/ContextComponentResolver.java
new file mode 100644
index 0000000..09bccd9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/ContextComponentResolver.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2019 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;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+/**
+ * Used during Service and Activity instantiation to make them injectable.
+ */
+public class ContextComponentResolver implements ContextComponentHelper {
+    private final Map<Class<?>, Provider<Object>> mCreators;
+
+    @Inject
+    ContextComponentResolver(Map<Class<?>, Provider<Object>> creators) {
+        mCreators = creators;
+    }
+
+    /**
+     * Looks up the class name to see if Dagger has an instance of it.
+     */
+    @Override
+    public <T> T resolve(String className) {
+        for (Map.Entry<Class<?>, Provider<Object>> p : mCreators.entrySet()) {
+            if (p.getKey().getName().equals(className)) {
+                return (T) p.getValue().get();
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 6c36bc9..15bea24 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -16,7 +16,6 @@
 
 import android.annotation.Nullable;
 import android.app.INotificationManager;
-import android.content.Context;
 import android.content.res.Configuration;
 import android.hardware.SensorPrivacyManager;
 import android.hardware.display.NightDisplayListener;
@@ -114,7 +113,6 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.HashMap;
 import java.util.function.Consumer;
 
 import javax.inject.Inject;
@@ -138,9 +136,7 @@
  * they have no clients they should not have any registered resources like bound
  * services, registered receivers, etc.
  */
-public class Dependency extends SystemUI {
-    private static final String TAG = "Dependency";
-
+public class Dependency {
     /**
      * Key for getting a background Looper for background work.
      */
@@ -305,8 +301,20 @@
     public Dependency() {
     }
 
-    @Override
-    public void start() {
+
+    /**
+     * Initialize Depenency.
+     */
+    public static void initDependencies(SystemUIRootComponent rootComponent) {
+        if (sDependency != null) {
+            return;
+        }
+        sDependency = new Dependency();
+        rootComponent.createDependency().createSystemUI(sDependency);
+        sDependency.start();
+    }
+
+    protected void start() {
         // TODO: Think about ways to push these creation rules out of Dependency to cut down
         // on imports.
         mProviders.put(TIME_TICK_HANDLER, mTimeTickHandler::get);
@@ -486,10 +494,14 @@
         sDependency = this;
     }
 
-    @Override
-    public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        super.dump(fd, pw, args);
+    static void staticDump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        sDependency.dump(fd, pw, args);
+    }
 
+    /**
+     * {@see SystemUI.dump}
+     */
+    public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         // Make sure that the DumpController gets added to mDependencies, as they are only added
         // with Dependency#get.
         getDependency(DumpController.class);
@@ -509,9 +521,11 @@
                 .forEach(o -> ((Dumpable) o).dump(fd, pw, args));
     }
 
-    @Override
+    protected static void staticOnConfigurationChanged(Configuration newConfig) {
+        sDependency.onConfigurationChanged(newConfig);
+    }
+
     protected synchronized void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
         mDependencies.values().stream().filter(obj -> obj instanceof ConfigurationChangedReceiver)
                 .forEach(o -> ((ConfigurationChangedReceiver) o).onConfigurationChanged(newConfig));
     }
@@ -565,20 +579,6 @@
     }
 
     /**
-     * Used in separate processes (like tuner settings) to init the dependencies.
-     */
-    public static void initDependencies(Context context) {
-        if (sDependency != null) return;
-        Dependency d = new Dependency();
-        SystemUIFactory.getInstance().getRootComponent()
-                .createDependency()
-                .createSystemUI(d);
-        d.mContext = context;
-        d.mComponents = new HashMap<>();
-        d.start();
-    }
-
-    /**
      * Used in separate process teardown to ensure the context isn't leaked.
      *
      * TODO: Remove once PreferenceFragment doesn't reference getActivity()
@@ -629,15 +629,4 @@
     public interface DependencyInjector {
         void createSystemUI(Dependency dependency);
     }
-
-    public static class DependencyCreator implements Injector {
-        @Override
-        public SystemUI apply(Context context) {
-            Dependency dependency = new Dependency();
-            SystemUIFactory.getInstance().getRootComponent()
-                    .createDependency()
-                    .createSystemUI(dependency);
-            return dependency;
-        }
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender.java
deleted file mode 100644
index 05acdd0..0000000
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2019 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;
-
-import android.annotation.NonNull;
-import android.app.Notification;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.ArraySet;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.statusbar.NotificationLifetimeExtender;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-
-/**
- * Extends the lifetime of foreground notification services such that they show for at least
- * five seconds
- */
-public class ForegroundServiceLifetimeExtender implements NotificationLifetimeExtender {
-
-    private static final String TAG = "FGSLifetimeExtender";
-    @VisibleForTesting
-    static final int MIN_FGS_TIME_MS = 5000;
-
-    private NotificationSafeToRemoveCallback mNotificationSafeToRemoveCallback;
-    private ArraySet<NotificationEntry> mManagedEntries = new ArraySet<>();
-    private Handler mHandler = new Handler(Looper.getMainLooper());
-
-    public ForegroundServiceLifetimeExtender() {
-    }
-
-    @Override
-    public void setCallback(@NonNull NotificationSafeToRemoveCallback callback) {
-        mNotificationSafeToRemoveCallback = callback;
-    }
-
-    @Override
-    public boolean shouldExtendLifetime(@NonNull NotificationEntry entry) {
-        if ((entry.notification.getNotification().flags
-                & Notification.FLAG_FOREGROUND_SERVICE) == 0) {
-            return false;
-        }
-
-        long currentTime = System.currentTimeMillis();
-        return currentTime - entry.notification.getPostTime() < MIN_FGS_TIME_MS;
-    }
-
-    @Override
-    public boolean shouldExtendLifetimeForPendingNotification(
-            @NonNull NotificationEntry entry) {
-        return shouldExtendLifetime(entry);
-    }
-
-    @Override
-    public void setShouldManageLifetime(
-            @NonNull NotificationEntry entry, boolean shouldManage) {
-        if (!shouldManage) {
-            mManagedEntries.remove(entry);
-            return;
-        }
-
-        mManagedEntries.add(entry);
-
-        Runnable r = () -> {
-            if (mManagedEntries.contains(entry)) {
-                mManagedEntries.remove(entry);
-                if (mNotificationSafeToRemoveCallback != null) {
-                    mNotificationSafeToRemoveCallback.onSafeToRemove(entry.key);
-                }
-            }
-        };
-        long delayAmt = MIN_FGS_TIME_MS
-                - (System.currentTimeMillis() - entry.notification.getPostTime());
-        mHandler.postDelayed(r, delayAmt);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
index 0162deb..96b62ac 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
@@ -66,9 +66,6 @@
                 removeNotification(entry.notification);
             }
         });
-
-        notificationEntryManager.addNotificationLifetimeExtender(
-                new ForegroundServiceLifetimeExtender());
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java b/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java
index cb9523f..6fec92c 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java
@@ -75,7 +75,7 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        Dependency.initDependencies(getApplicationContext());
+        Dependency.initDependencies(SystemUIFactory.getInstance().getRootComponent());
 
         mMetricsLogger = Dependency.get(MetricsLogger.class);
 
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index bd91333..c0c14fb 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.os.HandlerThread;
+import android.os.Trace;
 import android.service.wallpaper.WallpaperService;
 import android.util.Log;
 import android.util.Size;
@@ -48,6 +49,7 @@
     private static final int DELAY_FINISH_RENDERING = 1000;
     private static final int INTERVAL_WAIT_FOR_RENDERING = 100;
     private static final int PATIENCE_WAIT_FOR_RENDERING = 10;
+    private static final boolean DEBUG = true;
     private HandlerThread mWorker;
 
     @Override
@@ -125,6 +127,10 @@
         @Override
         public void onAmbientModeChanged(boolean inAmbientMode, long animationDuration) {
             if (!mNeedTransition) return;
+            if (DEBUG) {
+                Log.d(TAG, "onAmbientModeChanged: inAmbient=" + inAmbientMode
+                        + ", duration=" + animationDuration);
+            }
             mWorker.getThreadHandler().post(
                     () -> mRenderer.updateAmbientMode(inAmbientMode, animationDuration));
             if (inAmbientMode && animationDuration == 0) {
@@ -177,6 +183,10 @@
         @Override
         public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
             mWorker.getThreadHandler().post(() -> {
+                if (DEBUG) {
+                    Log.d(TAG, "onSurfaceChanged: w=" + width + ", h=" + height);
+                }
+
                 mRenderer.onSurfaceChanged(width, height);
                 mNeedRedraw = true;
             });
@@ -185,16 +195,31 @@
         @Override
         public void onSurfaceRedrawNeeded(SurfaceHolder holder) {
             mWorker.getThreadHandler().post(() -> {
+                if (DEBUG) {
+                    Log.d(TAG, "onSurfaceRedrawNeeded: mNeedRedraw=" + mNeedRedraw);
+                }
+
                 if (mNeedRedraw) {
-                    preRender();
-                    requestRender();
-                    postRender();
+                    drawFrame();
                     mNeedRedraw = false;
                 }
             });
         }
 
         @Override
+        public void onVisibilityChanged(boolean visible) {
+            if (DEBUG) {
+                Log.d(TAG, "wallpaper visibility changes to: " + visible);
+            }
+        }
+
+        private void drawFrame() {
+            preRender();
+            requestRender();
+            postRender();
+        }
+
+        @Override
         public void onStatePostChange() {
             // When back to home, we try to release EGL, which is preserved in lock screen or aod.
             if (mController.getState() == StatusBarState.SHADE) {
@@ -204,8 +229,18 @@
 
         @Override
         public void preRender() {
+            if (DEBUG) {
+                Log.d(TAG, "preRender start");
+            }
+
             // This method should only be invoked from worker thread.
+            Trace.beginSection("ImageWallpaper#preRender");
             preRenderInternal();
+            Trace.endSection();
+
+            if (DEBUG) {
+                Log.d(TAG, "preRender end");
+            }
         }
 
         private void preRenderInternal() {
@@ -240,7 +275,9 @@
         @Override
         public void requestRender() {
             // This method should only be invoked from worker thread.
+            Trace.beginSection("ImageWallpaper#requestRender");
             requestRenderInternal();
+            Trace.endSection();
         }
 
         private void requestRenderInternal() {
@@ -262,9 +299,19 @@
 
         @Override
         public void postRender() {
+            if (DEBUG) {
+                Log.d(TAG, "postRender start");
+            }
+
             // This method should only be invoked from worker thread.
+            Trace.beginSection("ImageWallpaper#postRender");
             notifyWaitingThread();
             scheduleFinishRendering();
+            Trace.endSection();
+
+            if (DEBUG) {
+                Log.d(TAG, "postRender end");
+            }
         }
 
         private void notifyWaitingThread() {
@@ -289,12 +336,18 @@
         }
 
         private void finishRendering() {
+            if (DEBUG) {
+                Log.d(TAG, "finishRendering, preserve=" + needPreserveEglContext());
+            }
+
+            Trace.beginSection("ImageWallpaper#finishRendering");
             if (mEglHelper != null) {
                 mEglHelper.destroyEglSurface();
                 if (!needPreserveEglContext()) {
                     mEglHelper.destroyEglContext();
                 }
             }
+            Trace.endSection();
         }
 
         private boolean needPreserveEglContext() {
diff --git a/packages/SystemUI/src/com/android/systemui/ServiceBinder.java b/packages/SystemUI/src/com/android/systemui/ServiceBinder.java
new file mode 100644
index 0000000..6282c6e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/ServiceBinder.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 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;
+
+import com.android.systemui.doze.DozeService;
+
+import dagger.Binds;
+import dagger.Module;
+import dagger.multibindings.ClassKey;
+import dagger.multibindings.IntoMap;
+
+/**
+ * Services and Activities that are injectable should go here.
+ */
+@Module
+public abstract class ServiceBinder {
+
+    @Binds
+    public abstract ContextComponentHelper bindComponentHelper(
+            ContextComponentResolver componentHelper);
+
+    @Binds
+    @IntoMap
+    @ClassKey(DozeService.class)
+    public abstract Object bindDozeService(DozeService service);
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 84e0238..58c52a1 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -34,7 +34,6 @@
 import android.view.ViewConfiguration;
 import android.view.accessibility.AccessibilityEvent;
 
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.statusbar.FlingAnimationUtils;
@@ -98,7 +97,8 @@
 
     private final ArrayMap<View, Animator> mDismissPendingMap = new ArrayMap<>();
 
-    public SwipeHelper(int swipeDirection, Callback callback, Context context) {
+    public SwipeHelper(
+            int swipeDirection, Callback callback, Context context, FalsingManager falsingManager) {
         mContext = context;
         mCallback = callback;
         mHandler = new Handler();
@@ -113,7 +113,7 @@
         mDensityScale =  res.getDisplayMetrics().density;
         mFalsingThreshold = res.getDimensionPixelSize(R.dimen.swipe_helper_falsing_threshold);
         mFadeDependingOnAmountSwiped = res.getBoolean(R.bool.config_fadeDependingOnAmountSwiped);
-        mFalsingManager = FalsingManagerFactory.getInstance(context);
+        mFalsingManager = falsingManager;
         mFlingAnimationUtils = new FlingAnimationUtils(context, getMaxEscapeAnimDuration() / 1000f);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java
new file mode 100644
index 0000000..8cb5948
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2019 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;
+
+import android.app.Application;
+
+import androidx.core.app.CoreComponentFactory;
+
+import javax.inject.Inject;
+
+/**
+ * Implementation of AppComponentFactory that injects into constructors.
+ */
+public class SystemUIAppComponentFactory extends CoreComponentFactory {
+
+    @Inject
+    public ContextComponentHelper mComponentHelper;
+
+    public SystemUIAppComponentFactory() {
+        super();
+    }
+
+    @Override
+    public Application instantiateApplication(ClassLoader cl, String className)
+            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+        Application app = super.instantiateApplication(cl, className);
+        if (app instanceof SystemUIApplication) {
+            ((SystemUIApplication) app).setContextAvailableCallback(
+                    context -> {
+                        SystemUIFactory.createFromConfig(context);
+                        SystemUIFactory.getInstance().getRootComponent().inject(
+                                SystemUIAppComponentFactory.this);
+                    }
+            );
+        }
+
+        return app;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index e89e6cb..48127a7 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -60,17 +60,30 @@
     private boolean mServicesStarted;
     private boolean mBootCompleted;
     private final Map<Class<?>, Object> mComponents = new HashMap<>();
+    private ContextAvailableCallback mContextAvailableCallback;
+
+    public SystemUIApplication() {
+        super();
+        Log.v(TAG, "SystemUIApplication constructed.");
+    }
 
     @Override
     public void onCreate() {
         super.onCreate();
+        Log.v(TAG, "SystemUIApplication created.");
+        // This line is used to setup Dagger's dependency injection and should be kept at the
+        // top of this method.
+        TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming",
+                Trace.TRACE_TAG_APP);
+        log.traceBegin("DependencyInjection");
+        mContextAvailableCallback.onContextAvailable(this);
+        log.traceEnd();
+
         // Set the application theme that is inherited by all services. Note that setting the
         // application theme in the manifest does only work for activities. Keep this in sync with
         // the theme set there.
         setTheme(R.style.Theme_SystemUI);
 
-        SystemUIFactory.createFromConfig(this);
-
         if (Process.myUserHandle().equals(UserHandle.SYSTEM)) {
             IntentFilter bootCompletedFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
             bootCompletedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
@@ -134,7 +147,7 @@
 
     /**
      * Ensures that all the Secondary user SystemUI services are running. If they are already
-     * running, this is a no-op. This is needed to conditinally start all the services, as we only
+     * running, this is a no-op. This is needed to conditionally start all the services, as we only
      * need to have it in the main process.
      * <p>This method must only be called from the main thread.</p>
      */
@@ -155,7 +168,9 @@
             // see ActivityManagerService.finishBooting()
             if ("1".equals(SystemProperties.get("sys.boot_completed"))) {
                 mBootCompleted = true;
-                if (DEBUG) Log.v(TAG, "BOOT_COMPLETED was already sent");
+                if (DEBUG) {
+                    Log.v(TAG, "BOOT_COMPLETED was already sent");
+                }
             }
         }
 
@@ -269,6 +284,7 @@
     @Override
     public void onConfigurationChanged(Configuration newConfig) {
         if (mServicesStarted) {
+            Dependency.staticOnConfigurationChanged(newConfig);
             int len = mServices.length;
             for (int i = 0; i < len; i++) {
                 if (mServices[i] != null) {
@@ -286,4 +302,12 @@
     public SystemUI[] getServices() {
         return mServices;
     }
+
+    void setContextAvailableCallback(ContextAvailableCallback callback) {
+        mContextAvailableCallback = callback;
+    }
+
+    interface ContextAvailableCallback {
+        void onContextAvailable(Context context);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java
new file mode 100644
index 0000000..262b5ec
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2019 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;
+
+import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
+import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME;
+
+import android.content.Context;
+
+import androidx.annotation.Nullable;
+
+import com.android.systemui.dock.DockManager;
+import com.android.systemui.dock.DockManagerImpl;
+import com.android.systemui.power.EnhancedEstimates;
+import com.android.systemui.power.EnhancedEstimatesImpl;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
+import com.android.systemui.statusbar.notification.collection.NotificationData;
+import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl;
+import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.StatusBar;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import dagger.Binds;
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * A dagger module for injecting default implementations of components of System UI that may be
+ * overridden by the System UI implementation.
+ */
+@Module
+abstract class SystemUIDefaultModule {
+
+    @Singleton
+    @Provides
+    @Named(LEAK_REPORT_EMAIL_NAME)
+    @Nullable
+    static String provideLeakReportEmail() {
+        return null;
+    }
+
+    @Binds
+    abstract EnhancedEstimates bindEnhancedEstimates(EnhancedEstimatesImpl enhancedEstimates);
+
+    @Binds
+    abstract NotificationLockscreenUserManager bindNotificationLockscreenUserManager(
+            NotificationLockscreenUserManagerImpl notificationLockscreenUserManager);
+
+    @Binds
+    abstract DockManager bindDockManager(DockManagerImpl dockManager);
+
+    @Binds
+    abstract NotificationData.KeyguardEnvironment bindKeyguardEnvironment(
+            KeyguardEnvironmentImpl keyguardEnvironment);
+
+    @Singleton
+    @Provides
+    static ShadeController provideShadeController(Context context) {
+        return SysUiServiceProvider.getComponent(context, StatusBar.class);
+    }
+
+    @Singleton
+    @Provides
+    @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME)
+    static boolean provideAllowNotificationLongPress() {
+        return true;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 0d85a3f..d151f7d 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -16,13 +16,8 @@
 
 package com.android.systemui;
 
-import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
-import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME;
-
-import android.annotation.Nullable;
 import android.app.AlarmManager;
 import android.content.Context;
-import android.content.pm.PackageManager;
 import android.os.Handler;
 import android.os.Looper;
 import android.util.Log;
@@ -33,63 +28,40 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.ViewMediatorCallback;
-import com.android.systemui.assist.AssistManager;
-import com.android.systemui.classifier.FalsingManagerFactory;
-import com.android.systemui.dock.DockManager;
-import com.android.systemui.fragments.FragmentService;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.power.EnhancedEstimates;
-import com.android.systemui.power.EnhancedEstimatesImpl;
 import com.android.systemui.statusbar.KeyguardIndicationController;
-import com.android.systemui.statusbar.NotificationListener;
-import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
 import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.ScrimView;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
-import com.android.systemui.statusbar.notification.collection.NotificationData;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.KeyguardBouncer;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl;
-import com.android.systemui.statusbar.phone.KeyguardLiftController;
 import com.android.systemui.statusbar.phone.LockIcon;
 import com.android.systemui.statusbar.phone.LockscreenWallpaper;
 import com.android.systemui.statusbar.phone.NotificationIconAreaController;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.ScrimState;
-import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.phone.UnlockMethodCache;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
-import com.android.systemui.util.AsyncSensorManager;
-import com.android.systemui.util.InjectionInflationController;
-import com.android.systemui.util.leak.GarbageMonitor;
 import com.android.systemui.volume.VolumeDialogComponent;
 
 import java.util.function.Consumer;
 
-import javax.inject.Named;
-import javax.inject.Singleton;
-
-import dagger.Component;
 import dagger.Module;
 import dagger.Provides;
 
 /**
  * Class factory to provide customizable SystemUI components.
  */
-@Module
 public class SystemUIFactory {
     private static final String TAG = "SystemUIFactory";
 
     static SystemUIFactory mFactory;
-    private SystemUIRootComponent mRootComponent;
+    protected SystemUIRootComponent mRootComponent;
 
     public static <T extends SystemUIFactory> T getInstance() {
         return (T) mFactory;
@@ -114,9 +86,16 @@
 
     public SystemUIFactory() {}
 
-    protected void init(Context context) {
-        mRootComponent = DaggerSystemUIFactory_SystemUIRootComponent.builder()
-                .systemUIFactory(this)
+    private void init(Context context) {
+        mRootComponent = buildSystemUIRootComponent(context);
+
+        // Every other part of our codebase currently relies on Dependency, so we
+        // really need to ensure the Dependency gets initialized early on.
+        Dependency.initDependencies(mRootComponent);
+    }
+
+    protected SystemUIRootComponent buildSystemUIRootComponent(Context context) {
+        return DaggerSystemUIRootComponent.builder()
                 .dependencyProvider(new com.android.systemui.DependencyProvider())
                 .contextHolder(new ContextHolder(context))
                 .build();
@@ -132,23 +111,24 @@
     }
 
     public KeyguardBouncer createKeyguardBouncer(Context context, ViewMediatorCallback callback,
-            LockPatternUtils lockPatternUtils,  ViewGroup container,
+            LockPatternUtils lockPatternUtils, ViewGroup container,
             DismissCallbackRegistry dismissCallbackRegistry,
             KeyguardBouncer.BouncerExpansionCallback expansionCallback,
-            KeyguardBypassController bypassController) {
+            FalsingManager falsingManager, KeyguardBypassController bypassController) {
         return new KeyguardBouncer(context, callback, lockPatternUtils, container,
-                dismissCallbackRegistry, FalsingManagerFactory.getInstance(context),
+                dismissCallbackRegistry, falsingManager,
                 expansionCallback, UnlockMethodCache.getInstance(context),
                 KeyguardUpdateMonitor.getInstance(context), bypassController,
                 new Handler(Looper.getMainLooper()));
     }
 
     public ScrimController createScrimController(ScrimView scrimBehind, ScrimView scrimInFront,
+            ScrimView scrimForBubble,
             LockscreenWallpaper lockscreenWallpaper,
             TriConsumer<ScrimState, Float, GradientColors> scrimStateListener,
             Consumer<Integer> scrimVisibleListener, DozeParameters dozeParameters,
             AlarmManager alarmManager, KeyguardMonitor keyguardMonitor) {
-        return new ScrimController(scrimBehind, scrimInFront, scrimStateListener,
+        return new ScrimController(scrimBehind, scrimInFront, scrimForBubble, scrimStateListener,
                 scrimVisibleListener, dozeParameters, alarmManager, keyguardMonitor);
     }
 
@@ -171,93 +151,8 @@
         return new VolumeDialogComponent(systemUi, context);
     }
 
-    @Singleton
-    @Provides
-    public NotificationData.KeyguardEnvironment provideKeyguardEnvironment(Context context) {
-        return new KeyguardEnvironmentImpl();
-    }
-
-    @Singleton
-    @Provides
-    public NotificationLockscreenUserManager provideNotificationLockscreenUserManager(
-            Context context) {
-        return new NotificationLockscreenUserManagerImpl(context);
-    }
-
-    @Singleton
-    @Provides
-    public AssistManager provideAssistManager(DeviceProvisionedController controller,
-            Context context) {
-        return new AssistManager(controller, context);
-    }
-
-    @Singleton
-    @Provides
-    @Nullable
-    public DockManager provideDockManager(Context context) {
-        return null;
-    }
-
-    @Singleton
-    @Provides
-    public NotificationEntryManager provideNotificationEntryManager(Context context) {
-        return new NotificationEntryManager(context);
-    }
-
-    @Singleton
-    @Provides
-    public EnhancedEstimates provideEnhancedEstimates(Context context) {
-        return new EnhancedEstimatesImpl();
-    }
-
-    @Singleton
-    @Provides
-    @Named(LEAK_REPORT_EMAIL_NAME)
-    @Nullable
-    public String provideLeakReportEmail() {
-        return null;
-    }
-
-    @Singleton
-    @Provides
-    @Nullable
-    public KeyguardLiftController provideKeyguardLiftController(Context context,
-            StatusBarStateController statusBarStateController,
-            AsyncSensorManager asyncSensorManager) {
-        if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
-            return null;
-        }
-        return new KeyguardLiftController(context, statusBarStateController, asyncSensorManager);
-    }
-
-    @Singleton
-    @Provides
-    public NotificationListener provideNotificationListener(Context context) {
-        return new NotificationListener(context);
-    }
-
-    @Singleton
-    @Provides
-    public NotificationInterruptionStateProvider provideNotificationInterruptionStateProvider(
-            Context context) {
-        return new NotificationInterruptionStateProvider(context);
-    }
-
-    @Singleton
-    @Provides
-    @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME)
-    public boolean provideAllowNotificationLongPress() {
-        return true;
-    }
-
-    @Singleton
-    @Provides
-    public ShadeController provideShadeController(Context context) {
-        return SysUiServiceProvider.getComponent(context, StatusBar.class);
-    }
-
     @Module
-    protected static class ContextHolder {
+    public static class ContextHolder {
         private Context mContext;
 
         public ContextHolder(Context context) {
@@ -269,29 +164,4 @@
             return mContext;
         }
     }
-
-    @Singleton
-    @Component(modules = {SystemUIFactory.class, DependencyProvider.class, DependencyBinder.class,
-            ContextHolder.class})
-    public interface SystemUIRootComponent {
-        @Singleton
-        Dependency.DependencyInjector createDependency();
-
-        @Singleton
-        StatusBar.StatusBarInjector getStatusBarInjector();
-
-        /**
-         * FragmentCreator generates all Fragments that need injection.
-         */
-        @Singleton
-        FragmentService.FragmentCreator createFragmentCreator();
-
-        /**
-         * ViewCreator generates all Views that need injection.
-         */
-        InjectionInflationController.ViewCreator createViewCreator();
-
-        @Singleton
-        GarbageMonitor createGarbageMonitor();
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/SystemUIModule.java
new file mode 100644
index 0000000..defa574
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIModule.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2019 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;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.pm.PackageManager;
+
+import com.android.systemui.assist.AssistModule;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.phone.KeyguardLiftController;
+import com.android.systemui.util.AsyncSensorManager;
+
+import javax.inject.Singleton;
+
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * A dagger module for injecting components of System UI that are not overridden by the System UI
+ * implementation.
+ */
+@Module(includes = {AssistModule.class})
+public abstract class SystemUIModule {
+
+    @Singleton
+    @Provides
+    @Nullable
+    static KeyguardLiftController provideKeyguardLiftController(Context context,
+            StatusBarStateController statusBarStateController,
+            AsyncSensorManager asyncSensorManager) {
+        if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
+            return null;
+        }
+        return new KeyguardLiftController(context, statusBarStateController, asyncSensorManager);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java b/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java
new file mode 100644
index 0000000..f18c8b2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2019 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;
+
+import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
+
+import com.android.systemui.fragments.FragmentService;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.util.InjectionInflationController;
+import com.android.systemui.util.leak.GarbageMonitor;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import dagger.Component;
+
+/**
+ * Root component for Dagger injection.
+ */
+@Singleton
+@Component(modules = {
+        DependencyProvider.class,
+        DependencyBinder.class,
+        ServiceBinder.class,
+        SystemUIFactory.ContextHolder.class,
+        SystemUIModule.class,
+        SystemUIDefaultModule.class})
+public interface SystemUIRootComponent {
+    /**
+     * Main dependency providing module.
+     */
+    @Singleton
+    Dependency.DependencyInjector createDependency();
+
+    /**
+     * Injects the StatusBar.
+     */
+    @Singleton
+    StatusBar.StatusBarInjector getStatusBarInjector();
+
+    /**
+     * FragmentCreator generates all Fragments that need injection.
+     */
+    @Singleton
+    FragmentService.FragmentCreator createFragmentCreator();
+
+    /**
+     * ViewCreator generates all Views that need injection.
+     */
+    InjectionInflationController.ViewCreator createViewCreator();
+
+    /**
+     * Creatse a GarbageMonitor.
+     */
+    @Singleton
+    GarbageMonitor createGarbageMonitor();
+
+    /**
+     * Whether notification long press is allowed.
+     */
+    @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME)
+    boolean allowNotificationLongPressName();
+
+    /**
+     * Injects into the supplied argument.
+     */
+    void inject(SystemUIAppComponentFactory factory);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUISecondaryUserService.java b/packages/SystemUI/src/com/android/systemui/SystemUISecondaryUserService.java
index c8a2e17..2d2d91d 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUISecondaryUserService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUISecondaryUserService.java
@@ -38,25 +38,8 @@
 
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        SystemUI[] services = ((SystemUIApplication) getApplication()).getServices();
-        if (args == null || args.length == 0) {
-            for (SystemUI ui: services) {
-                if (ui != null) {
-                    pw.println("dumping service: " + ui.getClass().getName());
-                    ui.dump(fd, pw, args);
-                }
-            }
-        } else {
-            String svc = args[0];
-            for (SystemUI ui: services) {
-                if (ui != null) {
-                    String name = ui.getClass().getName();
-                    if (name.endsWith(svc)) {
-                        ui.dump(fd, pw, args);
-                    }
-                }
-            }
-        }
+        SystemUIService.dumpServices(
+                ((SystemUIApplication) getApplication()).getServices(), fd, pw, args);
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
index dc1218d..1c5e800 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@@ -66,8 +66,14 @@
 
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        SystemUI[] services = ((SystemUIApplication) getApplication()).getServices();
+        dumpServices(((SystemUIApplication) getApplication()).getServices(), fd, pw, args);
+    }
+
+    static void dumpServices(
+            SystemUI[] services, FileDescriptor fd, PrintWriter pw, String[] args) {
         if (args == null || args.length == 0) {
+            pw.println("dumping service: " + Dependency.class.getName());
+            Dependency.staticDump(fd, pw, args);
             for (SystemUI ui: services) {
                 pw.println("dumping service: " + ui.getClass().getName());
                 ui.dump(fd, pw, args);
@@ -78,6 +84,9 @@
             }
         } else {
             String svc = args[0].toLowerCase();
+            if (Dependency.class.getName().endsWith(svc)) {
+                Dependency.staticDump(fd, pw, args);
+            }
             for (SystemUI ui: services) {
                 String name = ui.getClass().getName().toLowerCase();
                 if (name.endsWith(svc)) {
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java
index 6da3818..738ec80 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.assist;
 
+import static com.android.systemui.assist.AssistModule.ASSIST_HANDLE_THREAD_NAME;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.os.Handler;
@@ -28,20 +30,21 @@
 import com.android.internal.app.AssistUtils;
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.Dependency;
 import com.android.systemui.DumpController;
 import com.android.systemui.Dumpable;
 import com.android.systemui.ScreenDecorations;
-import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.phone.NavigationModeController;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.EnumMap;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
-import java.util.function.Supplier;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Provider;
+import javax.inject.Singleton;
 
 /**
  * A class for managing Assistant handle logic.
@@ -49,6 +52,7 @@
  * Controls when visual handles for Assistant gesture affordance should be shown or hidden using an
  * {@link AssistHandleBehavior}.
  */
+@Singleton
 public final class AssistHandleBehaviorController implements AssistHandleCallbacks, Dumpable {
 
     private static final String TAG = "AssistHandleBehavior";
@@ -67,10 +71,9 @@
     private final Handler mHandler;
     private final Runnable mHideHandles = this::hideHandles;
     private final Runnable mShowAndGo = this::showAndGoInternal;
-    private final Supplier<ScreenDecorations> mScreenDecorationsSupplier;
+    private final Provider<ScreenDecorations> mScreenDecorations;
     private final PhenotypeHelper mPhenotypeHelper;
-    private final Map<AssistHandleBehavior, BehaviorController> mBehaviorMap =
-            new EnumMap<>(AssistHandleBehavior.class);
+    private final Map<AssistHandleBehavior, BehaviorController> mBehaviorMap;
 
     private boolean mHandlesShowing = false;
     private long mHandlesLastHiddenAt;
@@ -82,41 +85,25 @@
     private AssistHandleBehavior mCurrentBehavior = AssistHandleBehavior.OFF;
     private boolean mInGesturalMode;
 
-    AssistHandleBehaviorController(Context context, AssistUtils assistUtils, Handler handler) {
-        this(
-                context,
-                assistUtils,
-                handler,
-                () -> SysUiServiceProvider.getComponent(context, ScreenDecorations.class),
-                new PhenotypeHelper(),
-                /* testBehavior = */ null);
-    }
-
-    @VisibleForTesting
+    @Inject
     AssistHandleBehaviorController(
             Context context,
             AssistUtils assistUtils,
-            Handler handler,
-            Supplier<ScreenDecorations> screenDecorationsSupplier,
+            @Named(ASSIST_HANDLE_THREAD_NAME) Handler handler,
+            Provider<ScreenDecorations> screenDecorations,
             PhenotypeHelper phenotypeHelper,
-            @Nullable BehaviorController testBehavior) {
+            Map<AssistHandleBehavior, BehaviorController> behaviorMap,
+            NavigationModeController navigationModeController,
+            DumpController dumpController) {
         mContext = context;
         mAssistUtils = assistUtils;
         mHandler = handler;
-        mScreenDecorationsSupplier = screenDecorationsSupplier;
+        mScreenDecorations = screenDecorations;
         mPhenotypeHelper = phenotypeHelper;
-        mBehaviorMap.put(AssistHandleBehavior.OFF, new AssistHandleOffBehavior());
-        mBehaviorMap.put(AssistHandleBehavior.LIKE_HOME, new AssistHandleLikeHomeBehavior());
-        mBehaviorMap.put(
-                AssistHandleBehavior.REMINDER_EXP,
-                new AssistHandleReminderExpBehavior(handler, phenotypeHelper));
-        if (testBehavior != null) {
-            mBehaviorMap.put(AssistHandleBehavior.TEST, testBehavior);
-        }
+        mBehaviorMap = behaviorMap;
 
         mInGesturalMode = QuickStepContract.isGesturalMode(
-                Dependency.get(NavigationModeController.class)
-                        .addListener(this::handleNavigationModeChange));
+                navigationModeController.addListener(this::handleNavigationModeChange));
 
         setBehavior(getBehaviorMode());
         mPhenotypeHelper.addOnPropertiesChangedListener(
@@ -128,7 +115,8 @@
                                 SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE, null));
                     }
                 });
-        Dependency.get(DumpController.class).addListener(this);
+
+        dumpController.addListener(this);
     }
 
     @Override // AssistHandleCallbacks
@@ -177,6 +165,12 @@
         mBehaviorMap.get(mCurrentBehavior).onAssistantGesturePerformed();
     }
 
+    void onAssistHandlesRequested() {
+        if (mInGesturalMode) {
+            mBehaviorMap.get(mCurrentBehavior).onAssistHandlesRequested();
+        }
+    }
+
     void setBehavior(AssistHandleBehavior behavior) {
         if (mCurrentBehavior == behavior) {
             return;
@@ -235,7 +229,7 @@
         }
 
         if (handlesUnblocked(ignoreThreshold)) {
-            ScreenDecorations screenDecorations = mScreenDecorationsSupplier.get();
+            ScreenDecorations screenDecorations = mScreenDecorations.get();
             if (screenDecorations == null) {
                 Log.w(TAG, "Couldn't show handles, ScreenDecorations unavailable");
             } else {
@@ -250,7 +244,7 @@
             return;
         }
 
-        ScreenDecorations screenDecorations = mScreenDecorationsSupplier.get();
+        ScreenDecorations screenDecorations = mScreenDecorations.get();
         if (screenDecorations == null) {
             Log.w(TAG, "Couldn't hide handles, ScreenDecorations unavailable");
         } else {
@@ -316,6 +310,7 @@
         void onModeActivated(Context context, AssistHandleCallbacks callbacks);
         default void onModeDeactivated() {}
         default void onAssistantGesturePerformed() {}
+        default void onAssistHandlesRequested() {}
         default void dump(PrintWriter pw, String prefix) {}
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleLikeHomeBehavior.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleLikeHomeBehavior.java
index 6cf2034..31115bb 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleLikeHomeBehavior.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleLikeHomeBehavior.java
@@ -20,18 +20,24 @@
 
 import androidx.annotation.Nullable;
 
-import com.android.systemui.Dependency;
 import com.android.systemui.assist.AssistHandleBehaviorController.BehaviorController;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.shared.system.QuickStepContract;
 
 import java.io.PrintWriter;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import dagger.Lazy;
+
 /**
  * Assistant Handle behavior that makes Assistant handles show/hide when the home handle is
  * shown/hidden, respectively.
  */
+@Singleton
 final class AssistHandleLikeHomeBehavior implements BehaviorController {
 
     private final StatusBarStateController.StateListener mStatusBarStateListener =
@@ -41,6 +47,28 @@
                     handleDozingChanged(isDozing);
                 }
             };
+    private final WakefulnessLifecycle.Observer mWakefulnessLifecycleObserver =
+            new WakefulnessLifecycle.Observer() {
+                @Override
+                public void onStartedWakingUp() {
+                    handleWakefullnessChanged(/* isAwake = */ false);
+                }
+
+                @Override
+                public void onFinishedWakingUp() {
+                    handleWakefullnessChanged(/* isAwake = */ true);
+                }
+
+                @Override
+                public void onStartedGoingToSleep() {
+                    handleWakefullnessChanged(/* isAwake = */ false);
+                }
+
+                @Override
+                public void onFinishedGoingToSleep() {
+                    handleWakefullnessChanged(/* isAwake = */ false);
+                }
+            };
     private final OverviewProxyService.OverviewProxyListener mOverviewProxyListener =
             new OverviewProxyService.OverviewProxyListener() {
         @Override
@@ -48,32 +76,45 @@
             handleSystemUiStateChange(sysuiStateFlags);
         }
     };
-    private final StatusBarStateController mStatusBarStateController;
-    private final OverviewProxyService mOverviewProxyService;
+
+    private final Lazy<StatusBarStateController> mStatusBarStateController;
+    private final Lazy<WakefulnessLifecycle> mWakefulnessLifecycle;
+    private final Lazy<OverviewProxyService> mOverviewProxyService;
 
     private boolean mIsDozing;
+    private boolean mIsAwake;
     private boolean mIsHomeHandleHiding;
 
     @Nullable private AssistHandleCallbacks mAssistHandleCallbacks;
 
-    AssistHandleLikeHomeBehavior() {
-        mStatusBarStateController = Dependency.get(StatusBarStateController.class);
-        mOverviewProxyService = Dependency.get(OverviewProxyService.class);
+    @Inject
+    AssistHandleLikeHomeBehavior(
+            Lazy<StatusBarStateController> statusBarStateController,
+            Lazy<WakefulnessLifecycle> wakefulnessLifecycle,
+            Lazy<OverviewProxyService> overviewProxyService) {
+        mStatusBarStateController = statusBarStateController;
+        mWakefulnessLifecycle = wakefulnessLifecycle;
+        mOverviewProxyService = overviewProxyService;
     }
 
     @Override
     public void onModeActivated(Context context, AssistHandleCallbacks callbacks) {
         mAssistHandleCallbacks = callbacks;
-        mIsDozing = mStatusBarStateController.isDozing();
-        mStatusBarStateController.addCallback(mStatusBarStateListener);
-        mOverviewProxyService.addCallback(mOverviewProxyListener);
+        mIsDozing = mStatusBarStateController.get().isDozing();
+        mStatusBarStateController.get().addCallback(mStatusBarStateListener);
+        mIsAwake = mWakefulnessLifecycle.get().getWakefulness()
+                == WakefulnessLifecycle.WAKEFULNESS_AWAKE;
+        mWakefulnessLifecycle.get().addObserver(mWakefulnessLifecycleObserver);
+        mOverviewProxyService.get().addCallback(mOverviewProxyListener);
         callbackForCurrentState();
     }
 
     @Override
     public void onModeDeactivated() {
         mAssistHandleCallbacks = null;
-        mOverviewProxyService.removeCallback(mOverviewProxyListener);
+        mStatusBarStateController.get().removeCallback(mStatusBarStateListener);
+        mWakefulnessLifecycle.get().removeObserver(mWakefulnessLifecycleObserver);
+        mOverviewProxyService.get().removeCallback(mOverviewProxyListener);
     }
 
     private static boolean isHomeHandleHiding(int sysuiStateFlags) {
@@ -89,6 +130,15 @@
         callbackForCurrentState();
     }
 
+    private void handleWakefullnessChanged(boolean isAwake) {
+        if (mIsAwake == isAwake) {
+            return;
+        }
+
+        mIsAwake = isAwake;
+        callbackForCurrentState();
+    }
+
     private void handleSystemUiStateChange(int sysuiStateFlags) {
         boolean isHomeHandleHiding = isHomeHandleHiding(sysuiStateFlags);
         if (mIsHomeHandleHiding == isHomeHandleHiding) {
@@ -104,18 +154,23 @@
             return;
         }
 
-        if (mIsHomeHandleHiding || mIsDozing) {
+        if (mIsHomeHandleHiding || !isFullyAwake()) {
             mAssistHandleCallbacks.hide();
         } else {
             mAssistHandleCallbacks.showAndStay();
         }
     }
 
+    private boolean isFullyAwake() {
+        return mIsAwake && !mIsDozing;
+    }
+
     @Override
     public void dump(PrintWriter pw, String prefix) {
-        pw.println("Current AssistHandleLikeHomeBehavior State:");
+        pw.println(prefix + "Current AssistHandleLikeHomeBehavior State:");
 
         pw.println(prefix + "   mIsDozing=" + mIsDozing);
+        pw.println(prefix + "   mIsAwake=" + mIsAwake);
         pw.println(prefix + "   mIsHomeHandleHiding=" + mIsHomeHandleHiding);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleOffBehavior.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleOffBehavior.java
index f4130ae..df913f9 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleOffBehavior.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleOffBehavior.java
@@ -20,9 +20,17 @@
 
 import com.android.systemui.assist.AssistHandleBehaviorController.BehaviorController;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
 /** Assistant handle behavior that hides the Assistant handles. */
+@Singleton
 final class AssistHandleOffBehavior implements BehaviorController {
 
+    @Inject
+    AssistHandleOffBehavior() {
+    }
+
     @Override
     public void onModeActivated(Context context, AssistHandleCallbacks callbacks) {
         callbacks.hide();
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
index f9ddeae..0394048 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
@@ -16,6 +16,9 @@
 
 package com.android.systemui.assist;
 
+import static com.android.systemui.assist.AssistModule.ASSIST_HANDLE_THREAD_NAME;
+import static com.android.systemui.assist.AssistModule.UPTIME_NAME;
+
 import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -24,14 +27,14 @@
 import android.content.IntentFilter;
 import android.content.pm.ResolveInfo;
 import android.os.Handler;
-import android.os.SystemClock;
 import android.provider.Settings;
 
 import androidx.annotation.Nullable;
+import androidx.slice.Clock;
 
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
-import com.android.systemui.Dependency;
 import com.android.systemui.assist.AssistHandleBehaviorController.BehaviorController;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -46,11 +49,18 @@
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import dagger.Lazy;
+
 /**
  * Assistant handle behavior that hides the handles when the phone is dozing or in immersive mode,
  * shows the handles when on lockscreen, and shows the handles temporarily when changing tasks or
  * entering overview.
  */
+@Singleton
 final class AssistHandleReminderExpBehavior implements BehaviorController {
 
     private static final String LEARNING_TIME_ELAPSED_KEY = "reminder_exp_learning_time_elapsed";
@@ -113,6 +123,28 @@
                     handleSystemUiStateChanged(sysuiStateFlags);
                 }
             };
+    private final WakefulnessLifecycle.Observer mWakefulnessLifecycleObserver =
+            new WakefulnessLifecycle.Observer() {
+                @Override
+                public void onStartedWakingUp() {
+                    handleWakefullnessChanged(/* isAwake = */ false);
+                }
+
+                @Override
+                public void onFinishedWakingUp() {
+                    handleWakefullnessChanged(/* isAwake = */ true);
+                }
+
+                @Override
+                public void onStartedGoingToSleep() {
+                    handleWakefullnessChanged(/* isAwake = */ false);
+                }
+
+                @Override
+                public void onFinishedGoingToSleep() {
+                    handleWakefullnessChanged(/* isAwake = */ false);
+                }
+            };
     private final BroadcastReceiver mDefaultHomeBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -122,14 +154,18 @@
     private final IntentFilter mDefaultHomeIntentFilter;
     private final Runnable mResetConsecutiveTaskSwitches = this::resetConsecutiveTaskSwitches;
 
+    private final Clock mClock;
     private final Handler mHandler;
     private final PhenotypeHelper mPhenotypeHelper;
-    private final StatusBarStateController mStatusBarStateController;
-    private final ActivityManagerWrapper mActivityManagerWrapper;
-    private final OverviewProxyService mOverviewProxyService;
+    private final Lazy<StatusBarStateController> mStatusBarStateController;
+    private final Lazy<ActivityManagerWrapper> mActivityManagerWrapper;
+    private final Lazy<OverviewProxyService> mOverviewProxyService;
+    private final Lazy<WakefulnessLifecycle> mWakefulnessLifecycle;
+    private final Lazy<PackageManagerWrapper> mPackageManagerWrapper;
 
     private boolean mOnLockscreen;
     private boolean mIsDozing;
+    private boolean mIsAwake;
     private int mRunningTaskId;
     private boolean mIsNavBarHidden;
     private boolean mIsLauncherShowing;
@@ -148,12 +184,24 @@
     @Nullable private AssistHandleCallbacks mAssistHandleCallbacks;
     @Nullable private ComponentName mDefaultHome;
 
-    AssistHandleReminderExpBehavior(Handler handler, PhenotypeHelper phenotypeHelper) {
+    @Inject
+    AssistHandleReminderExpBehavior(
+            @Named(UPTIME_NAME) Clock clock,
+            @Named(ASSIST_HANDLE_THREAD_NAME) Handler handler,
+            PhenotypeHelper phenotypeHelper,
+            Lazy<StatusBarStateController> statusBarStateController,
+            Lazy<ActivityManagerWrapper> activityManagerWrapper,
+            Lazy<OverviewProxyService> overviewProxyService,
+            Lazy<WakefulnessLifecycle> wakefulnessLifecycle,
+            Lazy<PackageManagerWrapper> packageManagerWrapper) {
+        mClock = clock;
         mHandler = handler;
         mPhenotypeHelper = phenotypeHelper;
-        mStatusBarStateController = Dependency.get(StatusBarStateController.class);
-        mActivityManagerWrapper = ActivityManagerWrapper.getInstance();
-        mOverviewProxyService = Dependency.get(OverviewProxyService.class);
+        mStatusBarStateController = statusBarStateController;
+        mActivityManagerWrapper = activityManagerWrapper;
+        mOverviewProxyService = overviewProxyService;
+        mWakefulnessLifecycle = wakefulnessLifecycle;
+        mPackageManagerWrapper = packageManagerWrapper;
         mDefaultHomeIntentFilter = new IntentFilter();
         for (String action : DEFAULT_HOME_CHANGE_ACTIONS) {
             mDefaultHomeIntentFilter.addAction(action);
@@ -167,13 +215,17 @@
         mConsecutiveTaskSwitches = 0;
         mDefaultHome = getCurrentDefaultHome();
         context.registerReceiver(mDefaultHomeBroadcastReceiver, mDefaultHomeIntentFilter);
-        mOnLockscreen = onLockscreen(mStatusBarStateController.getState());
-        mIsDozing = mStatusBarStateController.isDozing();
-        mStatusBarStateController.addCallback(mStatusBarStateListener);
-        ActivityManager.RunningTaskInfo runningTaskInfo = mActivityManagerWrapper.getRunningTask();
+        mOnLockscreen = onLockscreen(mStatusBarStateController.get().getState());
+        mIsDozing = mStatusBarStateController.get().isDozing();
+        mStatusBarStateController.get().addCallback(mStatusBarStateListener);
+        ActivityManager.RunningTaskInfo runningTaskInfo =
+                mActivityManagerWrapper.get().getRunningTask();
         mRunningTaskId = runningTaskInfo == null ? 0 : runningTaskInfo.taskId;
-        mActivityManagerWrapper.registerTaskStackListener(mTaskStackChangeListener);
-        mOverviewProxyService.addCallback(mOverviewProxyListener);
+        mActivityManagerWrapper.get().registerTaskStackListener(mTaskStackChangeListener);
+        mOverviewProxyService.get().addCallback(mOverviewProxyListener);
+        mIsAwake = mWakefulnessLifecycle.get().getWakefulness()
+                == WakefulnessLifecycle.WAKEFULNESS_AWAKE;
+        mWakefulnessLifecycle.get().addObserver(mWakefulnessLifecycleObserver);
 
         mLearningTimeElapsed = Settings.Secure.getLong(
                 context.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, /* default = */ 0);
@@ -181,7 +233,7 @@
                 context.getContentResolver(), LEARNING_EVENT_COUNT_KEY, /* default = */ 0);
         mLearnedHintLastShownEpochDay = Settings.Secure.getLong(
                 context.getContentResolver(), LEARNED_HINT_LAST_SHOWN_KEY, /* default = */ 0);
-        mLastLearningTimestamp = SystemClock.uptimeMillis();
+        mLastLearningTimestamp = mClock.currentTimeMillis();
 
         callbackForCurrentState(/* justUnlocked = */ false);
     }
@@ -196,9 +248,10 @@
             Settings.Secure.putLong(mContext.getContentResolver(), LEARNED_HINT_LAST_SHOWN_KEY, 0);
             mContext = null;
         }
-        mStatusBarStateController.removeCallback(mStatusBarStateListener);
-        mActivityManagerWrapper.unregisterTaskStackListener(mTaskStackChangeListener);
-        mOverviewProxyService.removeCallback(mOverviewProxyListener);
+        mStatusBarStateController.get().removeCallback(mStatusBarStateListener);
+        mActivityManagerWrapper.get().unregisterTaskStackListener(mTaskStackChangeListener);
+        mOverviewProxyService.get().removeCallback(mOverviewProxyListener);
+        mWakefulnessLifecycle.get().removeObserver(mWakefulnessLifecycleObserver);
     }
 
     @Override
@@ -211,15 +264,20 @@
                 mContext.getContentResolver(), LEARNING_EVENT_COUNT_KEY, ++mLearningCount);
     }
 
-    private static boolean isNavBarHidden(int sysuiStateFlags) {
-        return (sysuiStateFlags & QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN) != 0;
+    @Override
+    public void onAssistHandlesRequested() {
+        if (mAssistHandleCallbacks != null
+                && isFullyAwake()
+                && !mIsNavBarHidden
+                && !mOnLockscreen) {
+            mAssistHandleCallbacks.showAndGo();
+        }
     }
 
     @Nullable
-    private static ComponentName getCurrentDefaultHome() {
+    private ComponentName getCurrentDefaultHome() {
         List<ResolveInfo> homeActivities = new ArrayList<>();
-        ComponentName defaultHome =
-                PackageManagerWrapper.getInstance().getHomeActivities(homeActivities);
+        ComponentName defaultHome = mPackageManagerWrapper.get().getHomeActivities(homeActivities);
         if (defaultHome != null) {
             return defaultHome;
         }
@@ -258,6 +316,16 @@
         callbackForCurrentState(/* justUnlocked = */ false);
     }
 
+    private void handleWakefullnessChanged(boolean isAwake) {
+        if (mIsAwake == isAwake) {
+            return;
+        }
+
+        resetConsecutiveTaskSwitches();
+        mIsAwake = isAwake;
+        callbackForCurrentState(/* justUnlocked = */ false);
+    }
+
     private void handleTaskStackTopChanged(int taskId, @Nullable ComponentName taskComponentName) {
         if (mRunningTaskId == taskId || taskComponentName == null) {
             return;
@@ -275,7 +343,8 @@
     }
 
     private void handleSystemUiStateChanged(int sysuiStateFlags) {
-        boolean isNavBarHidden = isNavBarHidden(sysuiStateFlags);
+        boolean isNavBarHidden =
+                (sysuiStateFlags & QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN) != 0;
         if (mIsNavBarHidden == isNavBarHidden) {
             return;
         }
@@ -310,7 +379,7 @@
             return;
         }
 
-        if (mIsDozing || mIsNavBarHidden || mOnLockscreen || !getShowWhenTaught()) {
+        if (!isFullyAwake() || mIsNavBarHidden || mOnLockscreen || !getShowWhenTaught()) {
             mAssistHandleCallbacks.hide();
         } else if (justUnlocked) {
             long currentEpochDay = LocalDate.now().toEpochDay();
@@ -332,7 +401,7 @@
             return;
         }
 
-        if (mIsDozing || mIsNavBarHidden || isSuppressed()) {
+        if (!isFullyAwake() || mIsNavBarHidden || isSuppressed()) {
             mAssistHandleCallbacks.hide();
         } else if (mOnLockscreen) {
             mAssistHandleCallbacks.showAndStay();
@@ -362,14 +431,15 @@
             return;
         }
 
-        long currentTimestamp = SystemClock.uptimeMillis();
+        long currentTimestamp = mClock.currentTimeMillis();
         mLearningTimeElapsed += currentTimestamp - mLastLearningTimestamp;
         mLastLearningTimestamp = currentTimestamp;
-        Settings.Secure.putLong(
-                mContext.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, mLearningTimeElapsed);
 
         mIsLearned =
                 mLearningCount >= getLearningCount() || mLearningTimeElapsed >= getLearningTimeMs();
+
+        mHandler.post(() -> Settings.Secure.putLong(
+                mContext.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, mLearningTimeElapsed));
     }
 
     private void resetConsecutiveTaskSwitches() {
@@ -382,6 +452,10 @@
         mHandler.postDelayed(mResetConsecutiveTaskSwitches, getShowAndGoDelayResetTimeoutMs());
     }
 
+    private boolean isFullyAwake() {
+        return mIsAwake && !mIsDozing;
+    }
+
     private long getLearningTimeMs() {
         return mPhenotypeHelper.getLong(
                 SystemUiDeviceConfigFlags.ASSIST_HANDLES_LEARN_TIME_MS,
@@ -441,6 +515,7 @@
         pw.println(prefix + "Current AssistHandleReminderExpBehavior State:");
         pw.println(prefix + "   mOnLockscreen=" + mOnLockscreen);
         pw.println(prefix + "   mIsDozing=" + mIsDozing);
+        pw.println(prefix + "   mIsAwake=" + mIsAwake);
         pw.println(prefix + "   mRunningTaskId=" + mRunningTaskId);
         pw.println(prefix + "   mDefaultHome=" + mDefaultHome);
         pw.println(prefix + "   mIsNavBarHidden=" + mIsNavBarHidden);
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index 4a4fead..1a2d062 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -48,9 +48,13 @@
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
 /**
  * Class to manage everything related to assist in SystemUI.
  */
+@Singleton
 public class AssistManager implements ConfigurationChangedReceiver {
 
     /**
@@ -97,6 +101,8 @@
     private static final String INVOCATION_TIME_MS_KEY = "invocation_time_ms";
     private static final String INVOCATION_PHONE_STATE_KEY = "invocation_phone_state";
     public static final String INVOCATION_TYPE_KEY = "invocation_type";
+    protected static final String ACTION_KEY = "action";
+    protected static final String SHOW_ASSIST_HANDLES_ACTION = "show_assist_handles";
 
     public static final int INVOCATION_TYPE_GESTURE = 1;
     public static final int INVOCATION_TYPE_ACTIVE_EDGE = 2;
@@ -147,15 +153,19 @@
         }
     };
 
-    public AssistManager(DeviceProvisionedController controller, Context context) {
+    @Inject
+    public AssistManager(
+            DeviceProvisionedController controller,
+            Context context,
+            AssistUtils assistUtils,
+            AssistHandleBehaviorController handleController) {
         mContext = context;
         mDeviceProvisionedController = controller;
         mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
-        mAssistUtils = new AssistUtils(context);
+        mAssistUtils = assistUtils;
         mAssistDisclosure = new AssistDisclosure(context, new Handler());
         mPhoneStateMonitor = new PhoneStateMonitor(context);
-        mHandleController =
-                new AssistHandleBehaviorController(context, mAssistUtils, new Handler());
+        mHandleController = handleController;
 
         registerVoiceInteractionSessionListener();
         mInterestingConfigChanges = new InterestingConfigChanges(ActivityInfo.CONFIG_ORIENTATION
@@ -204,6 +214,9 @@
                         if (VERBOSE) {
                             Log.v(TAG, "UI hints received");
                         }
+                        if (SHOW_ASSIST_HANDLES_ACTION.equals(hints.getString(ACTION_KEY))) {
+                            requestAssistHandles();
+                        }
                     }
                 });
     }
@@ -277,6 +290,10 @@
         mUiController.onGestureCompletion(velocity);
     }
 
+    protected void requestAssistHandles() {
+        mHandleController.onAssistHandlesRequested();
+    }
+
     public void hideAssist() {
         mAssistUtils.hideCurrentSession();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistModule.java b/packages/SystemUI/src/com/android/systemui/assist/AssistModule.java
new file mode 100644
index 0000000..2a82d21
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistModule.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2019 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.assist;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.SystemClock;
+
+import androidx.slice.Clock;
+
+import com.android.internal.app.AssistUtils;
+import com.android.systemui.ScreenDecorations;
+import com.android.systemui.SysUiServiceProvider;
+
+import java.util.EnumMap;
+import java.util.Map;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import dagger.Module;
+import dagger.Provides;
+
+/** Module for dagger injections related to the Assistant. */
+@Module
+public abstract class AssistModule {
+
+    static final String ASSIST_HANDLE_THREAD_NAME = "assist_handle_thread";
+    static final String UPTIME_NAME = "uptime";
+
+    @Provides
+    @Singleton
+    @Named(ASSIST_HANDLE_THREAD_NAME)
+    static Handler provideBackgroundHandler() {
+        final HandlerThread backgroundHandlerThread =
+                new HandlerThread("AssistHandleThread");
+        backgroundHandlerThread.start();
+        return backgroundHandlerThread.getThreadHandler();
+    }
+
+    @Provides
+    @Singleton
+    static Map<AssistHandleBehavior, AssistHandleBehaviorController.BehaviorController>
+            provideAssistHandleBehaviorControllerMap(
+                    AssistHandleOffBehavior offBehavior,
+                    AssistHandleLikeHomeBehavior likeHomeBehavior,
+                    AssistHandleReminderExpBehavior reminderExpBehavior) {
+        Map<AssistHandleBehavior, AssistHandleBehaviorController.BehaviorController> map =
+                new EnumMap<>(AssistHandleBehavior.class);
+        map.put(AssistHandleBehavior.OFF, offBehavior);
+        map.put(AssistHandleBehavior.LIKE_HOME, likeHomeBehavior);
+        map.put(AssistHandleBehavior.REMINDER_EXP, reminderExpBehavior);
+        return map;
+    }
+
+    @Provides
+    static ScreenDecorations provideScreenDecorations(Context context) {
+        return SysUiServiceProvider.getComponent(context, ScreenDecorations.class);
+    }
+
+    @Provides
+    @Singleton
+    static AssistUtils provideAssistUtils(Context context) {
+        return new AssistUtils(context);
+    }
+
+    @Provides
+    @Singleton
+    @Named(UPTIME_NAME)
+    static Clock provideSystemClock() {
+        return SystemClock::uptimeMillis;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/assist/PhenotypeHelper.java b/packages/SystemUI/src/com/android/systemui/assist/PhenotypeHelper.java
index b3f57af..ff76adf 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/PhenotypeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/PhenotypeHelper.java
@@ -22,8 +22,18 @@
 
 import java.util.concurrent.Executor;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * Wrapper class for retrieving phenotype flag values.
+ *
+ * Can be mocked in tests for ease of testing the effects of particular values.
+ */
+@Singleton
 public class PhenotypeHelper {
 
+    @Inject
     public PhenotypeHelper() {}
 
     public long getLong(String name, long defaultValue) {
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
index bc782a7..bb3bd78 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
@@ -100,7 +100,9 @@
 
         int cornerRadiusBottom = DisplayUtils.getCornerRadiusBottom(context);
         int cornerRadiusTop = DisplayUtils.getCornerRadiusTop(context);
-        mViewHeight = Math.max(cornerRadiusBottom, cornerRadiusTop);
+        // ensure that height is non-zero even for square corners
+        mViewHeight = Math.max(Math.max(cornerRadiusBottom, cornerRadiusTop),
+            DisplayUtils.convertDpToPx(LIGHT_HEIGHT_DP, context));
 
         final int dualToneDarkTheme = Utils.getThemeAttr(mContext, R.attr.darkIconTheme);
         final int dualToneLightTheme = Utils.getThemeAttr(mContext, R.attr.lightIconTheme);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
index ce67577..cbbd3a0 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
@@ -499,6 +499,8 @@
         if (newState == STATE_PENDING_CONFIRMATION || newState == STATE_AUTHENTICATED) {
             mNegativeButton.setText(R.string.cancel);
             mNegativeButton.setContentDescription(getResources().getString(R.string.cancel));
+        } else {
+            mNegativeButton.setText(mBundle.getCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT));
         }
 
         updateIcon(mState, newState);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BadgeRenderer.java b/packages/SystemUI/src/com/android/systemui/bubbles/BadgeRenderer.java
deleted file mode 100644
index 74ad0fa..0000000
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BadgeRenderer.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.bubbles;
-
-import static android.graphics.Paint.ANTI_ALIAS_FLAG;
-import static android.graphics.Paint.FILTER_BITMAP_FLAG;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.util.Log;
-
-import com.android.systemui.R;
-
-// XXX: Mostly opied from launcher code / can we share?
-/**
- * Contains parameters necessary to draw a badge for an icon (e.g. the size of the badge).
- */
-public class BadgeRenderer {
-
-    private static final String TAG = "BadgeRenderer";
-
-    /** The badge sizes are defined as percentages of the app icon size. */
-    private static final float SIZE_PERCENTAGE = 0.38f;
-
-    /** Extra scale down of the dot. */
-    private static final float DOT_SCALE = 0.6f;
-
-    private final float mDotCenterOffset;
-    private final float mCircleRadius;
-    private final Paint mCirclePaint = new Paint(ANTI_ALIAS_FLAG | FILTER_BITMAP_FLAG);
-
-    public BadgeRenderer(Context context) {
-        mDotCenterOffset = getDotCenterOffset(context);
-        mCircleRadius = getDotRadius(mDotCenterOffset);
-    }
-
-    /** Space between the center of the dot and the top or left of the bubble stack. */
-    static float getDotCenterOffset(Context context) {
-        final int iconSizePx =
-                context.getResources().getDimensionPixelSize(R.dimen.individual_bubble_size);
-        return SIZE_PERCENTAGE * iconSizePx;
-    }
-
-    static float getDotRadius(float dotCenterOffset) {
-        int size = (int) (DOT_SCALE * dotCenterOffset);
-        return size / 2f;
-    }
-
-    /**
-     * Draw a circle in the top right corner of the given bounds.
-     *
-     * @param color The color (based on the icon) to use for the badge.
-     * @param iconBounds The bounds of the icon being badged.
-     * @param badgeScale The progress of the animation, from 0 to 1.
-     * @param spaceForOffset How much space to offset the badge up and to the left or right.
-     * @param onLeft Whether the badge should be draw on left or right side.
-     */
-    public void draw(Canvas canvas, int color, Rect iconBounds, float badgeScale,
-            Point spaceForOffset, boolean onLeft) {
-        if (iconBounds == null) {
-            Log.e(TAG, "Invalid null argument(s) passed in call to draw.");
-            return;
-        }
-        canvas.save();
-        // We draw the badge relative to its center.
-        int x = onLeft ? iconBounds.left : iconBounds.right;
-        float offset = onLeft ? (mDotCenterOffset / 2) : -(mDotCenterOffset / 2);
-        float badgeCenterX = x + offset;
-        float badgeCenterY = iconBounds.top + mDotCenterOffset / 2;
-
-        canvas.translate(badgeCenterX + spaceForOffset.x, badgeCenterY - spaceForOffset.y);
-
-        canvas.scale(badgeScale, badgeScale);
-        mCirclePaint.setColor(color);
-        canvas.drawCircle(0, 0, mCircleRadius, mCirclePaint);
-        canvas.restore();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
index 783780f..c0053d1 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
@@ -18,12 +18,13 @@
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
-import android.graphics.Point;
+import android.graphics.Path;
 import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.widget.ImageView;
 
 import com.android.internal.graphics.ColorUtils;
+import com.android.launcher3.icons.DotRenderer;
 import com.android.systemui.R;
 
 /**
@@ -31,16 +32,19 @@
  */
 public class BadgedImageView extends ImageView {
 
-    private BadgeRenderer mDotRenderer;
-    private int mIconSize;
     private Rect mTempBounds = new Rect();
-    private Point mTempPoint = new Point();
 
+    private DotRenderer mDotRenderer;
+    private DotRenderer.DrawParams mDrawParams;
+    private int mIconBitmapSize;
+    private int mDotColor;
     private float mDotScale = 0f;
-    private int mUpdateDotColor;
-    private boolean mShowUpdateDot;
+    private boolean mShowDot;
     private boolean mOnLeft;
 
+    /** Same as value in Launcher3 IconShape */
+    static final int DEFAULT_PATH_SIZE = 100;
+
     public BadgedImageView(Context context) {
         this(context, null);
     }
@@ -56,69 +60,100 @@
     public BadgedImageView(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        mIconSize = getResources().getDimensionPixelSize(R.dimen.individual_bubble_size);
-        mDotRenderer = new BadgeRenderer(getContext());
+        mIconBitmapSize = getResources().getDimensionPixelSize(R.dimen.bubble_icon_bitmap_size);
+        mDrawParams = new DotRenderer.DrawParams();
 
         TypedArray ta = context.obtainStyledAttributes(
-                new int[] {android.R.attr.colorBackgroundFloating});
+                new int[]{android.R.attr.colorBackgroundFloating});
         ta.recycle();
     }
 
     @Override
     public void onDraw(Canvas canvas) {
         super.onDraw(canvas);
-        if (mShowUpdateDot) {
-            getDrawingRect(mTempBounds);
-            mTempPoint.set((getWidth() - mIconSize) / 2, getPaddingTop());
-            mDotRenderer.draw(canvas, mUpdateDotColor, mTempBounds, mDotScale, mTempPoint,
-                    mOnLeft);
+        if (!mShowDot) {
+            return;
         }
+        getDrawingRect(mTempBounds);
+
+        mDrawParams.color = mDotColor;
+        mDrawParams.iconBounds = mTempBounds;
+        mDrawParams.leftAlign = mOnLeft;
+        mDrawParams.scale = mDotScale;
+
+        if (mDotRenderer == null) {
+            Path circlePath = new Path();
+            float radius = DEFAULT_PATH_SIZE * 0.5f;
+            circlePath.addCircle(radius /* x */, radius /* y */, radius, Path.Direction.CW);
+            mDotRenderer = new DotRenderer(mIconBitmapSize, circlePath, DEFAULT_PATH_SIZE);
+        }
+        mDotRenderer.draw(canvas, mDrawParams);
     }
 
     /**
      * Set whether the dot should appear on left or right side of the view.
      */
-    public void setDotPosition(boolean onLeft) {
+    void setDotOnLeft(boolean onLeft) {
         mOnLeft = onLeft;
         invalidate();
     }
 
-    public boolean getDotPosition() {
+    boolean getDotOnLeft() {
         return mOnLeft;
     }
 
     /**
      * Set whether the dot should show or not.
      */
-    public void setShowDot(boolean showBadge) {
-        mShowUpdateDot = showBadge;
+    void setShowDot(boolean showDot) {
+        mShowDot = showDot;
         invalidate();
     }
 
     /**
      * @return whether the dot is being displayed.
      */
-    public boolean isShowingDot() {
-        return mShowUpdateDot;
+    boolean isShowingDot() {
+        return mShowDot;
     }
 
     /**
      * The colour to use for the dot.
      */
     public void setDotColor(int color) {
-        mUpdateDotColor = ColorUtils.setAlphaComponent(color, 255 /* alpha */);
+        mDotColor = ColorUtils.setAlphaComponent(color, 255 /* alpha */);
+        invalidate();
+    }
+
+    /**
+     * @param iconPath The new icon path to use when calculating dot position.
+     */
+    public void drawDot(Path iconPath) {
+        mDotRenderer = new DotRenderer(mIconBitmapSize, iconPath, DEFAULT_PATH_SIZE);
         invalidate();
     }
 
     /**
      * How big the dot should be, fraction from 0 to 1.
      */
-    public void setDotScale(float fraction) {
+    void setDotScale(float fraction) {
         mDotScale = fraction;
         invalidate();
     }
 
-    public float getDotScale() {
-        return mDotScale;
+    /**
+     * Return dot position relative to bubble view container bounds.
+     */
+    float[] getDotCenter() {
+        float[] dotPosition;
+        if (mOnLeft) {
+            dotPosition = mDotRenderer.getLeftDotPosition();
+        } else {
+            dotPosition =  mDotRenderer.getRightDotPosition();
+        }
+        getDrawingRect(mTempBounds);
+        float dotCenterX = mTempBounds.width() * dotPosition[0];
+        float dotCenterY = mTempBounds.height() * dotPosition[1];
+        return new float[]{dotCenterX, dotCenterY};
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
index 5c6c397..c3cee35 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
@@ -20,38 +20,67 @@
 
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.Notification;
+import android.app.PendingIntent;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.os.Parcelable;
 import android.os.UserHandle;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
 import android.view.LayoutInflater;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.List;
 import java.util.Objects;
 
 /**
  * Encapsulates the data and UI elements of a bubble.
  */
 class Bubble {
-
-    private static final boolean DEBUG = false;
     private static final String TAG = "Bubble";
 
+    private NotificationEntry mEntry;
     private final String mKey;
     private final String mGroupId;
     private String mAppName;
-    private final BubbleExpandedView.OnBubbleBlockedListener mListener;
+    private Drawable mUserBadgedAppIcon;
 
     private boolean mInflated;
-    public NotificationEntry entry;
-    BubbleView iconView;
-    BubbleExpandedView expandedView;
+    private BubbleView mIconView;
+    private BubbleExpandedView mExpandedView;
+
     private long mLastUpdated;
     private long mLastAccessed;
-    private PackageManager mPm;
+    private boolean mIsRemoved;
+
+    /**
+     * Whether this notification should be shown in the shade when it is also displayed as a bubble.
+     *
+     * <p>When a notification is a bubble we don't show it in the shade once the bubble has been
+     * expanded</p>
+     */
+    private boolean mShowInShadeWhenBubble = true;
+
+    /**
+     * Whether the bubble should show a dot for the notification indicating updated content.
+     */
+    private boolean mShowBubbleUpdateDot = true;
+
+    /** Whether flyout text should be suppressed, regardless of any other flags or state. */
+    private boolean mSuppressFlyout;
 
     public static String groupId(NotificationEntry entry) {
         UserHandle user = entry.notification.getUser();
@@ -61,31 +90,27 @@
     /** Used in tests when no UI is required. */
     @VisibleForTesting(visibility = PRIVATE)
     Bubble(Context context, NotificationEntry e) {
-        this (context, e, null);
-    }
-
-    Bubble(Context context, NotificationEntry e,
-            BubbleExpandedView.OnBubbleBlockedListener listener) {
-        entry = e;
+        mEntry = e;
         mKey = e.key;
         mLastUpdated = e.notification.getPostTime();
         mGroupId = groupId(e);
-        mListener = listener;
 
-        mPm = context.getPackageManager();
+        PackageManager pm = context.getPackageManager();
         ApplicationInfo info;
         try {
-            info = mPm.getApplicationInfo(
-                entry.notification.getPackageName(),
+            info = pm.getApplicationInfo(
+                mEntry.notification.getPackageName(),
                 PackageManager.MATCH_UNINSTALLED_PACKAGES
                     | PackageManager.MATCH_DISABLED_COMPONENTS
                     | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
                     | PackageManager.MATCH_DIRECT_BOOT_AWARE);
             if (info != null) {
-                mAppName = String.valueOf(mPm.getApplicationLabel(info));
+                mAppName = String.valueOf(pm.getApplicationLabel(info));
             }
+            Drawable appIcon = pm.getApplicationIcon(mEntry.notification.getPackageName());
+            mUserBadgedAppIcon = pm.getUserBadgedIcon(appIcon, mEntry.notification.getUser());
         } catch (PackageManager.NameNotFoundException unused) {
-            mAppName = entry.notification.getPackageName();
+            mAppName = mEntry.notification.getPackageName();
         }
     }
 
@@ -93,12 +118,16 @@
         return mKey;
     }
 
+    public NotificationEntry getEntry() {
+        return mEntry;
+    }
+
     public String getGroupId() {
         return mGroupId;
     }
 
     public String getPackageName() {
-        return entry.notification.getPackageName();
+        return mEntry.notification.getPackageName();
     }
 
     public String getAppName() {
@@ -109,9 +138,23 @@
         return mInflated;
     }
 
-    public void updateDotVisibility() {
-        if (iconView != null) {
-            iconView.updateDotVisibility(true /* animate */);
+    void updateDotVisibility() {
+        if (mIconView != null) {
+            mIconView.updateDotVisibility(true /* animate */);
+        }
+    }
+
+    BubbleView getIconView() {
+        return mIconView;
+    }
+
+    BubbleExpandedView getExpandedView() {
+        return mExpandedView;
+    }
+
+    void cleanupExpandedState() {
+        if (mExpandedView != null) {
+            mExpandedView.cleanUpExpandedState();
         }
     }
 
@@ -119,14 +162,14 @@
         if (mInflated) {
             return;
         }
-        iconView = (BubbleView) inflater.inflate(
+        mIconView = (BubbleView) inflater.inflate(
                 R.layout.bubble_view, stackView, false /* attachToRoot */);
-        iconView.setNotif(entry);
+        mIconView.setBubble(this);
+        mIconView.setAppIcon(mUserBadgedAppIcon);
 
-        expandedView = (BubbleExpandedView) inflater.inflate(
+        mExpandedView = (BubbleExpandedView) inflater.inflate(
                 R.layout.bubble_expanded_view, stackView, false /* attachToRoot */);
-        expandedView.setEntry(entry, stackView, mAppName);
-        expandedView.setOnBlockedListener(mListener);
+        mExpandedView.setBubble(this, stackView, mAppName);
 
         mInflated = true;
     }
@@ -140,46 +183,38 @@
      * and setting {@code false} actually means rendering the expanded view in transparent.
      */
     void setContentVisibility(boolean visibility) {
-        if (expandedView != null) {
-            expandedView.setContentVisibility(visibility);
+        if (mExpandedView != null) {
+            mExpandedView.setContentVisibility(visibility);
         }
     }
 
-    void setDismissed() {
-        entry.setBubbleDismissed(true);
-        // TODO: move this somewhere where it can be guaranteed not to run until safe from flicker
-        if (expandedView != null) {
-            expandedView.cleanUpExpandedState();
-        }
-    }
-
-    void setEntry(NotificationEntry entry) {
-        this.entry = entry;
+    void updateEntry(NotificationEntry entry) {
+        mEntry = entry;
         mLastUpdated = entry.notification.getPostTime();
         if (mInflated) {
-            iconView.update(entry);
-            expandedView.update(entry);
+            mIconView.update(this);
+            mExpandedView.update(this);
         }
     }
 
     /**
      * @return the newer of {@link #getLastUpdateTime()} and {@link #getLastAccessTime()}
      */
-    public long getLastActivity() {
+    long getLastActivity() {
         return Math.max(mLastUpdated, mLastAccessed);
     }
 
     /**
      * @return the timestamp in milliseconds of the most recent notification entry for this bubble
      */
-    public long getLastUpdateTime() {
+    long getLastUpdateTime() {
         return mLastUpdated;
     }
 
     /**
      * @return the timestamp in milliseconds when this bubble was last displayed in expanded state
      */
-    public long getLastAccessTime() {
+    long getLastAccessTime() {
         return mLastAccessed;
     }
 
@@ -187,7 +222,7 @@
      * @return the display id of the virtual display on which bubble contents is drawn.
      */
     int getDisplayId() {
-        return expandedView != null ? expandedView.getVirtualDisplayId() : INVALID_DISPLAY;
+        return mExpandedView != null ? mExpandedView.getVirtualDisplayId() : INVALID_DISPLAY;
     }
 
     /**
@@ -195,14 +230,204 @@
      */
     void markAsAccessedAt(long lastAccessedMillis) {
         mLastAccessed = lastAccessedMillis;
-        entry.setShowInShadeWhenBubble(false);
+        setShowInShadeWhenBubble(false);
+        setShowBubbleDot(false);
     }
 
     /**
-     * @return whether bubble is from a notification associated with a foreground service.
+     * Whether this notification should be shown in the shade when it is also displayed as a
+     * bubble.
      */
-    public boolean isOngoing() {
-        return entry.isForegroundService();
+    boolean showInShadeWhenBubble() {
+        return !mEntry.isRowDismissed() && !shouldSuppressNotification()
+                && (!mEntry.isClearable() || mShowInShadeWhenBubble);
+    }
+
+    /**
+     * Sets whether this notification should be shown in the shade when it is also displayed as a
+     * bubble.
+     */
+    void setShowInShadeWhenBubble(boolean showInShade) {
+        mShowInShadeWhenBubble = showInShade;
+    }
+
+    /**
+     * Sets whether the bubble for this notification should show a dot indicating updated content.
+     */
+    void setShowBubbleDot(boolean showDot) {
+        mShowBubbleUpdateDot = showDot;
+    }
+
+    /**
+     * Whether the bubble for this notification should show a dot indicating updated content.
+     */
+    boolean showBubbleDot() {
+        return mShowBubbleUpdateDot && !mEntry.shouldSuppressNotificationDot();
+    }
+
+    /**
+     * Whether the flyout for the bubble should be shown.
+     */
+    boolean showFlyoutForBubble() {
+        return !mSuppressFlyout && !mEntry.shouldSuppressPeek()
+                && !mEntry.shouldSuppressNotificationList();
+    }
+
+    /**
+     * Set whether the flyout text for the bubble should be shown when an update is received.
+     *
+     * @param suppressFlyout whether the flyout text is shown
+     */
+    void setSuppressFlyout(boolean suppressFlyout) {
+        mSuppressFlyout = suppressFlyout;
+    }
+
+    /**
+     * Returns whether the notification for this bubble is a foreground service. It shows that this
+     * is an ongoing bubble.
+     */
+    boolean isOngoing() {
+        int flags = mEntry.notification.getNotification().flags;
+        return (flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
+    }
+
+    float getDesiredHeight(Context context) {
+        Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
+        boolean useRes = data.getDesiredHeightResId() != 0;
+        if (useRes) {
+            return getDimenForPackageUser(context, data.getDesiredHeightResId(),
+                    mEntry.notification.getPackageName(),
+                    mEntry.notification.getUser().getIdentifier());
+        } else {
+            return data.getDesiredHeight()
+                    * context.getResources().getDisplayMetrics().density;
+        }
+    }
+
+    String getDesiredHeightString() {
+        Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
+        boolean useRes = data.getDesiredHeightResId() != 0;
+        if (useRes) {
+            return String.valueOf(data.getDesiredHeightResId());
+        } else {
+            return String.valueOf(data.getDesiredHeight());
+        }
+    }
+
+    @Nullable
+    PendingIntent getBubbleIntent(Context context) {
+        Notification notif = mEntry.notification.getNotification();
+        Notification.BubbleMetadata data = notif.getBubbleMetadata();
+        if (BubbleController.canLaunchInActivityView(context, mEntry) && data != null) {
+            return data.getIntent();
+        }
+        return null;
+    }
+
+    Intent getSettingsIntent() {
+        final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_BUBBLE_SETTINGS);
+        intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
+        intent.putExtra(Settings.EXTRA_APP_UID, mEntry.notification.getUid());
+        intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
+        return intent;
+    }
+
+    /**
+     * Returns our best guess for the most relevant text summary of the latest update to this
+     * notification, based on its type. Returns null if there should not be an update message.
+     */
+    CharSequence getUpdateMessage(Context context) {
+        final Notification underlyingNotif = mEntry.notification.getNotification();
+        final Class<? extends Notification.Style> style = underlyingNotif.getNotificationStyle();
+
+        try {
+            if (Notification.BigTextStyle.class.equals(style)) {
+                // Return the big text, it is big so probably important. If it's not there use the
+                // normal text.
+                CharSequence bigText =
+                        underlyingNotif.extras.getCharSequence(Notification.EXTRA_BIG_TEXT);
+                return !TextUtils.isEmpty(bigText)
+                        ? bigText
+                        : underlyingNotif.extras.getCharSequence(Notification.EXTRA_TEXT);
+            } else if (Notification.MessagingStyle.class.equals(style)) {
+                final List<Notification.MessagingStyle.Message> messages =
+                        Notification.MessagingStyle.Message.getMessagesFromBundleArray(
+                                (Parcelable[]) underlyingNotif.extras.get(
+                                        Notification.EXTRA_MESSAGES));
+
+                final Notification.MessagingStyle.Message latestMessage =
+                        Notification.MessagingStyle.findLatestIncomingMessage(messages);
+
+                if (latestMessage != null) {
+                    final CharSequence personName = latestMessage.getSenderPerson() != null
+                            ? latestMessage.getSenderPerson().getName()
+                            : null;
+
+                    // Prepend the sender name if available since group chats also use messaging
+                    // style.
+                    if (!TextUtils.isEmpty(personName)) {
+                        return context.getResources().getString(
+                                R.string.notification_summary_message_format,
+                                personName,
+                                latestMessage.getText());
+                    } else {
+                        return latestMessage.getText();
+                    }
+                }
+            } else if (Notification.InboxStyle.class.equals(style)) {
+                CharSequence[] lines =
+                        underlyingNotif.extras.getCharSequenceArray(Notification.EXTRA_TEXT_LINES);
+
+                // Return the last line since it should be the most recent.
+                if (lines != null && lines.length > 0) {
+                    return lines[lines.length - 1];
+                }
+            } else if (Notification.MediaStyle.class.equals(style)) {
+                // Return nothing, media updates aren't typically useful as a text update.
+                return null;
+            } else {
+                // Default to text extra.
+                return underlyingNotif.extras.getCharSequence(Notification.EXTRA_TEXT);
+            }
+        } catch (ClassCastException | NullPointerException | ArrayIndexOutOfBoundsException e) {
+            // No use crashing, we'll just return null and the caller will assume there's no update
+            // message.
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+    private int getDimenForPackageUser(Context context, int resId, String pkg, int userId) {
+        PackageManager pm = context.getPackageManager();
+        Resources r;
+        if (pkg != null) {
+            try {
+                if (userId == UserHandle.USER_ALL) {
+                    userId = UserHandle.USER_SYSTEM;
+                }
+                r = pm.getResourcesForApplicationAsUser(pkg, userId);
+                return r.getDimensionPixelSize(resId);
+            } catch (PackageManager.NameNotFoundException ex) {
+                // Uninstalled, don't care
+            } catch (Resources.NotFoundException e) {
+                // Invalid res id, return 0 and user our default
+                Log.e(TAG, "Couldn't find desired height res id", e);
+            }
+        }
+        return 0;
+    }
+
+    private boolean shouldSuppressNotification() {
+        return mEntry.getBubbleMetadata() != null
+                && mEntry.getBubbleMetadata().isNotificationSuppressed();
+    }
+
+    boolean shouldAutoExpand() {
+        Notification.BubbleMetadata metadata = mEntry.getBubbleMetadata();
+        return metadata != null && metadata.getAutoExpandBubble();
     }
 
     @Override
@@ -210,6 +435,20 @@
         return "Bubble{" + mKey + '}';
     }
 
+    /**
+     * Description of current bubble state.
+     */
+    public void dump(
+            @NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
+        pw.print("key: "); pw.println(mKey);
+        pw.print("  showInShade:   "); pw.println(showInShadeWhenBubble());
+        pw.print("  showDot:       "); pw.println(showBubbleDot());
+        pw.print("  showFlyout:    "); pw.println(showFlyoutForBubble());
+        pw.print("  desiredHeight: "); pw.println(getDesiredHeightString());
+        pw.print("  suppressNotif: "); pw.println(shouldSuppressNotification());
+        pw.print("  autoExpand:    "); pw.println(shouldAutoExpand());
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index a23c99e..3cc91de 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -16,21 +16,24 @@
 
 package com.android.systemui.bubbles;
 
+import static android.app.Notification.FLAG_AUTOGROUP_SUMMARY;
 import static android.app.Notification.FLAG_BUBBLE;
-import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
-import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST;
-import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
 import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
 import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
 import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL_ALL;
 import static android.service.notification.NotificationListenerService.REASON_CANCEL;
 import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL;
+import static android.service.notification.NotificationListenerService.REASON_CLICK;
+import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.View.INVISIBLE;
 import static android.view.View.VISIBLE;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 
+import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_CONTROLLER;
+import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
+import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.systemui.statusbar.StatusBarState.SHADE;
 import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON;
 
@@ -39,9 +42,8 @@
 import static java.lang.annotation.ElementType.PARAMETER;
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
-import android.app.ActivityManager;
+import android.annotation.UserIdInt;
 import android.app.ActivityManager.RunningTaskInfo;
-import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.content.Context;
@@ -53,10 +55,11 @@
 import android.os.ServiceManager;
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService.RankingMap;
-import android.service.notification.StatusBarNotification;
 import android.service.notification.ZenModeConfig;
+import android.util.ArraySet;
 import android.util.Log;
 import android.util.Pair;
+import android.util.SparseSetArray;
 import android.view.Display;
 import android.view.IPinnedStackController;
 import android.view.IPinnedStackListener;
@@ -75,18 +78,23 @@
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.shared.system.WindowManagerWrapper;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationRemoveInterceptor;
 import com.android.systemui.statusbar.notification.NotificationEntryListener;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
+import com.android.systemui.statusbar.notification.collection.NotificationData;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationFlag;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ZenModeController;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
+import java.util.ArrayList;
 import java.util.List;
 
 import javax.inject.Inject;
@@ -101,12 +109,12 @@
 @Singleton
 public class BubbleController implements ConfigurationController.ConfigurationListener {
 
-    private static final String TAG = "BubbleController";
-    private static final boolean DEBUG = false;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleController" : TAG_BUBBLES;
 
     @Retention(SOURCE)
     @IntDef({DISMISS_USER_GESTURE, DISMISS_AGED, DISMISS_TASK_FINISHED, DISMISS_BLOCKED,
-            DISMISS_NOTIF_CANCEL, DISMISS_ACCESSIBILITY_ACTION, DISMISS_NO_LONGER_BUBBLE})
+            DISMISS_NOTIF_CANCEL, DISMISS_ACCESSIBILITY_ACTION, DISMISS_NO_LONGER_BUBBLE,
+            DISMISS_USER_CHANGED, DISMISS_GROUP_CANCELLED, DISMISS_INVALID_INTENT})
     @Target({FIELD, LOCAL_VARIABLE, PARAMETER})
     @interface DismissReason {}
 
@@ -117,24 +125,14 @@
     static final int DISMISS_NOTIF_CANCEL = 5;
     static final int DISMISS_ACCESSIBILITY_ACTION = 6;
     static final int DISMISS_NO_LONGER_BUBBLE = 7;
+    static final int DISMISS_USER_CHANGED = 8;
+    static final int DISMISS_GROUP_CANCELLED = 9;
+    static final int DISMISS_INVALID_INTENT = 10;
 
     public static final int MAX_BUBBLES = 5; // TODO: actually enforce this
 
-    // Enables some subset of notifs to automatically become bubbles
-    public static final boolean DEBUG_ENABLE_AUTO_BUBBLE = false;
-
     /** Flag to enable or disable the entire feature */
     private static final String ENABLE_BUBBLES = "experiment_enable_bubbles";
-    /** Auto bubble flags set whether different notif types should be presented as a bubble */
-    private static final String ENABLE_AUTO_BUBBLE_MESSAGES = "experiment_autobubble_messaging";
-    private static final String ENABLE_AUTO_BUBBLE_ONGOING = "experiment_autobubble_ongoing";
-    private static final String ENABLE_AUTO_BUBBLE_ALL = "experiment_autobubble_all";
-
-    /** Use an activityView for an auto-bubbled notifs if it has an appropriate content intent */
-    private static final String ENABLE_BUBBLE_CONTENT_INTENT = "experiment_bubble_content_intent";
-
-    private static final String BUBBLE_STIFFNESS = "experiment_bubble_stiffness";
-    private static final String BUBBLE_BOUNCINESS = "experiment_bubble_bounciness";
 
     private final Context mContext;
     private final NotificationEntryManager mNotificationEntryManager;
@@ -142,10 +140,16 @@
     private BubbleStateChangeListener mStateChangeListener;
     private BubbleExpandListener mExpandListener;
     @Nullable private BubbleStackView.SurfaceSynchronizer mSurfaceSynchronizer;
+    private final NotificationGroupManager mNotificationGroupManager;
 
     private BubbleData mBubbleData;
     @Nullable private BubbleStackView mStackView;
 
+    // Tracks the id of the current (foreground) user.
+    private int mCurrentUserId;
+    // Saves notification keys of active bubbles when users are switched.
+    private final SparseSetArray<String> mSavedBubbleKeysPerUser;
+
     // Bubbles get added to the status bar view
     private final StatusBarWindowController mStatusBarWindowController;
     private final ZenModeController mZenModeController;
@@ -157,6 +161,9 @@
     // Used for determining view rect for touch interaction
     private Rect mTempRect = new Rect();
 
+    // Listens to user switch so bubbles can be saved and restored.
+    private final NotificationLockscreenUserManager mNotifUserManager;
+
     /** Last known orientation, used to detect orientation changes in {@link #onConfigChanged}. */
     private int mOrientation = Configuration.ORIENTATION_UNDEFINED;
 
@@ -211,28 +218,38 @@
     public BubbleController(Context context, StatusBarWindowController statusBarWindowController,
             BubbleData data, ConfigurationController configurationController,
             NotificationInterruptionStateProvider interruptionStateProvider,
-            ZenModeController zenModeController) {
+            ZenModeController zenModeController,
+            NotificationLockscreenUserManager notifUserManager,
+            NotificationGroupManager groupManager) {
         this(context, statusBarWindowController, data, null /* synchronizer */,
-                configurationController, interruptionStateProvider, zenModeController);
+                configurationController, interruptionStateProvider, zenModeController,
+                notifUserManager, groupManager);
     }
 
     public BubbleController(Context context, StatusBarWindowController statusBarWindowController,
             BubbleData data, @Nullable BubbleStackView.SurfaceSynchronizer synchronizer,
             ConfigurationController configurationController,
             NotificationInterruptionStateProvider interruptionStateProvider,
-            ZenModeController zenModeController) {
+            ZenModeController zenModeController,
+            NotificationLockscreenUserManager notifUserManager,
+            NotificationGroupManager groupManager) {
         mContext = context;
         mNotificationInterruptionStateProvider = interruptionStateProvider;
+        mNotifUserManager = notifUserManager;
         mZenModeController = zenModeController;
         mZenModeController.addCallback(new ZenModeController.Callback() {
             @Override
             public void onZenChanged(int zen) {
-                updateStackViewForZenConfig();
+                if (mStackView != null) {
+                    mStackView.updateDots();
+                }
             }
 
             @Override
             public void onConfigChanged(ZenModeConfig config) {
-                updateStackViewForZenConfig();
+                if (mStackView != null) {
+                    mStackView.updateDots();
+                }
             }
         });
 
@@ -244,6 +261,24 @@
         mNotificationEntryManager = Dependency.get(NotificationEntryManager.class);
         mNotificationEntryManager.addNotificationEntryListener(mEntryListener);
         mNotificationEntryManager.setNotificationRemoveInterceptor(mRemoveInterceptor);
+        mNotificationGroupManager = groupManager;
+        mNotificationGroupManager.addOnGroupChangeListener(
+                new NotificationGroupManager.OnGroupChangeListener() {
+                    @Override
+                    public void onGroupSuppressionChanged(
+                            NotificationGroupManager.NotificationGroup group,
+                            boolean suppressed) {
+                        // More notifications could be added causing summary to no longer
+                        // be suppressed -- in this case need to remove the key.
+                        final String groupKey = group.summary != null
+                                ? group.summary.notification.getGroupKey()
+                                : null;
+                        if (!suppressed && groupKey != null
+                                && mBubbleData.isSummarySuppressed(groupKey)) {
+                            mBubbleData.removeSuppressedSummary(groupKey);
+                        }
+                    }
+                });
 
         mStatusBarWindowController = statusBarWindowController;
         mStatusBarStateListener = new StatusBarStateListener();
@@ -261,6 +296,16 @@
 
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+
+        mSavedBubbleKeysPerUser = new SparseSetArray<>();
+        mCurrentUserId = mNotifUserManager.getCurrentUserId();
+        mNotifUserManager.addUserChangedListener(
+                newUserId -> {
+                    saveBubbles(mCurrentUserId);
+                    mBubbleData.dismissAll(DISMISS_USER_CHANGED);
+                    restoreBubbles(newUserId);
+                    mCurrentUserId = newUserId;
+                });
     }
 
     /**
@@ -271,19 +316,55 @@
         if (mStackView == null) {
             mStackView = new BubbleStackView(mContext, mBubbleData, mSurfaceSynchronizer);
             ViewGroup sbv = mStatusBarWindowController.getStatusBarView();
-            // TODO(b/130237686): When you expand the shade on top of expanded bubble, there is no
-            //  scrim between bubble and the shade
-            int bubblePosition = sbv.indexOfChild(sbv.findViewById(R.id.scrim_behind)) + 1;
-            sbv.addView(mStackView, bubblePosition,
+            int bubbleScrimIndex = sbv.indexOfChild(sbv.findViewById(R.id.scrim_for_bubble));
+            int stackIndex = bubbleScrimIndex + 1;  // Show stack above bubble scrim.
+            sbv.addView(mStackView, stackIndex,
                     new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
             if (mExpandListener != null) {
                 mStackView.setExpandListener(mExpandListener);
             }
-
-            updateStackViewForZenConfig();
         }
     }
 
+    /**
+     * Records the notification key for any active bubbles. These are used to restore active
+     * bubbles when the user returns to the foreground.
+     *
+     * @param userId the id of the user
+     */
+    private void saveBubbles(@UserIdInt int userId) {
+        // First clear any existing keys that might be stored.
+        mSavedBubbleKeysPerUser.remove(userId);
+        // Add in all active bubbles for the current user.
+        for (Bubble bubble: mBubbleData.getBubbles()) {
+            mSavedBubbleKeysPerUser.add(userId, bubble.getKey());
+        }
+    }
+
+    /**
+     * Promotes existing notifications to Bubbles if they were previously bubbles.
+     *
+     * @param userId the id of the user
+     */
+    private void restoreBubbles(@UserIdInt int userId) {
+        NotificationData notificationData =
+                mNotificationEntryManager.getNotificationData();
+        ArraySet<String> savedBubbleKeys = mSavedBubbleKeysPerUser.get(userId);
+        if (savedBubbleKeys == null) {
+            // There were no bubbles saved for this used.
+            return;
+        }
+        for (NotificationEntry e : notificationData.getNotificationsForCurrentUser()) {
+            if (savedBubbleKeys.contains(e.key)
+                    && mNotificationInterruptionStateProvider.shouldBubbleUp(e)
+                    && canLaunchInActivityView(mContext, e)) {
+                updateBubble(e, /* suppressFlyout= */ true);
+            }
+        }
+        // Finally, remove the entries for this user now that bubbles are restored.
+        mSavedBubbleKeysPerUser.remove(mCurrentUserId);
+    }
+
     @Override
     public void onUiModeChanged() {
         if (mStackView != null) {
@@ -301,8 +382,8 @@
     @Override
     public void onConfigChanged(Configuration newConfig) {
         if (mStackView != null && newConfig != null && newConfig.orientation != mOrientation) {
-            mStackView.onOrientationChanged();
             mOrientation = newConfig.orientation;
+            mStackView.onOrientationChanged(newConfig.orientation);
         }
     }
 
@@ -360,6 +441,25 @@
         mBubbleData.setExpanded(false /* expanded */);
     }
 
+    /**
+     * True if either:
+     * (1) There is a bubble associated with the provided key and if its notification is hidden
+     *     from the shade.
+     * (2) There is a group summary associated with the provided key that is hidden from the shade
+     *     because it has been dismissed but still has child bubbles active.
+     *
+     * False otherwise.
+     */
+    public boolean isBubbleNotificationSuppressedFromShade(String key) {
+        boolean isBubbleAndSuppressed = mBubbleData.hasBubbleWithKey(key)
+                && !mBubbleData.getBubbleWithKey(key).showInShadeWhenBubble();
+        NotificationEntry entry = mNotificationEntryManager.getNotificationData().get(key);
+        String groupKey = entry != null ? entry.notification.getGroupKey() : null;
+        boolean isSuppressedSummary = mBubbleData.isSummarySuppressed(groupKey);
+        boolean isSummary = key.equals(mBubbleData.getSummaryKey(groupKey));
+        return (isSummary && isSuppressedSummary) || isBubbleAndSuppressed;
+    }
+
     void selectBubble(Bubble bubble) {
         mBubbleData.setSelectedBubble(bubble);
     }
@@ -406,11 +506,15 @@
      * @param notif the notification associated with this bubble.
      */
     void updateBubble(NotificationEntry notif) {
+        updateBubble(notif, /* supressFlyout */ false);
+    }
+
+    void updateBubble(NotificationEntry notif, boolean suppressFlyout) {
         // If this is an interruptive notif, mark that it's interrupted
         if (notif.importance >= NotificationManager.IMPORTANCE_HIGH) {
             notif.setInterruption();
         }
-        mBubbleData.notificationEntryUpdated(notif);
+        mBubbleData.notificationEntryUpdated(notif, suppressFlyout);
     }
 
     /**
@@ -423,7 +527,7 @@
         // TEMP: refactor to change this to pass entry
         Bubble bubble = mBubbleData.getBubbleWithKey(key);
         if (bubble != null) {
-            mBubbleData.notificationEntryRemoved(bubble.entry, reason);
+            mBubbleData.notificationEntryRemoved(bubble.getEntry(), reason);
         }
     }
 
@@ -432,33 +536,50 @@
             new NotificationRemoveInterceptor() {
             @Override
             public boolean onNotificationRemoveRequested(String key, int reason) {
-                if (!mBubbleData.hasBubbleWithKey(key)) {
+                NotificationEntry entry = mNotificationEntryManager.getNotificationData().get(key);
+                String groupKey = entry != null ? entry.notification.getGroupKey() : null;
+                ArrayList<Bubble> bubbleChildren = mBubbleData.getBubblesInGroup(groupKey);
+
+                boolean inBubbleData = mBubbleData.hasBubbleWithKey(key);
+                boolean isSuppressedSummary = (mBubbleData.isSummarySuppressed(groupKey)
+                        && mBubbleData.getSummaryKey(groupKey).equals(key));
+                boolean isSummary = entry != null
+                        && entry.notification.getNotification().isGroupSummary();
+                boolean isSummaryOfBubbles = (isSuppressedSummary || isSummary)
+                        && bubbleChildren != null && !bubbleChildren.isEmpty();
+
+                if (!inBubbleData && !isSummaryOfBubbles) {
                     return false;
                 }
-                NotificationEntry entry = mBubbleData.getBubbleWithKey(key).entry;
 
                 final boolean isClearAll = reason == REASON_CANCEL_ALL;
-                final boolean isUserDimiss = reason == REASON_CANCEL;
+                final boolean isUserDimiss = reason == REASON_CANCEL || reason == REASON_CLICK;
                 final boolean isAppCancel = reason == REASON_APP_CANCEL
                         || reason == REASON_APP_CANCEL_ALL;
+                final boolean isSummaryCancel = reason == REASON_GROUP_SUMMARY_CANCELED;
 
                 // Need to check for !appCancel here because the notification may have
                 // previously been dismissed & entry.isRowDismissed would still be true
-                boolean userRemovedNotif = (entry.isRowDismissed() && !isAppCancel)
-                        || isClearAll || isUserDimiss;
+                boolean userRemovedNotif = (entry != null && entry.isRowDismissed() && !isAppCancel)
+                        || isClearAll || isUserDimiss || isSummaryCancel;
+
+                if (isSummaryOfBubbles) {
+                    return handleSummaryRemovalInterception(entry, userRemovedNotif);
+                }
 
                 // The bubble notification sticks around in the data as long as the bubble is
                 // not dismissed and the app hasn't cancelled the notification.
-                boolean bubbleExtended = entry.isBubble() && !entry.isBubbleDismissed()
-                        && userRemovedNotif;
+                Bubble bubble = mBubbleData.getBubbleWithKey(key);
+                boolean bubbleExtended = entry != null && entry.isBubble() && userRemovedNotif;
                 if (bubbleExtended) {
-                    entry.setShowInShadeWhenBubble(false);
+                    bubble.setShowInShadeWhenBubble(false);
+                    bubble.setShowBubbleDot(false);
                     if (mStackView != null) {
                         mStackView.updateDotVisibility(entry.key);
                     }
                     mNotificationEntryManager.updateNotifications();
                     return true;
-                } else if (!userRemovedNotif && !entry.isBubbleDismissed()) {
+                } else if (!userRemovedNotif && entry != null) {
                     // This wasn't a user removal so we should remove the bubble as well
                     mBubbleData.notificationEntryRemoved(entry, DISMISS_NOTIF_CANCEL);
                     return false;
@@ -467,6 +588,52 @@
             }
         };
 
+    private boolean handleSummaryRemovalInterception(NotificationEntry summary,
+            boolean userRemovedNotif) {
+        String groupKey = summary.notification.getGroupKey();
+        ArrayList<Bubble> bubbleChildren = mBubbleData.getBubblesInGroup(groupKey);
+
+        if (userRemovedNotif) {
+            // If it's a user dismiss we mark the children to be hidden from the shade.
+            for (int i = 0; i < bubbleChildren.size(); i++) {
+                Bubble bubbleChild = bubbleChildren.get(i);
+                // As far as group manager is concerned, once a child is no longer shown
+                // in the shade, it is essentially removed.
+                mNotificationGroupManager.onEntryRemoved(bubbleChild.getEntry());
+                bubbleChild.setShowInShadeWhenBubble(false);
+                bubbleChild.setShowBubbleDot(false);
+                if (mStackView != null) {
+                    mStackView.updateDotVisibility(bubbleChild.getKey());
+                }
+            }
+            // And since all children are removed, remove the summary.
+            mNotificationGroupManager.onEntryRemoved(summary);
+
+            // If the summary was auto-generated we don't need to keep that notification around
+            // because apps can't cancel it; so we only intercept & suppress real summaries.
+            boolean isAutogroupSummary = (summary.notification.getNotification().flags
+                    & FLAG_AUTOGROUP_SUMMARY) != 0;
+            if (!isAutogroupSummary) {
+                mBubbleData.addSummaryToSuppress(summary.notification.getGroupKey(),
+                        summary.key);
+                // Tell shade to update for the suppression
+                mNotificationEntryManager.updateNotifications();
+            }
+            return !isAutogroupSummary;
+        } else {
+            // If it's not a user dismiss it's a cancel.
+            mBubbleData.removeSuppressedSummary(groupKey);
+
+            // Remove any associated bubble children.
+            for (int i = 0; i < bubbleChildren.size(); i++) {
+                Bubble bubbleChild = bubbleChildren.get(i);
+                mBubbleData.notificationEntryRemoved(bubbleChild.getEntry(),
+                        DISMISS_GROUP_CANCELLED);
+            }
+            return false;
+        }
+    }
+
     @SuppressWarnings("FieldCanBeLocal")
     private final NotificationEntryListener mEntryListener = new NotificationEntryListener() {
         @Override
@@ -476,17 +643,6 @@
             }
             if (mNotificationInterruptionStateProvider.shouldBubbleUp(entry)
                     && canLaunchInActivityView(mContext, entry)) {
-                updateShowInShadeForSuppressNotification(entry);
-            }
-        }
-
-        @Override
-        public void onEntryInflated(NotificationEntry entry, @InflationFlag int inflatedFlags) {
-            if (!areBubblesEnabled(mContext)) {
-                return;
-            }
-            if (mNotificationInterruptionStateProvider.shouldBubbleUp(entry)
-                    && canLaunchInActivityView(mContext, entry)) {
                 updateBubble(entry);
             }
         }
@@ -502,8 +658,7 @@
                 // It was previously a bubble but no longer a bubble -- lets remove it
                 removeBubble(entry.key, DISMISS_NO_LONGER_BUBBLE);
             } else if (shouldBubble) {
-                updateShowInShadeForSuppressNotification(entry);
-                entry.setBubbleDismissed(false); // updates come back as bubbles even if dismissed
+                Bubble b = mBubbleData.getBubbleWithKey(entry.key);
                 updateBubble(entry);
             }
         }
@@ -540,27 +695,60 @@
             }
 
             // Do removals, if any.
-            for (Pair<Bubble, Integer> removed : update.removedBubbles) {
+            ArrayList<Pair<Bubble, Integer>> removedBubbles =
+                    new ArrayList<>(update.removedBubbles);
+            for (Pair<Bubble, Integer> removed : removedBubbles) {
                 final Bubble bubble = removed.first;
                 @DismissReason final int reason = removed.second;
                 mStackView.removeBubble(bubble);
 
-                if (!mBubbleData.hasBubbleWithKey(bubble.getKey())
-                        && !bubble.entry.showInShadeWhenBubble()) {
-                    // The bubble is gone & the notification is gone, time to actually remove it
-                    mNotificationEntryManager.performRemoveNotification(bubble.entry.notification,
-                            UNDEFINED_DISMISS_REASON);
-                } else {
-                    // Update the flag for SysUI
-                    bubble.entry.notification.getNotification().flags &= ~FLAG_BUBBLE;
+                // If the bubble is removed for user switching, leave the notification in place.
+                if (reason != DISMISS_USER_CHANGED) {
+                    if (!mBubbleData.hasBubbleWithKey(bubble.getKey())
+                            && !bubble.showInShadeWhenBubble()) {
+                        // The bubble is gone & the notification is gone, time to actually remove it
+                        mNotificationEntryManager.performRemoveNotification(
+                                bubble.getEntry().notification, UNDEFINED_DISMISS_REASON);
+                    } else {
+                        // Update the flag for SysUI
+                        bubble.getEntry().notification.getNotification().flags &= ~FLAG_BUBBLE;
 
-                    // Make sure NoMan knows it's not a bubble anymore so anyone querying it will
-                    // get right result back
-                    try {
-                        mBarService.onNotificationBubbleChanged(bubble.getKey(),
-                                false /* isBubble */);
-                    } catch (RemoteException e) {
-                        // Bad things have happened
+                        // Make sure NoMan knows it's not a bubble anymore so anyone querying it
+                        // will get right result back
+                        try {
+                            mBarService.onNotificationBubbleChanged(bubble.getKey(),
+                                    false /* isBubble */);
+                        } catch (RemoteException e) {
+                            // Bad things have happened
+                        }
+                    }
+
+                    // Check if removed bubble has an associated suppressed group summary that needs
+                    // to be removed now.
+                    final String groupKey = bubble.getEntry().notification.getGroupKey();
+                    if (mBubbleData.isSummarySuppressed(groupKey)
+                            && mBubbleData.getBubblesInGroup(groupKey).isEmpty()) {
+                        // Time to actually remove the summary.
+                        String notifKey = mBubbleData.getSummaryKey(groupKey);
+                        mBubbleData.removeSuppressedSummary(groupKey);
+                        NotificationEntry entry =
+                                mNotificationEntryManager.getNotificationData().get(notifKey);
+                        mNotificationEntryManager.performRemoveNotification(
+                                entry.notification, UNDEFINED_DISMISS_REASON);
+                    }
+
+                    // Check if summary should be removed from NoManGroup
+                    NotificationEntry summary = mNotificationGroupManager.getLogicalGroupSummary(
+                            bubble.getEntry().notification);
+                    if (summary != null) {
+                        ArrayList<NotificationEntry> summaryChildren =
+                                mNotificationGroupManager.getLogicalChildren(summary.notification);
+                        boolean isSummaryThisNotif = summary.key.equals(bubble.getEntry().key);
+                        if (!isSummaryThisNotif
+                                && (summaryChildren == null || summaryChildren.isEmpty())) {
+                            mNotificationEntryManager.performRemoveNotification(
+                                    summary.notification, UNDEFINED_DISMISS_REASON);
+                        }
                     }
                 }
             }
@@ -575,6 +763,10 @@
 
             if (update.selectionChanged) {
                 mStackView.setSelectedBubble(update.selectedBubble);
+                if (update.selectedBubble != null) {
+                    mNotificationGroupManager.updateSuppression(
+                            update.selectedBubble.getEntry());
+                }
             }
 
             // Expanding? Apply this last.
@@ -585,7 +777,7 @@
             mNotificationEntryManager.updateNotifications();
             updateStack();
 
-            if (DEBUG) {
+            if (DEBUG_BUBBLE_CONTROLLER) {
                 Log.d(TAG, "[BubbleData]");
                 Log.d(TAG, formatBubblesString(mBubbleData.getBubbles(),
                         mBubbleData.getSelectedBubble()));
@@ -600,34 +792,6 @@
     };
 
     /**
-     * Updates the stack view's suppression flags from the latest config from the zen (do not
-     * disturb) controller.
-     */
-    private void updateStackViewForZenConfig() {
-        final ZenModeConfig zenModeConfig = mZenModeController.getConfig();
-
-        if (zenModeConfig == null || mStackView == null) {
-            return;
-        }
-
-        final int suppressedEffects = zenModeConfig.suppressedVisualEffects;
-        final boolean hideNotificationDotsSelected =
-                (suppressedEffects & SUPPRESSED_EFFECT_BADGE) != 0;
-        final boolean dontPopNotifsOnScreenSelected =
-                (suppressedEffects & SUPPRESSED_EFFECT_PEEK) != 0;
-        final boolean hideFromPullDownShadeSelected =
-                (suppressedEffects & SUPPRESSED_EFFECT_NOTIFICATION_LIST) != 0;
-
-        final boolean dndEnabled = mZenModeController.getZen() != Settings.Global.ZEN_MODE_OFF;
-
-        mStackView.setSuppressNewDot(
-                dndEnabled && hideNotificationDotsSelected);
-        mStackView.setSuppressFlyout(
-                dndEnabled && (dontPopNotifsOnScreenSelected
-                        || hideFromPullDownShadeSelected));
-    }
-
-    /**
      * Lets any listeners know if bubble state has changed.
      * Updates the visibility of the bubbles based on current state.
      * Does not un-bubble, just hides or un-hides. Notifies any
@@ -697,46 +861,16 @@
     }
 
     /**
-     * Whether the notification should automatically bubble or not. Gated by secure settings flags.
+     * Description of current bubble state.
      */
-    @VisibleForTesting
-    protected boolean shouldAutoBubbleForFlags(Context context, NotificationEntry entry) {
-        if (entry.isBubbleDismissed()) {
-            return false;
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("BubbleController state:");
+        mBubbleData.dump(fd, pw, args);
+        pw.println();
+        if (mStackView != null) {
+            mStackView.dump(fd, pw, args);
         }
-        StatusBarNotification n = entry.notification;
-
-        boolean autoBubbleMessages = shouldAutoBubbleMessages(context) || DEBUG_ENABLE_AUTO_BUBBLE;
-        boolean autoBubbleOngoing = shouldAutoBubbleOngoing(context) || DEBUG_ENABLE_AUTO_BUBBLE;
-        boolean autoBubbleAll = shouldAutoBubbleAll(context) || DEBUG_ENABLE_AUTO_BUBBLE;
-
-        boolean hasRemoteInput = false;
-        if (n.getNotification().actions != null) {
-            for (Notification.Action action : n.getNotification().actions) {
-                if (action.getRemoteInputs() != null) {
-                    hasRemoteInput = true;
-                    break;
-                }
-            }
-        }
-        boolean isCall = Notification.CATEGORY_CALL.equals(n.getNotification().category)
-                && n.isOngoing();
-        boolean isMusic = n.getNotification().hasMediaSession();
-        boolean isImportantOngoing = isMusic || isCall;
-
-        Class<? extends Notification.Style> style = n.getNotification().getNotificationStyle();
-        boolean isMessageType = Notification.CATEGORY_MESSAGE.equals(n.getNotification().category);
-        boolean isMessageStyle = Notification.MessagingStyle.class.equals(style);
-        return (((isMessageType && hasRemoteInput) || isMessageStyle) && autoBubbleMessages)
-                || (isImportantOngoing && autoBubbleOngoing)
-                || autoBubbleAll;
-    }
-
-    private void updateShowInShadeForSuppressNotification(NotificationEntry entry) {
-        boolean suppressNotification = entry.getBubbleMetadata() != null
-                && entry.getBubbleMetadata().isNotificationSuppressed()
-                && isForegroundApp(mContext, entry.notification.getPackageName());
-        entry.setShowInShadeWhenBubble(!suppressNotification);
+        pw.println();
     }
 
     static String formatBubblesString(List<Bubble> bubbles, Bubble selected) {
@@ -757,18 +891,6 @@
     }
 
     /**
-     * Return true if the applications with the package name is running in foreground.
-     *
-     * @param context application context.
-     * @param pkgName application package name.
-     */
-    public static boolean isForegroundApp(Context context, String pkgName) {
-        ActivityManager am = context.getSystemService(ActivityManager.class);
-        List<RunningTaskInfo> tasks = am.getRunningTasks(1 /* maxNum */);
-        return !tasks.isEmpty() && pkgName.equals(tasks.get(0).topActivity.getPackageName());
-    }
-
-    /**
      * This task stack listener is responsible for responding to tasks moved to the front
      * which are on the default (main) display. When this happens, expanded bubbles must be
      * collapsed so the user may interact with the app which was just moved to the front.
@@ -782,7 +904,9 @@
         @Override
         public void onTaskMovedToFront(RunningTaskInfo taskInfo) {
             if (mStackView != null && taskInfo.displayId == Display.DEFAULT_DISPLAY) {
-                mBubbleData.setExpanded(false);
+                if (!mStackView.isExpansionAnimating()) {
+                    mBubbleData.setExpanded(false);
+                }
             }
         }
 
@@ -802,31 +926,25 @@
 
         @Override
         public void onSingleTaskDisplayDrawn(int displayId) {
-            final Bubble expandedBubble = getExpandedBubble(mContext);
+            final Bubble expandedBubble = mStackView != null
+                    ? mStackView.getExpandedBubble()
+                    : null;
             if (expandedBubble != null && expandedBubble.getDisplayId() == displayId) {
                 expandedBubble.setContentVisibility(true);
             }
         }
-    }
 
-    private static boolean shouldAutoBubbleMessages(Context context) {
-        return Settings.Secure.getInt(context.getContentResolver(),
-                ENABLE_AUTO_BUBBLE_MESSAGES, 0) != 0;
-    }
-
-    private static boolean shouldAutoBubbleOngoing(Context context) {
-        return Settings.Secure.getInt(context.getContentResolver(),
-                ENABLE_AUTO_BUBBLE_ONGOING, 0) != 0;
-    }
-
-    private static boolean shouldAutoBubbleAll(Context context) {
-        return Settings.Secure.getInt(context.getContentResolver(),
-                ENABLE_AUTO_BUBBLE_ALL, 0) != 0;
-    }
-
-    static boolean shouldUseContentIntent(Context context) {
-        return Settings.Secure.getInt(context.getContentResolver(),
-                ENABLE_BUBBLE_CONTENT_INTENT, 0) != 0;
+        @Override
+        public void onSingleTaskDisplayEmpty(int displayId) {
+            final Bubble expandedBubble = mStackView != null
+                    ? mStackView.getExpandedBubble()
+                    : null;
+            int expandedId = expandedBubble != null ? expandedBubble.getDisplayId() : -1;
+            if (mStackView != null && mStackView.isExpanded() && expandedId == displayId) {
+                mBubbleData.setExpanded(false);
+            }
+            mBubbleData.notifyDisplayEmpty(displayId);
+        }
     }
 
     private static boolean areBubblesEnabled(Context context) {
@@ -834,20 +952,6 @@
                 ENABLE_BUBBLES, 1) != 0;
     }
 
-    /** Default stiffness to use for bubble physics animations. */
-    public static int getBubbleStiffness(Context context, int defaultStiffness) {
-        return Settings.Secure.getInt(
-                context.getContentResolver(), BUBBLE_STIFFNESS, defaultStiffness);
-    }
-
-    /** Default bounciness/damping ratio to use for bubble physics animations. */
-    public static float getBubbleBounciness(Context context, float defaultBounciness) {
-        return Settings.Secure.getInt(
-                context.getContentResolver(),
-                BUBBLE_BOUNCINESS,
-                (int) (defaultBounciness * 100)) / 100f;
-    }
-
     /**
      * Whether an intent is properly configured to display in an {@link android.app.ActivityView}.
      *
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
index 5575b35..eb826e5 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
@@ -16,6 +16,9 @@
 package com.android.systemui.bubbles;
 
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
+import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_DATA;
+import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
+import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
 
 import static java.util.stream.Collectors.toList;
 
@@ -33,11 +36,12 @@
 import com.android.systemui.bubbles.BubbleController.DismissReason;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -51,8 +55,7 @@
 @Singleton
 public class BubbleData {
 
-    private static final String TAG = "BubbleData";
-    private static final boolean DEBUG = false;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleData" : TAG_BUBBLES;
 
     private static final int MAX_BUBBLES = 5;
 
@@ -123,6 +126,19 @@
     @Nullable
     private Listener mListener;
 
+    /**
+     * We track groups with summaries that aren't visibly displayed but still kept around because
+     * the bubble(s) associated with the summary still exist.
+     *
+     * The summary must be kept around so that developers can cancel it (and hence the bubbles
+     * associated with it). This list is used to check if the summary should be hidden from the
+     * shade.
+     *
+     * Key: group key of the NotificationEntry
+     * Value: key of the NotificationEntry
+     */
+    private HashMap<String, String> mSuppressedGroupKeys = new HashMap<>();
+
     @Inject
     public BubbleData(Context context) {
         mContext = context;
@@ -148,7 +164,7 @@
     }
 
     public void setExpanded(boolean expanded) {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_DATA) {
             Log.d(TAG, "setExpanded: " + expanded);
         }
         setExpandedInternal(expanded);
@@ -156,29 +172,30 @@
     }
 
     public void setSelectedBubble(Bubble bubble) {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_DATA) {
             Log.d(TAG, "setSelectedBubble: " + bubble);
         }
         setSelectedBubbleInternal(bubble);
         dispatchPendingChanges();
     }
 
-    public void notificationEntryUpdated(NotificationEntry entry) {
-        if (DEBUG) {
+    void notificationEntryUpdated(NotificationEntry entry, boolean suppressFlyout) {
+        if (DEBUG_BUBBLE_DATA) {
             Log.d(TAG, "notificationEntryUpdated: " + entry);
         }
         Bubble bubble = getBubbleWithKey(entry.key);
         if (bubble == null) {
             // Create a new bubble
-            bubble = new Bubble(mContext, entry, this::onBubbleBlocked);
+            bubble = new Bubble(mContext, entry);
+            bubble.setSuppressFlyout(suppressFlyout);
             doAdd(bubble);
             trim();
         } else {
             // Updates an existing bubble
-            bubble.setEntry(entry);
+            bubble.updateEntry(entry);
             doUpdate(bubble);
         }
-        if (shouldAutoExpand(entry)) {
+        if (bubble.shouldAutoExpand()) {
             setSelectedBubbleInternal(bubble);
             if (!mExpanded) {
                 setExpandedInternal(true);
@@ -186,11 +203,14 @@
         } else if (mSelectedBubble == null) {
             setSelectedBubbleInternal(bubble);
         }
+        boolean isBubbleExpandedAndSelected = mExpanded && mSelectedBubble == bubble;
+        bubble.setShowInShadeWhenBubble(!isBubbleExpandedAndSelected);
+        bubble.setShowBubbleDot(!isBubbleExpandedAndSelected);
         dispatchPendingChanges();
     }
 
     public void notificationEntryRemoved(NotificationEntry entry, @DismissReason int reason) {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_DATA) {
             Log.d(TAG, "notificationEntryRemoved: entry=" + entry + " reason=" + reason);
         }
         doRemove(entry.key, reason);
@@ -222,8 +242,59 @@
         dispatchPendingChanges();
     }
 
+    /**
+     * Adds a group key indicating that the summary for this group should be suppressed.
+     *
+     * @param groupKey the group key of the group whose summary should be suppressed.
+     * @param notifKey the notification entry key of that summary.
+     */
+    void addSummaryToSuppress(String groupKey, String notifKey) {
+        mSuppressedGroupKeys.put(groupKey, notifKey);
+    }
+
+    /**
+     * Retrieves the notif entry key of the summary associated with the provided group key.
+     *
+     * @param groupKey the group to look up
+     * @return the key for the {@link NotificationEntry} that is the summary of this group.
+     */
+    String getSummaryKey(String groupKey) {
+        return mSuppressedGroupKeys.get(groupKey);
+    }
+
+    /**
+     * Removes a group key indicating that summary for this group should no longer be suppressed.
+     */
+    void removeSuppressedSummary(String groupKey) {
+        mSuppressedGroupKeys.remove(groupKey);
+    }
+
+    /**
+     * Whether the summary for the provided group key is suppressed.
+     */
+    boolean isSummarySuppressed(String groupKey) {
+        return mSuppressedGroupKeys.containsKey(groupKey);
+    }
+
+    /**
+     * Retrieves any bubbles that are part of the notification group represented by the provided
+     * group key.
+     */
+    ArrayList<Bubble> getBubblesInGroup(@Nullable String groupKey) {
+        ArrayList<Bubble> bubbleChildren = new ArrayList<>();
+        if (groupKey == null) {
+            return bubbleChildren;
+        }
+        for (Bubble b : mBubbles) {
+            if (groupKey.equals(b.getEntry().notification.getGroupKey())) {
+                bubbleChildren.add(b);
+            }
+        }
+        return bubbleChildren;
+    }
+
     private void doAdd(Bubble bubble) {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_DATA) {
             Log.d(TAG, "doAdd: " + bubble);
         }
         int minInsertPoint = 0;
@@ -256,7 +327,7 @@
     }
 
     private void doUpdate(Bubble bubble) {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_DATA) {
             Log.d(TAG, "doUpdate: " + bubble);
         }
         mStateChange.updatedBubble = bubble;
@@ -301,12 +372,11 @@
             Bubble newSelected = mBubbles.get(newIndex);
             setSelectedBubbleInternal(newSelected);
         }
-        bubbleToRemove.setDismissed();
-        maybeSendDeleteIntent(reason, bubbleToRemove.entry);
+        maybeSendDeleteIntent(reason, bubbleToRemove.getEntry());
     }
 
     public void dismissAll(@DismissReason int reason) {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_DATA) {
             Log.d(TAG, "dismissAll: reason=" + reason);
         }
         if (mBubbles.isEmpty()) {
@@ -316,13 +386,28 @@
         setSelectedBubbleInternal(null);
         while (!mBubbles.isEmpty()) {
             Bubble bubble = mBubbles.remove(0);
-            bubble.setDismissed();
-            maybeSendDeleteIntent(reason, bubble.entry);
+            maybeSendDeleteIntent(reason, bubble.getEntry());
             mStateChange.bubbleRemoved(bubble, reason);
         }
         dispatchPendingChanges();
     }
 
+    /**
+     * Indicates that the provided display is no longer in use and should be cleaned up.
+     *
+     * @param displayId the id of the display to clean up.
+     */
+    void notifyDisplayEmpty(int displayId) {
+        for (Bubble b : mBubbles) {
+            if (b.getDisplayId() == displayId) {
+                if (b.getExpandedView() != null) {
+                    b.getExpandedView().notifyDisplayEmpty();
+                }
+                return;
+            }
+        }
+    }
+
     private void dispatchPendingChanges() {
         if (mListener != null && mStateChange.anythingChanged()) {
             mListener.applyUpdate(mStateChange);
@@ -336,7 +421,7 @@
      * @param bubble the new selected bubble
      */
     private void setSelectedBubbleInternal(@Nullable Bubble bubble) {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_DATA) {
             Log.d(TAG, "setSelectedBubbleInternal: " + bubble);
         }
         if (Objects.equals(bubble, mSelectedBubble)) {
@@ -361,7 +446,7 @@
      * @param shouldExpand the new requested state
      */
     private void setExpandedInternal(boolean shouldExpand) {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_DATA) {
             Log.d(TAG, "setExpandedInternal: shouldExpand=" + shouldExpand);
         }
         if (mExpanded == shouldExpand) {
@@ -396,7 +481,7 @@
                     // bubble remains on top.
                     mBubbles.remove(mSelectedBubble);
                     mBubbles.add(0, mSelectedBubble);
-                    packGroup(0);
+                    mStateChange.orderChanged |= packGroup(0);
                 }
             }
         }
@@ -466,7 +551,7 @@
      * @return true if the position of any bubbles has changed as a result
      */
     private boolean packGroup(int position) {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_DATA) {
             Log.d(TAG, "packGroup: position=" + position);
         }
         Bubble groupStart = mBubbles.get(position);
@@ -495,7 +580,7 @@
      * @return true if the position of any bubbles changed as a result
      */
     private boolean repackAll() {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_DATA) {
             Log.d(TAG, "repackAll()");
         }
         if (mBubbles.isEmpty()) {
@@ -550,28 +635,6 @@
         }
     }
 
-    private void onBubbleBlocked(NotificationEntry entry) {
-        final String blockedGroupId = Bubble.groupId(entry);
-        int selectedIndex = mBubbles.indexOf(mSelectedBubble);
-        for (Iterator<Bubble> i = mBubbles.iterator(); i.hasNext(); ) {
-            Bubble bubble = i.next();
-            if (bubble.getGroupId().equals(blockedGroupId)) {
-                mStateChange.bubbleRemoved(bubble, BubbleController.DISMISS_BLOCKED);
-                i.remove();
-            }
-        }
-        if (mBubbles.isEmpty()) {
-            setExpandedInternal(false);
-            setSelectedBubbleInternal(null);
-        } else if (!mBubbles.contains(mSelectedBubble)) {
-            // choose a new one
-            int newIndex = Math.min(selectedIndex, mBubbles.size() - 1);
-            Bubble newSelected = mBubbles.get(newIndex);
-            setSelectedBubbleInternal(newSelected);
-        }
-        dispatchPendingChanges();
-    }
-
     private int indexForKey(String key) {
         for (int i = 0; i < mBubbles.size(); i++) {
             Bubble bubble = mBubbles.get(i);
@@ -610,9 +673,21 @@
         mListener = listener;
     }
 
-    boolean shouldAutoExpand(NotificationEntry entry) {
-        Notification.BubbleMetadata metadata = entry.getBubbleMetadata();
-        return metadata != null && metadata.getAutoExpandBubble()
-                && BubbleController.isForegroundApp(mContext, entry.notification.getPackageName());
+    /**
+     * Description of current bubble data state.
+     */
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.print("selected: "); pw.println(mSelectedBubble != null
+                ? mSelectedBubble.getKey()
+                : "null");
+        pw.print("expanded: "); pw.println(mExpanded);
+        pw.print("count:    "); pw.println(mBubbles.size());
+        for (Bubble bubble : mBubbles) {
+            bubble.dump(fd, pw, args);
+        }
+        pw.print("summaryKeys: "); pw.println(mSuppressedGroupKeys.size());
+        for (String key : mSuppressedGroupKeys.keySet()) {
+            pw.println("   suppressing: " + key);
+        }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java
new file mode 100644
index 0000000..b702d06
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bubbles;
+
+/**
+ * Common class for the various debug {@link android.util.Log} output configuration in the Bubbles
+ * package.
+ */
+public class BubbleDebugConfig {
+
+    // All output logs in the Bubbles package use the {@link #TAG_BUBBLES} string for tagging their
+    // log output. This makes it easy to identify the origin of the log message when sifting
+    // through a large amount of log output from multiple sources. However, it also makes trying
+    // to figure-out the origin of a log message while debugging the Bubbles a little painful. By
+    // setting this constant to true, log messages from the Bubbles package will be tagged with
+    // their class names instead fot the generic tag.
+    static final boolean TAG_WITH_CLASS_NAME = false;
+
+    // Default log tag for the Bubbles package.
+    static final String TAG_BUBBLES = "Bubbles";
+
+    static final boolean DEBUG_BUBBLE_CONTROLLER = false;
+    static final boolean DEBUG_BUBBLE_DATA = false;
+    static final boolean DEBUG_BUBBLE_STACK_VIEW = false;
+    static final boolean DEBUG_BUBBLE_EXPANDED_VIEW = false;
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDismissView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDismissView.java
index 4db1e27..9db371e 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDismissView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDismissView.java
@@ -16,18 +16,13 @@
 
 package com.android.systemui.bubbles;
 
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-
 import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.animation.AccelerateDecelerateInterpolator;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
-import android.widget.TextView;
 
 import androidx.dynamicanimation.animation.DynamicAnimation;
 import androidx.dynamicanimation.animation.SpringAnimation;
@@ -37,14 +32,13 @@
 
 /** Dismiss view that contains a scrim gradient, as well as a dismiss icon, text, and circle. */
 public class BubbleDismissView extends FrameLayout {
-    /** Duration for animations involving the dismiss target text/icon/gradient. */
+    /** Duration for animations involving the dismiss target text/icon. */
     private static final int DISMISS_TARGET_ANIMATION_BASE_DURATION = 150;
-
-    private View mDismissGradient;
+    private static final float SCALE_FOR_POP = 1.2f;
+    private static final float SCALE_FOR_DISMISS = 0.9f;
 
     private LinearLayout mDismissTarget;
     private ImageView mDismissIcon;
-    private TextView mDismissText;
     private View mDismissCircle;
 
     private SpringAnimation mDismissTargetAlphaSpring;
@@ -54,36 +48,15 @@
         super(context);
         setVisibility(GONE);
 
-        mDismissGradient = new FrameLayout(mContext);
-
-        FrameLayout.LayoutParams gradientParams =
-                new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
-        gradientParams.gravity = Gravity.BOTTOM;
-        mDismissGradient.setLayoutParams(gradientParams);
-
-        Drawable gradient = mContext.getResources().getDrawable(R.drawable.pip_dismiss_scrim);
-        gradient.setAlpha((int) (255 * 0.85f));
-        mDismissGradient.setBackground(gradient);
-
-        mDismissGradient.setVisibility(GONE);
-        addView(mDismissGradient);
-
         LayoutInflater.from(context).inflate(R.layout.bubble_dismiss_target, this, true);
         mDismissTarget = findViewById(R.id.bubble_dismiss_icon_container);
         mDismissIcon = findViewById(R.id.bubble_dismiss_close_icon);
-        mDismissText = findViewById(R.id.bubble_dismiss_text);
         mDismissCircle = findViewById(R.id.bubble_dismiss_circle);
 
         // Set up the basic target area animations. These are very simple animations that don't need
         // fancy interpolators.
         final AccelerateDecelerateInterpolator interpolator =
                 new AccelerateDecelerateInterpolator();
-        mDismissGradient.animate()
-                .setDuration(DISMISS_TARGET_ANIMATION_BASE_DURATION)
-                .setInterpolator(interpolator);
-        mDismissText.animate()
-                .setDuration(DISMISS_TARGET_ANIMATION_BASE_DURATION)
-                .setInterpolator(interpolator);
         mDismissIcon.animate()
                 .setDuration(DISMISS_TARGET_ANIMATION_BASE_DURATION)
                 .setInterpolator(interpolator);
@@ -108,110 +81,58 @@
             // safely assume it was animating out rather than in.
             if (alpha < 0.5f) {
                 // If the alpha spring was animating the view out, set it to GONE when it's done.
-                setVisibility(GONE);
+                setVisibility(INVISIBLE);
             }
         });
     }
 
-    /** Springs in the dismiss target and fades in the gradient. */
+    /** Springs in the dismiss target. */
     void springIn() {
         setVisibility(View.VISIBLE);
 
-        // Fade in the dismiss target (icon + text).
+        // Fade in the dismiss target icon.
+        mDismissIcon.animate()
+                .setDuration(50)
+                .scaleX(1f)
+                .scaleY(1f)
+                .alpha(1f);
         mDismissTarget.setAlpha(0f);
         mDismissTargetAlphaSpring.animateToFinalPosition(1f);
 
-        // Spring up the dismiss target (icon + text).
+        // Spring up the dismiss target.
         mDismissTarget.setTranslationY(mDismissTarget.getHeight() / 2f);
         mDismissTargetVerticalSpring.animateToFinalPosition(0);
 
-        // Fade in the gradient.
-        mDismissGradient.setVisibility(VISIBLE);
-        mDismissGradient.animate().alpha(1f);
+        mDismissCircle.setAlpha(0f);
+        mDismissCircle.setScaleX(SCALE_FOR_POP);
+        mDismissCircle.setScaleY(SCALE_FOR_POP);
 
-        // Make sure the dismiss elements are in the separated position (in case we hid the target
-        // while they were condensed to cover the bubbles being in the target).
-        mDismissIcon.setAlpha(1f);
-        mDismissIcon.setScaleX(1f);
-        mDismissIcon.setScaleY(1f);
-        mDismissIcon.setTranslationX(0f);
-        mDismissText.setAlpha(1f);
-        mDismissText.setTranslationX(0f);
+        // Fade in circle and reduce size.
+        mDismissCircle.animate()
+                .alpha(1f)
+                .scaleX(1f)
+                .scaleY(1f);
     }
 
-    /** Springs out the dismiss target and fades out the gradient. */
+    /** Springs out the dismiss target. */
     void springOut() {
+        // Fade out the target icon.
+        mDismissIcon.animate()
+                .setDuration(50)
+                .scaleX(SCALE_FOR_DISMISS)
+                .scaleY(SCALE_FOR_DISMISS)
+                .alpha(0f);
+
         // Fade out the target.
         mDismissTargetAlphaSpring.animateToFinalPosition(0f);
 
         // Spring the target down a bit.
         mDismissTargetVerticalSpring.animateToFinalPosition(mDismissTarget.getHeight() / 2f);
 
-        // Fade out the gradient and then set it to GONE so it's not in the SBV hierarchy.
-        mDismissGradient.animate().alpha(0f).withEndAction(
-                () -> mDismissGradient.setVisibility(GONE));
-
-        // Pop out the dismiss circle.
-        mDismissCircle.animate().alpha(0f).scaleX(1.2f).scaleY(1.2f);
-    }
-
-    /**
-     * Encircles the center of the dismiss target, pulling the X towards the center and hiding the
-     * text.
-     */
-    void animateEncircleCenterWithX(boolean encircle) {
-        // Pull the text towards the center if we're encircling (it'll be faded out, leaving only
-        // the X icon over the bubbles), or back to normal if we're un-encircling.
-        final float textTranslation = encircle
-                ? -mDismissIcon.getWidth() / 4f
-                : 0f;
-
-        // Center the icon if we're encircling, or put it back to normal if not.
-        final float iconTranslation = encircle
-                ? mDismissTarget.getWidth() / 2f
-                - mDismissIcon.getWidth() / 2f
-                - mDismissIcon.getLeft()
-                : 0f;
-
-        // Fade in/out the text and translate it.
-        mDismissText.animate()
-                .alpha(encircle ? 0f : 1f)
-                .translationX(textTranslation);
-
-        mDismissIcon.animate()
-                .setDuration(150)
-                .translationX(iconTranslation);
-
-        // Fade out the gradient if we're encircling (the bubbles will 'absorb' it by darkening
-        // themselves).
-        mDismissGradient.animate()
-                .alpha(encircle ? 0f : 1f);
-
-        // Prepare the circle to be 'dropped in'.
-        if (encircle) {
-            mDismissCircle.setAlpha(0f);
-            mDismissCircle.setScaleX(1.2f);
-            mDismissCircle.setScaleY(1.2f);
-        }
-
-        // Drop in the circle, or pull it back up.
+        // Pop out the circle.
         mDismissCircle.animate()
-                .alpha(encircle ? 1f : 0f)
-                .scaleX(encircle ? 1f : 0f)
-                .scaleY(encircle ? 1f : 0f);
-    }
-
-    /** Animates the circle and the centered icon out. */
-    void animateEncirclingCircleDisappearance() {
-        // Pop out the dismiss icon and circle.
-        mDismissIcon.animate()
-                .setDuration(50)
-                .scaleX(0.9f)
-                .scaleY(0.9f)
-                .alpha(0f);
-        mDismissCircle.animate()
-                .scaleX(0.9f)
-                .scaleY(0.9f)
+                .scaleX(SCALE_FOR_DISMISS)
+                .scaleY(SCALE_FOR_DISMISS)
                 .alpha(0f);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index 923ca20..521ebde 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -18,14 +18,15 @@
 
 import static android.view.Display.INVALID_DISPLAY;
 
-import static com.android.systemui.bubbles.BubbleController.DEBUG_ENABLE_AUTO_BUBBLE;
+import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_EXPANDED_VIEW;
+import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
+import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
 
-import android.annotation.Nullable;
 import android.app.ActivityOptions;
+import android.app.ActivityTaskManager;
 import android.app.ActivityView;
-import android.app.INotificationManager;
-import android.app.Notification;
 import android.app.PendingIntent;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
@@ -35,18 +36,17 @@
 import android.graphics.Color;
 import android.graphics.Insets;
 import android.graphics.Point;
+import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.ShapeDrawable;
-import android.os.ServiceManager;
-import android.os.UserHandle;
-import android.provider.Settings;
+import android.os.RemoteException;
 import android.service.notification.StatusBarNotification;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.StatsLog;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.WindowInsets;
+import android.view.WindowManager;
 import android.widget.LinearLayout;
 
 import com.android.internal.policy.ScreenDecorationsUtils;
@@ -54,15 +54,23 @@
 import com.android.systemui.R;
 import com.android.systemui.recents.TriangleShape;
 import com.android.systemui.statusbar.AlphaOptimizedButton;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
 
 /**
  * Container for the expanded bubble view, handles rendering the caret and settings icon.
  */
 public class BubbleExpandedView extends LinearLayout implements View.OnClickListener {
-    private static final String TAG = "BubbleExpandedView";
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleExpandedView" : TAG_BUBBLES;
+
+    private enum ActivityViewStatus {
+        // ActivityView is being initialized, cannot start an activity yet.
+        INITIALIZING,
+        // ActivityView is initialized, and ready to start an activity.
+        INITIALIZED,
+        // Activity runs in the ActivityView.
+        ACTIVITY_STARTED,
+        // ActivityView is released, so activity launching will no longer be permitted.
+        RELEASED,
+    }
 
     // The triangle pointing to the expanded view
     private View mPointerView;
@@ -71,50 +79,90 @@
     private AlphaOptimizedButton mSettingsIcon;
 
     // Views for expanded state
-    private ExpandableNotificationRow mNotifRow;
     private ActivityView mActivityView;
 
-    private boolean mActivityViewReady = false;
+    private ActivityViewStatus mActivityViewStatus = ActivityViewStatus.INITIALIZING;
+    private int mTaskId = -1;
+
     private PendingIntent mBubbleIntent;
 
     private boolean mKeyboardVisible;
     private boolean mNeedsNewHeight;
 
+    private Point mDisplaySize;
     private int mMinHeight;
     private int mSettingsIconHeight;
-    private int mBubbleHeight;
     private int mPointerWidth;
     private int mPointerHeight;
     private ShapeDrawable mPointerDrawable;
+    private Rect mTempRect = new Rect();
+    private int[] mTempLoc = new int[2];
+    private int mExpandedViewTouchSlop;
 
-    private NotificationEntry mEntry;
+    private Bubble mBubble;
     private PackageManager mPm;
     private String mAppName;
     private Drawable mAppIcon;
 
-    private INotificationManager mNotificationManagerService;
     private BubbleController mBubbleController = Dependency.get(BubbleController.class);
+    private WindowManager mWindowManager;
 
     private BubbleStackView mStackView;
 
-    private BubbleExpandedView.OnBubbleBlockedListener mOnBubbleBlockedListener;
-
     private ActivityView.StateCallback mStateCallback = new ActivityView.StateCallback() {
         @Override
         public void onActivityViewReady(ActivityView view) {
-            if (!mActivityViewReady) {
-                mActivityViewReady = true;
-                // Custom options so there is no activity transition animation
-                ActivityOptions options = ActivityOptions.makeCustomAnimation(getContext(),
-                        0 /* enterResId */, 0 /* exitResId */);
-                // Post to keep the lifecycle normal
-                post(() -> mActivityView.startActivity(mBubbleIntent, options));
+            if (DEBUG_BUBBLE_EXPANDED_VIEW) {
+                Log.d(TAG, "onActivityViewReady: mActivityViewStatus=" + mActivityViewStatus
+                        + " bubble=" + getBubbleKey());
+            }
+            switch (mActivityViewStatus) {
+                case INITIALIZING:
+                case INITIALIZED:
+                    // Custom options so there is no activity transition animation
+                    ActivityOptions options = ActivityOptions.makeCustomAnimation(getContext(),
+                            0 /* enterResId */, 0 /* exitResId */);
+                    // Post to keep the lifecycle normal
+                    post(() -> {
+                        if (DEBUG_BUBBLE_EXPANDED_VIEW) {
+                            Log.d(TAG, "onActivityViewReady: calling startActivity, "
+                                    + "bubble=" + getBubbleKey());
+                        }
+                        try {
+                            mActivityView.startActivity(mBubbleIntent, options);
+                        } catch (RuntimeException e) {
+                            // If there's a runtime exception here then there's something
+                            // wrong with the intent, we can't really recover / try to populate
+                            // the bubble again so we'll just remove it.
+                            Log.w(TAG, "Exception while displaying bubble: " + getBubbleKey()
+                                    + ", " + e.getMessage() + "; removing bubble");
+                            mBubbleController.removeBubble(mBubble.getKey(),
+                                    BubbleController.DISMISS_INVALID_INTENT);
+                        }
+                    });
+                    mActivityViewStatus = ActivityViewStatus.ACTIVITY_STARTED;
             }
         }
 
         @Override
         public void onActivityViewDestroyed(ActivityView view) {
-            mActivityViewReady = false;
+            if (DEBUG_BUBBLE_EXPANDED_VIEW) {
+                Log.d(TAG, "onActivityViewDestroyed: mActivityViewStatus=" + mActivityViewStatus
+                        + " bubble=" + getBubbleKey());
+            }
+            mActivityViewStatus = ActivityViewStatus.RELEASED;
+        }
+
+        @Override
+        public void onTaskCreated(int taskId, ComponentName componentName) {
+            if (DEBUG_BUBBLE_EXPANDED_VIEW) {
+                Log.d(TAG, "onTaskCreated: taskId=" + taskId
+                        + " bubble=" + getBubbleKey());
+            }
+            // Since Bubble ActivityView applies singleTaskDisplay this is
+            // guaranteed to only be called once per ActivityView. The taskId is
+            // saved to use for removeTask, preventing appearance in recent tasks.
+            mTaskId = taskId;
         }
 
         /**
@@ -125,9 +173,14 @@
          */
         @Override
         public void onTaskRemovalStarted(int taskId) {
-            if (mEntry != null) {
+            if (DEBUG_BUBBLE_EXPANDED_VIEW) {
+                Log.d(TAG, "onTaskRemovalStarted: taskId=" + taskId
+                        + " mActivityViewStatus=" + mActivityViewStatus
+                        + " bubble=" + getBubbleKey());
+            }
+            if (mBubble != null) {
                 // Must post because this is called from a binder thread.
-                post(() -> mBubbleController.removeBubble(mEntry.key,
+                post(() -> mBubbleController.removeBubble(mBubble.getKey(),
                         BubbleController.DISMISS_TASK_FINISHED));
             }
         }
@@ -149,20 +202,22 @@
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
         mPm = context.getPackageManager();
-        mMinHeight = getResources().getDimensionPixelSize(
-                R.dimen.bubble_expanded_default_height);
-        mPointerMargin = getResources().getDimensionPixelSize(R.dimen.bubble_pointer_margin);
-        try {
-            mNotificationManagerService = INotificationManager.Stub.asInterface(
-                    ServiceManager.getServiceOrThrow(Context.NOTIFICATION_SERVICE));
-        } catch (ServiceManager.ServiceNotFoundException e) {
-            Log.w(TAG, e);
-        }
+        mDisplaySize = new Point();
+        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+        // Get the real size -- this includes screen decorations (notches, statusbar, navbar).
+        mWindowManager.getDefaultDisplay().getRealSize(mDisplaySize);
+        Resources res = getResources();
+        mMinHeight = res.getDimensionPixelSize(R.dimen.bubble_expanded_default_height);
+        mPointerMargin = res.getDimensionPixelSize(R.dimen.bubble_pointer_margin);
+        mExpandedViewTouchSlop = res.getDimensionPixelSize(R.dimen.bubble_expanded_view_slop);
     }
 
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
+        if (DEBUG_BUBBLE_EXPANDED_VIEW) {
+            Log.d(TAG, "onFinishInflate: bubble=" + getBubbleKey());
+        }
 
         Resources res = getResources();
         mPointerView = findViewById(R.id.pointer_view);
@@ -173,16 +228,16 @@
         mPointerDrawable = new ShapeDrawable(TriangleShape.create(
                 mPointerWidth, mPointerHeight, true /* pointUp */));
         mPointerView.setBackground(mPointerDrawable);
-        mPointerView.setVisibility(GONE);
+        mPointerView.setVisibility(INVISIBLE);
 
         mSettingsIconHeight = getContext().getResources().getDimensionPixelSize(
-                R.dimen.bubble_expanded_header_height);
+                R.dimen.bubble_settings_size);
         mSettingsIcon = findViewById(R.id.settings_button);
         mSettingsIcon.setOnClickListener(this);
 
         mActivityView = new ActivityView(mContext, null /* attrs */, 0 /* defStyle */,
                 true /* singleTaskInstance */);
-
+        // Set ActivityView's alpha value as zero, since there is no view content to be shown.
         setContentVisibility(false);
         addView(mActivityView);
 
@@ -210,6 +265,10 @@
         });
     }
 
+    private String getBubbleKey() {
+        return mBubble != null ? mBubble.getKey() : "null";
+    }
+
     void applyThemeAttrs() {
         TypedArray ta = getContext().obtainStyledAttributes(R.styleable.BubbleExpandedView);
         int bgColor = ta.getColor(
@@ -235,6 +294,9 @@
         if (mActivityView != null) {
             mActivityView.setForwardedInsets(Insets.of(0, 0, 0, 0));
         }
+        if (DEBUG_BUBBLE_EXPANDED_VIEW) {
+            Log.d(TAG, "onDetachedFromWindow: bubble=" + getBubbleKey());
+        }
     }
 
     /**
@@ -246,6 +308,10 @@
      * and setting {@code false} actually means rendering the contents in transparent.
      */
     void setContentVisibility(boolean visibility) {
+        if (DEBUG_BUBBLE_EXPANDED_VIEW) {
+            Log.d(TAG, "setContentVisibility: visibility=" + visibility
+                    + " bubble=" + getBubbleKey());
+        }
         final float alpha = visibility ? 1f : 0f;
         mPointerView.setAlpha(alpha);
         if (mActivityView != null) {
@@ -259,44 +325,37 @@
      */
     void updateInsets(WindowInsets insets) {
         if (usingActivityView()) {
-            Point displaySize = new Point();
-            mActivityView.getContext().getDisplay().getSize(displaySize);
-            int[] windowLocation = mActivityView.getLocationOnScreen();
-            final int windowBottom = windowLocation[1] + mActivityView.getHeight();
-            final int keyboardHeight = insets.getSystemWindowInsetBottom()
-                    - insets.getStableInsetBottom();
-            final int insetsBottom = Math.max(0,
-                    windowBottom + keyboardHeight - displaySize.y);
+            int[] screenLoc = mActivityView.getLocationOnScreen();
+            final int activityViewBottom = screenLoc[1] + mActivityView.getHeight();
+            final int keyboardTop = mDisplaySize.y - Math.max(insets.getSystemWindowInsetBottom(),
+                    insets.getDisplayCutout() != null
+                            ? insets.getDisplayCutout().getSafeInsetBottom()
+                            : 0);
+            final int insetsBottom = Math.max(activityViewBottom - keyboardTop, 0);
             mActivityView.setForwardedInsets(Insets.of(0, 0, 0, insetsBottom));
         }
     }
 
     /**
-     * Sets the listener to notify when a bubble has been blocked.
+     * Sets the bubble used to populate this view.
      */
-    public void setOnBlockedListener(OnBubbleBlockedListener listener) {
-        mOnBubbleBlockedListener = listener;
-    }
+    public void setBubble(Bubble bubble, BubbleStackView stackView, String appName) {
+        if (DEBUG_BUBBLE_EXPANDED_VIEW) {
+            Log.d(TAG, "setBubble: bubble=" + (bubble != null ? bubble.getKey() : "null"));
+        }
 
-    /**
-     * Sets the notification entry used to populate this view.
-     */
-    public void setEntry(NotificationEntry entry, BubbleStackView stackView, String appName) {
         mStackView = stackView;
-        mEntry = entry;
+        mBubble = bubble;
         mAppName = appName;
 
-        ApplicationInfo info;
         try {
-            info = mPm.getApplicationInfo(
-                    entry.notification.getPackageName(),
+            ApplicationInfo info = mPm.getApplicationInfo(
+                    bubble.getPackageName(),
                     PackageManager.MATCH_UNINSTALLED_PACKAGES
                             | PackageManager.MATCH_DISABLED_COMPONENTS
                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
                             | PackageManager.MATCH_DIRECT_BOOT_AWARE);
-            if (info != null) {
-                mAppIcon = mPm.getApplicationIcon(info);
-            }
+            mAppIcon = mPm.getApplicationIcon(info);
         } catch (PackageManager.NameNotFoundException e) {
             // Do nothing.
         }
@@ -312,52 +371,46 @@
      * Lets activity view know it should be shown / populated.
      */
     public void populateExpandedView() {
+        if (DEBUG_BUBBLE_EXPANDED_VIEW) {
+            Log.d(TAG, "populateExpandedView: "
+                    + "bubble=" + getBubbleKey());
+        }
+
         if (usingActivityView()) {
             mActivityView.setCallback(mStateCallback);
         } else {
-            // We're using notification template
-            ViewGroup parent = (ViewGroup) mNotifRow.getParent();
-            if (parent == this) {
-                // Already added
-                return;
-            } else if (parent != null) {
-                // Still in the shade... remove it
-                parent.removeView(mNotifRow);
-            }
-            addView(mNotifRow, 1 /* index */);
-            mPointerView.setAlpha(1f);
+            Log.e(TAG, "Cannot populate expanded view.");
         }
     }
 
     /**
-     * Updates the entry backing this view. This will not re-populate ActivityView, it will
+     * Updates the bubble backing this view. This will not re-populate ActivityView, it will
      * only update the deep-links in the title, and the height of the view.
      */
-    public void update(NotificationEntry entry) {
-        if (entry.key.equals(mEntry.key)) {
-            mEntry = entry;
+    public void update(Bubble bubble) {
+        if (DEBUG_BUBBLE_EXPANDED_VIEW) {
+            Log.d(TAG, "update: bubble=" + (bubble != null ? bubble.getKey() : "null"));
+        }
+        if (bubble.getKey().equals(mBubble.getKey())) {
+            mBubble = bubble;
             updateSettingsContentDescription();
             updateHeight();
         } else {
-            Log.w(TAG, "Trying to update entry with different key, new entry: "
-                    + entry.key + " old entry: " + mEntry.key);
+            Log.w(TAG, "Trying to update entry with different key, new bubble: "
+                    + bubble.getKey() + " old bubble: " + bubble.getKey());
         }
     }
 
     private void updateExpandedView() {
-        mBubbleIntent = getBubbleIntent(mEntry);
+        if (DEBUG_BUBBLE_EXPANDED_VIEW) {
+            Log.d(TAG, "updateExpandedView: bubble="
+                    + getBubbleKey());
+        }
+
+        mBubbleIntent = mBubble.getBubbleIntent(mContext);
         if (mBubbleIntent != null) {
-            if (mNotifRow != null) {
-                // Clear out the row if we had it previously
-                removeView(mNotifRow);
-                mNotifRow = null;
-            }
             setContentVisibility(false);
             mActivityView.setVisibility(VISIBLE);
-        } else if (DEBUG_ENABLE_AUTO_BUBBLE) {
-            // Hide activity view if we had it previously
-            mActivityView.setVisibility(GONE);
-            mNotifRow = mEntry.getRow();
         }
         updateView();
     }
@@ -371,29 +424,12 @@
     }
 
     void updateHeight() {
+        if (DEBUG_BUBBLE_EXPANDED_VIEW) {
+            Log.d(TAG, "updateHeight: bubble=" + getBubbleKey());
+        }
         if (usingActivityView()) {
-            Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
-            float desiredHeight;
-            if (data == null) {
-                // This is a contentIntent based bubble, lets allow it to be the max height
-                // as it was forced into this mode and not prepared to be small
-                desiredHeight = mStackView.getMaxExpandedHeight();
-            } else {
-                boolean useRes = data.getDesiredHeightResId() != 0;
-                float desiredPx;
-                if (useRes) {
-                    desiredPx = getDimenForPackageUser(data.getDesiredHeightResId(),
-                            mEntry.notification.getPackageName(),
-                            mEntry.notification.getUser().getIdentifier());
-                } else {
-                    desiredPx = data.getDesiredHeight()
-                            * getContext().getResources().getDisplayMetrics().density;
-                }
-                desiredHeight = desiredPx > 0 ? desiredPx : mMinHeight;
-            }
-            int max = mStackView.getMaxExpandedHeight() - mSettingsIconHeight - mPointerHeight
-                    - mPointerMargin;
-            float height = Math.min(desiredHeight, max);
+            float desiredHeight = Math.max(mBubble.getDesiredHeight(mContext), mMinHeight);
+            float height = Math.min(desiredHeight, getMaxExpandedHeight());
             height = Math.max(height, mMinHeight);
             LayoutParams lp = (LayoutParams) mActivityView.getLayoutParams();
             mNeedsNewHeight =  lp.height != height;
@@ -401,28 +437,66 @@
                 // If the keyboard is visible... don't adjust the height because that will cause
                 // a configuration change and the keyboard will be lost.
                 lp.height = (int) height;
-                mBubbleHeight = (int) height;
                 mActivityView.setLayoutParams(lp);
                 mNeedsNewHeight = false;
             }
-        } else {
-            mBubbleHeight = mNotifRow != null ? mNotifRow.getIntrinsicHeight() : mMinHeight;
+            if (DEBUG_BUBBLE_EXPANDED_VIEW) {
+                Log.d(TAG, "updateHeight: bubble=" + getBubbleKey() + " height=" + height
+                        + " mNeedsNewHeight=" + mNeedsNewHeight);
+            }
         }
     }
 
+    private int getMaxExpandedHeight() {
+        mWindowManager.getDefaultDisplay().getRealSize(mDisplaySize);
+        int[] windowLocation = mActivityView.getLocationOnScreen();
+        int bottomInset = getRootWindowInsets() != null
+                ? getRootWindowInsets().getStableInsetBottom()
+                : 0;
+        return mDisplaySize.y - windowLocation[1] - mSettingsIconHeight - mPointerHeight
+                - mPointerMargin - bottomInset;
+    }
+
+    /**
+     * Whether the provided x, y values (in raw coordinates) are in a touchable area of the
+     * expanded view.
+     *
+     * The touchable areas are the ActivityView (plus some slop around it) and the manage button.
+     */
+    boolean intersectingTouchableContent(int rawX, int rawY) {
+        mTempRect.setEmpty();
+        if (mActivityView != null) {
+            mTempLoc = mActivityView.getLocationOnScreen();
+            mTempRect.set(mTempLoc[0] - mExpandedViewTouchSlop,
+                    mTempLoc[1] - mExpandedViewTouchSlop,
+                    mTempLoc[0] + mActivityView.getWidth() + mExpandedViewTouchSlop,
+                    mTempLoc[1] + mActivityView.getHeight() + mExpandedViewTouchSlop);
+        }
+        if (mTempRect.contains(rawX, rawY)) {
+            return true;
+        }
+        mTempLoc = mSettingsIcon.getLocationOnScreen();
+        mTempRect.set(mTempLoc[0],
+                mTempLoc[1],
+                mTempLoc[0] + mSettingsIcon.getWidth(),
+                mTempLoc[1] + mSettingsIcon.getHeight());
+        if (mTempRect.contains(rawX, rawY)) {
+            return true;
+        }
+        return false;
+    }
+
     @Override
     public void onClick(View view) {
-        if (mEntry == null) {
+        if (mBubble == null) {
             return;
         }
-        Notification n = mEntry.notification.getNotification();
         int id = view.getId();
         if (id == R.id.settings_button) {
-            Intent intent = getSettingsIntent(mEntry.notification.getPackageName(),
-                    mEntry.notification.getUid());
+            Intent intent = mBubble.getSettingsIntent();
             mStackView.collapseStack(() -> {
-                mContext.startActivityAsUser(intent, mEntry.notification.getUser());
-                logBubbleClickEvent(mEntry,
+                mContext.startActivityAsUser(intent, mBubble.getEntry().notification.getUser());
+                logBubbleClickEvent(mBubble,
                         StatsLog.BUBBLE_UICHANGED__ACTION__HEADER_GO_TO_SETTINGS);
             });
         }
@@ -442,13 +516,14 @@
      * Update appearance of the expanded view being displayed.
      */
     public void updateView() {
+        if (DEBUG_BUBBLE_EXPANDED_VIEW) {
+            Log.d(TAG, "updateView: bubble="
+                    + getBubbleKey());
+        }
         if (usingActivityView()
                 && mActivityView.getVisibility() == VISIBLE
                 && mActivityView.isAttachedToWindow()) {
             mActivityView.onLocationChanged();
-        } else if (mNotifRow != null) {
-            applyRowState(mNotifRow);
-            mPointerView.setAlpha(1f);
         }
         updateHeight();
     }
@@ -467,17 +542,44 @@
      * Removes and releases an ActivityView if one was previously created for this bubble.
      */
     public void cleanUpExpandedState() {
-        removeView(mNotifRow);
-
+        if (DEBUG_BUBBLE_EXPANDED_VIEW) {
+            Log.d(TAG, "cleanUpExpandedState: mActivityViewStatus=" + mActivityViewStatus
+                    + ", bubble=" + getBubbleKey());
+        }
         if (mActivityView == null) {
             return;
         }
-        if (mActivityViewReady) {
-            mActivityView.release();
+        switch (mActivityViewStatus) {
+            case INITIALIZED:
+            case ACTIVITY_STARTED:
+                mActivityView.release();
+        }
+        if (mTaskId != -1) {
+            try {
+                ActivityTaskManager.getService().removeTask(mTaskId);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed to remove taskId " + mTaskId);
+            }
+            mTaskId = -1;
         }
         removeView(mActivityView);
+
         mActivityView = null;
-        mActivityViewReady = false;
+    }
+
+    /**
+     * Called when the last task is removed from a {@link android.hardware.display.VirtualDisplay}
+     * which {@link ActivityView} uses.
+     */
+    void notifyDisplayEmpty() {
+        if (DEBUG_BUBBLE_EXPANDED_VIEW) {
+            Log.d(TAG, "notifyDisplayEmpty: bubble="
+                    + getBubbleKey()
+                    + " mActivityViewStatus=" + mActivityViewStatus);
+        }
+        if (mActivityViewStatus == ActivityViewStatus.ACTIVITY_STARTED) {
+            mActivityViewStatus = ActivityViewStatus.INITIALIZED;
+        }
     }
 
     private boolean usingActivityView() {
@@ -494,76 +596,14 @@
         return INVALID_DISPLAY;
     }
 
-    private void applyRowState(ExpandableNotificationRow view) {
-        view.reset();
-        view.setHeadsUp(false);
-        view.resetTranslation();
-        view.setOnKeyguard(false);
-        view.setClipBottomAmount(0);
-        view.setClipTopAmount(0);
-        view.setContentTransformationAmount(0, false);
-        view.setIconsVisible(true);
-
-        // TODO - Need to reset this (and others) when view goes back in shade, leave for now
-        // view.setTopRoundness(1, false);
-        // view.setBottomRoundness(1, false);
-
-        ExpandableViewState viewState = view.getViewState();
-        viewState = viewState == null ? new ExpandableViewState() : viewState;
-        viewState.height = view.getIntrinsicHeight();
-        viewState.gone = false;
-        viewState.hidden = false;
-        viewState.dimmed = false;
-        viewState.alpha = 1f;
-        viewState.notGoneIndex = -1;
-        viewState.xTranslation = 0;
-        viewState.yTranslation = 0;
-        viewState.zTranslation = 0;
-        viewState.scaleX = 1;
-        viewState.scaleY = 1;
-        viewState.inShelf = true;
-        viewState.headsUpIsVisible = false;
-        viewState.applyToView(view);
-    }
-
-    private Intent getSettingsIntent(String packageName, final int appUid) {
-        final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_BUBBLE_SETTINGS);
-        intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName);
-        intent.putExtra(Settings.EXTRA_APP_UID, appUid);
-        intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
-        return intent;
-    }
-
-    @Nullable
-    private PendingIntent getBubbleIntent(NotificationEntry entry) {
-        Notification notif = entry.notification.getNotification();
-        Notification.BubbleMetadata data = notif.getBubbleMetadata();
-        if (BubbleController.canLaunchInActivityView(mContext, entry) && data != null) {
-            return data.getIntent();
-        }
-        return null;
-    }
-
-    /**
-     * Listener that is notified when a bubble is blocked.
-     */
-    public interface OnBubbleBlockedListener {
-        /**
-         * Called when a bubble is blocked for the provided entry.
-         */
-        void onBubbleBlocked(NotificationEntry entry);
-    }
-
     /**
      * Logs bubble UI click event.
      *
-     * @param entry the bubble notification entry that user is interacting with.
+     * @param bubble the bubble notification entry that user is interacting with.
      * @param action the user interaction enum.
      */
-    private void logBubbleClickEvent(NotificationEntry entry, int action) {
-        StatusBarNotification notification = entry.notification;
+    private void logBubbleClickEvent(Bubble bubble, int action) {
+        StatusBarNotification notification = bubble.getEntry().notification;
         StatsLog.write(StatsLog.BUBBLE_UI_CHANGED,
                 notification.getPackageName(),
                 notification.getNotification().getChannelId(),
@@ -573,27 +613,8 @@
                 action,
                 mStackView.getNormalizedXPosition(),
                 mStackView.getNormalizedYPosition(),
-                entry.showInShadeWhenBubble(),
-                entry.isForegroundService(),
-                BubbleController.isForegroundApp(mContext, notification.getPackageName()));
-    }
-
-    private int getDimenForPackageUser(int resId, String pkg, int userId) {
-        Resources r;
-        if (pkg != null) {
-            try {
-                if (userId == UserHandle.USER_ALL) {
-                    userId = UserHandle.USER_SYSTEM;
-                }
-                r = mPm.getResourcesForApplicationAsUser(pkg, userId);
-                return r.getDimensionPixelSize(resId);
-            } catch (PackageManager.NameNotFoundException ex) {
-                // Uninstalled, don't care
-            } catch (Resources.NotFoundException e) {
-                // Invalid res id, return 0 and user our default
-                Log.e(TAG, "Couldn't find desired height res id", e);
-            }
-        }
-        return 0;
+                bubble.showInShadeWhenBubble(),
+                bubble.isOngoing(),
+                false /* isAppForeground (unused) */);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleFlyoutView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleFlyoutView.java
index 71f68c1..58f3f22 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleFlyoutView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleFlyoutView.java
@@ -39,8 +39,7 @@
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
-import androidx.dynamicanimation.animation.DynamicAnimation;
-import androidx.dynamicanimation.animation.SpringAnimation;
+import androidx.annotation.Nullable;
 
 import com.android.systemui.R;
 import com.android.systemui.recents.TriangleShape;
@@ -57,6 +56,9 @@
     private final int mFlyoutSpaceFromBubble;
     private final int mPointerSize;
     private final int mBubbleSize;
+    private final int mBubbleIconBitmapSize;
+    private final float mBubbleIconTopPadding;
+
     private final int mFlyoutElevation;
     private final int mBubbleElevation;
     private final int mFloatingBackgroundColor;
@@ -64,14 +66,11 @@
 
     private final ViewGroup mFlyoutTextContainer;
     private final TextView mFlyoutText;
-    /** Spring animation for the flyout. */
-    private final SpringAnimation mFlyoutSpring =
-            new SpringAnimation(this, DynamicAnimation.TRANSLATION_X);
 
     /** Values related to the 'new' dot which we use to figure out where to collapse the flyout. */
     private final float mNewDotRadius;
     private final float mNewDotSize;
-    private final float mNewDotOffsetFromBubbleBounds;
+    private final float mOriginalDotSize;
 
     /**
      * The paint used to draw the background, whose color changes as the flyout transitions to the
@@ -113,7 +112,6 @@
      */
     private float mFlyoutToDotWidthDelta = 0f;
     private float mFlyoutToDotHeightDelta = 0f;
-    private float mFlyoutToDotCornerRadiusDelta;
 
     /** The translation values when the flyout is completely transitioned into the dot. */
     private float mTranslationXWhenDot = 0f;
@@ -126,11 +124,18 @@
     private float mBgTranslationX;
     private float mBgTranslationY;
 
+    private float[] mDotCenter;
+
     /** The flyout's X translation when at rest (not animating or dragging). */
     private float mRestingTranslationX = 0f;
 
+    /** The badge sizes are defined as percentages of the app icon size. Same value as Launcher3. */
+    private static final float SIZE_PERCENTAGE = 0.228f;
+
+    private static final float DOT_SCALE = 1f;
+
     /** Callback to run when the flyout is hidden. */
-    private Runnable mOnHide;
+    @Nullable private Runnable mOnHide;
 
     public BubbleFlyoutView(Context context) {
         super(context);
@@ -143,11 +148,16 @@
         mFlyoutPadding = res.getDimensionPixelSize(R.dimen.bubble_flyout_padding_x);
         mFlyoutSpaceFromBubble = res.getDimensionPixelSize(R.dimen.bubble_flyout_space_from_bubble);
         mPointerSize = res.getDimensionPixelSize(R.dimen.bubble_flyout_pointer_size);
+
         mBubbleSize = res.getDimensionPixelSize(R.dimen.individual_bubble_size);
+        mBubbleIconBitmapSize = res.getDimensionPixelSize(R.dimen.bubble_icon_bitmap_size);
+        mBubbleIconTopPadding  = (mBubbleSize - mBubbleIconBitmapSize) / 2f;
+
         mBubbleElevation = res.getDimensionPixelSize(R.dimen.bubble_elevation);
         mFlyoutElevation = res.getDimensionPixelSize(R.dimen.bubble_flyout_elevation);
-        mNewDotOffsetFromBubbleBounds = BadgeRenderer.getDotCenterOffset(context);
-        mNewDotRadius = BadgeRenderer.getDotRadius(mNewDotOffsetFromBubbleBounds);
+
+        mOriginalDotSize = SIZE_PERCENTAGE * mBubbleIconBitmapSize;
+        mNewDotRadius = (DOT_SCALE * mOriginalDotSize) / 2f;
         mNewDotSize = mNewDotRadius * 2f;
 
         final TypedArray ta = mContext.obtainStyledAttributes(
@@ -156,7 +166,6 @@
                         android.R.attr.dialogCornerRadius});
         mFloatingBackgroundColor = ta.getColor(0, Color.WHITE);
         mCornerRadius = ta.getDimensionPixelSize(1, 0);
-        mFlyoutToDotCornerRadiusDelta = mNewDotRadius - mCornerRadius;
         ta.recycle();
 
         // Add padding for the pointer on either side, onDraw will draw it in this space.
@@ -193,17 +202,17 @@
         super.onDraw(canvas);
     }
 
-    /** Configures the flyout and animates it in. */
-    void showFlyout(
+    /** Configures the flyout, collapsed into to dot form. */
+    void setupFlyoutStartingAsDot(
             CharSequence updateMessage, PointF stackPos, float parentWidth,
-            boolean arrowPointingLeft, int dotColor, Runnable onHide) {
+            boolean arrowPointingLeft, int dotColor, @Nullable Runnable onLayoutComplete,
+            @Nullable Runnable onHide, float[] dotCenter) {
         mArrowPointingLeft = arrowPointingLeft;
         mDotColor = dotColor;
         mOnHide = onHide;
+        mDotCenter = dotCenter;
 
-        setCollapsePercent(0f);
-        setAlpha(0f);
-        setVisibility(VISIBLE);
+        setCollapsePercent(1f);
 
         // Set the flyout TextView's max width in terms of percent, and then subtract out the
         // padding so that the entire flyout view will be the desired width (rather than the
@@ -214,14 +223,16 @@
 
         // Wait for the TextView to lay out so we know its line count.
         post(() -> {
+            float restingTranslationY;
             // Multi line flyouts get top-aligned to the bubble.
             if (mFlyoutText.getLineCount() > 1) {
-                setTranslationY(stackPos.y);
+                restingTranslationY = stackPos.y + mBubbleIconTopPadding;
             } else {
                 // Single line flyouts are vertically centered with respect to the bubble.
-                setTranslationY(
-                        stackPos.y + (mBubbleSize - mFlyoutTextContainer.getHeight()) / 2f);
+                restingTranslationY =
+                        stackPos.y + (mBubbleSize - mFlyoutTextContainer.getHeight()) / 2f;
             }
+            setTranslationY(restingTranslationY);
 
             // Calculate the translation required to position the flyout next to the bubble stack,
             // with the desired padding.
@@ -229,40 +240,30 @@
                     ? stackPos.x + mBubbleSize + mFlyoutSpaceFromBubble
                     : stackPos.x - getWidth() - mFlyoutSpaceFromBubble;
 
-            // Translate towards the stack slightly.
-            setTranslationX(
-                    mRestingTranslationX + (arrowPointingLeft ? -mBubbleSize : mBubbleSize));
-
-            // Fade in the entire flyout and spring it to its normal position.
-            animate().alpha(1f);
-            mFlyoutSpring.animateToFinalPosition(mRestingTranslationX);
-
             // Calculate the difference in size between the flyout and the 'dot' so that we can
             // transform into the dot later.
             mFlyoutToDotWidthDelta = getWidth() - mNewDotSize;
             mFlyoutToDotHeightDelta = getHeight() - mNewDotSize;
 
             // Calculate the translation values needed to be in the correct 'new dot' position.
-            final float distanceFromFlyoutLeftToDotCenterX =
-                    mFlyoutSpaceFromBubble + mNewDotOffsetFromBubbleBounds / 2;
-            if (mArrowPointingLeft) {
-                mTranslationXWhenDot = -distanceFromFlyoutLeftToDotCenterX - mNewDotRadius;
-            } else {
-                mTranslationXWhenDot =
-                        getWidth() + distanceFromFlyoutLeftToDotCenterX - mNewDotRadius;
-            }
+            final float dotPositionX = stackPos.x + mDotCenter[0] - (mOriginalDotSize / 2f);
+            final float dotPositionY = stackPos.y + mDotCenter[1] - (mOriginalDotSize / 2f);
 
-            mTranslationYWhenDot =
-                    getHeight() / 2f
-                            - mNewDotRadius
-                            - mBubbleSize / 2f
-                            + mNewDotOffsetFromBubbleBounds / 2;
+            final float distanceFromFlyoutLeftToDotCenterX = mRestingTranslationX - dotPositionX;
+            final float distanceFromLayoutTopToDotCenterY = restingTranslationY - dotPositionY;
+
+            mTranslationXWhenDot = -distanceFromFlyoutLeftToDotCenterX;
+            mTranslationYWhenDot = -distanceFromLayoutTopToDotCenterY;
+            if (onLayoutComplete != null) {
+                onLayoutComplete.run();
+            }
         });
     }
 
     /**
-     * Hides the flyout and runs the optional callback passed into showFlyout. The flyout has been
-     * animated into the 'new' dot by the time we call this, so no animations are needed.
+     * Hides the flyout and runs the optional callback passed into setupFlyoutStartingAsDot.
+     * The flyout has been animated into the 'new' dot by the time we call this, so no animations
+     * are needed.
      */
     void hideFlyout() {
         if (mOnHide != null) {
@@ -275,6 +276,13 @@
 
     /** Sets the percentage that the flyout should be collapsed into dot form. */
     void setCollapsePercent(float percentCollapsed) {
+        // This is unlikely, but can happen in a race condition where the flyout view hasn't been
+        // laid out and returns 0 for getWidth(). We check for this condition at the sites where
+        // this method is called, but better safe than sorry.
+        if (Float.isNaN(percentCollapsed)) {
+            return;
+        }
+
         mPercentTransitionedToDot = Math.max(0f, Math.min(percentCollapsed, 1f));
         mPercentStillFlyout = (1f - mPercentTransitionedToDot);
 
@@ -311,8 +319,8 @@
         // percentage.
         final float width = getWidth() - (mFlyoutToDotWidthDelta * mPercentTransitionedToDot);
         final float height = getHeight() - (mFlyoutToDotHeightDelta * mPercentTransitionedToDot);
-        final float cornerRadius = mCornerRadius
-                - (mFlyoutToDotCornerRadiusDelta * mPercentTransitionedToDot);
+        final float interpolatedRadius = mNewDotRadius * mPercentTransitionedToDot
+                + mCornerRadius * (1 - mPercentTransitionedToDot);
 
         // Translate the flyout background towards the collapsed 'dot' state.
         mBgTranslationX = mTranslationXWhenDot * mPercentTransitionedToDot;
@@ -336,7 +344,7 @@
         canvas.save();
         canvas.translate(mBgTranslationX, mBgTranslationY);
         renderPointerTriangle(canvas, width, height);
-        canvas.drawRoundRect(mBgRect, cornerRadius, cornerRadius, mBgPaint);
+        canvas.drawRoundRect(mBgRect, interpolatedRadius, interpolatedRadius, mBgPaint);
         canvas.restore();
     }
 
@@ -379,7 +387,10 @@
         if (!mTriangleOutline.isEmpty()) {
             // Draw the rect into the outline as a path so we can merge the triangle path into it.
             final Path rectPath = new Path();
-            rectPath.addRoundRect(mBgRect, mCornerRadius, mCornerRadius, Path.Direction.CW);
+            final float interpolatedRadius = mNewDotRadius * mPercentTransitionedToDot
+                    + mCornerRadius * (1 - mPercentTransitionedToDot);
+            rectPath.addRoundRect(mBgRect, interpolatedRadius,
+                    interpolatedRadius, Path.Direction.CW);
             outline.setConvexPath(rectPath);
 
             // Get rid of the triangle path once it has disappeared behind the flyout.
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java
new file mode 100644
index 0000000..a1c77c0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.bubbles;
+
+import android.content.Context;
+
+import com.android.launcher3.icons.BaseIconFactory;
+import com.android.systemui.R;
+
+/**
+ * Factory for creating normalized bubble icons.
+ * We are not using Launcher's IconFactory because bubbles only runs on the UI thread,
+ * so there is no need to manage a pool across multiple threads.
+ */
+public class BubbleIconFactory extends BaseIconFactory {
+    protected BubbleIconFactory(Context context) {
+        super(context, context.getResources().getConfiguration().densityDpi,
+                context.getResources().getDimensionPixelSize(R.dimen.individual_bubble_size));
+    }
+
+    public int getBadgeSize() {
+        return mContext.getResources().getDimensionPixelSize(
+                com.android.launcher3.icons.R.dimen.profile_badge_size);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index f87bcef..b68b762 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -19,16 +19,20 @@
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 
+import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_STACK_VIEW;
+import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
+import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
 import android.annotation.NonNull;
 import android.app.Notification;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.ColorMatrix;
 import android.graphics.ColorMatrixColorFilter;
-import android.graphics.Outline;
 import android.graphics.Paint;
 import android.graphics.Point;
 import android.graphics.PointF;
@@ -41,11 +45,11 @@
 import android.util.Log;
 import android.util.StatsLog;
 import android.view.Choreographer;
+import android.view.DisplayCutout;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewOutlineProvider;
 import android.view.ViewTreeObserver;
 import android.view.WindowInsets;
 import android.view.WindowManager;
@@ -69,6 +73,8 @@
 import com.android.systemui.bubbles.animation.StackAnimationController;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.ArrayList;
@@ -79,8 +85,7 @@
  * Renders bubbles in a stack and handles animating expanded and collapsed states.
  */
 public class BubbleStackView extends FrameLayout {
-    private static final String TAG = "BubbleStackView";
-    private static final boolean DEBUG = false;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleStackView" : TAG_BUBBLES;
 
     /** How far the flyout needs to be dragged before it's dismissed regardless of velocity. */
     static final float FLYOUT_DRAG_PERCENT_DISMISS = 0.25f;
@@ -160,9 +165,14 @@
     private BubbleFlyoutView mFlyout;
     /** Runnable that fades out the flyout and then sets it to GONE. */
     private Runnable mHideFlyout = () -> animateFlyoutCollapsed(true, 0 /* velX */);
+    /**
+     * Callback to run after the flyout hides. Also called if a new flyout is shown before the
+     * previous one animates out.
+     */
+    private Runnable mAfterFlyoutHides;
 
     /** Layout change listener that moves the stack to the nearest valid position on rotation. */
-    private OnLayoutChangeListener mMoveStackToValidPositionOnLayoutListener;
+    private OnLayoutChangeListener mOrientationChangedListener;
     /** Whether the stack was on the left side of the screen prior to rotation. */
     private boolean mWasOnLeftBeforeRotation = false;
     /**
@@ -172,18 +182,17 @@
     private float mVerticalPosPercentBeforeRotation = -1;
 
     private int mBubbleSize;
-    private int mBubblePadding;
+    private int mBubblePaddingTop;
+    private int mBubbleTouchPadding;
     private int mExpandedViewPadding;
     private int mExpandedAnimateXDistance;
     private int mExpandedAnimateYDistance;
     private int mPointerHeight;
     private int mStatusBarHeight;
-    private int mPipDismissHeight;
     private int mImeOffset;
-
+    private BubbleIconFactory mBubbleIconFactory;
     private Bubble mExpandedBubble;
     private boolean mIsExpanded;
-    private boolean mImeVisible;
 
     /** Whether the stack is currently on the left side of the screen, or animating there. */
     private boolean mStackOnLeftOrWillBe = false;
@@ -191,9 +200,20 @@
     /** Whether a touch gesture, such as a stack/bubble drag or flyout drag, is in progress. */
     private boolean mIsGestureInProgress = false;
 
+    /** Description of current animation controller state. */
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("Stack view state:");
+        pw.print("  gestureInProgress:    "); pw.println(mIsGestureInProgress);
+        pw.print("  showingDismiss:       "); pw.println(mShowingDismiss);
+        pw.print("  isExpansionAnimating: "); pw.println(mIsExpansionAnimating);
+        pw.print("  draggingInDismiss:    "); pw.println(mDraggingInDismissTarget);
+        pw.print("  animatingMagnet:      "); pw.println(mAnimatingMagnet);
+        mStackAnimationController.dump(fd, pw, args);
+        mExpandedAnimationController.dump(fd, pw, args);
+    }
+
     private BubbleTouchHandler mTouchHandler;
     private BubbleController.BubbleExpandListener mExpandListener;
-    private BubbleExpandedView.OnBubbleBlockedListener mBlockedListener;
 
     private boolean mViewUpdatedRequested = false;
     private boolean mIsExpansionAnimating = false;
@@ -225,7 +245,7 @@
                 @Override
                 public boolean onPreDraw() {
                     getViewTreeObserver().removeOnPreDrawListener(mViewUpdater);
-                    applyCurrentState();
+                    updateExpandedView();
                     mViewUpdatedRequested = false;
                     return true;
                 }
@@ -270,6 +290,11 @@
     private float mFlyoutDragDeltaX = 0f;
 
     /**
+     * Runnable that animates in the flyout. This reference is needed to cancel delayed postings.
+     */
+    private Runnable mAnimateInFlyout;
+
+    /**
      * End listener for the flyout spring that either posts a runnable to hide the flyout, or hides
      * it immediately.
      */
@@ -282,13 +307,13 @@
                 }
             };
 
-    @NonNull private final SurfaceSynchronizer mSurfaceSynchronizer;
+    @NonNull
+    private final SurfaceSynchronizer mSurfaceSynchronizer;
 
     private BubbleDismissView mDismissContainer;
     private Runnable mAfterMagnet;
 
-    private boolean mSuppressNewDot = false;
-    private boolean mSuppressFlyout = false;
+    private int mOrientation = Configuration.ORIENTATION_UNDEFINED;
 
     public BubbleStackView(Context context, BubbleData data,
             @Nullable SurfaceSynchronizer synchronizer) {
@@ -302,7 +327,8 @@
 
         Resources res = getResources();
         mBubbleSize = res.getDimensionPixelSize(R.dimen.individual_bubble_size);
-        mBubblePadding = res.getDimensionPixelSize(R.dimen.bubble_padding);
+        mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
+        mBubbleTouchPadding = res.getDimensionPixelSize(R.dimen.bubble_touch_padding);
         mExpandedAnimateXDistance =
                 res.getDimensionPixelSize(R.dimen.bubble_expanded_animate_x_distance);
         mExpandedAnimateYDistance =
@@ -311,13 +337,12 @@
 
         mStatusBarHeight =
                 res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
-        mPipDismissHeight = mContext.getResources().getDimensionPixelSize(
-                R.dimen.pip_dismiss_gradient_height);
         mImeOffset = res.getDimensionPixelSize(R.dimen.pip_ime_offset);
 
         mDisplaySize = new Point();
         WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
-        wm.getDefaultDisplay().getSize(mDisplaySize);
+        // We use the real size & subtract screen decorations / window insets ourselves when needed
+        wm.getDefaultDisplay().getRealSize(mDisplaySize);
 
         mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
 
@@ -325,8 +350,9 @@
         int elevation = res.getDimensionPixelSize(R.dimen.bubble_elevation);
 
         mStackAnimationController = new StackAnimationController();
+
         mExpandedAnimationController = new ExpandedAnimationController(
-                mDisplaySize, mExpandedViewPadding);
+                mDisplaySize, mExpandedViewPadding, res.getConfiguration().orientation);
         mSurfaceSynchronizer = synchronizer != null ? synchronizer : DEFAULT_SURFACE_SYNCHRONIZER;
 
         mBubbleContainer = new PhysicsAnimationLayout(context);
@@ -335,6 +361,8 @@
         mBubbleContainer.setClipChildren(false);
         addView(mBubbleContainer, new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
 
+        mBubbleIconFactory = new BubbleIconFactory(context);
+
         mExpandedViewContainer = new FrameLayout(context);
         mExpandedViewContainer.setElevation(elevation);
         mExpandedViewContainer.setPadding(mExpandedViewPadding, mExpandedViewPadding,
@@ -342,15 +370,9 @@
         mExpandedViewContainer.setClipChildren(false);
         addView(mExpandedViewContainer);
 
-        mFlyout = new BubbleFlyoutView(context);
-        mFlyout.setVisibility(GONE);
-        mFlyout.animate()
-                .setDuration(FLYOUT_ALPHA_ANIMATION_DURATION)
-                .setInterpolator(new AccelerateDecelerateInterpolator());
-        addView(mFlyout, new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
-
+        setUpFlyout();
         mFlyoutTransitionSpring.setSpring(new SpringForce()
-                .setStiffness(SpringForce.STIFFNESS_MEDIUM)
+                .setStiffness(SpringForce.STIFFNESS_LOW)
                 .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY));
         mFlyoutTransitionSpring.addEndListener(mAfterFlyoutTransitionSpring);
 
@@ -361,13 +383,6 @@
                 Gravity.BOTTOM));
         addView(mDismissContainer);
 
-        mDismissContainer = new BubbleDismissView(mContext);
-        mDismissContainer.setLayoutParams(new FrameLayout.LayoutParams(
-                MATCH_PARENT,
-                getResources().getDimensionPixelSize(R.dimen.pip_dismiss_gradient_height),
-                Gravity.BOTTOM));
-        addView(mDismissContainer);
-
         mExpandedViewXAnim =
                 new SpringAnimation(mExpandedViewContainer, DynamicAnimation.TRANSLATION_X);
         mExpandedViewXAnim.setSpring(
@@ -383,7 +398,7 @@
                         .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY));
         mExpandedViewYAnim.addEndListener((anim, cancelled, value, velocity) -> {
             if (mIsExpanded && mExpandedBubble != null) {
-                mExpandedBubble.expandedView.updateView();
+                mExpandedBubble.getExpandedView().updateView();
             }
         });
 
@@ -392,34 +407,58 @@
         mBubbleContainer.bringToFront();
 
         setOnApplyWindowInsetsListener((View view, WindowInsets insets) -> {
-            final int keyboardHeight = insets.getSystemWindowInsetBottom()
-                    - insets.getStableInsetBottom();
             if (!mIsExpanded || mIsExpansionAnimating) {
                 return view.onApplyWindowInsets(insets);
             }
-            mImeVisible = keyboardHeight != 0;
-
-            float newY = getYPositionForExpandedView();
-            if (newY < 0) {
-                // TODO: This means our expanded content is too big to fit on screen. Right now
-                // we'll let it translate off but we should be clipping it & pushing the header
-                // down so that it always remains visible.
-            }
-            mExpandedViewYAnim.animateToFinalPosition(newY);
             mExpandedAnimationController.updateYPosition(
                     // Update the insets after we're done translating otherwise position
                     // calculation for them won't be correct.
-                    () -> mExpandedBubble.expandedView.updateInsets(insets));
+                    () -> mExpandedBubble.getExpandedView().updateInsets(insets));
             return view.onApplyWindowInsets(insets);
         });
 
-        mMoveStackToValidPositionOnLayoutListener =
+        mOrientationChangedListener =
                 (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
+                    mExpandedAnimationController.updateOrientation(mOrientation, mDisplaySize);
+                    mStackAnimationController.updateOrientation(mOrientation);
+
+                    // Reposition & adjust the height for new orientation
+                    if (mIsExpanded) {
+                        mExpandedViewContainer.setTranslationY(getExpandedViewY());
+                        mExpandedBubble.getExpandedView().updateView();
+                    }
+
+                    // Need to update the padding around the view
+                    WindowInsets insets = getRootWindowInsets();
+                    int leftPadding = mExpandedViewPadding;
+                    int rightPadding = mExpandedViewPadding;
+                    if (insets != null) {
+                        // Can't have the expanded view overlaying notches
+                        int cutoutLeft = 0;
+                        int cutoutRight = 0;
+                        DisplayCutout cutout = insets.getDisplayCutout();
+                        if (cutout != null) {
+                            cutoutLeft = cutout.getSafeInsetLeft();
+                            cutoutRight = cutout.getSafeInsetRight();
+                        }
+                        // Or overlaying nav or status bar
+                        leftPadding += Math.max(cutoutLeft, insets.getStableInsetLeft());
+                        rightPadding += Math.max(cutoutRight, insets.getStableInsetRight());
+                    }
+                    mExpandedViewContainer.setPadding(leftPadding, mExpandedViewPadding,
+                            rightPadding, mExpandedViewPadding);
+
+                    if (mIsExpanded) {
+                        // Re-draw bubble row and pointer for new orientation.
+                        mExpandedAnimationController.expandFromStack(() -> {
+                            updatePointerPosition();
+                        } /* after */);
+                    }
                     if (mVerticalPosPercentBeforeRotation >= 0) {
                         mStackAnimationController.moveStackToSimilarPositionAfterRotation(
                                 mWasOnLeftBeforeRotation, mVerticalPosPercentBeforeRotation);
                     }
-                    removeOnLayoutChangeListener(mMoveStackToValidPositionOnLayoutListener);
+                    removeOnLayoutChangeListener(mOrientationChangedListener);
                 };
 
         // This must be a separate OnDrawListener since it should be called for every draw.
@@ -449,25 +488,53 @@
         });
     }
 
+    private void setUpFlyout() {
+        if (mFlyout != null) {
+            removeView(mFlyout);
+        }
+        mFlyout = new BubbleFlyoutView(getContext());
+        mFlyout.setVisibility(GONE);
+        mFlyout.animate()
+                .setDuration(FLYOUT_ALPHA_ANIMATION_DURATION)
+                .setInterpolator(new AccelerateDecelerateInterpolator());
+        addView(mFlyout, new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
+    }
+
     /**
      * Handle theme changes.
      */
     public void onThemeChanged() {
+        // Recreate icon factory to update default adaptive icon scale.
+        mBubbleIconFactory = new BubbleIconFactory(mContext);
+        setUpFlyout();
         for (Bubble b: mBubbleData.getBubbles()) {
-            b.iconView.updateViews();
-            b.expandedView.applyThemeAttrs();
+            b.getIconView().setBubbleIconFactory(mBubbleIconFactory);
+            b.getIconView().updateViews();
+            b.getExpandedView().applyThemeAttrs();
         }
     }
 
     /** Respond to the phone being rotated by repositioning the stack and hiding any flyouts. */
-    public void onOrientationChanged() {
+    public void onOrientationChanged(int orientation) {
+        mOrientation = orientation;
+
+        // Display size is based on the rotation device was in when requested, we should update it
+        // We use the real size & subtract screen decorations / window insets ourselves when needed
+        WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
+        wm.getDefaultDisplay().getRealSize(mDisplaySize);
+
+        // Some resources change depending on orientation
+        Resources res = getContext().getResources();
+        mStatusBarHeight = res.getDimensionPixelSize(
+                com.android.internal.R.dimen.status_bar_height);
+        mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
+
         final RectF allowablePos = mStackAnimationController.getAllowableStackPositionRegion();
         mWasOnLeftBeforeRotation = mStackAnimationController.isStackOnLeftSide();
         mVerticalPosPercentBeforeRotation =
                 (mStackAnimationController.getStackPosition().y - allowablePos.top)
                         / (allowablePos.bottom - allowablePos.top);
-        addOnLayoutChangeListener(mMoveStackToValidPositionOnLayoutListener);
-
+        addOnLayoutChangeListener(mOrientationChangedListener);
         hideFlyoutImmediate();
     }
 
@@ -483,18 +550,6 @@
     }
 
     @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        float x = ev.getRawX();
-        float y = ev.getRawY();
-        // If we're expanded only intercept if the tap is outside of the widget container
-        if (mIsExpanded && isIntersecting(mExpandedViewContainer, x, y)) {
-            return false;
-        } else {
-            return isIntersecting(mBubbleContainer, x, y);
-        }
-    }
-
-    @Override
     public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfoInternal(info);
 
@@ -570,7 +625,7 @@
         }
         Bubble topBubble = mBubbleData.getBubbles().get(0);
         String appName = topBubble.getAppName();
-        Notification notification = topBubble.entry.notification.getNotification();
+        Notification notification = topBubble.getEntry().notification.getNotification();
         CharSequence titleCharSeq = notification.extras.getCharSequence(Notification.EXTRA_TITLE);
         String titleStr = getResources().getString(R.string.stream_notification);
         if (titleCharSeq != null) {
@@ -616,6 +671,7 @@
 
     /**
      * Updates the visibility of the 'dot' indicating an update on the bubble.
+     *
      * @param key the {@link NotificationEntry#key} associated with the bubble.
      */
     public void updateDotVisibility(String key) {
@@ -640,10 +696,17 @@
     }
 
     /**
+     * Whether the stack of bubbles is animating to or from expansion.
+     */
+    public boolean isExpansionAnimating() {
+        return mIsExpansionAnimating;
+    }
+
+    /**
      * The {@link BubbleView} that is expanded, null if one does not exist.
      */
     BubbleView getExpandedBubbleView() {
-        return mExpandedBubble != null ? mExpandedBubble.iconView : null;
+        return mExpandedBubble != null ? mExpandedBubble.getIconView() : null;
     }
 
     /**
@@ -664,36 +727,33 @@
         Bubble bubbleToExpand = mBubbleData.getBubbleWithKey(key);
         if (bubbleToExpand != null) {
             setSelectedBubble(bubbleToExpand);
-            bubbleToExpand.entry.setShowInShadeWhenBubble(false);
+            bubbleToExpand.setShowInShadeWhenBubble(false);
             setExpanded(true);
         }
     }
 
-    /**
-     * Sets the entry that should be expanded and expands if needed.
-     */
-    @VisibleForTesting
-    void setExpandedBubble(NotificationEntry entry) {
-        for (int i = 0; i < mBubbleContainer.getChildCount(); i++) {
-            BubbleView bv = (BubbleView) mBubbleContainer.getChildAt(i);
-            if (entry.equals(bv.getEntry())) {
-                setExpandedBubble(entry.key);
-            }
-        }
-    }
-
     // via BubbleData.Listener
     void addBubble(Bubble bubble) {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_STACK_VIEW) {
             Log.d(TAG, "addBubble: " + bubble);
         }
-        bubble.inflate(mInflater, this);
-        mBubbleContainer.addView(bubble.iconView, 0,
-                new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
-        ViewClippingUtil.setClippingDeactivated(bubble.iconView, true, mClippingParameters);
-        if (bubble.iconView != null) {
-            bubble.iconView.setSuppressDot(mSuppressNewDot, false /* animate */);
+
+        if (mBubbleContainer.getChildCount() == 0) {
+            mStackOnLeftOrWillBe = mStackAnimationController.isStackOnLeftSide();
         }
+
+        bubble.inflate(mInflater, this);
+        bubble.getIconView().setBubbleIconFactory(mBubbleIconFactory);
+        bubble.getIconView().updateViews();
+
+        // Set the dot position to the opposite of the side the stack is resting on, since the stack
+        // resting slightly off-screen would result in the dot also being off-screen.
+        bubble.getIconView().setDotPosition(
+                !mStackOnLeftOrWillBe /* onLeft */, false /* animate */);
+
+        mBubbleContainer.addView(bubble.getIconView(), 0,
+                new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
+        ViewClippingUtil.setClippingDeactivated(bubble.getIconView(), true, mClippingParameters);
         animateInFlyoutForBubble(bubble);
         requestUpdate();
         logBubbleEvent(bubble, StatsLog.BUBBLE_UICHANGED__ACTION__POSTED);
@@ -702,13 +762,14 @@
 
     // via BubbleData.Listener
     void removeBubble(Bubble bubble) {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_STACK_VIEW) {
             Log.d(TAG, "removeBubble: " + bubble);
         }
         // Remove it from the views
-        int removedIndex = mBubbleContainer.indexOfChild(bubble.iconView);
+        int removedIndex = mBubbleContainer.indexOfChild(bubble.getIconView());
         if (removedIndex >= 0) {
             mBubbleContainer.removeViewAt(removedIndex);
+            bubble.cleanupExpandedState();
             logBubbleEvent(bubble, StatsLog.BUBBLE_UICHANGED__ACTION__DISMISSED);
         } else {
             Log.d(TAG, "was asked to remove Bubble, but didn't find the view! " + bubble);
@@ -726,8 +787,10 @@
     public void updateBubbleOrder(List<Bubble> bubbles) {
         for (int i = 0; i < bubbles.size(); i++) {
             Bubble bubble = bubbles.get(i);
-            mBubbleContainer.reorderView(bubble.iconView, i);
+            mBubbleContainer.reorderView(bubble.getIconView(), i);
         }
+
+        updateBubbleZOrdersAndDotPosition(false /* animate */);
     }
 
     /**
@@ -737,7 +800,7 @@
      */
     // via BubbleData.Listener
     public void setSelectedBubble(@Nullable Bubble bubbleToSelect) {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_STACK_VIEW) {
             Log.d(TAG, "setSelectedBubble: " + bubbleToSelect);
         }
         if (mExpandedBubble != null && mExpandedBubble.equals(bubbleToSelect)) {
@@ -760,9 +823,8 @@
                 requestUpdate();
                 logBubbleEvent(previouslySelected, StatsLog.BUBBLE_UICHANGED__ACTION__COLLAPSED);
                 logBubbleEvent(bubbleToSelect, StatsLog.BUBBLE_UICHANGED__ACTION__EXPANDED);
-                notifyExpansionChanged(previouslySelected.entry, false /* expanded */);
-                notifyExpansionChanged(bubbleToSelect == null ? null : bubbleToSelect.entry,
-                        true /* expanded */);
+                notifyExpansionChanged(previouslySelected, false /* expanded */);
+                notifyExpansionChanged(bubbleToSelect, true /* expanded */);
             });
         }
     }
@@ -774,42 +836,32 @@
      */
     // via BubbleData.Listener
     public void setExpanded(boolean shouldExpand) {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_STACK_VIEW) {
             Log.d(TAG, "setExpanded: " + shouldExpand);
         }
-        boolean wasExpanded = mIsExpanded;
-        if (shouldExpand == wasExpanded) {
+        if (shouldExpand == mIsExpanded) {
             return;
         }
-        if (wasExpanded) {
-            // Collapse the stack
-            mExpandedViewContainer.setAlpha(0.0f);
-            // TODO: In order to prevent flicker, code below should be executed after the alpha
-            // value set on the mExpandedViewContainer is reflected on the screen. However, we
-            // cannot just postpone the execution like #setSelectedBubble(), since some of member
-            // variables referred by the code are overridden before the execution.
-            if (mExpandedBubble != null) {
-                mExpandedBubble.setContentVisibility(false);
-            }
-            animateExpansion(false /* expand */);
+        if (mIsExpanded) {
+            animateCollapse();
             logBubbleEvent(mExpandedBubble, StatsLog.BUBBLE_UICHANGED__ACTION__COLLAPSED);
         } else {
-            // Expand the stack
-            animateExpansion(true /* expand */);
+            animateExpansion();
             // TODO: move next line to BubbleData
             logBubbleEvent(mExpandedBubble, StatsLog.BUBBLE_UICHANGED__ACTION__EXPANDED);
             logBubbleEvent(mExpandedBubble, StatsLog.BUBBLE_UICHANGED__ACTION__STACK_EXPANDED);
         }
-        notifyExpansionChanged(mExpandedBubble.entry, mIsExpanded);
+        notifyExpansionChanged(mExpandedBubble, mIsExpanded);
     }
 
     /**
      * Dismiss the stack of bubbles.
+     *
      * @deprecated
      */
     @Deprecated
     void stackDismissed(int reason) {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_STACK_VIEW) {
             Log.d(TAG, "stackDismissed: reason=" + reason);
         }
         mBubbleData.dismissAll(reason);
@@ -826,21 +878,23 @@
         float y = event.getRawY();
         if (mIsExpanded) {
             if (isIntersecting(mBubbleContainer, x, y)) {
+                // Could be tapping or dragging a bubble while expanded
                 for (int i = 0; i < mBubbleContainer.getChildCount(); i++) {
                     BubbleView view = (BubbleView) mBubbleContainer.getChildAt(i);
                     if (isIntersecting(view, x, y)) {
                         return view;
                     }
                 }
-            } else if (isIntersecting(mExpandedViewContainer, x, y)) {
-                return mExpandedViewContainer;
             }
-            // Outside parts of view we care about.
+            BubbleExpandedView bev = (BubbleExpandedView) mExpandedViewContainer.getChildAt(0);
+            if (bev.intersectingTouchableContent((int) x, (int) y)) {
+                return bev;
+            }
+            // Outside of the parts we care about.
             return null;
         } else if (mFlyout.getVisibility() == VISIBLE && isIntersecting(mFlyout, x, y)) {
             return mFlyout;
         }
-
         // If it wasn't an individual bubble in the expanded state, or the flyout, it's the stack.
         return this;
     }
@@ -859,7 +913,7 @@
     @Deprecated
     @MainThread
     void collapseStack() {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_STACK_VIEW) {
             Log.d(TAG, "collapseStack()");
         }
         mBubbleData.setExpanded(false);
@@ -871,7 +925,7 @@
     @Deprecated
     @MainThread
     void collapseStack(Runnable endRunnable) {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_STACK_VIEW) {
             Log.d(TAG, "collapseStack(endRunnable)");
         }
         collapseStack();
@@ -889,73 +943,83 @@
     @Deprecated
     @MainThread
     void expandStack() {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_STACK_VIEW) {
             Log.d(TAG, "expandStack()");
         }
         mBubbleData.setExpanded(true);
     }
 
-    /**
-     * Tell the stack to animate to collapsed or expanded state.
-     */
-    private void animateExpansion(boolean shouldExpand) {
-        if (DEBUG) {
-            Log.d(TAG, "animateExpansion: shouldExpand=" + shouldExpand);
-        }
-        if (mIsExpanded != shouldExpand) {
-            hideFlyoutImmediate();
-
-            mIsExpanded = shouldExpand;
-            updateExpandedBubble();
-            applyCurrentState();
-
-            mIsExpansionAnimating = true;
-
-            Runnable updateAfter = () -> {
-                applyCurrentState();
-                mIsExpansionAnimating = false;
-                requestUpdate();
-            };
-
-            if (shouldExpand) {
-                mBubbleContainer.setActiveController(mExpandedAnimationController);
-                mExpandedAnimationController.expandFromStack(() -> {
-                    updatePointerPosition();
-                    updateAfter.run();
-                } /* after */);
-            } else {
-                mBubbleContainer.cancelAllAnimations();
-                mExpandedAnimationController.collapseBackToStack(
-                        mStackAnimationController.getStackPositionAlongNearestHorizontalEdge(),
-                        () -> {
-                            mBubbleContainer.setActiveController(mStackAnimationController);
-                            updateAfter.run();
-                        });
-            }
-
-            final float xStart =
-                    mStackAnimationController.getStackPosition().x < getWidth() / 2
-                            ? -mExpandedAnimateXDistance
-                            : mExpandedAnimateXDistance;
-
-            final float yStart = Math.min(
-                    mStackAnimationController.getStackPosition().y,
-                    mExpandedAnimateYDistance);
-            final float yDest = getYPositionForExpandedView();
-
-            if (shouldExpand) {
-                mExpandedViewContainer.setTranslationX(xStart);
-                mExpandedViewContainer.setTranslationY(yStart);
-            }
-
-            mExpandedViewXAnim.animateToFinalPosition(shouldExpand ? 0f : xStart);
-            mExpandedViewYAnim.animateToFinalPosition(shouldExpand ? yDest : yStart);
-        }
+    private void beforeExpandedViewAnimation() {
+        hideFlyoutImmediate();
+        updateExpandedBubble();
+        updateExpandedView();
+        mIsExpansionAnimating = true;
     }
 
-    private void notifyExpansionChanged(NotificationEntry entry, boolean expanded) {
-        if (mExpandListener != null) {
-            mExpandListener.onBubbleExpandChanged(expanded, entry != null ? entry.key : null);
+    private void afterExpandedViewAnimation() {
+        updateExpandedView();
+        mIsExpansionAnimating = false;
+        requestUpdate();
+    }
+
+    private void animateCollapse() {
+        mIsExpanded = false;
+        final Bubble previouslySelected = mExpandedBubble;
+        beforeExpandedViewAnimation();
+
+        mBubbleContainer.cancelAllAnimations();
+        mExpandedAnimationController.collapseBackToStack(
+                mStackAnimationController.getStackPositionAlongNearestHorizontalEdge()
+                /* collapseTo */,
+                () -> {
+                    mBubbleContainer.setActiveController(mStackAnimationController);
+                    afterExpandedViewAnimation();
+                    previouslySelected.setContentVisibility(false);
+                });
+
+        mExpandedViewXAnim.animateToFinalPosition(getCollapsedX());
+        mExpandedViewYAnim.animateToFinalPosition(getCollapsedY());
+        mExpandedViewContainer.animate()
+                .setDuration(100)
+                .alpha(0f);
+    }
+
+    private void animateExpansion() {
+        mIsExpanded = true;
+        beforeExpandedViewAnimation();
+
+        mBubbleContainer.setActiveController(mExpandedAnimationController);
+        mExpandedAnimationController.expandFromStack(() -> {
+            updatePointerPosition();
+            afterExpandedViewAnimation();
+        } /* after */);
+
+
+        mExpandedViewContainer.setTranslationX(getCollapsedX());
+        mExpandedViewContainer.setTranslationY(getCollapsedY());
+        mExpandedViewContainer.setAlpha(0f);
+
+        mExpandedViewXAnim.animateToFinalPosition(0f);
+        mExpandedViewYAnim.animateToFinalPosition(getExpandedViewY());
+        mExpandedViewContainer.animate()
+                .setDuration(100)
+                .alpha(1f);
+    }
+
+    private float getCollapsedX() {
+        return mStackAnimationController.getStackPosition().x < getWidth() / 2
+                ? -mExpandedAnimateXDistance
+                : mExpandedAnimateXDistance;
+    }
+
+    private float getCollapsedY() {
+        return Math.min(mStackAnimationController.getStackPosition().y,
+                mExpandedAnimateYDistance);
+    }
+
+    private void notifyExpansionChanged(Bubble bubble, boolean expanded) {
+        if (mExpandListener != null && bubble != null) {
+            mExpandListener.onBubbleExpandChanged(expanded, bubble.getKey());
         }
     }
 
@@ -968,7 +1032,7 @@
 
     /** Moves the bubbles out of the way if they're going to be over the keyboard. */
     public void onImeVisibilityChanged(boolean visible, int height) {
-        mStackAnimationController.setImeHeight(height + mImeOffset);
+        mStackAnimationController.setImeHeight(visible ? height + mImeOffset : 0);
 
         if (!mIsExpanded) {
             mStackAnimationController.animateForImeVisibility(visible);
@@ -977,7 +1041,7 @@
 
     /** Called when a drag operation on an individual bubble has started. */
     public void onBubbleDragStart(View bubble) {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_STACK_VIEW) {
             Log.d(TAG, "onBubbleDragStart: bubble=" + bubble);
         }
         mExpandedAnimationController.prepareForBubbleDrag(bubble);
@@ -996,7 +1060,7 @@
     /** Called when a drag operation on an individual bubble has finished. */
     public void onBubbleDragFinish(
             View bubble, float x, float y, float velX, float velY) {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_STACK_VIEW) {
             Log.d(TAG, "onBubbleDragFinish: bubble=" + bubble);
         }
 
@@ -1005,11 +1069,11 @@
         }
 
         mExpandedAnimationController.snapBubbleBack(bubble, velX, velY);
-        springOutDismissTargetAndHideCircle();
+        hideDismissTarget();
     }
 
     void onDragStart() {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_STACK_VIEW) {
             Log.d(TAG, "onDragStart()");
         }
         if (mIsExpanded || mIsExpansionAnimating) {
@@ -1033,7 +1097,7 @@
     }
 
     void onDragFinish(float x, float y, float velX, float velY) {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_STACK_VIEW) {
             Log.d(TAG, "onDragFinish");
         }
 
@@ -1046,8 +1110,8 @@
                 StatsLog.BUBBLE_UICHANGED__ACTION__STACK_MOVED);
 
         mStackOnLeftOrWillBe = newStackX <= 0;
-        updateBubbleShadowsAndDotPosition(true /* animate */);
-        springOutDismissTargetAndHideCircle();
+        updateBubbleZOrdersAndDotPosition(true /* animate */);
+        hideDismissTarget();
     }
 
     void onFlyoutDragStart() {
@@ -1055,6 +1119,12 @@
     }
 
     void onFlyoutDragged(float deltaX) {
+        // This shouldn't happen, but if it does, just wait until the flyout lays out. This method
+        // is continually called.
+        if (mFlyout.getWidth() <= 0) {
+            return;
+        }
+
         final boolean onLeft = mStackAnimationController.isStackOnLeftSide();
         mFlyoutDragDeltaX = deltaX;
 
@@ -1062,7 +1132,7 @@
                 onLeft ? -deltaX / mFlyout.getWidth() : deltaX / mFlyout.getWidth();
         mFlyout.setCollapsePercent(Math.min(1f, Math.max(0f, collapsePercent)));
 
-        // Calculate how to translate the flyout if it has been dragged too far in etiher direction.
+        // Calculate how to translate the flyout if it has been dragged too far in either direction.
         float overscrollTranslation = 0f;
         if (collapsePercent < 0f || collapsePercent > 1f) {
             // Whether we are more than 100% transitioned to the dot.
@@ -1073,7 +1143,6 @@
             // after it has already become the dot.
             final boolean overscrollingLeft =
                     (onLeft && collapsePercent > 1f) || (!onLeft && collapsePercent < 0f);
-
             overscrollTranslation =
                     (overscrollingPastDot ? collapsePercent - 1f : collapsePercent * -1)
                             * (overscrollingLeft ? -1 : 1)
@@ -1086,6 +1155,19 @@
     }
 
     /**
+     * Set when the flyout is tapped, so that we can expand the bubble associated with the flyout
+     * once it collapses.
+     */
+    @Nullable private Bubble mBubbleToExpandAfterFlyoutCollapse = null;
+
+    void onFlyoutTapped() {
+        mBubbleToExpandAfterFlyoutCollapse = mBubbleData.getSelectedBubble();
+
+        mFlyout.removeCallbacks(mHideFlyout);
+        mHideFlyout.run();
+    }
+
+    /**
      * Called when the flyout drag has finished, and returns true if the gesture successfully
      * dismissed the flyout.
      */
@@ -1181,9 +1263,6 @@
 
                 animateDesaturateAndDarken(magnetView, true);
             }
-
-            mDismissContainer.animateEncircleCenterWithX(true);
-
         } else {
             mAnimatingMagnet = false;
 
@@ -1194,8 +1273,6 @@
                 mExpandedAnimationController.demagnetizeBubbleTo(x, y, velX, velY);
                 animateDesaturateAndDarken(magnetView, false);
             }
-
-            mDismissContainer.animateEncircleCenterWithX(false);
         }
 
         mVibrator.vibrate(VibrationEffect.get(toTarget
@@ -1214,7 +1291,7 @@
             mAfterMagnet = null;
 
             mVibrator.vibrate(VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
-            mDismissContainer.animateEncirclingCircleDisappearance();
+            mDismissContainer.springOut();
 
             // 'Implode' the stack and then hide the dismiss target.
             if (touchedView == this) {
@@ -1252,7 +1329,7 @@
         }
     }
 
-    /** Animates in the dismiss target, including the gradient behind it. */
+    /** Animates in the dismiss target. */
     private void springInDismissTarget() {
         if (mShowingDismiss) {
             return;
@@ -1270,7 +1347,7 @@
      * Animates the dismiss target out, as well as the circle that encircles the bubbles, if they
      * were dragged into the target and encircled.
      */
-    private void springOutDismissTargetAndHideCircle() {
+    private void hideDismissTarget() {
         if (!mShowingDismiss) {
             return;
         }
@@ -1287,6 +1364,12 @@
     /** Animates the flyout collapsed (to dot), or the reverse, starting with the given velocity. */
     private void animateFlyoutCollapsed(boolean collapsed, float velX) {
         final boolean onLeft = mStackAnimationController.isStackOnLeftSide();
+        // If the flyout was tapped, we want a higher stiffness for the collapse animation so it's
+        // faster.
+        mFlyoutTransitionSpring.getSpring().setStiffness(
+                (mBubbleToExpandAfterFlyoutCollapse != null)
+                        ? SpringForce.STIFFNESS_MEDIUM
+                        : SpringForce.STIFFNESS_LOW);
         mFlyoutTransitionSpring
                 .setStartValue(mFlyoutDragDeltaX)
                 .setStartVelocity(velX)
@@ -1295,123 +1378,121 @@
                         : 0f);
     }
 
-    /**
-     * Calculates how large the expanded view of the bubble can be. This takes into account the
-     * y position when the bubbles are expanded as well as the bounds of the dismiss target.
-     */
-    int getMaxExpandedHeight() {
-        int expandedY = (int) mExpandedAnimationController.getExpandedY();
-        // PIP dismiss view uses FLAG_LAYOUT_IN_SCREEN so we need to subtract the bottom inset
-        int pipDismissHeight = mPipDismissHeight - getBottomInset();
-        return mDisplaySize.y - expandedY - mBubbleSize - pipDismissHeight;
+    /** Updates the dot visibility, this is used in response to a zen mode config change. */
+    void updateDots() {
+        int bubbsCount = mBubbleContainer.getChildCount();
+        for (int i = 0; i < bubbsCount; i++) {
+            BubbleView bv = (BubbleView) mBubbleContainer.getChildAt(i);
+            // If nothing changed the animation won't happen
+            bv.updateDotVisibility(true /* animate */);
+        }
     }
 
     /**
      * Calculates the y position of the expanded view when it is expanded.
      */
-    float getYPositionForExpandedView() {
-        return getStatusBarHeight() + mBubbleSize + mBubblePadding + mPointerHeight;
+    float getExpandedViewY() {
+        return getStatusBarHeight() + mBubbleSize + mBubblePaddingTop + mPointerHeight;
     }
 
     /**
-     * Called when the height of the currently expanded view has changed (not via an
-     * update to the bubble's desired height but for some other reason, e.g. permission view
-     * goes away).
-     */
-    void onExpandedHeightChanged() {
-        if (mIsExpanded) {
-            requestUpdate();
-        }
-    }
-
-    /** Sets whether all bubbles in the stack should not show the 'new' dot. */
-    void setSuppressNewDot(boolean suppressNewDot) {
-        mSuppressNewDot = suppressNewDot;
-
-        for (int i = 0; i < mBubbleContainer.getChildCount(); i++) {
-            BubbleView bv = (BubbleView) mBubbleContainer.getChildAt(i);
-            bv.setSuppressDot(suppressNewDot, true /* animate */);
-        }
-    }
-
-    /**
-     * Sets whether the flyout should not appear, even if the notif otherwise would generate one.
-     */
-    void setSuppressFlyout(boolean suppressFlyout) {
-        mSuppressFlyout = suppressFlyout;
-    }
-
-    /**
-     * Callback to run after the flyout hides. Also called if a new flyout is shown before the
-     * previous one animates out.
-     */
-    private Runnable mAfterFlyoutHides;
-
-    /**
      * Animates in the flyout for the given bubble, if available, and then hides it after some time.
      */
     @VisibleForTesting
     void animateInFlyoutForBubble(Bubble bubble) {
-        final CharSequence updateMessage = bubble.entry.getUpdateMessage(getContext());
+        final CharSequence updateMessage = bubble.getUpdateMessage(getContext());
 
-        // Show the message if one exists, and we're not expanded or animating expansion.
-        if (updateMessage != null
-                && !isExpanded()
-                && !mIsExpansionAnimating
-                && !mIsGestureInProgress
-                && !mSuppressFlyout) {
-            if (bubble.iconView != null) {
-                // Temporarily suppress the dot while the flyout is visible.
-                bubble.iconView.setSuppressDot(
-                        true /* suppressDot */, false /* animate */);
+        if (!bubble.showFlyoutForBubble()) {
+            // In case flyout was suppressed for this update, reset now.
+            bubble.setSuppressFlyout(false);
+            return;
+        }
 
-                mFlyoutDragDeltaX = 0f;
-                mFlyout.setAlpha(0f);
+        if (updateMessage == null
+                || isExpanded()
+                || mIsExpansionAnimating
+                || mIsGestureInProgress
+                || mBubbleToExpandAfterFlyoutCollapse != null) {
+            // Skip the message if none exists, we're expanded or animating expansion, or we're
+            // about to expand a bubble from the previous tapped flyout.
+            return;
+        }
 
-                if (mAfterFlyoutHides != null) {
-                    mAfterFlyoutHides.run();
-                }
+        if (bubble.getIconView() != null) {
+            // Temporarily suppress the dot while the flyout is visible.
+            bubble.getIconView().setSuppressDot(
+                    true /* suppressDot */, false /* animate */);
 
-                mAfterFlyoutHides = () -> {
-                    if (bubble.iconView == null) {
-                        return;
-                    }
+            mFlyout.removeCallbacks(mAnimateInFlyout);
+            mFlyoutDragDeltaX = 0f;
 
-                    // If we're going to suppress the dot, make it visible first so it'll
-                    // visibly animate away.
-                    if (mSuppressNewDot) {
-                        bubble.iconView.setSuppressDot(
-                                false /* suppressDot */, false /* animate */);
-                    }
-
-                    // Reset dot suppression. If we're not suppressing due to DND, then
-                    // stop suppressing it with no animation (since the flyout has
-                    // transformed into the dot). If we are suppressing due to DND, animate
-                    // it away.
-                    bubble.iconView.setSuppressDot(
-                            mSuppressNewDot /* suppressDot */,
-                            mSuppressNewDot /* animate */);
-                };
-
-                // Post in case layout isn't complete and getWidth returns 0.
-                post(() -> {
-                    // An auto-expanding bubble could have been posted during the time it takes to
-                    // layout.
-                    if (isExpanded()) {
-                        return;
-                    }
-
-                    mFlyout.showFlyout(
-                            updateMessage, mStackAnimationController.getStackPosition(), getWidth(),
-                            mStackAnimationController.isStackOnLeftSide(),
-                            bubble.iconView.getBadgeColor(), mAfterFlyoutHides);
-                });
+            if (mAfterFlyoutHides != null) {
+                mAfterFlyoutHides.run();
             }
 
-            mFlyout.removeCallbacks(mHideFlyout);
-            mFlyout.postDelayed(mHideFlyout, FLYOUT_HIDE_AFTER);
-            logBubbleEvent(bubble, StatsLog.BUBBLE_UICHANGED__ACTION__FLYOUT);
+            mAfterFlyoutHides = () -> {
+                final boolean suppressDot = !bubble.showBubbleDot();
+                // If we're going to suppress the dot, make it visible first so it'll
+                // visibly animate away.
+                if (suppressDot) {
+                    bubble.getIconView().setSuppressDot(
+                            false /* suppressDot */, false /* animate */);
+                }
+                // Reset dot suppression. If we're not suppressing due to DND, then
+                // stop suppressing it with no animation (since the flyout has
+                // transformed into the dot). If we are suppressing due to DND, animate
+                // it away.
+                bubble.getIconView().setSuppressDot(
+                        suppressDot /* suppressDot */,
+                        suppressDot /* animate */);
+
+                if (mBubbleToExpandAfterFlyoutCollapse != null) {
+                    mBubbleData.setSelectedBubble(mBubbleToExpandAfterFlyoutCollapse);
+                    mBubbleData.setExpanded(true);
+                    mBubbleToExpandAfterFlyoutCollapse = null;
+                }
+            };
+
+            mFlyout.setVisibility(INVISIBLE);
+
+            // Post in case layout isn't complete and getWidth returns 0.
+            post(() -> {
+                // An auto-expanding bubble could have been posted during the time it takes to
+                // layout.
+                if (isExpanded()) {
+                    return;
+                }
+
+                final Runnable afterShow = () -> {
+                    mAnimateInFlyout = () -> {
+                        mFlyout.setVisibility(VISIBLE);
+                        bubble.getIconView().setSuppressDot(
+                                true /* suppressDot */, false /* animate */);
+                        mFlyoutDragDeltaX =
+                                mStackAnimationController.isStackOnLeftSide()
+                                        ? -mFlyout.getWidth()
+                                        : mFlyout.getWidth();
+                        animateFlyoutCollapsed(false /* collapsed */, 0 /* velX */);
+                        mFlyout.postDelayed(mHideFlyout, FLYOUT_HIDE_AFTER);
+                    };
+
+                    mFlyout.postDelayed(mAnimateInFlyout, 200);
+                };
+
+                mFlyout.setupFlyoutStartingAsDot(
+                        updateMessage, mStackAnimationController.getStackPosition(), getWidth(),
+                        mStackAnimationController.isStackOnLeftSide(),
+                        bubble.getIconView().getBadgeColor(),
+                        afterShow,
+                        mAfterFlyoutHides,
+                        bubble.getIconView().getDotCenter());
+                mFlyout.bringToFront();
+            });
         }
+
+        mFlyout.removeCallbacks(mHideFlyout);
+        mFlyout.postDelayed(mHideFlyout, FLYOUT_HIDE_AFTER);
+        logBubbleEvent(bubble, StatsLog.BUBBLE_UICHANGED__ACTION__FLYOUT);
     }
 
     /** Hide the flyout immediately and cancel any pending hide runnables. */
@@ -1420,6 +1501,7 @@
             mAfterFlyoutHides.run();
         }
 
+        mFlyout.removeCallbacks(mAnimateInFlyout);
         mFlyout.removeCallbacks(mHideFlyout);
         mFlyout.hideFlyout();
     }
@@ -1430,6 +1512,11 @@
             if (mBubbleContainer.getChildCount() > 0) {
                 mBubbleContainer.getChildAt(0).getBoundsOnScreen(outRect);
             }
+            // Increase the touch target size of the bubble
+            outRect.top -= mBubbleTouchPadding;
+            outRect.left -= mBubbleTouchPadding;
+            outRect.right += mBubbleTouchPadding;
+            outRect.bottom += mBubbleTouchPadding;
         } else {
             mBubbleContainer.getBoundsOnScreen(outRect);
         }
@@ -1454,14 +1541,6 @@
         return 0;
     }
 
-    private int getBottomInset() {
-        if (getRootWindowInsets() != null) {
-            WindowInsets insets = getRootWindowInsets();
-            return insets.getSystemWindowInsetBottom();
-        }
-        return 0;
-    }
-
     private boolean isIntersecting(View view, float x, float y) {
         mTempLoc = view.getLocationOnScreen();
         mTempRect.set(mTempLoc[0], mTempLoc[1], mTempLoc[0] + view.getWidth(),
@@ -1479,33 +1558,33 @@
     }
 
     private void updateExpandedBubble() {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_STACK_VIEW) {
             Log.d(TAG, "updateExpandedBubble()");
         }
         mExpandedViewContainer.removeAllViews();
         if (mExpandedBubble != null && mIsExpanded) {
-            mExpandedViewContainer.addView(mExpandedBubble.expandedView);
-            mExpandedBubble.expandedView.populateExpandedView();
+            mExpandedViewContainer.addView(mExpandedBubble.getExpandedView());
+            mExpandedBubble.getExpandedView().populateExpandedView();
             mExpandedViewContainer.setVisibility(mIsExpanded ? VISIBLE : GONE);
             mExpandedViewContainer.setAlpha(1.0f);
         }
     }
 
-    private void applyCurrentState() {
-        if (DEBUG) {
-            Log.d(TAG, "applyCurrentState: mIsExpanded=" + mIsExpanded);
+    private void updateExpandedView() {
+        if (DEBUG_BUBBLE_STACK_VIEW) {
+            Log.d(TAG, "updateExpandedView: mIsExpanded=" + mIsExpanded);
         }
 
         mExpandedViewContainer.setVisibility(mIsExpanded ? VISIBLE : GONE);
         if (mIsExpanded) {
             // First update the view so that it calculates a new height (ensuring the y position
             // calculation is correct)
-            mExpandedBubble.expandedView.updateView();
-            final float y = getYPositionForExpandedView();
+            mExpandedBubble.getExpandedView().updateView();
+            final float y = getExpandedViewY();
             if (!mExpandedViewYAnim.isRunning()) {
                 // We're not animating so set the value
                 mExpandedViewContainer.setTranslationY(y);
-                mExpandedBubble.expandedView.updateView();
+                mExpandedBubble.getExpandedView().updateView();
             } else {
                 // We are animating so update the value; there is an end listener on the animator
                 // that will ensure expandedeView.updateView gets called.
@@ -1514,29 +1593,17 @@
         }
 
         mStackOnLeftOrWillBe = mStackAnimationController.isStackOnLeftSide();
-        updateBubbleShadowsAndDotPosition(false);
+        updateBubbleZOrdersAndDotPosition(false);
     }
 
     /** Sets the appropriate Z-order and dot position for each bubble in the stack. */
-    private void updateBubbleShadowsAndDotPosition(boolean animate) {
-        int bubbsCount = mBubbleContainer.getChildCount();
-        for (int i = 0; i < bubbsCount; i++) {
+    private void updateBubbleZOrdersAndDotPosition(boolean animate) {
+        int bubbleCount = mBubbleContainer.getChildCount();
+        for (int i = 0; i < bubbleCount; i++) {
             BubbleView bv = (BubbleView) mBubbleContainer.getChildAt(i);
             bv.updateDotVisibility(true /* animate */);
             bv.setZ((BubbleController.MAX_BUBBLES
                     * getResources().getDimensionPixelSize(R.dimen.bubble_elevation)) - i);
-
-            // Draw the shadow around the circle inscribed within the bubble's bounds. This
-            // (intentionally) does not draw a shadow behind the update dot, which should be drawing
-            // its own shadow since it's on a different (higher) plane.
-            bv.setOutlineProvider(new ViewOutlineProvider() {
-                @Override
-                public void getOutline(View view, Outline outline) {
-                    outline.setOval(0, 0, mBubbleSize, mBubbleSize);
-                }
-            });
-            bv.setClipToOutline(false);
-
             // If the dot is on the left, and so is the stack, we need to change the dot position.
             if (bv.getDotPositionOnLeft() == mStackOnLeftOrWillBe) {
                 bv.setDotPosition(!mStackOnLeftOrWillBe, animate);
@@ -1545,7 +1612,7 @@
     }
 
     private void updatePointerPosition() {
-        if (DEBUG) {
+        if (DEBUG_BUBBLE_STACK_VIEW) {
             Log.d(TAG, "updatePointerPosition()");
         }
 
@@ -1557,13 +1624,11 @@
         int index = getBubbleIndex(expandedBubble);
         float bubbleLeftFromScreenLeft = mExpandedAnimationController.getBubbleLeft(index);
         float halfBubble = mBubbleSize / 2f;
+        float bubbleCenter = bubbleLeftFromScreenLeft + halfBubble;
+        // Padding might be adjusted for insets, so get it directly from the view
+        bubbleCenter -= mExpandedViewContainer.getPaddingLeft();
 
-        // Bubbles live in expanded view container (x includes expanded view padding).
-        // Pointer lives in expanded view, which has padding (x does not include padding).
-        // Remove padding when deriving pointer location from bubbles.
-        float bubbleCenter = bubbleLeftFromScreenLeft + halfBubble - mExpandedViewPadding;
-
-        expandedBubble.expandedView.setPointerPosition(bubbleCenter);
+        expandedBubble.getExpandedView().setPointerPosition(bubbleCenter);
     }
 
     /**
@@ -1584,7 +1649,7 @@
         if (bubble == null) {
             return 0;
         }
-        return mBubbleContainer.indexOfChild(bubble.iconView);
+        return mBubbleContainer.indexOfChild(bubble.getIconView());
     }
 
     /**
@@ -1617,8 +1682,8 @@
      * @param action the user interaction enum.
      */
     private void logBubbleEvent(@Nullable Bubble bubble, int action) {
-        if (bubble == null || bubble.entry == null
-                || bubble.entry.notification == null) {
+        if (bubble == null || bubble.getEntry() == null
+                || bubble.getEntry().notification == null) {
             StatsLog.write(StatsLog.BUBBLE_UI_CHANGED,
                     null /* package name */,
                     null /* notification channel */,
@@ -1630,9 +1695,9 @@
                     getNormalizedYPosition(),
                     false /* unread bubble */,
                     false /* on-going bubble */,
-                    false /* foreground bubble */);
+                    false /* isAppForeground (unused) */);
         } else {
-            StatusBarNotification notification = bubble.entry.notification;
+            StatusBarNotification notification = bubble.getEntry().notification;
             StatsLog.write(StatsLog.BUBBLE_UI_CHANGED,
                     notification.getPackageName(),
                     notification.getNotification().getChannelId(),
@@ -1642,9 +1707,9 @@
                     action,
                     getNormalizedXPosition(),
                     getNormalizedYPosition(),
-                    bubble.entry.showInShadeWhenBubble(),
-                    bubble.entry.isForegroundService(),
-                    BubbleController.isForegroundApp(mContext, notification.getPackageName()));
+                    bubble.showInShadeWhenBubble(),
+                    bubble.isOngoing(),
+                    false /* isAppForeground (unused) */);
         }
     }
 
@@ -1656,7 +1721,7 @@
         if (!isExpanded()) {
             return false;
         }
-        return mExpandedBubble.expandedView.performBackPressIfNeeded();
+        return mExpandedBubble.getExpandedView().performBackPressIfNeeded();
     }
 
     /** For debugging only */
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java
index 8fe8bd3..4240e06 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.graphics.PointF;
-import android.os.Handler;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
@@ -45,7 +44,6 @@
      */
     private static final float INDIVIDUAL_BUBBLE_DISMISS_MIN_VELOCITY = 6000f;
 
-    private static final String TAG = "BubbleTouchHandler";
     /**
      * When the stack is flung towards the bottom of the screen, it'll be dismissed if it's flung
      * towards the center of the screen (where the dismiss target is). This value is the width of
@@ -66,11 +64,10 @@
     private int mTouchSlopSquared;
     private VelocityTracker mVelocityTracker;
 
-    private boolean mInDismissTarget;
-    private Handler mHandler = new Handler();
-
     /** View that was initially touched, when we received the first ACTION_DOWN event. */
     private View mTouchedView;
+    /** Whether the current touched view is in the dismiss target. */
+    private boolean mInDismissTarget;
 
     BubbleTouchHandler(BubbleStackView stackView,
             BubbleData bubbleData, Context context) {
@@ -98,6 +95,15 @@
             return false;
         }
 
+        if (!(mTouchedView instanceof BubbleView)
+                && !(mTouchedView instanceof BubbleStackView)
+                && !(mTouchedView instanceof BubbleFlyoutView)) {
+            // Not touching anything touchable, but we shouldn't collapse (e.g. touching edge
+            // of expanded view).
+            resetForNextGesture();
+            return false;
+        }
+
         final boolean isStack = mStack.equals(mTouchedView);
         final boolean isFlyout = mStack.getFlyoutView().equals(mTouchedView);
         final float rawX = event.getRawX();
@@ -193,9 +199,8 @@
                                 }
                             });
                 } else if (isFlyout) {
-                    // TODO(b/129768381): Expand if tapped, dismiss if swiped away.
                     if (!mBubbleData.isExpanded() && !mMovedEnough) {
-                        mBubbleData.setExpanded(true);
+                        mStack.onFlyoutTapped();
                     }
                 } else if (mMovedEnough) {
                     if (isStack) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java
index 6f1ed28..603c416 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java
@@ -19,16 +19,23 @@
 import android.annotation.Nullable;
 import android.app.Notification;
 import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.Path;
 import android.graphics.drawable.AdaptiveIconDrawable;
+import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.graphics.drawable.InsetDrawable;
 import android.util.AttributeSet;
+import android.util.PathParser;
 import android.widget.FrameLayout;
 
 import com.android.internal.graphics.ColorUtils;
+import com.android.launcher3.icons.ShadowGenerator;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -38,23 +45,25 @@
  * A floating object on the screen that can post message updates.
  */
 public class BubbleView extends FrameLayout {
-    private static final String TAG = "BubbleView";
 
     private static final int DARK_ICON_ALPHA = 180;
     private static final double ICON_MIN_CONTRAST = 4.1;
-    private static final int DEFAULT_BACKGROUND_COLOR =  Color.LTGRAY;
+    private static final int DEFAULT_BACKGROUND_COLOR = Color.LTGRAY;
     // Same value as Launcher3 badge code
     private static final float WHITE_SCRIM_ALPHA = 0.54f;
     private Context mContext;
 
     private BadgedImageView mBadgedImageView;
     private int mBadgeColor;
-    private int mPadding;
     private int mIconInset;
+    private Drawable mUserBadgedAppIcon;
+
+    // mBubbleIconFactory cannot be static because it depends on Context.
+    private BubbleIconFactory mBubbleIconFactory;
 
     private boolean mSuppressDot = false;
 
-    private NotificationEntry mEntry;
+    private Bubble mBubble;
 
     public BubbleView(Context context) {
         this(context, null);
@@ -71,8 +80,6 @@
     public BubbleView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
         mContext = context;
-        // XXX: can this padding just be on the view and we look it up?
-        mPadding = getResources().getDimensionPixelSize(R.dimen.bubble_view_padding);
         mIconInset = getResources().getDimensionPixelSize(R.dimen.bubble_icon_inset);
     }
 
@@ -88,16 +95,15 @@
     }
 
     /**
-     * Populates this view with a notification.
+     * Populates this view with a bubble.
      * <p>
-     * This should only be called when a new notification is being set on the view, updates to the
-     * current notification should use {@link #update(NotificationEntry)}.
+     * This should only be called when a new bubble is being set on the view, updates to the
+     * current bubble should use {@link #update(Bubble)}.
      *
-     * @param entry the notification to display as a bubble.
+     * @param bubble the bubble to display in this view.
      */
-    public void setNotif(NotificationEntry entry) {
-        mEntry = entry;
-        updateViews();
+    public void setBubble(Bubble bubble) {
+        mBubble = bubble;
     }
 
     /**
@@ -105,7 +111,7 @@
      */
     @Nullable
     public NotificationEntry getEntry() {
-        return mEntry;
+        return mBubble != null ? mBubble.getEntry() : null;
     }
 
     /**
@@ -113,24 +119,34 @@
      */
     @Nullable
     public String getKey() {
-        return (mEntry != null) ? mEntry.key : null;
+        return (mBubble != null) ? mBubble.getKey() : null;
     }
 
     /**
-     * Updates the UI based on the entry, updates badge and animates messages as needed.
+     * Updates the UI based on the bubble, updates badge and animates messages as needed.
      */
-    public void update(NotificationEntry entry) {
-        mEntry = entry;
+    public void update(Bubble bubble) {
+        mBubble = bubble;
         updateViews();
     }
 
     /**
+     * @param factory Factory for creating normalized bubble icons.
+     */
+    public void setBubbleIconFactory(BubbleIconFactory factory) {
+        mBubbleIconFactory = factory;
+    }
+
+    public void setAppIcon(Drawable appIcon) {
+        mUserBadgedAppIcon = appIcon;
+    }
+    /**
      * @return the {@link ExpandableNotificationRow} view to display notification content when the
      * bubble is expanded.
      */
     @Nullable
     public ExpandableNotificationRow getRowView() {
-        return (mEntry != null) ? mEntry.getRow() : null;
+        return (mBubble != null) ? mBubble.getEntry().getRow() : null;
     }
 
     /** Changes the dot's visibility to match the bubble view's state. */
@@ -150,18 +166,23 @@
 
     /** Sets the position of the 'new' dot, animating it out and back in if requested. */
     void setDotPosition(boolean onLeft, boolean animate) {
-        if (animate && onLeft != mBadgedImageView.getDotPosition() && !mSuppressDot) {
+        if (animate && onLeft != mBadgedImageView.getDotOnLeft() && !mSuppressDot) {
             animateDot(false /* showDot */, () -> {
-                mBadgedImageView.setDotPosition(onLeft);
+                mBadgedImageView.setDotOnLeft(onLeft);
                 animateDot(true /* showDot */, null);
             });
         } else {
-            mBadgedImageView.setDotPosition(onLeft);
+            mBadgedImageView.setDotOnLeft(onLeft);
         }
     }
 
+    float[] getDotCenter() {
+        float[] unscaled = mBadgedImageView.getDotCenter();
+        return new float[]{unscaled[0], unscaled[1]};
+    }
+
     boolean getDotPositionOnLeft() {
-        return mBadgedImageView.getDotPosition();
+        return mBadgedImageView.getDotOnLeft();
     }
 
     /**
@@ -169,7 +190,7 @@
      * after animation if requested.
      */
     private void updateDotVisibility(boolean animate, Runnable after) {
-        boolean showDot = getEntry().showInShadeWhenBubble() && !mSuppressDot;
+        boolean showDot = mBubble.showBubbleDot() && !mSuppressDot;
 
         if (animate) {
             animateDot(showDot, after);
@@ -186,7 +207,6 @@
             if (showDot) {
                 mBadgedImageView.setShowDot(true);
             }
-
             mBadgedImageView.clearAnimation();
             mBadgedImageView.animate().setDuration(200)
                     .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
@@ -207,37 +227,60 @@
     }
 
     void updateViews() {
-        if (mEntry == null) {
+        if (mBubble == null || mBubbleIconFactory == null) {
             return;
         }
-        Notification.BubbleMetadata metadata = mEntry.getBubbleMetadata();
-        Notification n = mEntry.notification.getNotification();
-        Icon ic;
-        boolean needsTint;
-        if (metadata != null) {
-            ic = metadata.getIcon();
-            needsTint = ic.getType() != Icon.TYPE_ADAPTIVE_BITMAP;
-        } else {
-            needsTint = n.getLargeIcon() == null;
-            ic = needsTint ? n.getSmallIcon() : n.getLargeIcon();
-        }
+        // Update icon.
+        Notification.BubbleMetadata metadata = mBubble.getEntry().getBubbleMetadata();
+        Notification n = mBubble.getEntry().notification.getNotification();
+        Icon ic = metadata.getIcon();
+        boolean needsTint = ic.getType() != Icon.TYPE_ADAPTIVE_BITMAP;
+
         Drawable iconDrawable = ic.loadDrawable(mContext);
         if (needsTint) {
-            mBadgedImageView.setImageDrawable(buildIconWithTint(iconDrawable, n.color));
-        } else {
-            mBadgedImageView.setImageDrawable(iconDrawable);
+            iconDrawable = buildIconWithTint(iconDrawable, n.color);
         }
+        Bitmap bubbleIcon = mBubbleIconFactory.createBadgedIconBitmap(iconDrawable,
+                null /* user */,
+                true /* shrinkNonAdaptiveIcons */).icon;
+
+        // Give it a shadow
+        Bitmap userBadgedBitmap = mBubbleIconFactory.createIconBitmap(mUserBadgedAppIcon,
+                1f, mBubbleIconFactory.getBadgeSize());
+        Canvas c = new Canvas();
+        ShadowGenerator shadowGenerator = new ShadowGenerator(mBubbleIconFactory.getBadgeSize());
+        c.setBitmap(userBadgedBitmap);
+        shadowGenerator.recreateIcon(Bitmap.createBitmap(userBadgedBitmap), c);
+
+        mBubbleIconFactory.badgeWithDrawable(bubbleIcon,
+                new BitmapDrawable(mContext.getResources(), userBadgedBitmap));
+        mBadgedImageView.setImageBitmap(bubbleIcon);
+
+        // Update badge.
         int badgeColor = determineDominateColor(iconDrawable, n.color);
         mBadgeColor = badgeColor;
         mBadgedImageView.setDotColor(badgeColor);
-        animateDot(mEntry.showInShadeWhenBubble() /* showDot */, null /* after */);
+
+        // Update dot.
+        Path iconPath = PathParser.createPathFromPathData(
+                getResources().getString(com.android.internal.R.string.config_icon_mask));
+        Matrix matrix = new Matrix();
+        float scale = mBubbleIconFactory.getNormalizer().getScale(iconDrawable,
+                null /* outBounds */, null /* path */, null /* outMaskShape */);
+        float radius = BadgedImageView.DEFAULT_PATH_SIZE / 2f;
+        matrix.setScale(scale /* x scale */, scale /* y scale */, radius /* pivot x */,
+                radius /* pivot y */);
+        iconPath.transform(matrix);
+        mBadgedImageView.drawDot(iconPath);
+
+        animateDot(mBubble.showBubbleDot() /* showDot */, null /* after */);
     }
 
     int getBadgeColor() {
         return mBadgeColor;
     }
 
-    private Drawable buildIconWithTint(Drawable iconDrawable, int backgroundColor) {
+    private AdaptiveIconDrawable buildIconWithTint(Drawable iconDrawable, int backgroundColor) {
         iconDrawable = checkTint(iconDrawable, backgroundColor);
         InsetDrawable foreground = new InsetDrawable(iconDrawable, mIconInset);
         ColorDrawable background = new ColorDrawable(backgroundColor);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
index 1fa0e12..59d68bc 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
@@ -16,9 +16,12 @@
 
 package com.android.systemui.bubbles.animation;
 
+import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.graphics.Path;
 import android.graphics.Point;
 import android.graphics.PointF;
+import android.view.DisplayCutout;
 import android.view.View;
 import android.view.WindowInsets;
 
@@ -26,10 +29,13 @@
 import androidx.dynamicanimation.animation.DynamicAnimation;
 import androidx.dynamicanimation.animation.SpringForce;
 
+import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 
 import com.google.android.collect.Sets;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.Set;
 
 /**
@@ -46,24 +52,29 @@
      */
     private static final int ANIMATE_TRANSLATION_FACTOR = 4;
 
-    /** How much to scale down bubbles when they're animating in/out. */
-    private static final float ANIMATE_SCALE_PERCENT = 0.5f;
+    /** Duration of the expand/collapse target path animation. */
+    private static final int EXPAND_COLLAPSE_TARGET_ANIM_DURATION = 175;
 
-    /** The stack position to collapse back to in {@link #collapseBackToStack}. */
-    private PointF mCollapseToPoint;
+    /** Stiffness for the expand/collapse path-following animation. */
+    private static final int EXPAND_COLLAPSE_ANIM_STIFFNESS = 1000;
+
+    /** What percentage of the screen to use when centering the bubbles in landscape. */
+    private static final float CENTER_BUBBLES_LANDSCAPE_PERCENT = 0.66f;
 
     /** Horizontal offset between bubbles, which we need to know to re-stack them. */
     private float mStackOffsetPx;
-    /** Spacing between bubbles in the expanded state. */
-    private float mBubblePaddingPx;
+    /** Space between status bar and bubbles in the expanded state. */
+    private float mBubblePaddingTop;
     /** Size of each bubble. */
     private float mBubbleSizePx;
     /** Height of the status bar. */
     private float mStatusBarHeight;
     /** Size of display. */
     private Point mDisplaySize;
-    /** Size of dismiss target at bottom of screen. */
-    private float mPipDismissHeight;
+    /** Max number of bubbles shown in row above expanded view.*/
+    private int mBubblesMaxRendered;
+    /** What the current screen orientation is. */
+    private int mScreenOrientation;
 
     /** Whether the dragged-out bubble is in the dismiss target. */
     private boolean mIndividualBubbleWithinDismissTarget = false;
@@ -86,10 +97,13 @@
     private boolean mSpringingBubbleToTouch = false;
 
     private int mExpandedViewPadding;
+    private float mLauncherGridDiff;
 
-    public ExpandedAnimationController(Point displaySize, int expandedViewPadding) {
-        mDisplaySize = displaySize;
+    public ExpandedAnimationController(Point displaySize, int expandedViewPadding,
+            int orientation) {
+        updateOrientation(orientation, displaySize);
         mExpandedViewPadding = expandedViewPadding;
+        mLauncherGridDiff = 30f;
     }
 
     /**
@@ -109,7 +123,7 @@
         mAnimatingExpand = true;
         mAfterExpand = after;
 
-        startOrUpdateExpandAnimation();
+        startOrUpdatePathAnimation(true /* expanding */);
     }
 
     /** Animate collapsing the bubbles back to their stacked position. */
@@ -119,43 +133,105 @@
         mAfterCollapse = after;
         mCollapsePoint = collapsePoint;
 
-        startOrUpdateCollapseAnimation();
+        startOrUpdatePathAnimation(false /* expanding */);
     }
 
-    private void startOrUpdateExpandAnimation() {
-        animationsForChildrenFromIndex(
-                0, /* startIndex */
-                (index, animation) -> animation.position(getBubbleLeft(index), getExpandedY()))
-                .startAll(() -> {
-                    mAnimatingExpand = false;
-
-                    if (mAfterExpand != null) {
-                        mAfterExpand.run();
-                    }
-
-                    mAfterExpand = null;
-                });
+    /**
+     * Update effective screen width based on current orientation.
+     * @param orientation Landscape or portrait.
+     * @param displaySize Updated display size.
+     */
+    public void updateOrientation(int orientation, Point displaySize) {
+        mScreenOrientation = orientation;
+        mDisplaySize = displaySize;
+        if (mLayout != null) {
+            Resources res = mLayout.getContext().getResources();
+            mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
+            mStatusBarHeight = res.getDimensionPixelSize(
+                    com.android.internal.R.dimen.status_bar_height);
+        }
     }
 
-    private void startOrUpdateCollapseAnimation() {
-        // Stack to the left if we're going to the left, or right if not.
-        final float sideMultiplier = mLayout.isFirstChildXLeftOfCenter(mCollapsePoint.x) ? -1 : 1;
-        animationsForChildrenFromIndex(
-                0, /* startIndex */
-                (index, animation) -> {
-                    animation.position(
-                            mCollapsePoint.x + (sideMultiplier * index * mStackOffsetPx),
-                            mCollapsePoint.y);
-                })
-                .startAll(() -> {
-                    mAnimatingCollapse = false;
+    /**
+     * Animates the bubbles along a curved path, either to expand them along the top or collapse
+     * them back into a stack.
+     */
+    private void startOrUpdatePathAnimation(boolean expanding) {
+        Runnable after;
 
-                    if (mAfterCollapse != null) {
-                        mAfterCollapse.run();
-                    }
+        if (expanding) {
+            after = () -> {
+                mAnimatingExpand = false;
 
-                    mAfterCollapse = null;
-                });
+                if (mAfterExpand != null) {
+                    mAfterExpand.run();
+                }
+
+                mAfterExpand = null;
+            };
+        } else {
+            after = () -> {
+                mAnimatingCollapse = false;
+
+                if (mAfterCollapse != null) {
+                    mAfterCollapse.run();
+                }
+
+                mAfterCollapse = null;
+            };
+        }
+
+        // Animate each bubble individually, since each path will end in a different spot.
+        animationsForChildrenFromIndex(0, (index, animation) -> {
+            final View bubble = mLayout.getChildAt(index);
+
+            // Start a path at the bubble's current position.
+            final Path path = new Path();
+            path.moveTo(bubble.getTranslationX(), bubble.getTranslationY());
+
+            final float expandedY = getExpandedY();
+            if (expanding) {
+                // If we're expanding, first draw a line from the bubble's current position to the
+                // top of the screen.
+                path.lineTo(bubble.getTranslationX(), expandedY);
+
+                // Then, draw a line across the screen to the bubble's resting position.
+                path.lineTo(getBubbleLeft(index), expandedY);
+            } else {
+                final float sideMultiplier =
+                        mLayout.isFirstChildXLeftOfCenter(mCollapsePoint.x) ? -1 : 1;
+                final float stackedX = mCollapsePoint.x + (sideMultiplier * index * mStackOffsetPx);
+
+                // If we're collapsing, draw a line from the bubble's current position to the side
+                // of the screen where the bubble will be stacked.
+                path.lineTo(stackedX, expandedY);
+
+                // Then, draw a line down to the stack position.
+                path.lineTo(stackedX, mCollapsePoint.y);
+            }
+
+            // The lead bubble should be the bubble with the longest distance to travel when we're
+            // expanding, and the bubble with the shortest distance to travel when we're collapsing.
+            // During expansion from the left side, the last bubble has to travel to the far right
+            // side, so we have it lead and 'pull' the rest of the bubbles into place. From the
+            // right side, the first bubble is traveling to the top left, so it leads. During
+            // collapse to the left, the first bubble has the shortest travel time back to the stack
+            // position, so it leads (and vice versa).
+            final boolean firstBubbleLeads =
+                    (expanding && !mLayout.isFirstChildXLeftOfCenter(bubble.getTranslationX()))
+                            || (!expanding && mLayout.isFirstChildXLeftOfCenter(mCollapsePoint.x));
+            final int startDelay = firstBubbleLeads
+                    ? (index * 10)
+                    : ((mLayout.getChildCount() - index) * 10);
+
+            animation
+                    .followAnimatedTargetAlongPath(
+                            path,
+                            EXPAND_COLLAPSE_TARGET_ANIM_DURATION /* targetAnimDuration */,
+                            Interpolators.LINEAR /* targetAnimInterpolator */)
+                    .withStartDelay(startDelay)
+                    .withStiffness(EXPAND_COLLAPSE_ANIM_STIFFNESS);
+        }).startAll(after);
     }
 
     /** Prepares the given bubble to be dragged out. */
@@ -265,6 +341,7 @@
     public void onGestureFinished() {
         mBubbleDraggedOutEnough = false;
         mBubbleDraggingOut = null;
+        updateBubblePositions();
     }
 
     /**
@@ -276,41 +353,38 @@
                 0, (i, anim) -> anim.translationY(getExpandedY())).startAll(after);
     }
 
-    /**
-     * Animates the bubbles, starting at the given index, to the left or right by the given number
-     * of bubble widths. Passing zero for numBubbleWidths will animate the bubbles to their normal
-     * positions.
-     */
-    private void animateStackByBubbleWidthsStartingFrom(int numBubbleWidths, int startIndex) {
-        animationsForChildrenFromIndex(
-                startIndex,
-                (index, animation) ->
-                        animation.translationX(getXForChildAtIndex(index + numBubbleWidths)))
-            .startAll();
-    }
-
     /** The Y value of the row of expanded bubbles. */
     public float getExpandedY() {
         if (mLayout == null || mLayout.getRootWindowInsets() == null) {
             return 0;
         }
         final WindowInsets insets = mLayout.getRootWindowInsets();
-        return mBubblePaddingPx + Math.max(
+        return mBubblePaddingTop + Math.max(
             mStatusBarHeight,
             insets.getDisplayCutout() != null
                 ? insets.getDisplayCutout().getSafeInsetTop()
                 : 0);
     }
 
+    /** Description of current animation controller state. */
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("ExpandedAnimationController state:");
+        pw.print("  isActive:          "); pw.println(isActiveController());
+        pw.print("  animatingExpand:   "); pw.println(mAnimatingExpand);
+        pw.print("  animatingCollapse: "); pw.println(mAnimatingCollapse);
+        pw.print("  bubbleInDismiss:   "); pw.println(mIndividualBubbleWithinDismissTarget);
+        pw.print("  springingBubble:   "); pw.println(mSpringingBubbleToTouch);
+    }
+
     @Override
     void onActiveControllerForLayout(PhysicsAnimationLayout layout) {
         final Resources res = layout.getResources();
         mStackOffsetPx = res.getDimensionPixelSize(R.dimen.bubble_stack_offset);
-        mBubblePaddingPx = res.getDimensionPixelSize(R.dimen.bubble_padding);
+        mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
         mBubbleSizePx = res.getDimensionPixelSize(R.dimen.individual_bubble_size);
         mStatusBarHeight =
                 res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
-        mPipDismissHeight = res.getDimensionPixelSize(R.dimen.pip_dismiss_gradient_height);
+        mBubblesMaxRendered = res.getInteger(R.integer.bubbles_max_rendered);
 
         // Ensure that all child views are at 1x scale, and visible, in case they were animating
         // in.
@@ -351,11 +425,11 @@
         // If a bubble is added while the expand/collapse animations are playing, update the
         // animation to include the new bubble.
         if (mAnimatingExpand) {
-            startOrUpdateExpandAnimation();
+            startOrUpdatePathAnimation(true /* expanding */);
         } else if (mAnimatingCollapse) {
-            startOrUpdateCollapseAnimation();
+            startOrUpdatePathAnimation(false /* expanding */);
         } else {
-            child.setTranslationX(getXForChildAtIndex(index));
+            child.setTranslationX(getBubbleLeft(index));
             animationForChild(child)
                     .translationY(
                             getExpandedY() - mBubbleSizePx * ANIMATE_TRANSLATION_FACTOR, /* from */
@@ -389,6 +463,12 @@
     @Override
     void onChildReordered(View child, int oldIndex, int newIndex) {
         updateBubblePositions();
+
+        // We expect reordering during collapse, since we'll put the last selected bubble on top.
+        // Update the collapse animation so they end up in the right stacked positions.
+        if (mAnimatingCollapse) {
+            startOrUpdatePathAnimation(false /* expanding */);
+        }
     }
 
     private void updateBubblePositions() {
@@ -411,35 +491,100 @@
         }
     }
 
-    /** Returns the appropriate X translation value for a bubble at the given index. */
-    private float getXForChildAtIndex(int index) {
-        return mBubblePaddingPx + (mBubbleSizePx + mBubblePaddingPx) * index;
-    }
-
     /**
      * @param index Bubble index in row.
      * @return Bubble left x from left edge of screen.
      */
     public float getBubbleLeft(int index) {
-        float bubbleLeftFromRowLeft = index * (mBubbleSizePx + mBubblePaddingPx);
-        return getRowLeft() + bubbleLeftFromRowLeft;
+        final float bubbleFromRowLeft = index * (mBubbleSizePx + getSpaceBetweenBubbles());
+        return getRowLeft() + bubbleFromRowLeft;
+    }
+
+    /**
+     * When expanded, the bubbles are centered in the screen. In portrait, all available space is
+     * used. In landscape we have too much space so the value is restricted. This method accounts
+     * for window decorations (nav bar, cutouts).
+     *
+     * @return the desired width to display the expanded bubbles in.
+     */
+    private float getWidthForDisplayingBubbles() {
+        final float availableWidth = getAvailableScreenWidth(true /* includeStableInsets */);
+        if (mScreenOrientation == Configuration.ORIENTATION_LANDSCAPE) {
+            // display size y in landscape will be the smaller dimension of the screen
+            return Math.max(mDisplaySize.y, availableWidth * CENTER_BUBBLES_LANDSCAPE_PERCENT);
+        } else {
+            return availableWidth;
+        }
+    }
+
+    /**
+     * Determines the available screen width without the cutout.
+     *
+     * @param subtractStableInsets Whether or not stable insets should also be removed from the
+     *                            returned width.
+     * @return the total screen width available accounting for cutouts and insets,
+     * iff {@param includeStableInsets} is true.
+     */
+    private float getAvailableScreenWidth(boolean subtractStableInsets) {
+        float availableSize = mDisplaySize.x;
+        WindowInsets insets = mLayout != null ? mLayout.getRootWindowInsets() : null;
+        if (insets != null) {
+            int cutoutLeft = 0;
+            int cutoutRight = 0;
+            DisplayCutout cutout = insets.getDisplayCutout();
+            if (cutout != null) {
+                cutoutLeft = cutout.getSafeInsetLeft();
+                cutoutRight = cutout.getSafeInsetRight();
+            }
+            final int stableLeft = subtractStableInsets ? insets.getStableInsetLeft() : 0;
+            final int stableRight = subtractStableInsets ? insets.getStableInsetRight() : 0;
+            availableSize -= Math.max(stableLeft, cutoutLeft);
+            availableSize -= Math.max(stableRight, cutoutRight);
+        }
+        return availableSize;
     }
 
     private float getRowLeft() {
         if (mLayout == null) {
             return 0;
         }
+
         int bubbleCount = mLayout.getChildCount();
 
-        // Width calculations.
-        double bubble = bubbleCount * mBubbleSizePx;
-        float gap = (bubbleCount - 1) * mBubblePaddingPx;
-        float row = gap + (float) bubble;
+        final float totalBubbleWidth = bubbleCount * mBubbleSizePx;
+        final float totalGapWidth = (bubbleCount - 1) * getSpaceBetweenBubbles();
+        final float rowWidth = totalGapWidth + totalBubbleWidth;
 
-        float halfRow = row / 2f;
-        float centerScreen = mDisplaySize.x / 2;
-        float rowLeftFromScreenLeft = centerScreen - halfRow;
+        // This display size we're using includes the size of the insets, we want the true
+        // center of the display minus the notch here, which means we should include the
+        // stable insets (e.g. status bar, nav bar) in this calculation.
+        final float trueCenter = getAvailableScreenWidth(false /* subtractStableInsets */) / 2f;
+        final float halfRow = rowWidth / 2f;
+        final float rowLeft = trueCenter - halfRow;
 
-        return rowLeftFromScreenLeft;
+        return rowLeft;
+    }
+
+    /**
+     * @return Space between bubbles in row above expanded view.
+     */
+    private float getSpaceBetweenBubbles() {
+        /**
+         * Ordered left to right:
+         *  Screen edge
+         *      [mExpandedViewPadding]
+         *  Expanded view edge
+         *      [launcherGridDiff] --- arbitrary value until launcher exports widths
+         *  Launcher's app icon grid edge that we must match
+         */
+        final float rowMargins = (mExpandedViewPadding + mLauncherGridDiff) * 2;
+        final float maxRowWidth = getWidthForDisplayingBubbles() - rowMargins;
+
+        final float totalBubbleWidth = mBubblesMaxRendered * mBubbleSizePx;
+        final float totalGapWidth = maxRowWidth - totalBubbleWidth;
+
+        final int gapCount = mBubblesMaxRendered - 1;
+        final float gapWidth = totalGapWidth / gapCount;
+        return gapWidth;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
index 3a33392..563a0a7 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
@@ -16,7 +16,14 @@
 
 package com.android.systemui.bubbles.animation;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
 import android.content.Context;
+import android.graphics.Path;
+import android.graphics.PointF;
+import android.util.FloatProperty;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
@@ -160,7 +167,7 @@
 
         /** Whether this controller is the currently active controller for its associated layout. */
         protected boolean isActiveController() {
-            return this == mLayout.mController;
+            return mLayout != null && this == mLayout.mController;
         }
 
         protected void setLayout(PhysicsAnimationLayout layout) {
@@ -232,7 +239,7 @@
                 }
 
                 if (endActions != null) {
-                    mLayout.setEndActionForMultipleProperties(
+                    setEndActionForMultipleProperties(
                             runAllEndActions,
                             allAnimatedProperties.toArray(
                                     new DynamicAnimation.ViewProperty[0]));
@@ -243,6 +250,44 @@
                 }
             };
         }
+
+        /**
+         * Sets an end action that will be run when all child animations for a given property have
+         * stopped running.
+         */
+        protected void setEndActionForProperty(
+                Runnable action, DynamicAnimation.ViewProperty property) {
+            mLayout.mEndActionForProperty.put(property, action);
+        }
+
+        /**
+         * Sets an end action that will be run when all child animations for all of the given
+         * properties have stopped running.
+         */
+        protected void setEndActionForMultipleProperties(
+                Runnable action, DynamicAnimation.ViewProperty... properties) {
+            final Runnable checkIfAllFinished = () -> {
+                if (!mLayout.arePropertiesAnimating(properties)) {
+                    action.run();
+
+                    for (DynamicAnimation.ViewProperty property : properties) {
+                        removeEndActionForProperty(property);
+                    }
+                }
+            };
+
+            for (DynamicAnimation.ViewProperty property : properties) {
+                setEndActionForProperty(checkIfAllFinished, property);
+            }
+        }
+
+        /**
+         * Removes the end listener that would have been called when all child animations for a
+         * given property stopped running.
+         */
+        protected void removeEndActionForProperty(DynamicAnimation.ViewProperty property) {
+            mLayout.mEndActionForProperty.remove(property);
+        }
     }
 
     /**
@@ -275,43 +320,6 @@
         }
     }
 
-    /**
-     * Sets an end action that will be run when all child animations for a given property have
-     * stopped running.
-     */
-    public void setEndActionForProperty(Runnable action, DynamicAnimation.ViewProperty property) {
-        mEndActionForProperty.put(property, action);
-    }
-
-    /**
-     * Sets an end action that will be run when all child animations for all of the given properties
-     * have stopped running.
-     */
-    public void setEndActionForMultipleProperties(
-            Runnable action, DynamicAnimation.ViewProperty... properties) {
-        final Runnable checkIfAllFinished = () -> {
-            if (!arePropertiesAnimating(properties)) {
-                action.run();
-
-                for (DynamicAnimation.ViewProperty property : properties) {
-                    removeEndActionForProperty(property);
-                }
-            }
-        };
-
-        for (DynamicAnimation.ViewProperty property : properties) {
-            setEndActionForProperty(checkIfAllFinished, property);
-        }
-    }
-
-    /**
-     * Removes the end listener that would have been called when all child animations for a given
-     * property stopped running.
-     */
-    public void removeEndActionForProperty(DynamicAnimation.ViewProperty property) {
-        mEndActionForProperty.remove(property);
-    }
-
     @Override
     public void addView(View child, int index, ViewGroup.LayoutParams params) {
         addViewInternal(child, index, params, false /* isReorder */);
@@ -372,11 +380,22 @@
     /** Checks whether any animations of the given properties are running on the given view. */
     public boolean arePropertiesAnimatingOnView(
             View view, DynamicAnimation.ViewProperty... properties) {
+        final ObjectAnimator targetAnimator = getTargetAnimatorFromView(view);
         for (DynamicAnimation.ViewProperty property : properties) {
             final SpringAnimation animation = getAnimationFromView(property, view);
             if (animation != null && animation.isRunning()) {
                 return true;
             }
+
+            // If the target animator is running, its update listener will trigger the translation
+            // physics animations at some point. We should consider the translation properties to be
+            // be animating in this case, even if the physics animations haven't been started yet.
+            final boolean isTranslation =
+                    property.equals(DynamicAnimation.TRANSLATION_X)
+                            || property.equals(DynamicAnimation.TRANSLATION_Y);
+            if (isTranslation && targetAnimator != null && targetAnimator.isRunning()) {
+                return true;
+            }
         }
 
         return false;
@@ -388,8 +407,18 @@
             return;
         }
 
+        cancelAllAnimationsOfProperties(
+                mController.getAnimatedProperties().toArray(new DynamicAnimation.ViewProperty[]{}));
+    }
+
+    /** Cancels all animations that are running on all child views, for the given properties. */
+    public void cancelAllAnimationsOfProperties(DynamicAnimation.ViewProperty... properties) {
+        if (mController == null) {
+            return;
+        }
+
         for (int i = 0; i < getChildCount(); i++) {
-            for (DynamicAnimation.ViewProperty property : mController.getAnimatedProperties()) {
+            for (DynamicAnimation.ViewProperty property : properties) {
                 final DynamicAnimation anim = getAnimationAtIndex(property, i);
                 if (anim != null) {
                     anim.cancel();
@@ -400,6 +429,14 @@
 
     /** Cancels all of the physics animations running on the given view. */
     public void cancelAnimationsOnView(View view) {
+        // If present, cancel the target animator so it doesn't restart the translation physics
+        // animations.
+        final ObjectAnimator targetAnimator = getTargetAnimatorFromView(view);
+        if (targetAnimator != null) {
+            targetAnimator.cancel();
+        }
+
+        // Cancel physics animations on the view.
         for (DynamicAnimation.ViewProperty property : mController.getAnimatedProperties()) {
             getAnimationFromView(property, view).cancel();
         }
@@ -470,6 +507,11 @@
         return (SpringAnimation) view.getTag(getTagIdForProperty(property));
     }
 
+    /** Retrieves the target animator from the view via the view tag system. */
+    @Nullable private ObjectAnimator getTargetAnimatorFromView(View view) {
+        return (ObjectAnimator) view.getTag(R.id.target_animator_tag);
+    }
+
     /** Sets up SpringAnimations of the given property for each child view in the layout. */
     private void setUpAnimationsForProperty(DynamicAnimation.ViewProperty property) {
         for (int i = 0; i < getChildCount(); i++) {
@@ -587,7 +629,7 @@
          * End actions to call when both TRANSLATION_X and TRANSLATION_Y animations have completed,
          * if {@link #position} was used to animate TRANSLATION_X and TRANSLATION_Y simultaneously.
          */
-        private Runnable[] mPositionEndActions;
+        @Nullable private Runnable[] mPositionEndActions;
 
         /**
          * All of the properties that have been set and will animate when {@link #start} is called.
@@ -603,6 +645,46 @@
         /** The animation controller that last retrieved this animator instance. */
         private PhysicsAnimationController mAssociatedController;
 
+        /**
+         * Animator used to traverse the path provided to {@link #followAnimatedTargetAlongPath}. As
+         * the path is traversed, the view's translation spring animation final positions are
+         * updated such that the view 'follows' the current position on the path.
+         */
+        @Nullable private ObjectAnimator mPathAnimator;
+
+        /** Current position on the path. This is animated by {@link #mPathAnimator}. */
+        private PointF mCurrentPointOnPath = new PointF();
+
+        /**
+         * FloatProperty instances that can be passed to {@link ObjectAnimator} to animate the value
+         * of {@link #mCurrentPointOnPath}.
+         */
+        private final FloatProperty<PhysicsPropertyAnimator> mCurrentPointOnPathXProperty =
+                new FloatProperty<PhysicsPropertyAnimator>("PathX") {
+            @Override
+            public void setValue(PhysicsPropertyAnimator object, float value) {
+                mCurrentPointOnPath.x = value;
+            }
+
+            @Override
+            public Float get(PhysicsPropertyAnimator object) {
+                return mCurrentPointOnPath.x;
+            }
+        };
+
+        private final FloatProperty<PhysicsPropertyAnimator> mCurrentPointOnPathYProperty =
+                new FloatProperty<PhysicsPropertyAnimator>("PathY") {
+            @Override
+            public void setValue(PhysicsPropertyAnimator object, float value) {
+                mCurrentPointOnPath.y = value;
+            }
+
+            @Override
+            public Float get(PhysicsPropertyAnimator object) {
+                return mCurrentPointOnPath.y;
+            }
+        };
+
         protected PhysicsPropertyAnimator(View view) {
             this.mView = view;
         }
@@ -628,6 +710,7 @@
 
         /** Animate the view's translationX value to the provided value. */
         public PhysicsPropertyAnimator translationX(float translationX, Runnable... endActions) {
+            mPathAnimator = null; // We aren't using the path anymore if we're translating.
             return property(DynamicAnimation.TRANSLATION_X, translationX, endActions);
         }
 
@@ -640,6 +723,7 @@
 
         /** Animate the view's translationY value to the provided value. */
         public PhysicsPropertyAnimator translationY(float translationY, Runnable... endActions) {
+            mPathAnimator = null; // We aren't using the path anymore if we're translating.
             return property(DynamicAnimation.TRANSLATION_Y, translationY, endActions);
         }
 
@@ -661,6 +745,46 @@
             return translationY(translationY);
         }
 
+        /**
+         * Animates a 'target' point that moves along the given path, using the provided duration
+         * and interpolator to animate the target. The view itself is animated using physics-based
+         * animations, whose final positions are updated to the target position as it animates. This
+         * results in the view 'following' the target in a realistic way.
+         *
+         * This method will override earlier calls to {@link #translationX}, {@link #translationY},
+         * or {@link #position}, ultimately animating the view's position to the final point on the
+         * given path.
+         *
+         * Any provided end listeners will be called when the physics-based animations kicked off by
+         * the moving target have completed - not when the target animation completes.
+         */
+        public PhysicsPropertyAnimator followAnimatedTargetAlongPath(
+                Path path,
+                int targetAnimDuration,
+                TimeInterpolator targetAnimInterpolator,
+                Runnable... endActions) {
+            mPathAnimator = ObjectAnimator.ofFloat(
+                    this, mCurrentPointOnPathXProperty, mCurrentPointOnPathYProperty, path);
+            mPathAnimator.setDuration(targetAnimDuration);
+            mPathAnimator.setInterpolator(targetAnimInterpolator);
+
+            mPositionEndActions = endActions;
+
+            // Remove translation related values since we're going to ignore them and follow the
+            // path instead.
+            clearTranslationValues();
+            return this;
+        }
+
+        private void clearTranslationValues() {
+            mAnimatedProperties.remove(DynamicAnimation.TRANSLATION_X);
+            mAnimatedProperties.remove(DynamicAnimation.TRANSLATION_Y);
+            mInitialPropertyValues.remove(DynamicAnimation.TRANSLATION_X);
+            mInitialPropertyValues.remove(DynamicAnimation.TRANSLATION_Y);
+            mEndActionForProperty.remove(DynamicAnimation.TRANSLATION_X);
+            mEndActionForProperty.remove(DynamicAnimation.TRANSLATION_Y);
+        }
+
         /** Animate the view's scaleX value to the provided value. */
         public PhysicsPropertyAnimator scaleX(float scaleX, Runnable... endActions) {
             return property(DynamicAnimation.SCALE_X, scaleX, endActions);
@@ -742,7 +866,7 @@
             if (after != null && after.length > 0) {
                 final DynamicAnimation.ViewProperty[] propertiesArray =
                         properties.toArray(new DynamicAnimation.ViewProperty[0]);
-                setEndActionForMultipleProperties(() -> {
+                mAssociatedController.setEndActionForMultipleProperties(() -> {
                     for (Runnable callback : after) {
                         callback.run();
                     }
@@ -774,8 +898,20 @@
                         new Runnable[]{waitForBothXAndY});
             }
 
+            if (mPathAnimator != null) {
+                startPathAnimation();
+            }
+
             // Actually start the animations.
             for (DynamicAnimation.ViewProperty property : properties) {
+                // Don't start translation animations if we're using a path animator, the update
+                // listeners added to that animator will take care of that.
+                if (mPathAnimator != null
+                        && (property.equals(DynamicAnimation.TRANSLATION_X)
+                            || property.equals(DynamicAnimation.TRANSLATION_Y))) {
+                    return;
+                }
+
                 if (mInitialPropertyValues.containsKey(property)) {
                     property.setValue(mView, mInitialPropertyValues.get(property));
                 }
@@ -797,7 +933,16 @@
 
         /** Returns the set of properties that will animate once {@link #start} is called. */
         protected Set<DynamicAnimation.ViewProperty> getAnimatedProperties() {
-            return mAnimatedProperties.keySet();
+            final HashSet<DynamicAnimation.ViewProperty> animatedProperties = new HashSet<>(
+                    mAnimatedProperties.keySet());
+
+            // If we're using a path animator, it'll kick off translation animations.
+            if (mPathAnimator != null) {
+                animatedProperties.add(DynamicAnimation.TRANSLATION_X);
+                animatedProperties.add(DynamicAnimation.TRANSLATION_Y);
+            }
+
+            return animatedProperties;
         }
 
         /**
@@ -812,7 +957,7 @@
                 long startDelay,
                 float stiffness,
                 float dampingRatio,
-                Runnable[] afterCallbacks) {
+                Runnable... afterCallbacks) {
             if (view != null) {
                 final SpringAnimation animation =
                         (SpringAnimation) view.getTag(getTagIdForProperty(property));
@@ -855,6 +1000,92 @@
             }
         }
 
+        /**
+         * Updates the final position of a view's animation, without changing any of the animation's
+         * other settings. Calling this before an initial call to {@link #animateValueForChild} will
+         * work, but result in unknown values for stiffness, etc. and is not recommended.
+         */
+        private void updateValueForChild(
+                DynamicAnimation.ViewProperty property, View view, float position) {
+            if (view != null) {
+                final SpringAnimation animation =
+                        (SpringAnimation) view.getTag(getTagIdForProperty(property));
+                final SpringForce animationSpring = animation.getSpring();
+
+                if (animationSpring == null) {
+                    return;
+                }
+
+                animationSpring.setFinalPosition(position);
+                animation.start();
+            }
+        }
+
+        /**
+         * Configures the path animator to respect the settings passed into the animation builder
+         * and adds update listeners that update the translation physics animations. Then, starts
+         * the path animation.
+         */
+        protected void startPathAnimation() {
+            final SpringForce defaultSpringForceX = mController.getSpringForce(
+                    DynamicAnimation.TRANSLATION_X, mView);
+            final SpringForce defaultSpringForceY = mController.getSpringForce(
+                    DynamicAnimation.TRANSLATION_Y, mView);
+
+            if (mStartDelay > 0) {
+                mPathAnimator.setStartDelay(mStartDelay);
+            }
+
+            final Runnable updatePhysicsAnims = () -> {
+                updateValueForChild(
+                        DynamicAnimation.TRANSLATION_X, mView, mCurrentPointOnPath.x);
+                updateValueForChild(
+                        DynamicAnimation.TRANSLATION_Y, mView, mCurrentPointOnPath.y);
+            };
+
+            mPathAnimator.addUpdateListener(pathAnim -> updatePhysicsAnims.run());
+            mPathAnimator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animation) {
+                    animateValueForChild(
+                            DynamicAnimation.TRANSLATION_X,
+                            mView,
+                            mCurrentPointOnPath.x,
+                            mDefaultStartVelocity,
+                            0 /* startDelay */,
+                            mStiffness >= 0 ? mStiffness : defaultSpringForceX.getStiffness(),
+                            mDampingRatio >= 0
+                                    ? mDampingRatio
+                                    : defaultSpringForceX.getDampingRatio());
+
+                    animateValueForChild(
+                            DynamicAnimation.TRANSLATION_Y,
+                            mView,
+                            mCurrentPointOnPath.y,
+                            mDefaultStartVelocity,
+                            0 /* startDelay */,
+                            mStiffness >= 0 ? mStiffness : defaultSpringForceY.getStiffness(),
+                            mDampingRatio >= 0
+                                    ? mDampingRatio
+                                    : defaultSpringForceY.getDampingRatio());
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    updatePhysicsAnims.run();
+                }
+            });
+
+            // If there's a target animator saved for the view, make sure it's not running.
+            final ObjectAnimator targetAnimator = getTargetAnimatorFromView(mView);
+            if (targetAnimator != null) {
+                targetAnimator.cancel();
+            }
+
+            mView.setTag(R.id.target_animator_tag, mPathAnimator);
+            mPathAnimator.start();
+        }
+
         private void clearAnimator() {
             mInitialPropertyValues.clear();
             mAnimatedProperties.clear();
@@ -864,6 +1095,8 @@
             mStiffness = -1;
             mDampingRatio = -1;
             mEndActionsForProperty.clear();
+            mPathAnimator = null;
+            mPositionEndActions = null;
         }
 
         /**
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
index ab8752e4..2ec09a9 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
@@ -23,6 +23,7 @@
 import android.view.View;
 import android.view.WindowInsets;
 
+import androidx.annotation.Nullable;
 import androidx.dynamicanimation.animation.DynamicAnimation;
 import androidx.dynamicanimation.animation.FlingAnimation;
 import androidx.dynamicanimation.animation.FloatPropertyCompat;
@@ -33,6 +34,8 @@
 
 import com.google.android.collect.Sets;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.HashMap;
 import java.util.Set;
 
@@ -53,6 +56,10 @@
     /** Translation factor (multiplied by stack offset) to use for bubbles being animated in/out. */
     private static final int ANIMATE_TRANSLATION_FACTOR = 4;
 
+    /** Values to use for animating bubbles in. */
+    private static final float ANIMATE_IN_STIFFNESS = 1000f;
+    private static final int ANIMATE_IN_START_DELAY = 25;
+
     /**
      * Values to use for the default {@link SpringForce} provided to the physics animation layout.
      */
@@ -92,7 +99,7 @@
     private boolean mStackMovedToStartPosition = false;
 
     /** The most recent position in which the stack was resting on the edge of the screen. */
-    private PointF mRestingStackPosition;
+    @Nullable private PointF mRestingStackPosition;
 
     /** The height of the most recently visible IME. */
     private float mImeHeight = 0f;
@@ -139,14 +146,16 @@
 
     /** Horizontal offset of bubbles in the stack. */
     private float mStackOffset;
-    /** Diameter of the bubbles themselves. */
-    private int mIndividualBubbleSize;
+    /** Diameter of the bubble icon. */
+    private int mBubbleIconBitmapSize;
+    /** Width of the bubble (icon and padding). */
+    private int mBubbleSize;
     /**
      * The amount of space to add between the bubbles and certain UI elements, such as the top of
      * the screen or the IME. This does not apply to the left/right sides of the screen since the
      * stack goes offscreen intentionally.
      */
-    private int mBubblePadding;
+    private int mBubblePaddingTop;
     /** How far offscreen the stack rests. */
     private int mBubbleOffscreen;
     /** How far down the screen the stack starts, when there is no pre-existing location. */
@@ -185,7 +194,7 @@
             return false;
         }
 
-        float stackCenter = mStackPosition.x + mIndividualBubbleSize / 2;
+        float stackCenter = mStackPosition.x + mBubbleIconBitmapSize / 2;
         float screenCenter = mLayout.getWidth() / 2;
         return stackCenter < screenCenter;
     }
@@ -197,18 +206,18 @@
      */
     public void springStack(float destinationX, float destinationY) {
         springFirstBubbleWithStackFollowing(DynamicAnimation.TRANSLATION_X,
-                    new SpringForce()
+                new SpringForce()
                         .setStiffness(SPRING_AFTER_FLING_STIFFNESS)
                         .setDampingRatio(SPRING_AFTER_FLING_DAMPING_RATIO),
-                    0 /* startXVelocity */,
-                    destinationX);
+                0 /* startXVelocity */,
+                destinationX);
 
         springFirstBubbleWithStackFollowing(DynamicAnimation.TRANSLATION_Y,
-                    new SpringForce()
+                new SpringForce()
                         .setStiffness(SPRING_AFTER_FLING_STIFFNESS)
                         .setDampingRatio(SPRING_AFTER_FLING_DAMPING_RATIO),
-                    0 /* startYVelocity */,
-                    destinationY);
+                0 /* startYVelocity */,
+                destinationY);
     }
 
     /**
@@ -218,7 +227,7 @@
      * @return The X value that the stack will end up at after the fling/spring.
      */
     public float flingStackThenSpringToEdge(float x, float velX, float velY) {
-        final boolean stackOnLeftSide = x - mIndividualBubbleSize / 2 < mLayout.getWidth() / 2;
+        final boolean stackOnLeftSide = x - mBubbleIconBitmapSize / 2 < mLayout.getWidth() / 2;
 
         final boolean stackShouldFlingLeft = stackOnLeftSide
                 ? velX < ESCAPE_VELOCITY
@@ -230,6 +239,12 @@
         final float destinationRelativeX = stackShouldFlingLeft
                 ? stackBounds.left : stackBounds.right;
 
+        // If all bubbles were removed during a drag event, just return the X we would have animated
+        // to if there were still bubbles.
+        if (mLayout == null || mLayout.getChildCount() == 0) {
+            return destinationRelativeX;
+        }
+
         // Minimum velocity required for the stack to make it to the targeted side of the screen,
         // taking friction into account (4.2f is the number that friction scalars are multiplied by
         // in DynamicAnimation.DragForce). This is an estimate - it could possibly be slightly off,
@@ -262,15 +277,6 @@
                         .setDampingRatio(SPRING_AFTER_FLING_DAMPING_RATIO),
                 /* destination */ null);
 
-        mLayout.setEndActionForMultipleProperties(
-                () -> {
-                    mRestingStackPosition = new PointF();
-                    mRestingStackPosition.set(mStackPosition);
-                    mLayout.removeEndActionForProperty(DynamicAnimation.TRANSLATION_X);
-                    mLayout.removeEndActionForProperty(DynamicAnimation.TRANSLATION_Y);
-                },
-                DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y);
-
         // If we're flinging now, there's no more touch event to catch up to.
         mFirstBubbleSpringingToTouch = false;
         mIsMovingFromFlinging = true;
@@ -304,6 +310,18 @@
         setStackPosition(new PointF(x, y));
     }
 
+    /** Description of current animation controller state. */
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("StackAnimationController state:");
+        pw.print("  isActive:             "); pw.println(isActiveController());
+        pw.print("  restingStackPos:      ");
+        pw.println(mRestingStackPosition != null ? mRestingStackPosition.toString() : "null");
+        pw.print("  currentStackPos:      "); pw.println(mStackPosition.toString());
+        pw.print("  isMovingFromFlinging: "); pw.println(mIsMovingFromFlinging);
+        pw.print("  withinDismiss:        "); pw.println(mWithinDismissTarget);
+        pw.print("  firstBubbleSpringing: "); pw.println(mFirstBubbleSpringingToTouch);
+    }
+
     /**
      * Flings the first bubble along the given property's axis, using the provided configuration
      * values. When the animation ends - either by hitting the min/max, or by friction sufficiently
@@ -317,7 +335,7 @@
             SpringForce spring,
             Float finalPosition) {
         Log.d(TAG, String.format("Flinging %s.",
-                        PhysicsAnimationLayout.getReadablePropertyName(property)));
+                PhysicsAnimationLayout.getReadablePropertyName(property)));
 
         StackPositionProperty firstBubbleProperty = new StackPositionProperty(property);
         final float currentValue = firstBubbleProperty.getValue(this);
@@ -347,6 +365,9 @@
 
                 .addEndListener((animation, canceled, endValue, endVelocity) -> {
                     if (!canceled) {
+                        mRestingStackPosition = new PointF();
+                        mRestingStackPosition.set(mStackPosition);
+
                         springFirstBubbleWithStackFollowing(property, spring, endVelocity,
                                 finalPosition != null
                                         ? finalPosition
@@ -368,8 +389,8 @@
         cancelStackPositionAnimation(DynamicAnimation.TRANSLATION_X);
         cancelStackPositionAnimation(DynamicAnimation.TRANSLATION_Y);
 
-        mLayout.removeEndActionForProperty(DynamicAnimation.TRANSLATION_X);
-        mLayout.removeEndActionForProperty(DynamicAnimation.TRANSLATION_Y);
+        removeEndActionForProperty(DynamicAnimation.TRANSLATION_X);
+        removeEndActionForProperty(DynamicAnimation.TRANSLATION_Y);
     }
 
     /** Save the current IME height so that we know where the stack bounds should be. */
@@ -427,7 +448,7 @@
                                     : 0);
             allowableRegion.right =
                     mLayout.getWidth()
-                            - mIndividualBubbleSize
+                            - mBubbleSize
                             + mBubbleOffscreen
                             - Math.max(
                             insets.getSystemWindowInsetRight(),
@@ -436,7 +457,7 @@
                                     : 0);
 
             allowableRegion.top =
-                    mBubblePadding
+                    mBubblePaddingTop
                             + Math.max(
                             mStatusBarHeight,
                             insets.getDisplayCutout() != null
@@ -444,9 +465,9 @@
                                     : 0);
             allowableRegion.bottom =
                     mLayout.getHeight()
-                            - mIndividualBubbleSize
-                            - mBubblePadding
-                            - (mImeHeight > Float.MIN_VALUE ? mImeHeight + mBubblePadding : 0f)
+                            - mBubbleSize
+                            - mBubblePaddingTop
+                            - (mImeHeight > Float.MIN_VALUE ? mImeHeight + mBubblePaddingTop : 0f)
                             - Math.max(
                             insets.getSystemWindowInsetBottom(),
                             insets.getDisplayCutout() != null
@@ -516,13 +537,19 @@
         mWithinDismissTarget = true;
         mFirstBubbleSpringingToTouch = false;
 
-        animationForChildAtIndex(0)
-                .translationX(mLayout.getWidth() / 2f - mIndividualBubbleSize / 2f)
-                .translationY(destY, after)
-                .withPositionStartVelocities(velX, velY)
-                .withStiffness(SpringForce.STIFFNESS_MEDIUM)
-                .withDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)
-                .start();
+        springFirstBubbleWithStackFollowing(
+                DynamicAnimation.TRANSLATION_X,
+                new SpringForce()
+                        .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)
+                        .setStiffness(SpringForce.STIFFNESS_MEDIUM),
+                velX, mLayout.getWidth() / 2f - mBubbleIconBitmapSize / 2f);
+
+        springFirstBubbleWithStackFollowing(
+                DynamicAnimation.TRANSLATION_Y,
+                new SpringForce()
+                        .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)
+                        .setStiffness(SpringForce.STIFFNESS_MEDIUM),
+                velY, destY, after);
     }
 
     /**
@@ -550,7 +577,7 @@
      */
     protected void springFirstBubbleWithStackFollowing(
             DynamicAnimation.ViewProperty property, SpringForce spring,
-            float vel, float finalPosition) {
+            float vel, float finalPosition, @Nullable Runnable... after) {
 
         if (mLayout.getChildCount() == 0) {
             return;
@@ -564,6 +591,13 @@
         SpringAnimation springAnimation =
                 new SpringAnimation(this, firstBubbleProperty)
                         .setSpring(spring)
+                        .addEndListener((dynamicAnimation, b, v, v1) -> {
+                            if (after != null) {
+                                for (Runnable callback : after) {
+                                    callback.run();
+                                }
+                            }
+                        })
                         .setStartVelocity(vel);
 
         cancelStackPositionAnimation(property);
@@ -620,13 +654,18 @@
 
     @Override
     void onChildAdded(View child, int index) {
+        // Don't animate additions within the dismiss target.
+        if (mWithinDismissTarget) {
+            return;
+        }
+
         if (mLayout.getChildCount() == 1) {
             // If this is the first child added, position the stack in its starting position.
             moveStackToStartPosition();
         } else if (isStackPositionSet() && mLayout.indexOfChild(child) == 0) {
             // Otherwise, animate the bubble in if it's the newest bubble. If we're adding a bubble
             // to the back of the stack, it'll be largely invisible so don't bother animating it in.
-            animateInBubble(child);
+            animateInBubble(child, index);
         }
     }
 
@@ -641,24 +680,29 @@
                 .translationX(mStackPosition.x - (-xOffset * ANIMATE_TRANSLATION_FACTOR))
                 .start();
 
+        // If there are other bubbles, pull them into the correct position.
         if (mLayout.getChildCount() > 0) {
             animationForChildAtIndex(0).translationX(mStackPosition.x).start();
         } else {
-            // Set the start position back to the default since we're out of bubbles. New bubbles
-            // will then animate in from the start position.
-            mStackPosition = getDefaultStartPosition();
+            // If there's no other bubbles, and we were in the dismiss target, reset the flag.
+            mWithinDismissTarget = false;
         }
     }
 
     @Override
-    void onChildReordered(View child, int oldIndex, int newIndex) {}
+    void onChildReordered(View child, int oldIndex, int newIndex) {
+        if (isStackPositionSet()) {
+            setStackPosition(mStackPosition);
+        }
+    }
 
     @Override
     void onActiveControllerForLayout(PhysicsAnimationLayout layout) {
         Resources res = layout.getResources();
         mStackOffset = res.getDimensionPixelSize(R.dimen.bubble_stack_offset);
-        mIndividualBubbleSize = res.getDimensionPixelSize(R.dimen.individual_bubble_size);
-        mBubblePadding = res.getDimensionPixelSize(R.dimen.bubble_padding);
+        mBubbleSize = res.getDimensionPixelSize(R.dimen.individual_bubble_size);
+        mBubbleIconBitmapSize = res.getDimensionPixelSize(R.dimen.bubble_icon_bitmap_size);
+        mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
         mBubbleOffscreen = res.getDimensionPixelSize(R.dimen.bubble_stack_offscreen);
         mStackStartingVerticalOffset =
                 res.getDimensionPixelSize(R.dimen.bubble_stack_starting_offset_y);
@@ -666,6 +710,20 @@
                 res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
     }
 
+    /**
+     * Update effective screen width based on current orientation.
+     * @param orientation Landscape or portrait.
+     */
+    public void updateOrientation(int orientation) {
+        if (mLayout != null) {
+            Resources res = mLayout.getContext().getResources();
+            mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
+            mStatusBarHeight = res.getDimensionPixelSize(
+                    com.android.internal.R.dimen.status_bar_height);
+        }
+    }
+
+
     /** Moves the stack, without any animation, to the starting position. */
     private void moveStackToStartPosition() {
         // Post to ensure that the layout's width and height have been calculated.
@@ -679,7 +737,7 @@
 
             // Animate in the top bubble now that we're visible.
             if (mLayout.getChildCount() > 0) {
-                animateInBubble(mLayout.getChildAt(0));
+                animateInBubble(mLayout.getChildAt(0), 0 /* index */);
             }
         });
     }
@@ -715,7 +773,9 @@
 
         // If we're not the active controller, we don't want to physically move the bubble views.
         if (isActiveController()) {
-            mLayout.cancelAllAnimations();
+            // Cancel animations that could be moving the views.
+            mLayout.cancelAllAnimationsOfProperties(
+                    DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y);
             cancelStackPositionAnimations();
 
             // Since we're not using the chained animations, apply the offsets manually.
@@ -742,21 +802,34 @@
     }
 
     /** Animates in the given bubble. */
-    private void animateInBubble(View child) {
+    private void animateInBubble(View child, int index) {
         if (!isActiveController()) {
             return;
         }
 
-        child.setTranslationY(mStackPosition.y);
+        final float xOffset =
+                getOffsetForChainedPropertyAnimation(DynamicAnimation.TRANSLATION_X);
 
-        float xOffset = getOffsetForChainedPropertyAnimation(DynamicAnimation.TRANSLATION_X);
+        // Position the new bubble in the correct position, scaled down completely.
+        child.setTranslationX(mStackPosition.x + xOffset * index);
+        child.setTranslationY(mStackPosition.y);
+        child.setScaleX(0f);
+        child.setScaleY(0f);
+
+        // Push the subsequent views out of the way, if there are subsequent views.
+        if (index + 1 < mLayout.getChildCount()) {
+            animationForChildAtIndex(index + 1)
+                    .translationX(mStackPosition.x + xOffset * (index + 1))
+                    .withStiffness(SpringForce.STIFFNESS_LOW)
+                    .start();
+        }
+
+        // Scale in the new bubble, slightly delayed.
         animationForChild(child)
-                .scaleX(ANIMATE_IN_STARTING_SCALE /* from */, 1f /* to */)
-                .scaleY(ANIMATE_IN_STARTING_SCALE /* from */, 1f /* to */)
-                .alpha(0f /* from */, 1f /* to */)
-                .translationX(
-                        mStackPosition.x - ANIMATE_TRANSLATION_FACTOR * xOffset /* from */,
-                        mStackPosition.x /* to */)
+                .scaleX(1f)
+                .scaleY(1f)
+                .withStiffness(ANIMATE_IN_STIFFNESS)
+                .withStartDelay(mLayout.getChildCount() > 1 ? ANIMATE_IN_START_DELAY : 0)
                 .start();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFactory.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFactory.java
deleted file mode 100644
index 01921f0..0000000
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFactory.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.classifier;
-
-import android.content.Context;
-
-import com.android.systemui.Dependency;
-import com.android.systemui.plugins.FalsingManager;
-
-/**
- * When the phone is locked, listens to touch, sensor and phone events and sends them to
- * DataCollector and HumanInteractionClassifier.
- *
- * It does not collect touch events when the bouncer shows up.
- *
- * TODO: FalsingManager supports dependency injection. Use it.
- */
-public class FalsingManagerFactory {
-    private static FalsingManager sInstance = null;
-
-    private FalsingManagerFactory() {}
-
-    public static FalsingManager getInstance(Context context) {
-        if (sInstance == null) {
-            sInstance = Dependency.get(FalsingManager.class);
-        }
-        return sInstance;
-    }
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java
new file mode 100644
index 0000000..ea175ed
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2019 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.classifier;
+
+import android.net.Uri;
+import android.view.MotionEvent;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.plugins.FalsingManager;
+
+import java.io.PrintWriter;
+
+/**
+ * Simple Fake for testing where {@link FalsingManager} is required.
+ */
+public class FalsingManagerFake implements FalsingManager {
+    private boolean mIsFalseTouch;
+    private boolean mIsUnlockingDisabled;
+    private boolean mIsClassiferEnabled;
+    private boolean mShouldEnforceBouncer;
+    private boolean mIsReportingEnabled;
+
+    @Override
+    public void onSucccessfulUnlock() {
+
+    }
+
+    @Override
+    public void onNotificationActive() {
+
+    }
+
+    @Override
+    public void setShowingAod(boolean showingAod) {
+
+    }
+
+    @Override
+    public void onNotificatonStartDraggingDown() {
+
+    }
+
+    @VisibleForTesting
+    public void setIsUnlockingDisabled(boolean isUnlockingDisabled) {
+        mIsUnlockingDisabled = isUnlockingDisabled;
+    }
+
+    @Override
+    public boolean isUnlockingDisabled() {
+        return mIsUnlockingDisabled;
+    }
+
+    @VisibleForTesting
+    public void setIsFalseTouch(boolean isFalseTouch) {
+        mIsFalseTouch = isFalseTouch;
+    }
+
+    @Override
+    public boolean isFalseTouch() {
+        return mIsFalseTouch;
+    }
+
+    @Override
+    public void onNotificatonStopDraggingDown() {
+
+    }
+
+    @Override
+    public void setNotificationExpanded() {
+
+    }
+
+    @VisibleForTesting
+    public void setIsClassiferEnabled(boolean isClassiferEnabled) {
+        mIsClassiferEnabled = isClassiferEnabled;
+    }
+
+    @Override
+    public boolean isClassiferEnabled() {
+        return mIsClassiferEnabled;
+    }
+
+    @Override
+    public void onQsDown() {
+
+    }
+
+    @Override
+    public void setQsExpanded(boolean expanded) {
+
+    }
+
+    @VisibleForTesting
+    public void setShouldEnforceBouncer(boolean shouldEnforceBouncer) {
+        mShouldEnforceBouncer = shouldEnforceBouncer;
+    }
+
+    @Override
+    public boolean shouldEnforceBouncer() {
+        return mShouldEnforceBouncer;
+    }
+
+    @Override
+    public void onTrackingStarted(boolean secure) {
+
+    }
+
+    @Override
+    public void onTrackingStopped() {
+
+    }
+
+    @Override
+    public void onLeftAffordanceOn() {
+
+    }
+
+    @Override
+    public void onCameraOn() {
+
+    }
+
+    @Override
+    public void onAffordanceSwipingStarted(boolean rightCorner) {
+
+    }
+
+    @Override
+    public void onAffordanceSwipingAborted() {
+
+    }
+
+    @Override
+    public void onStartExpandingFromPulse() {
+
+    }
+
+    @Override
+    public void onExpansionFromPulseStopped() {
+
+    }
+
+    @Override
+    public Uri reportRejectedTouch() {
+        return null;
+    }
+
+    @Override
+    public void onScreenOnFromTouch() {
+
+    }
+
+
+    @VisibleForTesting
+    public void setIsReportingEnabled(boolean isReportingEnabled) {
+        mIsReportingEnabled = isReportingEnabled;
+    }
+
+    @Override
+    public boolean isReportingEnabled() {
+        return mIsReportingEnabled;
+    }
+
+    @Override
+    public void onUnlockHintStarted() {
+
+    }
+
+    @Override
+    public void onCameraHintStarted() {
+
+    }
+
+    @Override
+    public void onLeftAffordanceHintStarted() {
+
+    }
+
+    @Override
+    public void onScreenTurningOn() {
+
+    }
+
+    @Override
+    public void onScreenOff() {
+
+    }
+
+    @Override
+    public void onNotificatonStopDismissing() {
+
+    }
+
+    @Override
+    public void onNotificationDismissed() {
+
+    }
+
+    @Override
+    public void onNotificatonStartDismissing() {
+
+    }
+
+    @Override
+    public void onNotificationDoubleTap(boolean accepted, float dx, float dy) {
+
+    }
+
+    @Override
+    public void onBouncerShown() {
+
+    }
+
+    @Override
+    public void onBouncerHidden() {
+
+    }
+
+    @Override
+    public void onTouchEvent(MotionEvent ev, int width, int height) {
+
+    }
+
+    @Override
+    public void dump(PrintWriter pw) {
+
+    }
+
+    @Override
+    public void cleanup() {
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
index ee79e6b..cff0622 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
@@ -27,14 +27,13 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.Dependency;
 import com.android.systemui.classifier.brightline.BrightLineFalsingManager;
 import com.android.systemui.classifier.brightline.FalsingDataProvider;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.FalsingPlugin;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.shared.plugins.PluginManager;
-import com.android.systemui.util.AsyncSensorManager;
+import com.android.systemui.util.ProximitySensor;
 
 import java.io.PrintWriter;
 
@@ -50,18 +49,23 @@
 @Singleton
 public class FalsingManagerProxy implements FalsingManager {
 
+    private static final String PROXIMITY_SENSOR_TAG = "FalsingManager";
+
+    private final ProximitySensor mProximitySensor;
     private FalsingManager mInternalFalsingManager;
     private final Handler mMainHandler;
 
     @Inject
     FalsingManagerProxy(Context context, PluginManager pluginManager,
-            @Named(MAIN_HANDLER_NAME) Handler handler) {
+            @Named(MAIN_HANDLER_NAME) Handler handler,
+            ProximitySensor proximitySensor) {
         mMainHandler = handler;
+        mProximitySensor = proximitySensor;
+        mProximitySensor.setTag(PROXIMITY_SENSOR_TAG);
         DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
                 command -> mMainHandler.post(command),
                 properties -> onDeviceConfigPropertiesChanged(context, properties.getNamespace())
-        );
-        setupFalsingManager(context);
+        );        setupFalsingManager(context);
         final PluginListener<FalsingPlugin> mPluginListener = new PluginListener<FalsingPlugin>() {
             public void onPluginConnected(FalsingPlugin plugin, Context context) {
                 FalsingManager pluginFalsingManager = plugin.getFalsingManager(context);
@@ -103,8 +107,8 @@
         } else {
             mInternalFalsingManager = new BrightLineFalsingManager(
                     new FalsingDataProvider(context.getResources().getDisplayMetrics()),
-                    Dependency.get(AsyncSensorManager.class),
-                    KeyguardUpdateMonitor.getInstance(context)
+                    KeyguardUpdateMonitor.getInstance(context),
+                    mProximitySensor
             );
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
index 9e0b702..b68a56d 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
@@ -19,10 +19,6 @@
 import static com.android.systemui.classifier.FalsingManagerImpl.FALSING_REMAIN_LOCKED;
 import static com.android.systemui.classifier.FalsingManagerImpl.FALSING_SUCCESS;
 
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
 import android.hardware.biometrics.BiometricSourceType;
 import android.net.Uri;
 import android.util.Log;
@@ -33,12 +29,11 @@
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.systemui.classifier.Classifier;
 import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.util.ProximitySensor;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 
 /**
  * FalsingManager designed to make clear why a touch was rejected.
@@ -48,9 +43,9 @@
     static final boolean DEBUG = false;
     private static final String TAG = "FalsingManagerPlugin";
 
-    private final SensorManager mSensorManager;
     private final FalsingDataProvider mDataProvider;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    private final ProximitySensor mProximitySensor;
     private boolean mSessionStarted;
     private MetricsLogger mMetricsLogger;
     private int mIsFalseTouchCalls;
@@ -58,20 +53,9 @@
     private boolean mScreenOn;
     private boolean mJustUnlockedWithFace;
 
-    private final ExecutorService mBackgroundExecutor = Executors.newSingleThreadExecutor();
-
     private final List<FalsingClassifier> mClassifiers;
 
-    private SensorEventListener mSensorEventListener = new SensorEventListener() {
-        @Override
-        public synchronized void onSensorChanged(SensorEvent event) {
-            onSensorEvent(event);
-        }
-
-        @Override
-        public void onAccuracyChanged(Sensor sensor, int accuracy) {
-        }
-    };
+    private ProximitySensor.ProximitySensorListener mSensorEventListener = this::onProximityEvent;
 
     private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback =
             new KeyguardUpdateMonitorCallback() {
@@ -87,11 +71,11 @@
 
     public BrightLineFalsingManager(
             FalsingDataProvider falsingDataProvider,
-            SensorManager sensorManager,
-            KeyguardUpdateMonitor keyguardUpdateMonitor) {
+            KeyguardUpdateMonitor keyguardUpdateMonitor,
+            ProximitySensor proximitySensor) {
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mDataProvider = falsingDataProvider;
-        mSensorManager = sensorManager;
+        mProximitySensor = proximitySensor;
         mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateCallback);
 
         mMetricsLogger = new MetricsLogger();
@@ -108,24 +92,12 @@
     }
 
     private void registerSensors() {
-        Sensor s = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
-        if (s != null) {
-            // This can be expensive, and doesn't need to happen on the main thread.
-            mBackgroundExecutor.submit(() -> {
-                logDebug("registering sensor listener");
-                mSensorManager.registerListener(
-                        mSensorEventListener, s, SensorManager.SENSOR_DELAY_GAME);
-            });
-        }
+        mProximitySensor.register(mSensorEventListener);
     }
 
 
     private void unregisterSensors() {
-        // This can be expensive, and doesn't need to happen on the main thread.
-        mBackgroundExecutor.submit(() -> {
-            logDebug("unregistering sensor listener");
-            mSensorManager.unregisterListener(mSensorEventListener);
-        });
+        mProximitySensor.unregister(mSensorEventListener);
     }
 
     private void sessionStart() {
@@ -187,10 +159,10 @@
         mClassifiers.forEach((classifier) -> classifier.onTouchEvent(motionEvent));
     }
 
-    private void onSensorEvent(SensorEvent sensorEvent) {
+    private void onProximityEvent(ProximitySensor.ProximityEvent proximityEvent) {
         // TODO: some of these classifiers might allow us to abort early, meaning we don't have to
         // make these calls.
-        mClassifiers.forEach((classifier) -> classifier.onSensorEvent(sensorEvent));
+        mClassifiers.forEach((classifier) -> classifier.onProximityEvent(proximityEvent));
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java
index 685e7c5..bf39751 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java
@@ -16,10 +16,10 @@
 
 package com.android.systemui.classifier.brightline;
 
-import android.hardware.SensorEvent;
 import android.view.MotionEvent;
 
 import com.android.systemui.classifier.Classifier;
+import com.android.systemui.util.ProximitySensor;
 
 import java.util.List;
 
@@ -98,9 +98,9 @@
     void onTouchEvent(MotionEvent motionEvent) {};
 
     /**
-     * Called whenever a SensorEvent occurs, specifically the ProximitySensor.
+     * Called when a ProximityEvent occurs (change in near/far).
      */
-    void onSensorEvent(SensorEvent sensorEvent) {};
+    void onProximityEvent(ProximitySensor.ProximityEvent proximityEvent) {};
 
     /**
      * The phone screen has turned on and we need to begin falsing detection.
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java
index 2644bf9..5045095 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java
@@ -19,11 +19,11 @@
 import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_PROXIMITY_PERCENT_COVERED_THRESHOLD;
 import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
 
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
 import android.provider.DeviceConfig;
 import android.view.MotionEvent;
 
+import com.android.systemui.util.ProximitySensor;
+
 
 /**
  * False touch if proximity sensor is covered for more than a certain percentage of the gesture.
@@ -97,14 +97,12 @@
     }
 
     @Override
-    public void onSensorEvent(SensorEvent sensorEvent) {
-        if (sensorEvent.sensor.getType() == Sensor.TYPE_PROXIMITY) {
-            logDebug("Sensor is: " + (sensorEvent.values[0] < sensorEvent.sensor.getMaximumRange())
-                    + " at time " + sensorEvent.timestamp);
-            update(
-                    sensorEvent.values[0] < sensorEvent.sensor.getMaximumRange(),
-                    sensorEvent.timestamp);
-        }
+    public void onProximityEvent(
+            ProximitySensor.ProximityEvent proximityEvent) {
+        boolean near = proximityEvent.getNear();
+        long timestampNs = proximityEvent.getTimestampNs();
+        logDebug("Sensor is: " + near + " at time " + timestampNs);
+        update(near, timestampNs);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/dock/DockManagerImpl.java b/packages/SystemUI/src/com/android/systemui/dock/DockManagerImpl.java
new file mode 100644
index 0000000..fa7f503
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dock/DockManagerImpl.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 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.dock;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
+public class DockManagerImpl implements DockManager {
+
+    @Inject
+    public DockManagerImpl() {
+    }
+
+    @Override
+    public void addListener(DockEventListener callback) {
+    }
+
+    @Override
+    public void removeListener(DockEventListener callback) {
+    }
+
+    @Override
+    public boolean isDocked() {
+        return false;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeAuthRemover.java b/packages/SystemUI/src/com/android/systemui/doze/DozeAuthRemover.java
index e6a9e47..e5a54b8 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeAuthRemover.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeAuthRemover.java
@@ -25,7 +25,7 @@
  */
 public class DozeAuthRemover implements DozeMachine.Part {
 
-    KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
 
     public DozeAuthRemover(Context context) {
         mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index d22d2c3..0e124e4 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -28,10 +28,12 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.SystemUIApplication;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.dock.DockManager;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
 import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.util.AsyncSensorManager;
 import com.android.systemui.util.wakelock.DelayedWakeLock;
 import com.android.systemui.util.wakelock.WakeLock;
@@ -42,11 +44,12 @@
     }
 
     /** Creates a DozeMachine with its parts for {@code dozeService}. */
-    public DozeMachine assembleMachine(DozeService dozeService) {
+    public DozeMachine assembleMachine(DozeService dozeService, FalsingManager falsingManager) {
         Context context = dozeService;
         SensorManager sensorManager = Dependency.get(AsyncSensorManager.class);
         AlarmManager alarmManager = context.getSystemService(AlarmManager.class);
         DockManager dockManager = Dependency.get(DockManager.class);
+        WakefulnessLifecycle wakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class);
 
         DozeHost host = getHost(dozeService);
         AmbientDisplayConfiguration config = new AmbientDisplayConfiguration(context);
@@ -61,10 +64,11 @@
         wrappedService = DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(wrappedService,
                 params);
 
-        DozeMachine machine = new DozeMachine(wrappedService, config, wakeLock);
+        DozeMachine machine = new DozeMachine(wrappedService, config, wakeLock,
+                wakefulnessLifecycle, Dependency.get(BatteryController.class));
         machine.setParts(new DozeMachine.Part[]{
                 new DozePauser(handler, machine, alarmManager, params.getPolicy()),
-                new DozeFalsingManagerAdapter(FalsingManagerFactory.getInstance(context)),
+                new DozeFalsingManagerAdapter(falsingManager),
                 createDozeTriggers(context, sensorManager, host, alarmManager, config, params,
                         handler, wakeLock, machine, dockManager),
                 createDozeUi(context, host, wakeLock, machine, handler, alarmManager, params),
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index 8bf2256..7f2d527 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -24,7 +24,10 @@
 import android.view.Display;
 
 import com.android.internal.util.Preconditions;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.keyguard.WakefulnessLifecycle.Wakefulness;
 import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.util.Assert;
 import com.android.systemui.util.wakelock.WakeLock;
 
@@ -118,6 +121,8 @@
     private final Service mDozeService;
     private final WakeLock mWakeLock;
     private final AmbientDisplayConfiguration mConfig;
+    private final WakefulnessLifecycle mWakefulnessLifecycle;
+    private final BatteryController mBatteryController;
     private Part[] mParts;
 
     private final ArrayList<State> mQueuedRequests = new ArrayList<>();
@@ -126,10 +131,13 @@
     private boolean mWakeLockHeldForCurrentState = false;
 
     public DozeMachine(Service service, AmbientDisplayConfiguration config,
-            WakeLock wakeLock) {
+            WakeLock wakeLock, WakefulnessLifecycle wakefulnessLifecycle,
+            BatteryController batteryController) {
         mDozeService = service;
         mConfig = config;
+        mWakefulnessLifecycle = wakefulnessLifecycle;
         mWakeLock = wakeLock;
+        mBatteryController = batteryController;
     }
 
     /** Initializes the set of {@link Part}s. Must be called exactly once after construction. */
@@ -312,6 +320,9 @@
             Log.i(TAG, "Dropping pulse done because current state is already done: " + mState);
             return mState;
         }
+        if (requestedState == State.DOZE_AOD && mBatteryController.isAodPowerSave()) {
+            return State.DOZE;
+        }
         if (requestedState == State.DOZE_REQUEST_PULSE && !mState.canPulse()) {
             Log.i(TAG, "Dropping pulse request because current state can't pulse: " + mState);
             return mState;
@@ -334,9 +345,18 @@
         switch (state) {
             case INITIALIZED:
             case DOZE_PULSE_DONE:
-                transitionTo(mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)
-                        ? DozeMachine.State.DOZE_AOD : DozeMachine.State.DOZE,
-                        DozeLog.PULSE_REASON_NONE);
+                final State nextState;
+                @Wakefulness int wakefulness = mWakefulnessLifecycle.getWakefulness();
+                if (wakefulness == WakefulnessLifecycle.WAKEFULNESS_AWAKE
+                        || wakefulness == WakefulnessLifecycle.WAKEFULNESS_WAKING) {
+                    nextState = State.FINISH;
+                } else if (mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)) {
+                    nextState = State.DOZE_AOD;
+                } else {
+                    nextState = State.DOZE;
+                }
+
+                transitionTo(nextState, DozeLog.PULSE_REASON_NONE);
                 break;
             default:
                 break;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 2db7306..9e1514c 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -25,12 +25,15 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.plugins.DozeServicePlugin;
 import com.android.systemui.plugins.DozeServicePlugin.RequestDoze;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.shared.plugins.PluginManager;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
+import javax.inject.Inject;
+
 public class DozeService extends DreamService
         implements DozeMachine.Service, RequestDoze, PluginListener<DozeServicePlugin> {
     private static final String TAG = "DozeService";
@@ -40,6 +43,7 @@
     private DozeServicePlugin mDozePlugin;
     private PluginManager mPluginManager;
 
+    @Inject
     public DozeService() {
         setDebug(DEBUG);
     }
@@ -56,7 +60,8 @@
         }
         mPluginManager = Dependency.get(PluginManager.class);
         mPluginManager.addPluginListener(this, DozeServicePlugin.class, false /* allowMultiple */);
-        mDozeMachine = new DozeFactory().assembleMachine(this);
+        mDozeMachine = new DozeFactory().assembleMachine(
+                this, Dependency.get(FalsingManager.class));
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index bab64db..6199a0d 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -345,7 +345,6 @@
 
     private void checkTriggersAtInit() {
         if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR
-                || mDozeHost.isPowerSaveActive()
                 || mDozeHost.isBlockingDoze()
                 || !mDozeHost.isProvisioned()) {
             mMachine.requestState(DozeMachine.State.FINISH);
@@ -574,8 +573,8 @@
 
         @Override
         public void onPowerSaveChanged(boolean active) {
-            if (active) {
-                mMachine.requestState(DozeMachine.State.FINISH);
+            if (mDozeHost.isPowerSaveActive()) {
+                mMachine.requestState(DozeMachine.State.DOZE);
             }
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 1f33af8..3869e77 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -83,7 +83,8 @@
      */
     private void updateAnimateScreenOff() {
         if (mCanAnimateTransition) {
-            final boolean controlScreenOff = mDozeParameters.getAlwaysOn() && mKeyguardShowing;
+            final boolean controlScreenOff = mDozeParameters.getAlwaysOn() && mKeyguardShowing
+                    && !mHost.isPowerSaveActive();
             mDozeParameters.setControlScreenOffAnimation(controlScreenOff);
             mHost.setAnimateScreenOff(controlScreenOff);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java
index 8dbaf0f..b4cc571 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java
@@ -22,7 +22,7 @@
 
 import com.android.systemui.ConfigurationChangedReceiver;
 import com.android.systemui.Dumpable;
-import com.android.systemui.SystemUIFactory;
+import com.android.systemui.SystemUIRootComponent;
 import com.android.systemui.qs.QSFragment;
 import com.android.systemui.statusbar.phone.NavigationBarFragment;
 
@@ -51,7 +51,7 @@
     private final FragmentCreator mFragmentCreator;
 
     @Inject
-    public FragmentService(SystemUIFactory.SystemUIRootComponent rootComponent) {
+    public FragmentService(SystemUIRootComponent rootComponent) {
         mFragmentCreator = rootComponent.createFragmentCreator();
         initInjectionMap();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 0e4c155..ff02e71 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -614,7 +614,7 @@
             mHandler.postDelayed(new Runnable() {
                 @Override
                 public void run() {
-                    mScreenshotHelper.takeScreenshot(1, true, true, mHandler);
+                    mScreenshotHelper.takeScreenshot(1, true, true, mHandler, null);
                     MetricsLogger.action(mContext,
                             MetricsEvent.ACTION_SCREENSHOT_POWER_MENU);
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java
index b154e66..39c9632 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java
@@ -19,6 +19,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
+import android.util.Log;
 
 import com.android.systemui.Interpolators;
 
@@ -30,6 +31,7 @@
     private static final String TAG = ImageRevealHelper.class.getSimpleName();
     private static final float MAX_REVEAL = 0f;
     private static final float MIN_REVEAL = 1f;
+    private static final boolean DEBUG = true;
 
     private final ValueAnimator mAnimator;
     private final RevealStateListener mRevealListener;
@@ -56,8 +58,13 @@
 
             @Override
             public void onAnimationEnd(Animator animation) {
-                if (!mIsCanceled && mRevealListener != null) {
-                    mRevealListener.onRevealEnd();
+                if (mRevealListener != null) {
+                    if (DEBUG) {
+                        Log.d(TAG, "transition end, cancel=" + mIsCanceled + ", reveal=" + mReveal);
+                    }
+                    if (!mIsCanceled) {
+                        mRevealListener.onRevealEnd();
+                    }
                 }
                 mIsCanceled = false;
             }
@@ -65,6 +72,9 @@
             @Override
             public void onAnimationStart(Animator animation) {
                 if (mRevealListener != null) {
+                    if (DEBUG) {
+                        Log.d(TAG, "transition start");
+                    }
                     mRevealListener.onRevealStart(true /* animate */);
                 }
             }
@@ -82,6 +92,9 @@
     }
 
     void updateAwake(boolean awake, long duration) {
+        if (DEBUG) {
+            Log.d(TAG, "updateAwake: awake=" + awake + ", duration=" + duration);
+        }
         mAwake = awake;
         mAnimator.setDuration(duration);
         if (duration == 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
index 7b22a49..be6f7bf 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
@@ -46,6 +46,7 @@
     private static final String TAG = ImageWallpaperRenderer.class.getSimpleName();
     private static final float SCALE_VIEWPORT_MIN = 1f;
     private static final float SCALE_VIEWPORT_MAX = 1.1f;
+    private static final boolean DEBUG = true;
 
     private final WallpaperManager mWallpaperManager;
     private final ImageGLProgram mProgram;
@@ -107,13 +108,24 @@
     }
 
     private boolean loadBitmap() {
+        if (DEBUG) {
+            Log.d(TAG, "loadBitmap: mBitmap=" + mBitmap);
+        }
         if (mWallpaperManager != null && mBitmap == null) {
             mBitmap = mWallpaperManager.getBitmap();
             mWallpaperManager.forgetLoadedWallpaper();
             if (mBitmap != null) {
-                mSurfaceSize.set(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
+                float scale = (float) mScissor.height() / mBitmap.getHeight();
+                int surfaceHeight = Math.max(mScissor.height(), mBitmap.getHeight());
+                int surfaceWidth = scale > 1f
+                        ? Math.round(mBitmap.getWidth() * scale)
+                        : mBitmap.getWidth();
+                mSurfaceSize.set(0, 0, surfaceWidth, surfaceHeight);
             }
         }
+        if (DEBUG) {
+            Log.d(TAG, "loadBitmap done, surface size=" + mSurfaceSize);
+        }
         return mBitmap != null;
     }
 
@@ -188,16 +200,28 @@
 
     @Override
     public void onRevealStart(boolean animate) {
+        if (DEBUG) {
+            Log.v(TAG, "onRevealStart: start, anim=" + animate);
+        }
+
         if (animate) {
             mScissorMode = true;
             // Use current display area of texture.
             mWallpaper.adjustTextureCoordinates(mSurfaceSize, mScissor, mXOffset, mYOffset);
         }
         mProxy.preRender();
+
+        if (DEBUG) {
+            Log.v(TAG, "onRevealStart: done");
+        }
     }
 
     @Override
     public void onRevealEnd() {
+        if (DEBUG) {
+            Log.v(TAG, "onRevealEnd: start, mScissorMode=" + mScissorMode);
+        }
+
         if (mScissorMode) {
             mScissorMode = false;
             // reset texture coordinates to use full texture.
@@ -206,6 +230,10 @@
             mProxy.requestRender();
         }
         mProxy.postRender();
+
+        if (DEBUG) {
+            Log.v(TAG, "onRevealEnd: done");
+        }
     }
 
     @Override
@@ -218,6 +246,7 @@
         out.print(prefix); out.print("mXOffset="); out.print(mXOffset);
         out.print(prefix); out.print("mYOffset="); out.print(mYOffset);
         out.print(prefix); out.print("threshold="); out.print(mImageProcessHelper.getThreshold());
+        out.print(prefix); out.print("mReveal="); out.print(mImageRevealHelper.getReveal());
         mWallpaper.dump(prefix, fd, out, args);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index e9f99ac..f424a8e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -81,10 +81,11 @@
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.Dependency;
+import com.android.systemui.R;
 import com.android.systemui.SystemUI;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.UiOffloadThread;
-import com.android.systemui.classifier.FalsingManagerFactory;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.NotificationPanelView;
@@ -713,8 +714,7 @@
 
         // Assume keyguard is showing (unless it's disabled) until we know for sure, unless Keyguard
         // is disabled.
-        if (mContext.getResources().getBoolean(
-                com.android.keyguard.R.bool.config_enableKeyguardService)) {
+        if (mContext.getResources().getBoolean(R.bool.config_enableKeyguardService)) {
             setShowingLocked(!shouldWaitForProvisioning()
                     && !mLockPatternUtils.isLockScreenDisabled(
                             KeyguardUpdateMonitor.getCurrentUser()), true /* forceCallbacks */);
@@ -1599,7 +1599,7 @@
                     Trace.beginSection("KeyguardViewMediator#handleMessage START_KEYGUARD_EXIT_ANIM");
                     StartKeyguardExitAnimParams params = (StartKeyguardExitAnimParams) msg.obj;
                     handleStartKeyguardExitAnimation(params.startTime, params.fadeoutDuration);
-                    FalsingManagerFactory.getInstance(mContext).onSucccessfulUnlock();
+                    Dependency.get(FalsingManager.class).onSucccessfulUnlock();
                     Trace.endSection();
                     break;
                 case KEYGUARD_DONE_PENDING_TIMEOUT:
@@ -2071,10 +2071,11 @@
     public StatusBarKeyguardViewManager registerStatusBar(StatusBar statusBar,
             ViewGroup container, NotificationPanelView panelView,
             BiometricUnlockController biometricUnlockController, ViewGroup lockIconContainer,
-            View notificationContainer, KeyguardBypassController bypassController) {
+            View notificationContainer, KeyguardBypassController bypassController,
+            FalsingManager falsingManager) {
         mStatusBarKeyguardViewManager.registerStatusBar(statusBar, container, panelView,
                 biometricUnlockController, mDismissCallbackRegistry, lockIconContainer,
-                notificationContainer, bypassController);
+                notificationContainer, bypassController, falsingManager);
         return mStatusBarKeyguardViewManager;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
index 52a0214..d17f2f6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
@@ -16,12 +16,15 @@
 
 package com.android.systemui.keyguard;
 
+import android.annotation.IntDef;
 import android.os.Trace;
 
 import com.android.systemui.Dumpable;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
@@ -33,6 +36,15 @@
 public class WakefulnessLifecycle extends Lifecycle<WakefulnessLifecycle.Observer> implements
         Dumpable {
 
+    @IntDef(prefix = { "WAKEFULNESS_" }, value = {
+            WAKEFULNESS_ASLEEP,
+            WAKEFULNESS_WAKING,
+            WAKEFULNESS_AWAKE,
+            WAKEFULNESS_GOING_TO_SLEEP,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Wakefulness {}
+
     public static final int WAKEFULNESS_ASLEEP = 0;
     public static final int WAKEFULNESS_WAKING = 1;
     public static final int WAKEFULNESS_AWAKE = 2;
@@ -44,7 +56,7 @@
     public WakefulnessLifecycle() {
     }
 
-    public int getWakefulness() {
+    public @Wakefulness int getWakefulness() {
         return mWakefulness;
     }
 
@@ -86,7 +98,7 @@
         pw.println("  mWakefulness=" + mWakefulness);
     }
 
-    private void setWakefulness(int wakefulness) {
+    private void setWakefulness(@Wakefulness int wakefulness) {
         mWakefulness = wakefulness;
         Trace.traceCounter(Trace.TRACE_TAG_APP, "wakefulness", wakefulness);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 1740290..3be3422 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -16,6 +16,9 @@
 
 package com.android.systemui.pip.phone;
 
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
 import android.app.IActivityManager;
@@ -182,7 +185,6 @@
         ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
 
         mInputConsumerController = InputConsumerController.getPipInputConsumer();
-        mInputConsumerController.registerInputConsumer();
         mMediaController = new PipMediaController(context, mActivityManager);
         mMenuController = new PipMenuActivityController(context, mActivityManager, mMediaController,
                 mInputConsumerController);
@@ -190,6 +192,18 @@
                 mMenuController, mInputConsumerController);
         mAppOpsListener = new PipAppOpsListener(context, mActivityManager,
                 mTouchHandler.getMotionHelper());
+
+        // If SystemUI restart, and it already existed a pinned stack,
+        // register the pip input consumer to ensure touch can send to it.
+        try {
+            ActivityManager.StackInfo stackInfo = mActivityTaskManager.getStackInfo(
+                    WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
+            if (stackInfo != null) {
+                mInputConsumerController.registerInputConsumer();
+            }
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index 86ce60d..ec6d7ff 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -48,7 +48,6 @@
 import android.content.Intent;
 import android.content.pm.ParceledListSlice;
 import android.graphics.Color;
-import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
@@ -64,7 +63,6 @@
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.WindowManager.LayoutParams;
 import android.view.accessibility.AccessibilityManager;
@@ -92,6 +90,7 @@
     public static final int MESSAGE_UPDATE_ACTIONS = 4;
     public static final int MESSAGE_UPDATE_DISMISS_FRACTION = 5;
     public static final int MESSAGE_ANIMATION_ENDED = 6;
+    public static final int MESSAGE_TOUCH_EVENT = 7;
 
     private static final int INITIAL_DISMISS_DELAY = 3500;
     private static final int POST_INTERACTION_DISMISS_DELAY = 2000;
@@ -129,10 +128,6 @@
                 }
             };
 
-    private PipTouchState mTouchState;
-    private PointF mDownPosition = new PointF();
-    private PointF mDownDelta = new PointF();
-    private ViewConfiguration mViewConfig;
     private Handler mHandler = new Handler();
     private Messenger mToControllerMessenger;
     private Messenger mMessenger = new Messenger(new Handler() {
@@ -170,6 +165,12 @@
                     mAllowTouches = true;
                     break;
                 }
+
+                case MESSAGE_TOUCH_EVENT: {
+                    final MotionEvent ev = (MotionEvent) msg.obj;
+                    dispatchTouchEvent(ev);
+                    break;
+                }
             }
         }
     });
@@ -185,15 +186,7 @@
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         // Set the flags to allow us to watch for outside touches and also hide the menu and start
         // manipulating the PIP in the same touch gesture
-        mViewConfig = ViewConfiguration.get(this);
-        mTouchState = new PipTouchState(mViewConfig, mHandler, () -> {
-            if (mMenuState == MENU_STATE_CLOSE) {
-                showPipMenu();
-            } else {
-                expandPip();
-            }
-        });
-        getWindow().addFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | LayoutParams.FLAG_SLIPPERY);
+        getWindow().addFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
 
         super.onCreate(savedInstanceState);
         setContentView(R.layout.pip_menu_activity);
@@ -205,32 +198,6 @@
         mViewRoot.setBackground(mBackgroundDrawable);
         mMenuContainer = findViewById(R.id.menu_container);
         mMenuContainer.setAlpha(0);
-        mMenuContainer.setOnTouchListener((v, event) -> {
-            mTouchState.onTouchEvent(event);
-            switch (event.getAction()) {
-                case MotionEvent.ACTION_UP:
-                    if (mTouchState.isDoubleTap() || mMenuState == MENU_STATE_FULL) {
-                        // Expand to fullscreen if this is a double tap or we are already expanded
-                        expandPip();
-                    } else if (!mTouchState.isWaitingForDoubleTap()) {
-                        // User has stalled long enough for this not to be a drag or a double tap,
-                        // just expand the menu if necessary
-                        if (mMenuState == MENU_STATE_CLOSE) {
-                            showPipMenu();
-                        }
-                    } else {
-                        // Next touch event _may_ be the second tap for the double-tap, schedule a
-                        // fallback runnable to trigger the menu if no touch event occurs before the
-                        // next tap
-                        mTouchState.scheduleDoubleTapTimeoutCallback();
-                    }
-                    // Fall through
-                case MotionEvent.ACTION_CANCEL:
-                    mTouchState.reset();
-                    break;
-            }
-            return true;
-        });
         mSettingsButton = findViewById(R.id.settings);
         mSettingsButton.setAlpha(0);
         mSettingsButton.setOnClickListener((v) -> {
@@ -240,8 +207,11 @@
         });
         mDismissButton = findViewById(R.id.dismiss);
         mDismissButton.setAlpha(0);
-        mDismissButton.setOnClickListener((v) -> {
-            dismissPip();
+        mDismissButton.setOnClickListener(v -> dismissPip());
+        findViewById(R.id.expand_button).setOnClickListener(v -> {
+            if (mMenuContainer.getAlpha() != 0) {
+                expandPip();
+            }
         });
         mActionsGroup = findViewById(R.id.actions_group);
         mBetweenActionPaddingLand = getResources().getDimensionPixelSize(
@@ -301,27 +271,14 @@
     @Override
     public boolean dispatchTouchEvent(MotionEvent ev) {
         if (!mAllowTouches) {
-            return super.dispatchTouchEvent(ev);
+            return false;
         }
 
         // On the first action outside the window, hide the menu
         switch (ev.getAction()) {
             case MotionEvent.ACTION_OUTSIDE:
                 hideMenu();
-                break;
-            case MotionEvent.ACTION_DOWN:
-                mDownPosition.set(ev.getX(), ev.getY());
-                mDownDelta.set(0f, 0f);
-                break;
-            case MotionEvent.ACTION_MOVE:
-                mDownDelta.set(ev.getX() - mDownPosition.x, ev.getY() - mDownPosition.y);
-                if (mDownDelta.length() > mViewConfig.getScaledTouchSlop()
-                        && mMenuState != MENU_STATE_NONE) {
-                    // Restore the input consumer and let that drive the movement of this menu
-                    notifyRegisterInputConsumer();
-                    cancelDelayedFinish();
-                }
-                break;
+                return true;
         }
         return super.dispatchTouchEvent(ev);
     }
@@ -384,7 +341,6 @@
             if (allowMenuTimeout) {
                 repostDelayedFinish(POST_INTERACTION_DISMISS_DELAY);
             }
-            notifyUnregisterInputConsumer();
         }
     }
 
@@ -509,11 +465,13 @@
                     actionView.setContentDescription(action.getContentDescription());
                     if (action.isEnabled()) {
                         actionView.setOnClickListener(v -> {
-                            try {
-                                action.getActionIntent().send();
-                            } catch (CanceledException e) {
-                                Log.w(TAG, "Failed to send action", e);
-                            }
+                            mHandler.post(() -> {
+                                try {
+                                    action.getActionIntent().send();
+                                } catch (CanceledException e) {
+                                    Log.w(TAG, "Failed to send action", e);
+                                }
+                            });
                         });
                     }
                     actionView.setEnabled(action.isEnabled());
@@ -557,18 +515,6 @@
         mBackgroundDrawable.setAlpha(alpha);
     }
 
-    private void notifyRegisterInputConsumer() {
-        Message m = Message.obtain();
-        m.what = PipMenuActivityController.MESSAGE_REGISTER_INPUT_CONSUMER;
-        sendMessage(m, "Could not notify controller to register input consumer");
-    }
-
-    private void notifyUnregisterInputConsumer() {
-        Message m = Message.obtain();
-        m.what = PipMenuActivityController.MESSAGE_UNREGISTER_INPUT_CONSUMER;
-        sendMessage(m, "Could not notify controller to unregister input consumer");
-    }
-
     private void notifyMenuStateChange(int menuState) {
         mMenuState = menuState;
         Message m = Message.obtain();
@@ -586,11 +532,6 @@
         }, false /* notifyMenuVisibility */, false /* isDismissing */);
     }
 
-    private void minimizePip() {
-        sendEmptyMessage(PipMenuActivityController.MESSAGE_MINIMIZE_PIP,
-                "Could not notify controller to minimize PIP");
-    }
-
     private void dismissPip() {
         // Do not notify menu visibility when hiding the menu, the controller will do this when it
         // handles the message
@@ -600,12 +541,6 @@
         }, false /* notifyMenuVisibility */, true /* isDismissing */);
     }
 
-    private void showPipMenu() {
-        Message m = Message.obtain();
-        m.what = PipMenuActivityController.MESSAGE_SHOW_MENU;
-        sendMessage(m, "Could not notify controller to show PIP menu");
-    }
-
     private void showSettings() {
         final Pair<ComponentName, Integer> topPipActivityInfo =
                 PipUtils.getTopPinnedActivity(this, ActivityManager.getService());
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
index 46d53e4..57c04c3 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
@@ -37,6 +37,7 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.Log;
+import android.view.MotionEvent;
 
 import com.android.systemui.pip.phone.PipMediaController.ActionListener;
 import com.android.systemui.shared.system.InputConsumerController;
@@ -156,14 +157,6 @@
                     mListeners.forEach(l -> l.onPipShowMenu());
                     break;
                 }
-                case MESSAGE_REGISTER_INPUT_CONSUMER: {
-                    mInputConsumerController.registerInputConsumer();
-                    break;
-                }
-                case MESSAGE_UNREGISTER_INPUT_CONSUMER: {
-                    mInputConsumerController.unregisterInputConsumer();
-                    break;
-                }
                 case MESSAGE_UPDATE_ACTIVITY_CALLBACK: {
                     mToActivityMessenger = msg.replyTo;
                     setStartActivityRequested(false);
@@ -212,15 +205,12 @@
     }
 
     public void onActivityPinned() {
-        if (mMenuState == MENU_STATE_NONE) {
-            // If the menu is not visible, then re-register the input consumer if it is not already
-            // registered
-            mInputConsumerController.registerInputConsumer();
-        }
+        mInputConsumerController.registerInputConsumer();
     }
 
     public void onActivityUnpinned() {
         hideMenu();
+        mInputConsumerController.unregisterInputConsumer();
         setStartActivityRequested(false);
     }
 
@@ -494,11 +484,7 @@
             Log.d(TAG, "onMenuStateChanged() mMenuState=" + mMenuState
                     + " menuState=" + menuState + " resize=" + resize);
         }
-        if (menuState == MENU_STATE_NONE) {
-            mInputConsumerController.registerInputConsumer();
-        } else {
-            mInputConsumerController.unregisterInputConsumer();
-        }
+
         if (menuState != mMenuState) {
             mListeners.forEach(l -> l.onPipMenuStateChanged(menuState, resize));
             if (menuState == MENU_STATE_FULL) {
@@ -520,6 +506,22 @@
         mStartActivityRequestedTime = requested ? SystemClock.uptimeMillis() : 0;
     }
 
+    /**
+     * Handles touch event sent from pip input consumer.
+     */
+    void handleTouchEvent(MotionEvent ev) {
+        if (mToActivityMessenger != null) {
+            Message m = Message.obtain();
+            m.what = PipMenuActivity.MESSAGE_TOUCH_EVENT;
+            m.obj = ev;
+            try {
+                mToActivityMessenger.send(m);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Could not dispatch touch event", e);
+            }
+        }
+    }
+
     public void dump(PrintWriter pw, String prefix) {
         final String innerPrefix = prefix + "  ";
         pw.println(prefix + TAG);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index b05058a..30cf412 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -363,6 +363,8 @@
         // Update the touch state
         mTouchState.onTouchEvent(ev);
 
+        boolean shouldDeliverToMenu = mMenuState != MENU_STATE_NONE;
+
         switch (ev.getAction()) {
             case MotionEvent.ACTION_DOWN: {
                 mMotionHelper.synchronizePinnedStackBounds();
@@ -378,6 +380,8 @@
                         break;
                     }
                 }
+
+                shouldDeliverToMenu = !mTouchState.isDragging();
                 break;
             }
             case MotionEvent.ACTION_UP: {
@@ -394,6 +398,7 @@
                 // Fall through to clean up
             }
             case MotionEvent.ACTION_CANCEL: {
+                shouldDeliverToMenu = !mTouchState.startedDragging() && !mTouchState.isDragging();
                 mTouchState.reset();
                 break;
             }
@@ -425,7 +430,20 @@
                 break;
             }
         }
-        return mMenuState == MENU_STATE_NONE;
+
+        // Deliver the event to PipMenuActivity to handle button click if the menu has shown.
+        if (shouldDeliverToMenu) {
+            final MotionEvent cloneEvent = MotionEvent.obtain(ev);
+            // Send the cancel event and cancel menu timeout if it starts to drag.
+            if (mTouchState.startedDragging()) {
+                cloneEvent.setAction(MotionEvent.ACTION_CANCEL);
+                mMenuController.pokeMenu();
+            }
+
+            mMenuController.handleTouchEvent(cloneEvent);
+        }
+
+        return true;
     }
 
     /**
@@ -741,11 +759,11 @@
                 mMotionHelper.animateToClosestSnapTarget(mMovementBounds, null /* updateListener */,
                         null /* animatorListener */);
                 setMinimizedStateInternal(false);
+            } else if (mTouchState.isDoubleTap()) {
+                // Expand to fullscreen if this is a double tap
+                mMotionHelper.expandPip();
             } else if (mMenuState != MENU_STATE_FULL) {
-                if (mTouchState.isDoubleTap()) {
-                    // Expand to fullscreen if this is a double tap
-                    mMotionHelper.expandPip();
-                } else if (!mTouchState.isWaitingForDoubleTap()) {
+                if (!mTouchState.isWaitingForDoubleTap()) {
                     // User has stalled long enough for this not to be a drag or a double tap, just
                     // expand the menu
                     mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
@@ -756,9 +774,6 @@
                     // next tap
                     mTouchState.scheduleDoubleTapTimeoutCallback();
                 }
-            } else {
-                mMenuController.hideMenu();
-                mMotionHelper.expandPip();
             }
             return true;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
index 69efbc8..e3f65ef 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
@@ -106,6 +106,7 @@
                 mIsDoubleTap = !mPreviouslyDragging &&
                         (mDownTouchTime - mLastDownTouchTime) < DOUBLE_TAP_TIMEOUT;
                 mIsWaitingForDoubleTap = false;
+                mIsDragging = false;
                 mLastDownTouchTime = mDownTouchTime;
                 if (mDoubleTapTimeoutCallback != null) {
                     mHandler.removeCallbacks(mDoubleTapTimeoutCallback);
diff --git a/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java b/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java
index 9b1f23a..78f5350 100644
--- a/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java
@@ -2,8 +2,16 @@
 
 import com.android.settingslib.fuelgauge.Estimate;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
 public class EnhancedEstimatesImpl implements EnhancedEstimates {
 
+    @Inject
+    public EnhancedEstimatesImpl() {
+    }
+
     @Override
     public boolean isHybridNotificationEnabled() {
         return false;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index 991d9fa..0403a05 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -248,7 +248,9 @@
         int numPages = Math.max(nTiles / mPages.get(0).maxTiles(), 1);
 
         // Add one more not full page if needed
-        numPages += (nTiles % mPages.get(0).maxTiles() == 0 ? 0 : 1);
+        if (nTiles > numPages * mPages.get(0).maxTiles()) {
+            numPages++;
+        }
 
         final int NP = mPages.size();
         for (int i = 0; i < NP; i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroup.java b/packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroup.java
index 255a4ba..cca889c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroup.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroup.java
@@ -26,6 +26,7 @@
 import android.util.Log;
 import android.view.View;
 import android.widget.LinearLayout;
+import android.widget.TextView;
 
 import androidx.annotation.VisibleForTesting;
 
@@ -54,6 +55,7 @@
 
     private View[] mCarrierDividers = new View[SIM_SLOTS - 1];
     private QSCarrier[] mCarrierGroups = new QSCarrier[SIM_SLOTS];
+    private TextView mNoSimTextView;
     private final CellSignalState[] mInfos = new CellSignalState[SIM_SLOTS];
     private CarrierTextController mCarrierTextController;
     private ActivityStarter mActivityStarter;
@@ -93,10 +95,13 @@
         mCarrierDividers[0] = findViewById(R.id.qs_carrier_divider1);
         mCarrierDividers[1] = findViewById(R.id.qs_carrier_divider2);
 
+        mNoSimTextView = findViewById(R.id.no_carrier_text);
+
         for (int i = 0; i < SIM_SLOTS; i++) {
             mInfos[i] = new CellSignalState();
             mCarrierGroups[i].setOnClickListener(this);
         }
+        mNoSimTextView.setOnClickListener(this);
 
         CharSequence separator = mContext.getString(
                 com.android.internal.R.string.kg_text_message_separator);
@@ -153,50 +158,47 @@
 
     @Override
     public void updateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) {
-        if (info.airplaneMode) {
-            setVisibility(View.GONE);
-        } else {
-            setVisibility(View.VISIBLE);
-            if (info.anySimReady) {
-                boolean[] slotSeen = new boolean[SIM_SLOTS];
-                if (info.listOfCarriers.length == info.subscriptionIds.length) {
-                    for (int i = 0; i < SIM_SLOTS && i < info.listOfCarriers.length; i++) {
-                        int slot = getSlotIndex(info.subscriptionIds[i]);
-                        if (slot >= SIM_SLOTS) {
-                            Log.w(TAG, "updateInfoCarrier - slot: " + slot);
-                            continue;
-                        }
-                        if (slot == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
-                            Log.e(TAG,
-                                    "Invalid SIM slot index for subscription: "
-                                            + info.subscriptionIds[i]);
-                            continue;
-                        }
-                        mInfos[slot].visible = true;
-                        slotSeen[slot] = true;
-                        mCarrierGroups[slot].setCarrierText(
-                                info.listOfCarriers[i].toString().trim());
-                        mCarrierGroups[slot].setVisibility(View.VISIBLE);
+        mNoSimTextView.setVisibility(View.GONE);
+        if (!info.airplaneMode && info.anySimReady) {
+            boolean[] slotSeen = new boolean[SIM_SLOTS];
+            if (info.listOfCarriers.length == info.subscriptionIds.length) {
+                for (int i = 0; i < SIM_SLOTS && i < info.listOfCarriers.length; i++) {
+                    int slot = getSlotIndex(info.subscriptionIds[i]);
+                    if (slot >= SIM_SLOTS) {
+                        Log.w(TAG, "updateInfoCarrier - slot: " + slot);
+                        continue;
                     }
-                    for (int i = 0; i < SIM_SLOTS; i++) {
-                        if (!slotSeen[i]) {
-                            mInfos[i].visible = false;
-                            mCarrierGroups[i].setVisibility(View.GONE);
-                        }
+                    if (slot == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
+                        Log.e(TAG,
+                                "Invalid SIM slot index for subscription: "
+                                        + info.subscriptionIds[i]);
+                        continue;
                     }
-                } else {
-                    Log.e(TAG, "Carrier information arrays not of same length");
+                    mInfos[slot].visible = true;
+                    slotSeen[slot] = true;
+                    mCarrierGroups[slot].setCarrierText(
+                            info.listOfCarriers[i].toString().trim());
+                    mCarrierGroups[slot].setVisibility(View.VISIBLE);
+                }
+                for (int i = 0; i < SIM_SLOTS; i++) {
+                    if (!slotSeen[i]) {
+                        mInfos[i].visible = false;
+                        mCarrierGroups[i].setVisibility(View.GONE);
+                    }
                 }
             } else {
-                mInfos[0].visible = false;
-                mCarrierGroups[0].setCarrierText(info.carrierText);
-                mCarrierGroups[0].setVisibility(View.VISIBLE);
-                for (int i = 1; i < SIM_SLOTS; i++) {
-                    mInfos[i].visible = false;
-                    mCarrierGroups[i].setCarrierText("");
-                    mCarrierGroups[i].setVisibility(View.GONE);
-                }
+                Log.e(TAG, "Carrier information arrays not of same length");
             }
+        } else {
+            // No sims or airplane mode (but not WFC). Do not show QSCarrierGroup, instead just show
+            // info.carrierText in a different view.
+            for (int i = 0; i < SIM_SLOTS; i++) {
+                mInfos[i].visible = false;
+                mCarrierGroups[i].setCarrierText("");
+                mCarrierGroups[i].setVisibility(View.GONE);
+            }
+            mNoSimTextView.setText(info.carrierText);
+            mNoSimTextView.setVisibility(View.VISIBLE);
         }
         handleUpdateState();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index f0413cd..be8a8fd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -111,13 +111,25 @@
                 + mQSPanel.getMeasuredHeight() + getPaddingBottom();
         super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
                 MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
-
         // QSCustomizer will always be the height of the screen, but do this after
         // other measuring to avoid changing the height of the QS.
         mQSCustomizer.measure(widthMeasureSpec,
                 MeasureSpec.makeMeasureSpec(getDisplayHeight(), MeasureSpec.EXACTLY));
     }
 
+
+    @Override
+    protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed,
+            int parentHeightMeasureSpec, int heightUsed) {
+        // Do not measure QSPanel again when doing super.onMeasure.
+        // This prevents the pages in PagedTileLayout to be remeasured with a different (incorrect)
+        // size to the one used for determining the number of rows and then the number of pages.
+        if (child != mQSPanel) {
+            super.measureChildWithMargins(child, parentWidthMeasureSpec, widthUsed,
+                    parentHeightMeasureSpec, heightUsed);
+        }
+    }
+
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index 83b000d..38153ec 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -38,8 +38,8 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
-import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.qs.QSDetailClipper;
@@ -52,6 +52,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.inject.Inject;
+
 /**
  * Allows full-screen customization of QS, through show() and hide().
  *
@@ -66,6 +68,8 @@
 
     private final QSDetailClipper mClipper;
     private final LightBarController mLightBarController;
+    private KeyguardMonitor mKeyguardMonitor;
+    private final ScreenLifecycle mScreenLifecycle;
     private final TileQueryHelper mTileQueryHelper;
     private final View mTransparentView;
 
@@ -82,7 +86,11 @@
     private boolean mOpening;
     private boolean mIsShowingNavBackdrop;
 
-    public QSCustomizer(Context context, AttributeSet attrs) {
+    @Inject
+    public QSCustomizer(Context context, AttributeSet attrs,
+            LightBarController lightBarController,
+            KeyguardMonitor keyguardMonitor,
+            ScreenLifecycle screenLifecycle) {
         super(new ContextThemeWrapper(context, R.style.edit_theme), attrs);
 
         LayoutInflater.from(getContext()).inflate(R.layout.qs_customize_panel_content, this);
@@ -115,7 +123,9 @@
         DefaultItemAnimator animator = new DefaultItemAnimator();
         animator.setMoveDuration(TileAdapter.MOVE_DURATION);
         mRecyclerView.setItemAnimator(animator);
-        mLightBarController = Dependency.get(LightBarController.class);
+        mLightBarController = lightBarController;
+        mKeyguardMonitor = keyguardMonitor;
+        mScreenLifecycle = screenLifecycle;
         updateNavBackDrop(getResources().getConfiguration());
     }
 
@@ -177,7 +187,7 @@
             queryTiles();
             mNotifQsContainer.setCustomizerAnimating(true);
             mNotifQsContainer.setCustomizerShowing(true);
-            Dependency.get(KeyguardMonitor.class).addCallback(mKeyguardCallback);
+            mKeyguardMonitor.addCallback(mKeyguardCallback);
             updateNavColors();
         }
     }
@@ -193,7 +203,7 @@
             queryTiles();
             mNotifQsContainer.setCustomizerAnimating(false);
             mNotifQsContainer.setCustomizerShowing(true);
-            Dependency.get(KeyguardMonitor.class).addCallback(mKeyguardCallback);
+            mKeyguardMonitor.addCallback(mKeyguardCallback);
             updateNavColors();
         }
     }
@@ -203,16 +213,21 @@
     }
 
     public void hide() {
+        final boolean animate = mScreenLifecycle.getScreenState() != ScreenLifecycle.SCREEN_OFF;
         if (isShown) {
             MetricsLogger.hidden(getContext(), MetricsProto.MetricsEvent.QS_EDIT);
             isShown = false;
             mToolbar.dismissPopupMenus();
             setCustomizing(false);
             save();
-            mClipper.animateCircularClip(mX, mY, false, mCollapseAnimationListener);
-            mNotifQsContainer.setCustomizerAnimating(true);
+            if (animate) {
+                mClipper.animateCircularClip(mX, mY, false, mCollapseAnimationListener);
+            } else {
+                setVisibility(View.GONE);
+            }
+            mNotifQsContainer.setCustomizerAnimating(animate);
             mNotifQsContainer.setCustomizerShowing(false);
-            Dependency.get(KeyguardMonitor.class).removeCallback(mKeyguardCallback);
+            mKeyguardMonitor.removeCallback(mKeyguardCallback);
             updateNavColors();
         }
     }
@@ -268,7 +283,7 @@
 
     public void saveInstanceState(Bundle outState) {
         if (isShown) {
-            Dependency.get(KeyguardMonitor.class).removeCallback(mKeyguardCallback);
+            mKeyguardMonitor.removeCallback(mKeyguardCallback);
         }
         outState.putBoolean(EXTRA_QS_CUSTOMIZING, mCustomizing);
     }
@@ -300,7 +315,7 @@
         @Override
         public void onKeyguardShowingChanged() {
             if (!isAttachedToWindow()) return;
-            if (Dependency.get(KeyguardMonitor.class).isShowing() && !mOpening) {
+            if (mKeyguardMonitor.isShowing() && !mOpening) {
                 hide();
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
index b135f7b..effea6a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
@@ -159,8 +159,11 @@
             mBindTryCount++;
             try {
                 mIsBound = mContext.bindServiceAsUser(mIntent, this,
-                        Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE
-                        | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS, mUser);
+                        Context.BIND_AUTO_CREATE
+                                | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE
+                                | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS
+                                | Context.BIND_WAIVE_PRIORITY,
+                        mUser);
             } catch (SecurityException e) {
                 Log.e(TAG, "Failed to bind to service", e);
                 mIsBound = false;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 664ea8b..cb87f59 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -41,8 +41,10 @@
 import com.android.systemui.R;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.DetailAdapter;
+import com.android.systemui.plugins.qs.QSIconView;
 import com.android.systemui.plugins.qs.QSTile.SignalState;
 import com.android.systemui.qs.QSHost;
+import com.android.systemui.qs.SignalTileView;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 import com.android.systemui.statusbar.policy.NetworkController;
@@ -79,6 +81,11 @@
     }
 
     @Override
+    public QSIconView createTileView(Context context) {
+        return new SignalTileView(context);
+    }
+
+    @Override
     public DetailAdapter getDetailAdapter() {
         return mDetailAdapter;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
index 91d38bd..187a3bd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
@@ -76,8 +76,11 @@
                 UserSwitcherController.UserRecord item) {
             UserDetailItemView v = UserDetailItemView.convertOrInflate(
                     mContext, convertView, parent);
-            if (v != convertView) {
+            if (!item.isCurrent || item.isGuest) {
                 v.setOnClickListener(this);
+            } else {
+                v.setOnClickListener(null);
+                v.setClickable(false);
             }
             String name = getName(mContext, item);
             if (item.picture == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index a9896f5..0383dee 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -22,34 +22,34 @@
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.Service;
+import android.content.ContentResolver;
+import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
+import android.graphics.Point;
 import android.graphics.drawable.Icon;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.VirtualDisplay;
 import android.media.MediaRecorder;
-import android.media.ThumbnailUtils;
 import android.media.projection.MediaProjection;
 import android.media.projection.MediaProjectionManager;
 import android.net.Uri;
-import android.os.Environment;
 import android.os.IBinder;
 import android.provider.MediaStore;
 import android.provider.Settings;
 import android.util.DisplayMetrics;
 import android.util.Log;
+import android.util.Size;
 import android.view.Surface;
 import android.widget.Toast;
 
-import androidx.core.content.FileProvider;
-
 import com.android.systemui.R;
 
 import java.io.File;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.nio.file.Files;
-import java.nio.file.Path;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 
@@ -76,12 +76,10 @@
     private static final String ACTION_DELETE = "com.android.systemui.screenrecord.DELETE";
 
     private static final int TOTAL_NUM_TRACKS = 1;
-    private static final String RECORD_DIR = "Captures"; // TODO: use a translatable string
     private static final int VIDEO_BIT_RATE = 6000000;
     private static final int VIDEO_FRAME_RATE = 30;
     private static final int AUDIO_BIT_RATE = 16;
     private static final int AUDIO_SAMPLE_RATE = 44100;
-    private static final String FILE_PROVIDER = "com.android.systemui.fileprovider";
 
     private MediaProjectionManager mMediaProjectionManager;
     private MediaProjection mMediaProjection;
@@ -117,11 +115,11 @@
 
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
-        Log.d(TAG, "RecordingService is starting");
         if (intent == null) {
             return Service.START_NOT_STICKY;
         }
         String action = intent.getAction();
+        Log.d(TAG, "onStartCommand " + action);
 
         NotificationManager notificationManager =
                 (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
@@ -157,26 +155,7 @@
 
             case ACTION_STOP:
                 stopRecording();
-
-                // Move temp file to user directory
-                File recordDir = new File(
-                        Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES),
-                        RECORD_DIR);
-                recordDir.mkdirs();
-
-                String fileName = new SimpleDateFormat("'screen-'yyyyMMdd-HHmmss'.mp4'")
-                        .format(new Date());
-                Path path = new File(recordDir, fileName).toPath();
-
-                try {
-                    Files.move(mTempFile.toPath(), path);
-                    Notification notification = createSaveNotification(path);
-                    notificationManager.notify(NOTIFICATION_ID, notification);
-                } catch (IOException e) {
-                    e.printStackTrace();
-                    Toast.makeText(this, R.string.screenrecord_delete_error, Toast.LENGTH_LONG)
-                            .show();
-                }
+                saveRecording(notificationManager);
                 break;
 
             case ACTION_PAUSE:
@@ -190,8 +169,7 @@
                 break;
 
             case ACTION_SHARE:
-                File shareFile = new File(intent.getStringExtra(EXTRA_PATH));
-                Uri shareUri = FileProvider.getUriForFile(this, FILE_PROVIDER, shareFile);
+                Uri shareUri = Uri.parse(intent.getStringExtra(EXTRA_PATH));
 
                 Intent shareIntent = new Intent(Intent.ACTION_SEND)
                         .setType("video/mp4")
@@ -211,20 +189,18 @@
                 // Close quick shade
                 sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
 
-                File file = new File(intent.getStringExtra(EXTRA_PATH));
-                if (file.delete()) {
-                    Toast.makeText(
-                            this,
-                            R.string.screenrecord_delete_description,
-                            Toast.LENGTH_LONG).show();
+                ContentResolver resolver = getContentResolver();
+                Uri uri = Uri.parse(intent.getStringExtra(EXTRA_PATH));
+                resolver.delete(uri, null, null);
 
-                    // Remove notification
-                    notificationManager.cancel(NOTIFICATION_ID);
-                } else {
-                    Log.e(TAG, "Error deleting screen recording!");
-                    Toast.makeText(this, R.string.screenrecord_delete_error, Toast.LENGTH_LONG)
-                            .show();
-                }
+                Toast.makeText(
+                        this,
+                        R.string.screenrecord_delete_description,
+                        Toast.LENGTH_LONG).show();
+
+                // Remove notification
+                notificationManager.cancel(NOTIFICATION_ID);
+                Log.d(TAG, "Deleted recording " + uri);
                 break;
         }
         return Service.START_STICKY;
@@ -295,6 +271,7 @@
 
             mMediaRecorder.start();
         } catch (IOException e) {
+            Log.e(TAG, "Error starting screen recording: " + e.getMessage());
             e.printStackTrace();
             throw new RuntimeException(e);
         }
@@ -352,13 +329,10 @@
         notificationManager.notify(NOTIFICATION_ID, mRecordingNotificationBuilder.build());
     }
 
-    private Notification createSaveNotification(Path path) {
-        Uri saveUri = FileProvider.getUriForFile(this, FILE_PROVIDER, path.toFile());
-        Log.d(TAG, "Screen recording saved to " + path.toString());
-
+    private Notification createSaveNotification(Uri uri) {
         Intent viewIntent = new Intent(Intent.ACTION_VIEW)
                 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION)
-                .setDataAndType(saveUri, "video/mp4");
+                .setDataAndType(uri, "video/mp4");
 
         Notification.Action shareAction = new Notification.Action.Builder(
                 Icon.createWithResource(this, R.drawable.ic_android),
@@ -366,7 +340,7 @@
                 PendingIntent.getService(
                         this,
                         REQUEST_CODE,
-                        getShareIntent(this, path.toString()),
+                        getShareIntent(this, uri.toString()),
                         PendingIntent.FLAG_UPDATE_CURRENT))
                 .build();
 
@@ -376,7 +350,7 @@
                 PendingIntent.getService(
                         this,
                         REQUEST_CODE,
-                        getDeleteIntent(this, path.toString()),
+                        getDeleteIntent(this, uri.toString()),
                         PendingIntent.FLAG_UPDATE_CURRENT))
                 .build();
 
@@ -394,8 +368,15 @@
                 .setAutoCancel(true);
 
         // Add thumbnail if available
-        Bitmap thumbnailBitmap = ThumbnailUtils.createVideoThumbnail(path.toString(),
-                MediaStore.Video.Thumbnails.MINI_KIND);
+        Bitmap thumbnailBitmap = null;
+        try {
+            ContentResolver resolver = getContentResolver();
+            Size size = Point.convert(MediaStore.ThumbnailConstants.MINI_SIZE);
+            thumbnailBitmap = resolver.loadThumbnail(uri, size, null);
+        } catch (IOException e) {
+            Log.e(TAG, "Error creating thumbnail: " + e.getMessage());
+            e.printStackTrace();
+        }
         if (thumbnailBitmap != null) {
             Notification.BigPictureStyle pictureStyle = new Notification.BigPictureStyle()
                     .bigPicture(thumbnailBitmap)
@@ -417,6 +398,38 @@
         stopSelf();
     }
 
+    private void saveRecording(NotificationManager notificationManager) {
+        String fileName = new SimpleDateFormat("'screen-'yyyyMMdd-HHmmss'.mp4'")
+                .format(new Date());
+
+        ContentValues values = new ContentValues();
+        values.put(MediaStore.Video.Media.DISPLAY_NAME, fileName);
+        values.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
+        values.put(MediaStore.Video.Media.DATE_ADDED, System.currentTimeMillis());
+        values.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis());
+
+        ContentResolver resolver = getContentResolver();
+        Uri collectionUri = MediaStore.Video.Media.getContentUri(
+                MediaStore.VOLUME_EXTERNAL_PRIMARY);
+        Uri itemUri = resolver.insert(collectionUri, values);
+
+        try {
+            // Add to the mediastore
+            OutputStream os = resolver.openOutputStream(itemUri, "w");
+            Files.copy(mTempFile.toPath(), os);
+            os.close();
+
+            Notification notification = createSaveNotification(itemUri);
+            notificationManager.notify(NOTIFICATION_ID, notification);
+
+            mTempFile.delete();
+        } catch (IOException e) {
+            Log.e(TAG, "Error saving screen recording: " + e.getMessage());
+            Toast.makeText(this, R.string.screenrecord_delete_error, Toast.LENGTH_LONG)
+                    .show();
+        }
+    }
+
     private void setTapsVisible(boolean turnOn) {
         int value = turnOn ? 1 : 0;
         Settings.System.putInt(getApplicationContext().getContentResolver(),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
index 8385c8e..5adee40 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
@@ -29,7 +29,6 @@
 import com.android.systemui.Gefingerpoken;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 
@@ -59,14 +58,15 @@
     private FalsingManager mFalsingManager;
 
     public DragDownHelper(Context context, View host, ExpandHelper.Callback callback,
-            DragDownCallback dragDownCallback) {
+            DragDownCallback dragDownCallback,
+            FalsingManager falsingManager) {
         mMinDragDistance = context.getResources().getDimensionPixelSize(
                 R.dimen.keyguard_drag_down_min_distance);
         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
         mCallback = callback;
         mDragDownCallback = dragDownCallback;
         mHost = host;
-        mFalsingManager = FalsingManagerFactory.getInstance(context);
+        mFalsingManager = falsingManager;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 4be93df..6f87b29 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -562,11 +562,11 @@
             return;
         }
 
-        String message = mContext.getString(R.string.keyguard_unlock);
         if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
+            String message = mContext.getString(R.string.keyguard_retry);
             mStatusBarKeyguardViewManager.showBouncerMessage(message, mInitialTextColorState);
         } else if (mKeyguardUpdateMonitor.isScreenOn()) {
-            showTransientIndication(message);
+            showTransientIndication(mContext.getString(R.string.keyguard_unlock));
             hideTransientIndicationDelayed(BaseKeyguardCallback.HIDE_DELAY_MS);
         }
     }
@@ -650,7 +650,6 @@
             if (!updateMonitor.isUnlockingWithBiometricAllowed()) {
                 return;
             }
-            animatePadlockError();
             boolean showSwipeToUnlock =
                     msgId == KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
             if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
@@ -676,7 +675,11 @@
                 return;
             }
             animatePadlockError();
-            if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
+            if (msgId == FaceManager.FACE_ERROR_TIMEOUT) {
+                // The face timeout message is not very actionable, let's ask the user to
+                // manually retry.
+                showSwipeUpToUnlock();
+            } else if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
                 mStatusBarKeyguardViewManager.showBouncerMessage(errString, mInitialTextColorState);
             } else if (updateMonitor.isScreenOn()) {
                 showTransientIndication(errString);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLifetimeExtender.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLifetimeExtender.java
index 48e2923..0f295ba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLifetimeExtender.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLifetimeExtender.java
@@ -27,18 +27,6 @@
     boolean shouldExtendLifetime(@NonNull NotificationEntry entry);
 
     /**
-     * It's possible that a notification was canceled before it ever became visible. This callback
-     * gives lifetime extenders a chance to make sure it shows up. For example if a foreground
-     * service is canceled too quickly but we still want to make sure a FGS notification shows.
-     * @param pendingEntry the canceled (but pending) entry
-     * @return true if the notification lifetime should be extended
-     */
-    default boolean shouldExtendLifetimeForPendingNotification(
-            @NonNull NotificationEntry pendingEntry) {
-        return false;
-    }
-
-    /**
      * Sets whether or not the lifetime should be managed by the extender.  In practice, if
      * shouldManage is true, this is where the extender starts managing the entry internally and is
      * now responsible for calling {@link NotificationSafeToRemoveCallback#onSafeToRemove(String)}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
index c375574..1400921 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
@@ -37,11 +37,15 @@
 
 import java.util.ArrayList;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
 /**
  * This class handles listening to notification updates and passing them along to
  * NotificationPresenter to be displayed to the user.
  */
 @SuppressLint("OverrideAbstract")
+@Singleton
 public class NotificationListener extends NotificationListenerWithPlugins {
     private static final String TAG = "NotificationListener";
 
@@ -56,6 +60,7 @@
     private final ArrayList<NotificationSettingsListener> mSettingsListeners = new ArrayList<>();
     private final Context mContext;
 
+    @Inject
     public NotificationListener(Context context) {
         mContext = context;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index e08a5ae..802a7d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -58,10 +58,14 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
 /**
  * Handles keeping track of the current user, profiles, and various things related to hiding
  * contents, redacting notifications, and the lockscreen.
  */
+@Singleton
 public class NotificationLockscreenUserManagerImpl implements
         Dumpable, NotificationLockscreenUserManager, StateListener {
     private static final String TAG = "LockscreenUserManager";
@@ -171,6 +175,7 @@
         return mEntryManager;
     }
 
+    @Inject
     public NotificationLockscreenUserManagerImpl(Context context) {
         mContext = context;
         mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index 6e75c03..66a0619 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -28,7 +28,7 @@
 import android.view.ViewGroup;
 
 import com.android.systemui.R;
-import com.android.systemui.bubbles.BubbleData;
+import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -85,7 +85,7 @@
      * possible.
      */
     private final boolean mAlwaysExpandNonGroupedNotification;
-    private final BubbleData mBubbleData;
+    private final BubbleController mBubbleController;
     private final DynamicPrivacyController mDynamicPrivacyController;
     private final KeyguardBypassController mBypassController;
 
@@ -107,8 +107,8 @@
             StatusBarStateController statusBarStateController,
             NotificationEntryManager notificationEntryManager,
             Lazy<ShadeController> shadeController,
-            BubbleData bubbleData,
             KeyguardBypassController bypassController,
+            BubbleController bubbleController,
             DynamicPrivacyController privacyController) {
         mHandler = mainHandler;
         mLockscreenUserManager = notificationLockscreenUserManager;
@@ -121,7 +121,7 @@
         Resources res = context.getResources();
         mAlwaysExpandNonGroupedNotification =
                 res.getBoolean(R.bool.config_alwaysExpandNonGroupedNotifications);
-        mBubbleData = bubbleData;
+        mBubbleController = bubbleController;
         mDynamicPrivacyController = privacyController;
         privacyController.addListener(this);
     }
@@ -147,7 +147,7 @@
         for (int i = 0; i < N; i++) {
             NotificationEntry ent = activeNotifications.get(i);
             if (ent.isRowDismissed() || ent.isRowRemoved()
-                    || (mBubbleData.hasBubbleWithKey(ent.key) && !ent.showInShadeWhenBubble())) {
+                    || mBubbleController.isBubbleNotificationSuppressedFromShade(ent.key)) {
                 // we don't want to update removed notifications because they could
                 // temporarily become children if they were isolated before.
                 continue;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
index 986486a..a70dc7c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
@@ -27,12 +27,13 @@
 import android.view.MotionEvent
 import android.view.VelocityTracker
 import android.view.ViewConfiguration
+import com.android.systemui.Dependency
 
 import com.android.systemui.Gefingerpoken
 import com.android.systemui.Interpolators
 import com.android.systemui.R
-import com.android.systemui.classifier.FalsingManagerFactory
 import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.ExpandableView
@@ -41,7 +42,6 @@
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.phone.ShadeController
-import com.android.systemui.statusbar.policy.HeadsUpManager
 
 import javax.inject.Inject
 import javax.inject.Singleton
@@ -52,11 +52,14 @@
  */
 @Singleton
 class PulseExpansionHandler @Inject
-constructor(context: Context,
-            private val wakeUpCoordinator: NotificationWakeUpCoordinator,
-            private val bypassController: KeyguardBypassController,
-            private val headsUpManager: HeadsUpManagerPhone,
-            private val roundnessManager: NotificationRoundnessManager) : Gefingerpoken {
+constructor(
+    context: Context,
+    private val wakeUpCoordinator: NotificationWakeUpCoordinator,
+    private val bypassController: KeyguardBypassController,
+    private val headsUpManager: HeadsUpManagerPhone,
+    private val roundnessManager: NotificationRoundnessManager,
+    private val statusBarStateController: StatusBarStateController
+) : Gefingerpoken {
     companion object {
         private val RUBBERBAND_FACTOR_STATIC = 0.25f
         private val SPRING_BACK_ANIMATION_LENGTH_MS = 375
@@ -115,7 +118,7 @@
         mMinDragDistance = context.resources.getDimensionPixelSize(
                 R.dimen.keyguard_drag_down_min_distance)
         mTouchSlop = ViewConfiguration.get(context).scaledTouchSlop.toFloat()
-        mFalsingManager = FalsingManagerFactory.getInstance(context)
+        mFalsingManager = Dependency.get(FalsingManager::class.java)
         mPowerManager = context.getSystemService(PowerManager::class.java)
     }
 
@@ -124,8 +127,8 @@
     }
 
     private fun maybeStartExpansion(event: MotionEvent): Boolean {
-        if (!wakeUpCoordinator.canShowPulsingHuns || qsExpanded
-                || bouncerShowing) {
+        if (!wakeUpCoordinator.canShowPulsingHuns || qsExpanded ||
+                bouncerShowing) {
             return false
         }
         if (velocityTracker == null) {
@@ -160,18 +163,18 @@
             }
 
             MotionEvent.ACTION_UP -> {
-                recycleVelocityTracker();
+                recycleVelocityTracker()
             }
 
             MotionEvent.ACTION_CANCEL -> {
-                recycleVelocityTracker();
+                recycleVelocityTracker()
             }
         }
         return false
     }
 
     private fun recycleVelocityTracker() {
-        velocityTracker?.recycle();
+        velocityTracker?.recycle()
         velocityTracker = null
     }
 
@@ -187,7 +190,8 @@
             MotionEvent.ACTION_MOVE -> updateExpansionHeight(moveDistance)
             MotionEvent.ACTION_UP -> {
                 velocityTracker!!.computeCurrentVelocity(1000 /* units */)
-                val canExpand = moveDistance > 0 && velocityTracker!!.getYVelocity() > -1000
+                val canExpand = moveDistance > 0 && velocityTracker!!.getYVelocity() > -1000 &&
+                        statusBarStateController.state != StatusBarState.SHADE
                 if (!mFalsingManager.isUnlockingDisabled && !isFalseTouch && canExpand) {
                     finishExpansion()
                 } else {
@@ -216,7 +220,7 @@
                     "com.android.systemui:PULSEDRAG")
         }
         shadeController.goToLockedShade(mStartingChild)
-        leavingLockscreen = true;
+        leavingLockscreen = true
         isExpanding = false
         if (mStartingChild is ExpandableNotificationRow) {
             val row = mStartingChild as ExpandableNotificationRow?
@@ -227,7 +231,7 @@
     private fun updateExpansionHeight(height: Float) {
         var expansionHeight = max(height, 0.0f)
         if (!mReachedWakeUpHeight && height > mWakeUpHeight) {
-            mReachedWakeUpHeight = true;
+            mReachedWakeUpHeight = true
         }
         if (mStartingChild != null) {
             val child = mStartingChild!!
@@ -317,9 +321,11 @@
         } else null
     }
 
-    fun setUp(stackScroller: NotificationStackScrollLayout,
-              expansionCallback: ExpansionCallback,
-              shadeController: ShadeController) {
+    fun setUp(
+        stackScroller: NotificationStackScrollLayout,
+        expansionCallback: ExpansionCallback,
+        shadeController: ShadeController
+    ) {
         this.expansionCallback = expansionCallback
         this.shadeController = shadeController
         this.stackScroller = stackScroller
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index f0eeb04..abf29c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -20,6 +20,7 @@
 import android.animation.ValueAnimator;
 import android.text.format.DateFormat;
 import android.util.FloatProperty;
+import android.util.Log;
 import android.view.View;
 import android.view.animation.Interpolator;
 
@@ -136,6 +137,11 @@
         // Record the to-be mState and mLastState
         recordHistoricalState(state, mState);
 
+        // b/139259891
+        if (mState == StatusBarState.SHADE && state == StatusBarState.SHADE_LOCKED) {
+            Log.e(TAG, "Invalid state transition: SHADE -> SHADE_LOCKED", new Throwable());
+        }
+
         synchronized (mListeners) {
             for (RankedListener rl : new ArrayList<>(mListeners)) {
                 rl.mListener.onStatePreChange(mState, state);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java
index d9328fa..e4bd4fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java
@@ -107,7 +107,7 @@
      */
     public boolean isInLockedDownShade() {
         if (!mStatusBarKeyguardViewManager.isShowing()
-                || !mStatusBarKeyguardViewManager.isSecure()) {
+                || !mUnlockMethodCache.isMethodSecure()) {
             return false;
         }
         int state = mStateController.getState();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index 5958d9d..f8fef7d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -54,11 +54,15 @@
 import java.util.List;
 import java.util.Map;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
 /**
  * NotificationEntryManager is responsible for the adding, removing, and updating of notifications.
  * It also handles tasks such as their inflation and their interaction with other
  * Notification.*Manager objects.
  */
+@Singleton
 public class NotificationEntryManager implements
         Dumpable,
         NotificationContentInflater.InflationCallback,
@@ -118,6 +122,7 @@
         }
     }
 
+    @Inject
     public NotificationEntryManager(Context context) {
         mNotificationData = new NotificationData();
     }
@@ -276,25 +281,11 @@
         }
 
         final NotificationEntry entry = mNotificationData.get(key);
+
+        abortExistingInflation(key);
+
         boolean lifetimeExtended = false;
 
-        // Notification was canceled before it got inflated
-        if (entry == null) {
-            NotificationEntry pendingEntry = mPendingNotifications.get(key);
-            if (pendingEntry != null) {
-                for (NotificationLifetimeExtender extender : mNotificationLifetimeExtenders) {
-                    if (extender.shouldExtendLifetimeForPendingNotification(pendingEntry)) {
-                        extendLifetime(pendingEntry, extender);
-                        lifetimeExtended = true;
-                    }
-                }
-            }
-        }
-
-        if (!lifetimeExtended) {
-            abortExistingInflation(key);
-        }
-
         if (entry != null) {
             // If a manager needs to keep the notification around for whatever reason, we
             // keep the notification
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationFilter.java
index 154d7b35..f99662e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationFilter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationFilter.java
@@ -133,11 +133,6 @@
                 }
             }
         }
-
-        if (entry.isBubble() && !entry.showInShadeWhenBubble()) {
-            return true;
-        }
-
         return false;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java
index 4fc6461..ef09434 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java
@@ -39,12 +39,16 @@
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
 /**
  * Provides heads-up and pulsing state for notification entries.
  */
+@Singleton
 public class NotificationInterruptionStateProvider {
 
     private static final String TAG = "InterruptionStateProvider";
@@ -53,17 +57,16 @@
     private static final boolean ENABLE_HEADS_UP = true;
     private static final String SETTING_HEADS_UP_TICKER = "ticker_gets_heads_up";
 
-    private final StatusBarStateController mStatusBarStateController =
-            Dependency.get(StatusBarStateController.class);
-    private final NotificationFilter mNotificationFilter = Dependency.get(NotificationFilter.class);
+    private final StatusBarStateController mStatusBarStateController;
+    private final NotificationFilter mNotificationFilter;
     private final AmbientDisplayConfiguration mAmbientDisplayConfiguration;
 
     private final Context mContext;
     private final PowerManager mPowerManager;
     private final IDreamManager mDreamManager;
+    private final BatteryController mBatteryController;
 
     private NotificationPresenter mPresenter;
-    private ShadeController mShadeController;
     private HeadsUpManager mHeadsUpManager;
     private HeadsUpSuppressor mHeadsUpSuppressor;
 
@@ -72,12 +75,17 @@
     protected boolean mUseHeadsUp = false;
     private boolean mDisableNotificationAlerts;
 
-    public NotificationInterruptionStateProvider(Context context) {
+    @Inject
+    public NotificationInterruptionStateProvider(Context context, NotificationFilter filter,
+            StatusBarStateController stateController, BatteryController batteryController) {
         this(context,
                 (PowerManager) context.getSystemService(Context.POWER_SERVICE),
                 IDreamManager.Stub.asInterface(
                         ServiceManager.checkService(DreamService.DREAM_SERVICE)),
-                new AmbientDisplayConfiguration(context));
+                new AmbientDisplayConfiguration(context),
+                filter,
+                batteryController,
+                stateController);
     }
 
     @VisibleForTesting
@@ -85,11 +93,17 @@
             Context context,
             PowerManager powerManager,
             IDreamManager dreamManager,
-            AmbientDisplayConfiguration ambientDisplayConfiguration) {
+            AmbientDisplayConfiguration ambientDisplayConfiguration,
+            NotificationFilter notificationFilter,
+            BatteryController batteryController,
+            StatusBarStateController statusBarStateController) {
         mContext = context;
         mPowerManager = powerManager;
         mDreamManager = dreamManager;
+        mBatteryController = batteryController;
         mAmbientDisplayConfiguration = ambientDisplayConfiguration;
+        mNotificationFilter = notificationFilter;
+        mStatusBarStateController = statusBarStateController;
     }
 
     /** Sets up late-binding dependencies for this component. */
@@ -97,29 +111,39 @@
             NotificationPresenter notificationPresenter,
             HeadsUpManager headsUpManager,
             HeadsUpSuppressor headsUpSuppressor) {
+        setUpWithPresenter(notificationPresenter, headsUpManager, headsUpSuppressor,
+                new ContentObserver(Dependency.get(Dependency.MAIN_HANDLER)) {
+                    @Override
+                    public void onChange(boolean selfChange) {
+                        boolean wasUsing = mUseHeadsUp;
+                        mUseHeadsUp = ENABLE_HEADS_UP && !mDisableNotificationAlerts
+                                && Settings.Global.HEADS_UP_OFF != Settings.Global.getInt(
+                                mContext.getContentResolver(),
+                                Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
+                                Settings.Global.HEADS_UP_OFF);
+                        Log.d(TAG, "heads up is " + (mUseHeadsUp ? "enabled" : "disabled"));
+                        if (wasUsing != mUseHeadsUp) {
+                            if (!mUseHeadsUp) {
+                                Log.d(TAG,
+                                        "dismissing any existing heads up notification on disable"
+                                                + " event");
+                                mHeadsUpManager.releaseAllImmediately();
+                            }
+                        }
+                    }
+                });
+    }
+
+    /** Sets up late-binding dependencies for this component. */
+    public void setUpWithPresenter(
+            NotificationPresenter notificationPresenter,
+            HeadsUpManager headsUpManager,
+            HeadsUpSuppressor headsUpSuppressor,
+            ContentObserver observer) {
         mPresenter = notificationPresenter;
         mHeadsUpManager = headsUpManager;
         mHeadsUpSuppressor = headsUpSuppressor;
-
-        mHeadsUpObserver = new ContentObserver(Dependency.get(Dependency.MAIN_HANDLER)) {
-            @Override
-            public void onChange(boolean selfChange) {
-                boolean wasUsing = mUseHeadsUp;
-                mUseHeadsUp = ENABLE_HEADS_UP && !mDisableNotificationAlerts
-                        && Settings.Global.HEADS_UP_OFF != Settings.Global.getInt(
-                        mContext.getContentResolver(),
-                        Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
-                        Settings.Global.HEADS_UP_OFF);
-                Log.d(TAG, "heads up is " + (mUseHeadsUp ? "enabled" : "disabled"));
-                if (wasUsing != mUseHeadsUp) {
-                    if (!mUseHeadsUp) {
-                        Log.d(TAG,
-                                "dismissing any existing heads up notification on disable event");
-                        mHeadsUpManager.releaseAllImmediately();
-                    }
-                }
-            }
-        };
+        mHeadsUpObserver = observer;
 
         if (ENABLE_HEADS_UP) {
             mContext.getContentResolver().registerContentObserver(
@@ -133,13 +157,6 @@
         mHeadsUpObserver.onChange(true); // set up
     }
 
-    private ShadeController getShadeController() {
-        if (mShadeController == null) {
-            mShadeController = Dependency.get(ShadeController.class);
-        }
-        return mShadeController;
-    }
-
     /**
      * Whether the notification should appear as a bubble with a fly-out on top of the screen.
      *
@@ -148,6 +165,15 @@
      */
     public boolean shouldBubbleUp(NotificationEntry entry) {
         final StatusBarNotification sbn = entry.notification;
+
+        if (!canAlertCommon(entry)) {
+            return false;
+        }
+
+        if (!canAlertAwakeCommon(entry)) {
+            return false;
+        }
+
         if (!entry.canBubble) {
             if (DEBUG) {
                 Log.d(TAG, "No bubble up: not allowed to bubble: " + sbn.getKey());
@@ -172,10 +198,6 @@
             return false;
         }
 
-        if (!canHeadsUpCommon(entry)) {
-            return false;
-        }
-
         return true;
     }
 
@@ -196,6 +218,21 @@
     private boolean shouldHeadsUpWhenAwake(NotificationEntry entry) {
         StatusBarNotification sbn = entry.notification;
 
+        if (!mUseHeadsUp) {
+            if (DEBUG_HEADS_UP) {
+                Log.d(TAG, "No heads up: no huns");
+            }
+            return false;
+        }
+
+        if (!canAlertCommon(entry)) {
+            return false;
+        }
+
+        if (!canAlertAwakeCommon(entry)) {
+            return false;
+        }
+
         boolean inShade = mStatusBarStateController.getState() == SHADE;
         if (entry.isBubble() && inShade) {
             if (DEBUG_HEADS_UP) {
@@ -205,17 +242,13 @@
             return false;
         }
 
-        if (!canAlertCommon(entry)) {
+        if (entry.shouldSuppressPeek()) {
             if (DEBUG_HEADS_UP) {
-                Log.d(TAG, "No heads up: notification shouldn't alert: " + sbn.getKey());
+                Log.d(TAG, "No heads up: suppressed by DND: " + sbn.getKey());
             }
             return false;
         }
 
-        if (!canHeadsUpCommon(entry)) {
-            return false;
-        }
-
         if (entry.importance < NotificationManager.IMPORTANCE_HIGH) {
             if (DEBUG_HEADS_UP) {
                 Log.d(TAG, "No heads up: unimportant notification: " + sbn.getKey());
@@ -265,6 +298,13 @@
             return false;
         }
 
+        if (mBatteryController.isAodPowerSave()) {
+            if (DEBUG_HEADS_UP) {
+                Log.d(TAG, "No pulsing: disabled by battery saver: " + sbn.getKey());
+            }
+            return false;
+        }
+
         if (!canAlertCommon(entry)) {
             if (DEBUG_HEADS_UP) {
                 Log.d(TAG, "No pulsing: notification shouldn't alert: " + sbn.getKey());
@@ -289,16 +329,13 @@
     }
 
     /**
-     * Common checks between regular heads up and when pulsing.  See
-     * {@link #shouldHeadsUp(NotificationEntry)} and
-     * {@link #shouldHeadsUpWhenDozing(NotificationEntry)}.  Notifications that fail any of these
-     * checks
-     * should not alert at all.
+     * Common checks between regular & AOD heads up and bubbles.
      *
      * @param entry the entry to check
      * @return true if these checks pass, false if the notification should not alert
      */
-    protected boolean canAlertCommon(NotificationEntry entry) {
+    @VisibleForTesting
+    public boolean canAlertCommon(NotificationEntry entry) {
         StatusBarNotification sbn = entry.notification;
 
         if (mNotificationFilter.shouldFilterOut(entry)) {
@@ -315,46 +352,36 @@
             }
             return false;
         }
-
         return true;
     }
 
     /**
-     * Common checks between heads up alerting and bubble fly out alerting. See
-     * {@link #shouldHeadsUp(NotificationEntry)} and
-     * {@link #shouldBubbleUp(NotificationEntry)}. Notifications that fail any of these
-     * checks should not interrupt the user on screen.
+     * Common checks between alerts that occur while the device is awake (heads up & bubbles).
      *
      * @param entry the entry to check
-     * @return true if these checks pass, false if the notification should not interrupt on screen
+     * @return true if these checks pass, false if the notification should not alert
      */
-    public boolean canHeadsUpCommon(NotificationEntry entry) {
+    @VisibleForTesting
+    public boolean canAlertAwakeCommon(NotificationEntry entry) {
         StatusBarNotification sbn = entry.notification;
 
-        if (!mUseHeadsUp || mPresenter.isDeviceInVrMode()) {
+        if (mPresenter.isDeviceInVrMode()) {
             if (DEBUG_HEADS_UP) {
-                Log.d(TAG, "No heads up: no huns or vr mode");
-            }
-            return false;
-        }
-
-        if (entry.shouldSuppressPeek()) {
-            if (DEBUG_HEADS_UP) {
-                Log.d(TAG, "No heads up: suppressed by DND: " + sbn.getKey());
+                Log.d(TAG, "No alerting: no huns or vr mode");
             }
             return false;
         }
 
         if (isSnoozedPackage(sbn)) {
             if (DEBUG_HEADS_UP) {
-                Log.d(TAG, "No heads up: snoozed package: " + sbn.getKey());
+                Log.d(TAG, "No alerting: snoozed package: " + sbn.getKey());
             }
             return false;
         }
 
         if (entry.hasJustLaunchedFullScreenIntent()) {
             if (DEBUG_HEADS_UP) {
-                Log.d(TAG, "No heads up: recent fullscreen: " + sbn.getKey());
+                Log.d(TAG, "No alerting: recent fullscreen: " + sbn.getKey());
             }
             return false;
         }
@@ -372,6 +399,18 @@
         mHeadsUpObserver.onChange(true);
     }
 
+    /** Whether all alerts are disabled. */
+    @VisibleForTesting
+    public boolean areNotificationAlertsDisabled() {
+        return mDisableNotificationAlerts;
+    }
+
+    /** Whether HUNs should be used. */
+    @VisibleForTesting
+    public boolean getUseHeadsUp() {
+        return mUseHeadsUp;
+    }
+
     protected NotificationPresenter getPresenter() {
         return mPresenter;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index fe88541..027e8e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -23,6 +23,7 @@
 import static android.app.Notification.CATEGORY_REMINDER;
 import static android.app.Notification.FLAG_BUBBLE;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
@@ -41,7 +42,6 @@
 import android.service.notification.NotificationListenerService;
 import android.service.notification.SnoozeCriterion;
 import android.service.notification.StatusBarNotification;
-import android.text.TextUtils;
 import android.util.ArraySet;
 import android.view.View;
 import android.widget.ImageView;
@@ -52,7 +52,6 @@
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.ContrastColorUtil;
-import com.android.systemui.R;
 import com.android.systemui.statusbar.InflationTask;
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.notification.InflationException;
@@ -156,19 +155,6 @@
     public boolean canBubble;
 
     /**
-     * Whether this notification should be shown in the shade when it is also displayed as a bubble.
-     *
-     * <p>When a notification is a bubble we don't show it in the shade once the bubble has been
-     * expanded</p>
-     */
-    private boolean mShowInShadeWhenBubble;
-
-    /**
-     * Whether the user has dismissed this notification when it was in bubble form.
-     */
-    private boolean mUserDismissedBubble;
-
-    /**
      * Whether this notification is shown to the user as a high priority notification: visible on
      * the lock screen/status bar and in the top section in the shade.
      */
@@ -244,31 +230,6 @@
         return (notification.getNotification().flags & FLAG_BUBBLE) != 0;
     }
 
-    public void setBubbleDismissed(boolean userDismissed) {
-        mUserDismissedBubble = userDismissed;
-    }
-
-    public boolean isBubbleDismissed() {
-        return mUserDismissedBubble;
-    }
-
-    /**
-     * Sets whether this notification should be shown in the shade when it is also displayed as a
-     * bubble.
-     */
-    public void setShowInShadeWhenBubble(boolean showInShade) {
-        mShowInShadeWhenBubble = showInShade;
-    }
-
-    /**
-     * Whether this notification should be shown in the shade when it is also displayed as a
-     * bubble.
-     */
-    public boolean showInShadeWhenBubble() {
-        // We always show it in the shade if non-clearable
-        return !isRowDismissed() && (!isClearable() || mShowInShadeWhenBubble);
-    }
-
     /**
      * Returns the data needed for a bubble for this notification, if it exists.
      */
@@ -463,72 +424,6 @@
     }
 
     /**
-     * Returns our best guess for the most relevant text summary of the latest update to this
-     * notification, based on its type. Returns null if there should not be an update message.
-     */
-    public CharSequence getUpdateMessage(Context context) {
-        final Notification underlyingNotif = notification.getNotification();
-        final Class<? extends Notification.Style> style = underlyingNotif.getNotificationStyle();
-
-        try {
-            if (Notification.BigTextStyle.class.equals(style)) {
-                // Return the big text, it is big so probably important. If it's not there use the
-                // normal text.
-                CharSequence bigText =
-                        underlyingNotif.extras.getCharSequence(Notification.EXTRA_BIG_TEXT);
-                return !TextUtils.isEmpty(bigText)
-                        ? bigText
-                        : underlyingNotif.extras.getCharSequence(Notification.EXTRA_TEXT);
-            } else if (Notification.MessagingStyle.class.equals(style)) {
-                final List<Notification.MessagingStyle.Message> messages =
-                        Notification.MessagingStyle.Message.getMessagesFromBundleArray(
-                                (Parcelable[]) underlyingNotif.extras.get(
-                                        Notification.EXTRA_MESSAGES));
-
-                final Notification.MessagingStyle.Message latestMessage =
-                        Notification.MessagingStyle.findLatestIncomingMessage(messages);
-
-                if (latestMessage != null) {
-                    final CharSequence personName = latestMessage.getSenderPerson() != null
-                            ? latestMessage.getSenderPerson().getName()
-                            : null;
-
-                    // Prepend the sender name if available since group chats also use messaging
-                    // style.
-                    if (!TextUtils.isEmpty(personName)) {
-                        return context.getResources().getString(
-                                R.string.notification_summary_message_format,
-                                personName,
-                                latestMessage.getText());
-                    } else {
-                        return latestMessage.getText();
-                    }
-                }
-            } else if (Notification.InboxStyle.class.equals(style)) {
-                CharSequence[] lines =
-                        underlyingNotif.extras.getCharSequenceArray(Notification.EXTRA_TEXT_LINES);
-
-                // Return the last line since it should be the most recent.
-                if (lines != null && lines.length > 0) {
-                    return lines[lines.length - 1];
-                }
-            } else if (Notification.MediaStyle.class.equals(style)) {
-                // Return nothing, media updates aren't typically useful as a text update.
-                return null;
-            } else {
-                // Default to text extra.
-                return underlyingNotif.extras.getCharSequence(Notification.EXTRA_TEXT);
-            }
-        } catch (ClassCastException | NullPointerException | ArrayIndexOutOfBoundsException e) {
-            // No use crashing, we'll just return null and the caller will assume there's no update
-            // message.
-            e.printStackTrace();
-        }
-
-        return null;
-    }
-
-    /**
      * Abort all existing inflation tasks
      */
     public void abortTask() {
@@ -875,6 +770,16 @@
         return shouldSuppressVisualEffect(SUPPRESSED_EFFECT_NOTIFICATION_LIST);
     }
 
+
+    /**
+     * Returns whether {@link Policy#SUPPRESSED_EFFECT_BADGE}
+     * is set for this entry. This badge is not an app badge, but rather an indicator of "unseen"
+     * content. Typically this is referred to as a "dot" internally in Launcher & SysUI code.
+     */
+    public boolean shouldSuppressNotificationDot() {
+        return shouldSuppressVisualEffect(SUPPRESSED_EFFECT_BADGE);
+    }
+
     /**
      * Categories that are explicitly called out on DND settings screens are always blocked, if
      * DND has flagged them, even if they are foreground or system notifications that might
@@ -942,12 +847,4 @@
             this.index = index;
         }
     }
-
-    /**
-     * Returns whether the notification is a foreground service. It shows that this is an ongoing
-     * bubble.
-     */
-    public boolean isForegroundService() {
-        return (notification.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index dca152f..8d73251 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -33,9 +33,9 @@
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.notification.FakeShadowView;
@@ -130,7 +130,7 @@
     private boolean mLastInSection;
     private boolean mFirstInSection;
     private boolean mIsBelowSpeedBump;
-    private FalsingManager mFalsingManager;
+    private final FalsingManager mFalsingManager;
 
     private float mNormalBackgroundVisibilityAmount;
     private float mDimmedBackgroundFadeInAmount = -1;
@@ -164,10 +164,10 @@
         super(context, attrs);
         mSlowOutFastInInterpolator = new PathInterpolator(0.8f, 0.0f, 0.6f, 1.0f);
         mSlowOutLinearInInterpolator = new PathInterpolator(0.8f, 0.0f, 1.0f, 1.0f);
+        mFalsingManager = Dependency.get(FalsingManager.class);  // TODO: inject into a controller.
         setClipChildren(false);
         setClipToPadding(false);
         updateColors();
-        mFalsingManager = FalsingManagerFactory.getInstance(context);
         mAccessibilityManager = AccessibilityManager.getInstance(mContext);
 
         mDoubleTapHelper = new DoubleTapHelper(this, (active) -> {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index ea31be4..12d537d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -74,7 +74,6 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
@@ -1209,12 +1208,12 @@
             mChildrenContainer.reInflateViews(mExpandClickListener, mEntry.notification);
         }
         if (mGuts != null) {
-            View oldGuts = mGuts;
+            NotificationGuts oldGuts = mGuts;
             int index = indexOfChild(oldGuts);
             removeView(oldGuts);
             mGuts = (NotificationGuts) LayoutInflater.from(mContext).inflate(
                     R.layout.notification_guts, this, false);
-            mGuts.setVisibility(oldGuts.getVisibility());
+            mGuts.setVisibility(oldGuts.isExposed() ? VISIBLE : GONE);
             addView(mGuts, index);
         }
         View oldMenu = mMenuRow == null ? null : mMenuRow.getMenuView();
@@ -1637,7 +1636,7 @@
 
     public ExpandableNotificationRow(Context context, AttributeSet attrs) {
         super(context, attrs);
-        mFalsingManager = FalsingManagerFactory.getInstance(context);
+        mFalsingManager = Dependency.get(FalsingManager.class);  // TODO: inject into a controller.
         mNotificationInflater = new NotificationContentInflater(this);
         mMenuRow = new NotificationMenuRow(mContext);
         mImageResolver = new NotificationInlineImageResolver(context,
@@ -2312,9 +2311,6 @@
 
     @Override
     public int getIntrinsicHeight() {
-        if (isShownAsBubble()) {
-            return getMaxExpandHeight();
-        }
         if (isUserLocked()) {
             return getActualHeight();
         }
@@ -2360,10 +2356,6 @@
         return mStatusbarStateController != null && mStatusbarStateController.isDozing();
     }
 
-    private boolean isShownAsBubble() {
-        return mEntry.isBubble() && !mEntry.showInShadeWhenBubble() && !mEntry.isBubbleDismissed();
-    }
-
     @Override
     public boolean isGroupExpanded() {
         return mGroupManager.isGroupExpanded(mStatusBarNotification);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index 48a8295..a612a17 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -264,7 +264,7 @@
                 mIsChildInGroup, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight,
                 packageContext);
         result = inflateSmartReplyViews(result, reInflateFlags, mRow.getEntry(),
-                mRow.getContext(), mRow.getHeadsUpManager(),
+                mRow.getContext(), packageContext, mRow.getHeadsUpManager(),
                 mRow.getExistingSmartRepliesAndActions());
         apply(
                 inflateSynchronously,
@@ -311,20 +311,21 @@
 
     private static InflationProgress inflateSmartReplyViews(InflationProgress result,
             @InflationFlag int reInflateFlags, NotificationEntry entry, Context context,
-            HeadsUpManager headsUpManager, SmartRepliesAndActions previousSmartRepliesAndActions) {
+            Context packageContext, HeadsUpManager headsUpManager,
+            SmartRepliesAndActions previousSmartRepliesAndActions) {
         SmartReplyConstants smartReplyConstants = Dependency.get(SmartReplyConstants.class);
         SmartReplyController smartReplyController = Dependency.get(SmartReplyController.class);
         if ((reInflateFlags & FLAG_CONTENT_VIEW_EXPANDED) != 0 && result.newExpandedView != null) {
             result.expandedInflatedSmartReplies =
                     InflatedSmartReplies.inflate(
-                            context, entry, smartReplyConstants, smartReplyController,
-                            headsUpManager, previousSmartRepliesAndActions);
+                            context, packageContext, entry, smartReplyConstants,
+                            smartReplyController, headsUpManager, previousSmartRepliesAndActions);
         }
         if ((reInflateFlags & FLAG_CONTENT_VIEW_HEADS_UP) != 0 && result.newHeadsUpView != null) {
             result.headsUpInflatedSmartReplies =
                     InflatedSmartReplies.inflate(
-                            context, entry, smartReplyConstants, smartReplyController,
-                            headsUpManager, previousSmartRepliesAndActions);
+                            context, packageContext, entry, smartReplyConstants,
+                            smartReplyController, headsUpManager, previousSmartRepliesAndActions);
         }
         return result;
     }
@@ -817,7 +818,7 @@
                         recoveredBuilder, mIsLowPriority, mIsChildInGroup, mUsesIncreasedHeight,
                         mUsesIncreasedHeadsUpHeight, packageContext);
                 return inflateSmartReplyViews(inflationProgress, mReInflateFlags, mRow.getEntry(),
-                        mRow.getContext(), mRow.getHeadsUpManager(),
+                        mRow.getContext(), packageContext, mRow.getHeadsUpManager(),
                         mRow.getExistingSmartRepliesAndActions());
             } catch (Exception e) {
                 mError = e;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java
index 4700baa..18d436f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java
@@ -421,7 +421,7 @@
     }
 
     /** Listener for animations executed in {@link #animateClose(int, int, boolean)}. */
-    private static class AnimateCloseListener extends AnimatorListenerAdapter {
+    private class AnimateCloseListener extends AnimatorListenerAdapter {
         final View mView;
         private final GutsContent mGutsContent;
 
@@ -433,8 +433,10 @@
         @Override
         public void onAnimationEnd(Animator animation) {
             super.onAnimationEnd(animation);
-            mView.setVisibility(View.GONE);
-            mGutsContent.onFinishedClosing();
+            if (!isExposed()) {
+                mView.setVisibility(View.GONE);
+                mGutsContent.onFinishedClosing();
+            }
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 8f7671a..719ec32 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -100,6 +100,7 @@
     protected String mKeyToRemoveOnGutsClosed;
 
     private StatusBar mStatusBar;
+    private Runnable mOpenRunnable;
 
     @Inject
     public NotificationGutsManager(
@@ -343,6 +344,7 @@
     public void closeAndSaveGuts(boolean removeLeavebehinds, boolean force, boolean removeControls,
             int x, int y, boolean resetMenu) {
         if (mNotificationGutsExposed != null) {
+            mNotificationGutsExposed.removeCallbacks(mOpenRunnable);
             mNotificationGutsExposed.closeControls(removeLeavebehinds, removeControls, x, y, force);
         }
         if (resetMenu) {
@@ -445,7 +447,7 @@
         // ensure that it's laid but not visible until actually laid out
         guts.setVisibility(View.INVISIBLE);
         // Post to ensure the the guts are properly laid out.
-        guts.post(new Runnable() {
+        mOpenRunnable = new Runnable() {
             @Override
             public void run() {
                 if (row.getWindowToken() == null) {
@@ -470,7 +472,8 @@
                 mListContainer.onHeightChanged(row, true /* needsAnimation */);
                 mGutsMenuItem = menuItem;
             }
-        });
+        };
+        guts.post(mOpenRunnable);
         return true;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index f50790f..688e8eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -86,7 +86,6 @@
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.FalsingManager;
@@ -516,7 +515,8 @@
             ActivityStarter activityStarter,
             StatusBarStateController statusBarStateController,
             HeadsUpManagerPhone headsUpManager,
-            KeyguardBypassController keyguardBypassController) {
+            KeyguardBypassController keyguardBypassController,
+            FalsingManager falsingManager) {
         super(context, attrs, 0, 0);
         Resources res = getResources();
 
@@ -531,6 +531,7 @@
         mHeadsUpManager.addListener(mRoundnessManager);
         mHeadsUpManager.setAnimationStateHandler(this::setHeadsUpGoingAwayAnimationsAllowed);
         mKeyguardBypassController = keyguardBypassController;
+        mFalsingManager = falsingManager;
 
         mSectionsManager =
                 new NotificationSectionsManager(
@@ -555,10 +556,9 @@
         mExpandHelper.setEventSource(this);
         mExpandHelper.setScrollAdapter(this);
         mSwipeHelper = new NotificationSwipeHelper(SwipeHelper.X, mNotificationCallback,
-                getContext(), mMenuEventListener);
+                getContext(), mMenuEventListener, mFalsingManager);
         mStackScrollAlgorithm = createStackScrollAlgorithm(context);
         initView(context);
-        mFalsingManager = FalsingManagerFactory.getInstance(context);
         mShouldDrawNotificationBackground =
                 res.getBoolean(R.bool.config_drawNotificationBackground);
         mFadeNotificationsOnDismiss =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
index 4dfc343..0968674 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
@@ -28,6 +28,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.SwipeHelper;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -50,9 +51,11 @@
     private boolean mIsExpanded;
     private boolean mPulsing;
 
-    public NotificationSwipeHelper(int swipeDirection, NotificationCallback callback,
-            Context context, NotificationMenuRowPlugin.OnMenuEventListener menuListener) {
-        super(swipeDirection, callback, context);
+    NotificationSwipeHelper(
+            int swipeDirection, NotificationCallback callback, Context context,
+            NotificationMenuRowPlugin.OnMenuEventListener menuListener,
+            FalsingManager falsingManager) {
+        super(swipeDirection, callback, context, falsingManager);
         mMenuListener = menuListener;
         mCallback = callback;
         mFalsingCheck = new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
index 4691a31..66b1dd8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
@@ -27,7 +27,6 @@
 
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.statusbar.FlingAnimationUtils;
 import com.android.systemui.statusbar.KeyguardAffordanceView;
@@ -59,7 +58,7 @@
     private KeyguardAffordanceView mLeftIcon;
     private KeyguardAffordanceView mRightIcon;
     private Animator mSwipeAnimator;
-    private FalsingManager mFalsingManager;
+    private final FalsingManager mFalsingManager;
     private int mMinBackgroundRadius;
     private boolean mMotionCancelled;
     private int mTouchTargetSize;
@@ -80,12 +79,13 @@
         }
     };
 
-    KeyguardAffordanceHelper(Callback callback, Context context) {
+    KeyguardAffordanceHelper(Callback callback, Context context, FalsingManager falsingManager) {
         mContext = context;
         mCallback = callback;
         initIcons();
         updateIcon(mLeftIcon, 0.0f, mLeftIcon.getRestingAlpha(), false, false, true, false);
         updateIcon(mRightIcon, 0.0f, mRightIcon.getRestingAlpha(), false, false, true, false);
+        mFalsingManager = falsingManager;
         initDimens();
     }
 
@@ -102,7 +102,6 @@
         mHintGrowAmount =
                 mContext.getResources().getDimensionPixelSize(R.dimen.hint_grow_amount_sideways);
         mFlingAnimationUtils = new FlingAnimationUtils(mContext, 0.4f);
-        mFalsingManager = FalsingManagerFactory.getInstance(mContext);
     }
 
     private void initIcons() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index dc9b373..0854e84 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -40,9 +40,9 @@
 import com.android.keyguard.KeyguardSecurityView;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.keyguard.R;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.DejankUtils;
+import com.android.systemui.R;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.plugins.FalsingManager;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardEnvironmentImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardEnvironmentImpl.java
index 925a19d..2c931ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardEnvironmentImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardEnvironmentImpl.java
@@ -25,6 +25,10 @@
 import com.android.systemui.statusbar.notification.collection.NotificationData.KeyguardEnvironment;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
 public class KeyguardEnvironmentImpl implements KeyguardEnvironment {
 
     private static final String TAG = "KeyguardEnvironmentImpl";
@@ -34,6 +38,7 @@
     private final DeviceProvisionedController mDeviceProvisionedController =
             Dependency.get(DeviceProvisionedController.class);
 
+    @Inject
     public KeyguardEnvironmentImpl() {
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
index f4635d1..f7b8a2e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
@@ -67,6 +67,9 @@
     }
 
     private fun updateListeningState() {
+        if (pickupSensor == null) {
+            return
+        }
         val onKeyguard = keyguardUpdateMonitor.isKeyguardVisible &&
                 !statusBarStateController.isDozing
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index 06a2225..ecfc45b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -604,7 +604,7 @@
      */
     public void onScrimVisibilityChanged(@ScrimVisibility int scrimsVisible) {
         if (mWakeAndUnlockRunning
-                && scrimsVisible == ScrimController.VISIBILITY_FULLY_TRANSPARENT) {
+                && scrimsVisible == ScrimController.TRANSPARENT) {
             mWakeAndUnlockRunning = false;
             update();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index f689a3e..a2740c8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.phone;
 
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
 
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
@@ -920,7 +921,8 @@
     }
 
     public void showPinningEscapeToast() {
-        mScreenPinningNotify.showEscapeToast(isRecentsButtonVisible());
+        mScreenPinningNotify.showEscapeToast(
+                mNavBarMode == NAV_BAR_MODE_GESTURAL, isRecentsButtonVisible());
     }
 
     public boolean isVertical() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index 0bbfbef..08602e1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -22,6 +22,7 @@
 import android.util.Log;
 
 import com.android.systemui.Dependency;
+import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
 import com.android.systemui.statusbar.StatusBarState;
@@ -53,12 +54,20 @@
     private HashMap<String, StatusBarNotification> mIsolatedEntries = new HashMap<>();
     private HeadsUpManager mHeadsUpManager;
     private boolean mIsUpdatingUnchangedGroup;
+    @Nullable private BubbleController mBubbleController = null;
 
     @Inject
     public NotificationGroupManager(StatusBarStateController statusBarStateController) {
         statusBarStateController.addCallback(this);
     }
 
+    private BubbleController getBubbleController() {
+        if (mBubbleController == null) {
+            mBubbleController = Dependency.get(BubbleController.class);
+        }
+        return mBubbleController;
+    }
+
     /**
      * Add a listener for changes to groups.
      *
@@ -187,12 +196,22 @@
         if (group == null) {
             return;
         }
+        int childCount = 0;
+        boolean hasBubbles = false;
+        for (String key : group.children.keySet()) {
+            if (!getBubbleController().isBubbleNotificationSuppressedFromShade(key)) {
+                childCount++;
+            } else {
+                hasBubbles = true;
+            }
+        }
+
         boolean prevSuppressed = group.suppressed;
         group.suppressed = group.summary != null && !group.expanded
-                && (group.children.size() == 1
-                || (group.children.size() == 0
+                && (childCount == 1
+                || (childCount == 0
                         && group.summary.notification.getNotification().isGroupSummary()
-                        && hasIsolatedChildren(group)));
+                        && (hasIsolatedChildren(group) || hasBubbles)));
         if (prevSuppressed != group.suppressed) {
             for (OnGroupChangeListener listener : mListeners) {
                 if (!mIsUpdatingUnchangedGroup) {
@@ -381,6 +400,17 @@
     }
 
     /**
+     * If there is a {@link NotificationGroup} associated with the provided entry, this method
+     * will update the suppression of that group.
+     */
+    public void updateSuppression(NotificationEntry entry) {
+        NotificationGroup group = mGroupMap.get(getGroupKey(entry.notification));
+        if (group != null) {
+            updateSuppression(group);
+        }
+    }
+
+    /**
      * Get the group key. May differ from the one in the notification due to the notification
      * being temporarily isolated.
      *
@@ -565,6 +595,7 @@
                         ? Log.getStackTraceString(child.getDebugThrowable())
                         : "");
             }
+            result += "\n    summary suppressed: " + suppressed;
             return result;
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index ba34069..1a3560e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -537,11 +537,7 @@
         if (dozeParameters.shouldControlScreenOff()) {
             mAodIcons.setTranslationY(-mAodIconAppearTranslation);
             mAodIcons.setAlpha(0);
-            mAodIcons.animate()
-                    .setInterpolator(Interpolators.DECELERATE_QUINT)
-                    .translationY(0)
-                    .setDuration(AOD_ICONS_APPEAR_DURATION)
-                    .start();
+            animateInAodIconTranslation();
             mAodIcons.animate()
                     .alpha(1)
                     .setInterpolator(Interpolators.LINEAR)
@@ -550,6 +546,14 @@
         }
     }
 
+    private void animateInAodIconTranslation() {
+        mAodIcons.animate()
+                .setInterpolator(Interpolators.DECELERATE_QUINT)
+                .translationY(0)
+                .setDuration(AOD_ICONS_APPEAR_DURATION)
+                .start();
+    }
+
     private void reloadAodColor() {
         mAodIconTint = Utils.getColorAttrDefaultColor(mContext,
                 R.attr.wallpaperTextColor);
@@ -606,14 +610,19 @@
                         mAodIcons.setAlpha(1.0f);
                         appearAodIcons();
                     } else {
+                        // Let's make sure the icon are translated to 0, since we cancelled it above
+                        animateInAodIconTranslation();
                         // We were fading out, let's fade in instead
                         CrossFadeHelper.fadeIn(mAodIcons);
                     }
                 } else {
+                    // Let's make sure the icon are translated to 0, since we cancelled it above
+                    animateInAodIconTranslation();
                     CrossFadeHelper.fadeOut(mAodIcons);
                 }
             } else {
                 mAodIcons.setAlpha(1.0f);
+                mAodIcons.setTranslationY(0);
                 mAodIcons.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index a0847b6..6bc0cf6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -39,6 +39,7 @@
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.hardware.biometrics.BiometricSourceType;
 import android.os.PowerManager;
 import android.os.SystemClock;
 import android.util.AttributeSet;
@@ -59,11 +60,11 @@
 import com.android.keyguard.KeyguardClockSwitch;
 import com.android.keyguard.KeyguardStatusView;
 import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
 import com.android.systemui.plugins.FalsingManager;
@@ -95,6 +96,7 @@
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
 import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
 import com.android.systemui.statusbar.policy.ZenModeController;
@@ -165,6 +167,46 @@
             R.id.keyguard_hun_animator_start_tag);
     private static final AnimationProperties KEYGUARD_HUN_PROPERTIES =
             new AnimationProperties().setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+    @VisibleForTesting
+    final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback =
+            new KeyguardUpdateMonitorCallback() {
+
+                @Override
+                public void onBiometricAuthenticated(int userId,
+                        BiometricSourceType biometricSourceType) {
+                    if (mFirstBypassAttempt && mUpdateMonitor.isUnlockingWithBiometricAllowed()) {
+                        mDelayShowingKeyguardStatusBar = true;
+                    }
+                }
+
+                @Override
+                public void onBiometricRunningStateChanged(boolean running,
+                        BiometricSourceType biometricSourceType) {
+                    boolean keyguardOrShadeLocked = mBarState == StatusBarState.KEYGUARD
+                            || mBarState == StatusBarState.SHADE_LOCKED;
+                    if (!running && mFirstBypassAttempt && keyguardOrShadeLocked && !mDozing
+                            && !mDelayShowingKeyguardStatusBar) {
+                        mFirstBypassAttempt = false;
+                        animateKeyguardStatusBarIn(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+                    }
+                }
+
+                @Override
+                public void onFinishedGoingToSleep(int why) {
+                    mFirstBypassAttempt = mKeyguardBypassController.getBypassEnabled();
+                    mDelayShowingKeyguardStatusBar = false;
+                }
+            };
+    private final KeyguardMonitor.Callback mKeyguardMonitorCallback =
+            new KeyguardMonitor.Callback() {
+                @Override
+                public void onKeyguardFadingAwayChanged() {
+                    if (!mKeyguardMonitor.isKeyguardFadingAway()) {
+                        mFirstBypassAttempt = false;
+                        mDelayShowingKeyguardStatusBar = false;
+                    }
+                }
+            };
 
     private final InjectionInflationController mInjectionInflationController;
     private final PowerManager mPowerManager;
@@ -172,8 +214,8 @@
     private final NotificationWakeUpCoordinator mWakeUpCoordinator;
     private final PulseExpansionHandler mPulseExpansionHandler;
     private final KeyguardBypassController mKeyguardBypassController;
-    private final KeyguardUpdateMonitor mUpdateMonitor;
-
+    @VisibleForTesting
+    protected KeyguardUpdateMonitor mUpdateMonitor;
     @VisibleForTesting
     protected KeyguardAffordanceHelper mAffordanceHelper;
     private KeyguardUserSwitcher mKeyguardUserSwitcher;
@@ -385,17 +427,29 @@
     private boolean mAllowExpandForSmallExpansion;
     private Runnable mExpandAfterLayoutRunnable;
 
+    /**
+     * If face auth with bypass is running for the first time after you turn on the screen.
+     * (From aod or screen off)
+     */
+    private boolean mFirstBypassAttempt;
+    /**
+     * If auth happens successfully during {@code mFirstBypassAttempt}, and we should wait until
+     * the keyguard is dismissed to show the status bar.
+     */
+    private boolean mDelayShowingKeyguardStatusBar;
+
     @Inject
     public NotificationPanelView(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
             InjectionInflationController injectionInflationController,
             NotificationWakeUpCoordinator coordinator,
             PulseExpansionHandler pulseExpansionHandler,
             DynamicPrivacyController dynamicPrivacyController,
-            KeyguardBypassController bypassController) {
+            KeyguardBypassController bypassController,
+            FalsingManager falsingManager) {
         super(context, attrs);
         setWillNotDraw(!DEBUG);
         mInjectionInflationController = injectionInflationController;
-        mFalsingManager = FalsingManagerFactory.getInstance(context);
+        mFalsingManager = falsingManager;
         mPowerManager = context.getSystemService(PowerManager.class);
         mWakeUpCoordinator = coordinator;
         mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
@@ -413,6 +467,8 @@
         mThemeResId = context.getThemeResId();
         mKeyguardBypassController = bypassController;
         mUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
+        mFirstBypassAttempt = mKeyguardBypassController.getBypassEnabled();
+        mKeyguardMonitor.addCallback(mKeyguardMonitorCallback);
         dynamicPrivacyController.addListener(this);
 
         mBottomAreaShadeAlphaAnimator = ValueAnimator.ofFloat(1f, 0);
@@ -485,6 +541,7 @@
         Dependency.get(StatusBarStateController.class).addCallback(this);
         Dependency.get(ZenModeController.class).addCallback(this);
         Dependency.get(ConfigurationController.class).addCallback(this);
+        mUpdateMonitor.registerCallback(mKeyguardUpdateCallback);
         // Theme might have changed between inflating this view and attaching it to the window, so
         // force a call to onThemeChanged
         onThemeChanged();
@@ -497,6 +554,7 @@
         Dependency.get(StatusBarStateController.class).removeCallback(this);
         Dependency.get(ZenModeController.class).removeCallback(this);
         Dependency.get(ConfigurationController.class).removeCallback(this);
+        mUpdateMonitor.removeCallback(mKeyguardUpdateCallback);
     }
 
     @Override
@@ -625,7 +683,7 @@
     }
 
     private void initBottomArea() {
-        mAffordanceHelper = new KeyguardAffordanceHelper(this, getContext());
+        mAffordanceHelper = new KeyguardAffordanceHelper(this, getContext(), mFalsingManager);
         mKeyguardBottomArea.setAffordanceHelper(mAffordanceHelper);
         mKeyguardBottomArea.setStatusBar(mStatusBar);
         mKeyguardBottomArea.setUserSetupComplete(mUserSetupComplete);
@@ -1738,7 +1796,8 @@
     private void setQsExpansion(float height) {
         height = Math.min(Math.max(height, mQsMinExpansionHeight), mQsMaxExpansionHeight);
         mQsFullyExpanded = height == mQsMaxExpansionHeight && mQsMaxExpansionHeight != 0;
-        if (height > mQsMinExpansionHeight && !mQsExpanded && !mStackScrollerOverscrolling) {
+        if (height > mQsMinExpansionHeight && !mQsExpanded && !mStackScrollerOverscrolling
+                && !mDozing) {
             setQsExpanded(true);
         } else if (height <= mQsMinExpansionHeight && mQsExpanded) {
             setQsExpanded(false);
@@ -2237,7 +2296,10 @@
                 * mKeyguardStatusBarAnimateAlpha;
         newAlpha *= 1.0f - mKeyguardHeadsUpShowingAmount;
         mKeyguardStatusBar.setAlpha(newAlpha);
-        mKeyguardStatusBar.setVisibility(newAlpha != 0f && !mDozing ? VISIBLE : INVISIBLE);
+        boolean hideForBypass = mFirstBypassAttempt && mUpdateMonitor.shouldListenForFace()
+                || mDelayShowingKeyguardStatusBar;
+        mKeyguardStatusBar.setVisibility(newAlpha != 0f && !mDozing && !hideForBypass
+                ? VISIBLE : INVISIBLE);
     }
 
     private void updateKeyguardBottomAreaAlpha() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index f8e1093..31600e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -42,7 +42,6 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.doze.DozeLog;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -111,7 +110,7 @@
     private FlingAnimationUtils mFlingAnimationUtils;
     private FlingAnimationUtils mFlingAnimationUtilsClosing;
     private FlingAnimationUtils mFlingAnimationUtilsDismissing;
-    private FalsingManager mFalsingManager;
+    private final FalsingManager mFalsingManager;
     private final VibratorHelper mVibratorHelper;
 
     /**
@@ -214,7 +213,7 @@
                 0.5f /* maxLengthSeconds */, 0.2f /* speedUpFactor */, 0.6f /* x2 */,
                 0.84f /* y2 */);
         mBounceInterpolator = new BounceInterpolator();
-        mFalsingManager = FalsingManagerFactory.getInstance(context);
+        mFalsingManager = Dependency.get(FalsingManager.class);  // TODO: inject into a controller.
         mNotificationsDragEnabled =
                 getResources().getBoolean(R.bool.config_enableNotificationShadeDrag);
         mVibratorHelper = Dependency.get(VibratorHelper.class);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenPinningNotify.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenPinningNotify.java
index f8731b4..071e00d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenPinningNotify.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenPinningNotify.java
@@ -51,7 +51,7 @@
     }
 
     /** Show a toast that describes the gesture the user should use to escape pinned mode. */
-    public void showEscapeToast(boolean isRecentsButtonVisible) {
+    public void showEscapeToast(boolean isGestureNavEnabled, boolean isRecentsButtonVisible) {
         long showToastTime = SystemClock.elapsedRealtime();
         if ((showToastTime - mLastShowToastTime) < SHOW_TOAST_MINIMUM_INTERVAL) {
             Slog.i(TAG, "Ignore toast since it is requested in very short interval.");
@@ -60,9 +60,11 @@
         if (mLastToast != null) {
             mLastToast.cancel();
         }
-        mLastToast = makeAllUserToastAndShow(isRecentsButtonVisible
-                ? R.string.screen_pinning_toast
-                : R.string.screen_pinning_toast_recents_invisible);
+        mLastToast = makeAllUserToastAndShow(isGestureNavEnabled
+                ? R.string.screen_pinning_toast_gesture_nav
+                : isRecentsButtonVisible
+                        ? R.string.screen_pinning_toast
+                        : R.string.screen_pinning_toast_recents_invisible);
         mLastShowToastTime = showToastTime;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index a7262cf..2f56717 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -79,23 +79,24 @@
     /**
      * When both scrims have 0 alpha.
      */
-    public static final int VISIBILITY_FULLY_TRANSPARENT = 0;
+    public static final int TRANSPARENT = 0;
     /**
      * When scrims aren't transparent (alpha 0) but also not opaque (alpha 1.)
      */
-    public static final int VISIBILITY_SEMI_TRANSPARENT = 1;
+    public static final int SEMI_TRANSPARENT = 1;
     /**
      * When at least 1 scrim is fully opaque (alpha set to 1.)
      */
-    public static final int VISIBILITY_FULLY_OPAQUE = 2;
+    public static final int OPAQUE = 2;
 
-    @IntDef(prefix = { "VISIBILITY_" }, value = {
-            VISIBILITY_FULLY_TRANSPARENT,
-            VISIBILITY_SEMI_TRANSPARENT,
-            VISIBILITY_FULLY_OPAQUE
+    @IntDef(prefix = {"VISIBILITY_"}, value = {
+            TRANSPARENT,
+            SEMI_TRANSPARENT,
+            OPAQUE
     })
     @Retention(RetentionPolicy.SOURCE)
-    public @interface ScrimVisibility {}
+    public @interface ScrimVisibility {
+    }
 
     /**
      * Default alpha value for most scrims.
@@ -123,8 +124,11 @@
 
     private ScrimState mState = ScrimState.UNINITIALIZED;
     private final Context mContext;
-    protected final ScrimView mScrimBehind;
+
     protected final ScrimView mScrimInFront;
+    protected final ScrimView mScrimBehind;
+    protected final ScrimView mScrimForBubble;
+
     private final UnlockMethodCache mUnlockMethodCache;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private final DozeParameters mDozeParameters;
@@ -153,10 +157,15 @@
     private Runnable mOnAnimationFinished;
     private boolean mDeferFinishedListener;
     private final Interpolator mInterpolator = new DecelerateInterpolator();
-    private float mCurrentInFrontAlpha  = NOT_INITIALIZED;
-    private float mCurrentBehindAlpha = NOT_INITIALIZED;
-    private int mCurrentInFrontTint;
-    private int mCurrentBehindTint;
+
+    private float mInFrontAlpha = NOT_INITIALIZED;
+    private float mBehindAlpha = NOT_INITIALIZED;
+    private float mBubbleAlpha = NOT_INITIALIZED;
+
+    private int mInFrontTint;
+    private int mBehindTint;
+    private int mBubbleTint;
+
     private boolean mWallpaperVisibilityTimedOut;
     private int mScrimsVisibility;
     private final TriConsumer<ScrimState, Float, GradientColors> mScrimStateListener;
@@ -175,14 +184,17 @@
     private boolean mWakeLockHeld;
     private boolean mKeyguardOccluded;
 
-    public ScrimController(ScrimView scrimBehind, ScrimView scrimInFront,
+    public ScrimController(ScrimView scrimBehind, ScrimView scrimInFront, ScrimView scrimForBubble,
             TriConsumer<ScrimState, Float, GradientColors> scrimStateListener,
             Consumer<Integer> scrimVisibleListener, DozeParameters dozeParameters,
             AlarmManager alarmManager, KeyguardMonitor keyguardMonitor) {
         mScrimBehind = scrimBehind;
         mScrimInFront = scrimInFront;
+        mScrimForBubble = scrimForBubble;
+
         mScrimStateListener = scrimStateListener;
         mScrimVisibleListener = scrimVisibleListener;
+
         mContext = scrimBehind.getContext();
         mUnlockMethodCache = UnlockMethodCache.getInstance(mContext);
         mDarkenWhileDragging = !mUnlockMethodCache.canSkipBouncer();
@@ -213,12 +225,13 @@
 
         final ScrimState[] states = ScrimState.values();
         for (int i = 0; i < states.length; i++) {
-            states[i].init(mScrimInFront, mScrimBehind, mDozeParameters);
+            states[i].init(mScrimInFront, mScrimBehind, mScrimForBubble, mDozeParameters);
             states[i].setScrimBehindAlphaKeyguard(mScrimBehindAlphaKeyguard);
         }
 
         mScrimBehind.setDefaultFocusHighlightEnabled(false);
         mScrimInFront.setDefaultFocusHighlightEnabled(false);
+        mScrimForBubble.setDefaultFocusHighlightEnabled(false);
 
         updateScrims();
     }
@@ -257,10 +270,14 @@
         mBlankScreen = state.getBlanksScreen();
         mAnimateChange = state.getAnimateChange();
         mAnimationDuration = state.getAnimationDuration();
-        mCurrentInFrontTint = state.getFrontTint();
-        mCurrentBehindTint = state.getBehindTint();
-        mCurrentInFrontAlpha = state.getFrontAlpha();
-        mCurrentBehindAlpha = state.getBehindAlpha();
+
+        mInFrontTint = state.getFrontTint();
+        mBehindTint = state.getBehindTint();
+        mBubbleTint = state.getBubbleTint();
+
+        mInFrontAlpha = state.getFrontAlpha();
+        mBehindAlpha = state.getBehindAlpha();
+        mBubbleAlpha = state.getBubbleAlpha();
         applyExpansionToAlpha();
 
         // Scrim might acquire focus when user is navigating with a D-pad or a keyboard.
@@ -393,21 +410,20 @@
         if (mExpansionFraction != fraction) {
             mExpansionFraction = fraction;
 
-            final boolean keyguardOrUnlocked = mState == ScrimState.UNLOCKED
-                    || mState == ScrimState.KEYGUARD || mState == ScrimState.PULSING;
-            if (!keyguardOrUnlocked || !mExpansionAffectsAlpha) {
+            boolean relevantState = (mState == ScrimState.UNLOCKED
+                    || mState == ScrimState.KEYGUARD
+                    || mState == ScrimState.PULSING
+                    || mState == ScrimState.BUBBLE_EXPANDED);
+            if (!(relevantState && mExpansionAffectsAlpha)) {
                 return;
             }
-
             applyExpansionToAlpha();
-
             if (mUpdatePending) {
                 return;
             }
-
             setOrAdaptCurrentAnimation(mScrimBehind);
             setOrAdaptCurrentAnimation(mScrimInFront);
-
+            setOrAdaptCurrentAnimation(mScrimForBubble);
             dispatchScrimState(mScrimBehind.getViewAlpha());
 
             // Reset wallpaper timeout if it's already timeout like expanding panel while PULSING
@@ -421,11 +437,10 @@
     }
 
     private void setOrAdaptCurrentAnimation(View scrim) {
-        if (!isAnimating(scrim)) {
-            updateScrimColor(scrim, getCurrentScrimAlpha(scrim), getCurrentScrimTint(scrim));
-        } else {
+        float alpha = getCurrentScrimAlpha(scrim);
+        if (isAnimating(scrim)) {
+            // Adapt current animation.
             ValueAnimator previousAnimator = (ValueAnimator) scrim.getTag(TAG_KEY_ANIM);
-            float alpha = getCurrentScrimAlpha(scrim);
             float previousEndValue = (Float) scrim.getTag(TAG_END_ALPHA);
             float previousStartValue = (Float) scrim.getTag(TAG_START_ALPHA);
             float relativeDiff = alpha - previousEndValue;
@@ -433,6 +448,9 @@
             scrim.setTag(TAG_START_ALPHA, newStartValue);
             scrim.setTag(TAG_END_ALPHA, alpha);
             previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
+        } else {
+            // Set animation.
+            updateScrimColor(scrim, alpha, getCurrentScrimTint(scrim));
         }
     }
 
@@ -441,27 +459,27 @@
             return;
         }
 
-        if (mState == ScrimState.UNLOCKED) {
+        if (mState == ScrimState.UNLOCKED || mState == ScrimState.BUBBLE_EXPANDED) {
             // Darken scrim as you pull down the shade when unlocked
             float behindFraction = getInterpolatedFraction();
             behindFraction = (float) Math.pow(behindFraction, 0.8f);
-            mCurrentBehindAlpha = behindFraction * GRADIENT_SCRIM_ALPHA_BUSY;
-            mCurrentInFrontAlpha = 0;
+            mBehindAlpha = behindFraction * GRADIENT_SCRIM_ALPHA_BUSY;
+            mInFrontAlpha = 0;
         } else if (mState == ScrimState.KEYGUARD || mState == ScrimState.PULSING) {
             // Either darken of make the scrim transparent when you
             // pull down the shade
             float interpolatedFract = getInterpolatedFraction();
             float alphaBehind = mState.getBehindAlpha();
             if (mDarkenWhileDragging) {
-                mCurrentBehindAlpha = MathUtils.lerp(GRADIENT_SCRIM_ALPHA_BUSY, alphaBehind,
+                mBehindAlpha = MathUtils.lerp(GRADIENT_SCRIM_ALPHA_BUSY, alphaBehind,
                         interpolatedFract);
-                mCurrentInFrontAlpha = 0;
+                mInFrontAlpha = mState.getFrontAlpha();
             } else {
-                mCurrentBehindAlpha = MathUtils.lerp(0 /* start */, alphaBehind,
+                mBehindAlpha = MathUtils.lerp(0 /* start */, alphaBehind,
                         interpolatedFract);
-                mCurrentInFrontAlpha = 0;
+                mInFrontAlpha = mState.getFrontAlpha();
             }
-            mCurrentBehindTint = ColorUtils.blendARGB(ScrimState.BOUNCER.getBehindTint(),
+            mBehindTint = ColorUtils.blendARGB(ScrimState.BOUNCER.getBehindTint(),
                     mState.getBehindTint(), interpolatedFract);
         }
     }
@@ -485,13 +503,14 @@
      * device is dozing when the light sensor is on.
      */
     public void setAodFrontScrimAlpha(float alpha) {
-        if (mState == ScrimState.AOD && mDozeParameters.getAlwaysOn()
-                && mCurrentInFrontAlpha != alpha) {
-            mCurrentInFrontAlpha = alpha;
+        if (((mState == ScrimState.AOD && mDozeParameters.getAlwaysOn())
+                || mState == ScrimState.PULSING) && mInFrontAlpha != alpha) {
+            mInFrontAlpha = alpha;
             updateScrims();
         }
 
         mState.AOD.setAodFrontScrimAlpha(alpha);
+        mState.PULSING.setAodFrontScrimAlpha(alpha);
     }
 
     /**
@@ -499,10 +518,10 @@
      * away once the display turns on.
      */
     public void prepareForGentleWakeUp() {
-        if (mState == ScrimState.AOD) {
-            mCurrentInFrontAlpha = 1f;
-            mCurrentInFrontTint = Color.BLACK;
-            mCurrentBehindTint = Color.BLACK;
+        if (mState == ScrimState.AOD && mDozeParameters.getAlwaysOn()) {
+            mInFrontAlpha = 1f;
+            mInFrontTint = Color.BLACK;
+            mBehindTint = Color.BLACK;
             mAnimateChange = false;
             updateScrims();
             mAnimateChange = true;
@@ -520,8 +539,8 @@
 
         if (mState == ScrimState.PULSING) {
             float newBehindAlpha = mState.getBehindAlpha();
-            if (mCurrentBehindAlpha != newBehindAlpha) {
-                mCurrentBehindAlpha = newBehindAlpha;
+            if (mBehindAlpha != newBehindAlpha) {
+                mBehindAlpha = newBehindAlpha;
                 updateScrims();
             }
         }
@@ -543,8 +562,11 @@
             // Only animate scrim color if the scrim view is actually visible
             boolean animateScrimInFront = mScrimInFront.getViewAlpha() != 0 && !mBlankScreen;
             boolean animateScrimBehind = mScrimBehind.getViewAlpha() != 0 && !mBlankScreen;
+            boolean animateScrimForBubble = mScrimForBubble.getViewAlpha() != 0 && !mBlankScreen;
+
             mScrimInFront.setColors(mColors, animateScrimInFront);
             mScrimBehind.setColors(mColors, animateScrimBehind);
+            mScrimForBubble.setColors(mColors, animateScrimForBubble);
 
             // Calculate minimum scrim opacity for white or black text.
             int textColor = mColors.supportsDarkText() ? Color.BLACK : Color.WHITE;
@@ -563,12 +585,13 @@
         boolean occludedKeyguard = (mState == ScrimState.PULSING || mState == ScrimState.AOD)
                 && mKeyguardOccluded;
         if (aodWallpaperTimeout || occludedKeyguard) {
-            mCurrentBehindAlpha = 1;
+            mBehindAlpha = 1;
         }
-
-        setScrimInFrontAlpha(mCurrentInFrontAlpha);
-        setScrimBehindAlpha(mCurrentBehindAlpha);
-
+        setScrimAlpha(mScrimInFront, mInFrontAlpha);
+        setScrimAlpha(mScrimBehind, mBehindAlpha);
+        setScrimAlpha(mScrimForBubble, mBubbleAlpha);
+        // The animation could have all already finished, let's call onFinished just in case
+        onFinished();
         dispatchScrimsVisible();
     }
 
@@ -579,11 +602,11 @@
     private void dispatchScrimsVisible() {
         final int currentScrimVisibility;
         if (mScrimInFront.getViewAlpha() == 1 || mScrimBehind.getViewAlpha() == 1) {
-            currentScrimVisibility = VISIBILITY_FULLY_OPAQUE;
+            currentScrimVisibility = OPAQUE;
         } else if (mScrimInFront.getViewAlpha() == 0 && mScrimBehind.getViewAlpha() == 0) {
-            currentScrimVisibility = VISIBILITY_FULLY_TRANSPARENT;
+            currentScrimVisibility = TRANSPARENT;
         } else {
-            currentScrimVisibility = VISIBILITY_SEMI_TRANSPARENT;
+            currentScrimVisibility = SEMI_TRANSPARENT;
         }
 
         if (mScrimsVisibility != currentScrimVisibility) {
@@ -600,18 +623,10 @@
             return 0;
         } else {
             // woo, special effects
-            return (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2f))));
+            return (float) (1f - 0.5f * (1f - Math.cos(3.14159f * Math.pow(1f - frac, 2f))));
         }
     }
 
-    private void setScrimBehindAlpha(float alpha) {
-        setScrimAlpha(mScrimBehind, alpha);
-    }
-
-    private void setScrimInFrontAlpha(float alpha) {
-        setScrimAlpha(mScrimInFront, alpha);
-    }
-
     private void setScrimAlpha(ScrimView scrim, float alpha) {
         if (alpha == 0f) {
             scrim.setClickable(false);
@@ -622,17 +637,26 @@
         updateScrim(scrim, alpha);
     }
 
+    private String getScrimName(ScrimView scrim) {
+        if (scrim == mScrimInFront) {
+            return "front_scrim";
+        } else if (scrim == mScrimBehind) {
+            return "back_scrim";
+        } else if (scrim == mScrimForBubble) {
+            return "bubble_scrim";
+        }
+        return "unknown_scrim";
+    }
+
     private void updateScrimColor(View scrim, float alpha, int tint) {
         alpha = Math.max(0, Math.min(1.0f, alpha));
         if (scrim instanceof ScrimView) {
             ScrimView scrimView = (ScrimView) scrim;
 
-            Trace.traceCounter(Trace.TRACE_TAG_APP,
-                    scrim == mScrimInFront ? "front_scrim_alpha" : "back_scrim_alpha",
+            Trace.traceCounter(Trace.TRACE_TAG_APP, getScrimName(scrimView) + "_alpha",
                     (int) (alpha * 255));
 
-            Trace.traceCounter(Trace.TRACE_TAG_APP,
-                    scrim == mScrimInFront ? "front_scrim_tint" : "back_scrim_tint",
+            Trace.traceCounter(Trace.TRACE_TAG_APP, getScrimName(scrimView) + "_tint",
                     Color.alpha(tint));
 
             scrimView.setTint(tint);
@@ -666,9 +690,9 @@
 
             @Override
             public void onAnimationEnd(Animator animation) {
+                scrim.setTag(TAG_KEY_ANIM, null);
                 onFinished(lastCallback);
 
-                scrim.setTag(TAG_KEY_ANIM, null);
                 dispatchScrimsVisible();
 
                 if (!mDeferFinishedListener && mOnAnimationFinished != null) {
@@ -689,9 +713,11 @@
 
     private float getCurrentScrimAlpha(View scrim) {
         if (scrim == mScrimInFront) {
-            return mCurrentInFrontAlpha;
+            return mInFrontAlpha;
         } else if (scrim == mScrimBehind) {
-            return mCurrentBehindAlpha;
+            return mBehindAlpha;
+        } else if (scrim == mScrimForBubble) {
+            return mBubbleAlpha;
         } else {
             throw new IllegalArgumentException("Unknown scrim view");
         }
@@ -699,9 +725,11 @@
 
     private int getCurrentScrimTint(View scrim) {
         if (scrim == mScrimInFront) {
-            return mCurrentInFrontTint;
+            return mInFrontTint;
         } else if (scrim == mScrimBehind) {
-            return mCurrentBehindTint;
+            return mBehindTint;
+        } else if (scrim == mScrimForBubble) {
+            return mBubbleTint;
         } else {
             throw new IllegalArgumentException("Unknown scrim view");
         }
@@ -728,6 +756,16 @@
     }
 
     private void onFinished(Callback callback) {
+        if (isAnimating(mScrimBehind)
+            || isAnimating(mScrimInFront)
+            || isAnimating(mScrimForBubble)) {
+            if (callback != null && callback != mCallback) {
+                // Since we only notify the callback that we're finished once everything has
+                // finished, we need to make sure that any changing callbacks are also invoked
+                callback.onFinished();
+            }
+            return;
+        }
         if (mWakeLockHeld) {
             mWakeLock.release(TAG);
             mWakeLockHeld = false;
@@ -744,8 +782,12 @@
         // When unlocking with fingerprint, we'll fade the scrims from black to transparent.
         // At the end of the animation we need to remove the tint.
         if (mState == ScrimState.UNLOCKED) {
-            mCurrentInFrontTint = Color.TRANSPARENT;
-            mCurrentBehindTint = Color.TRANSPARENT;
+            mInFrontTint = Color.TRANSPARENT;
+            mBehindTint = Color.TRANSPARENT;
+            mBubbleTint = Color.TRANSPARENT;
+            updateScrimColor(mScrimInFront, mInFrontAlpha, mInFrontTint);
+            updateScrimColor(mScrimBehind, mBehindAlpha, mBehindTint);
+            updateScrimColor(mScrimForBubble, mBubbleAlpha, mBubbleTint);
         }
     }
 
@@ -804,10 +846,7 @@
             } else {
                 // update the alpha directly
                 updateScrimColor(scrim, alpha, getCurrentScrimTint(scrim));
-                onFinished();
             }
-        } else {
-            onFinished();
         }
     }
 
@@ -850,6 +889,7 @@
 
     /**
      * Executes a callback after the frame has hit the display.
+     *
      * @param callback What to run.
      */
     @VisibleForTesting
@@ -893,16 +933,35 @@
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println(" ScrimController: ");
-        pw.print("  state: "); pw.println(mState);
-        pw.print("  frontScrim:"); pw.print(" viewAlpha="); pw.print(mScrimInFront.getViewAlpha());
-        pw.print(" alpha="); pw.print(mCurrentInFrontAlpha);
-        pw.print(" tint=0x"); pw.println(Integer.toHexString(mScrimInFront.getTint()));
+        pw.print("  state: ");
+        pw.println(mState);
 
-        pw.print("  backScrim:"); pw.print(" viewAlpha="); pw.print(mScrimBehind.getViewAlpha());
-        pw.print(" alpha="); pw.print(mCurrentBehindAlpha);
-        pw.print(" tint=0x"); pw.println(Integer.toHexString(mScrimBehind.getTint()));
+        pw.print("  frontScrim:");
+        pw.print(" viewAlpha=");
+        pw.print(mScrimInFront.getViewAlpha());
+        pw.print(" alpha=");
+        pw.print(mInFrontAlpha);
+        pw.print(" tint=0x");
+        pw.println(Integer.toHexString(mScrimInFront.getTint()));
 
-        pw.print("   mTracking="); pw.println(mTracking);
+        pw.print("  backScrim:");
+        pw.print(" viewAlpha=");
+        pw.print(mScrimBehind.getViewAlpha());
+        pw.print(" alpha=");
+        pw.print(mBehindAlpha);
+        pw.print(" tint=0x");
+        pw.println(Integer.toHexString(mScrimBehind.getTint()));
+
+        pw.print("  bubbleScrim:");
+        pw.print(" viewAlpha=");
+        pw.print(mScrimForBubble.getViewAlpha());
+        pw.print(" alpha=");
+        pw.print(mBubbleAlpha);
+        pw.print(" tint=0x");
+        pw.println(Integer.toHexString(mScrimForBubble.getTint()));
+
+        pw.print("   mTracking=");
+        pw.println(mTracking);
     }
 
     public void setWallpaperSupportsAmbientMode(boolean wallpaperSupportsAmbientMode) {
@@ -949,8 +1008,8 @@
         // in this case, back-scrim needs to be re-evaluated
         if (mState == ScrimState.AOD || mState == ScrimState.PULSING) {
             float newBehindAlpha = mState.getBehindAlpha();
-            if (mCurrentBehindAlpha != newBehindAlpha) {
-                mCurrentBehindAlpha = newBehindAlpha;
+            if (mBehindAlpha != newBehindAlpha) {
+                mBehindAlpha = newBehindAlpha;
                 updateScrims();
             }
         }
@@ -971,10 +1030,13 @@
     public interface Callback {
         default void onStart() {
         }
+
         default void onDisplayBlanked() {
         }
+
         default void onFinished() {
         }
+
         default void onCancelled() {
         }
         /** Returns whether to timeout wallpaper or not. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index 9fdd3b8..7463c7c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -36,7 +36,6 @@
      * On the lock screen.
      */
     KEYGUARD(0) {
-
         @Override
         public void prepare(ScrimState previousState) {
             mBlankScreen = false;
@@ -53,10 +52,13 @@
             } else {
                 mAnimationDuration = ScrimController.ANIMATION_DURATION;
             }
-            mCurrentInFrontTint = Color.BLACK;
-            mCurrentBehindTint = Color.BLACK;
-            mCurrentBehindAlpha = mScrimBehindAlphaKeyguard;
-            mCurrentInFrontAlpha = 0;
+            mFrontTint = Color.BLACK;
+            mBehindTint = Color.BLACK;
+            mBubbleTint = Color.TRANSPARENT;
+
+            mFrontAlpha = 0;
+            mBehindAlpha = mScrimBehindAlphaKeyguard;
+            mBubbleAlpha = 0;
         }
     },
 
@@ -66,8 +68,9 @@
     BOUNCER(1) {
         @Override
         public void prepare(ScrimState previousState) {
-            mCurrentBehindAlpha = ScrimController.GRADIENT_SCRIM_ALPHA_BUSY;
-            mCurrentInFrontAlpha = 0f;
+            mBehindAlpha = ScrimController.GRADIENT_SCRIM_ALPHA_BUSY;
+            mFrontAlpha = 0f;
+            mBubbleAlpha = 0f;
         }
     },
 
@@ -77,8 +80,9 @@
     BOUNCER_SCRIMMED(2) {
         @Override
         public void prepare(ScrimState previousState) {
-            mCurrentBehindAlpha = 0;
-            mCurrentInFrontAlpha = ScrimController.GRADIENT_SCRIM_ALPHA_BUSY;
+            mBehindAlpha = 0;
+            mBubbleAlpha = 0f;
+            mFrontAlpha = ScrimController.GRADIENT_SCRIM_ALPHA_BUSY;
         }
     },
 
@@ -88,8 +92,9 @@
     BRIGHTNESS_MIRROR(3) {
         @Override
         public void prepare(ScrimState previousState) {
-            mCurrentBehindAlpha = 0;
-            mCurrentInFrontAlpha = 0;
+            mBehindAlpha = 0;
+            mFrontAlpha = 0;
+            mBubbleAlpha = 0;
         }
     },
 
@@ -101,9 +106,16 @@
         public void prepare(ScrimState previousState) {
             final boolean alwaysOnEnabled = mDozeParameters.getAlwaysOn();
             mBlankScreen = mDisplayRequiresBlanking;
-            mCurrentInFrontAlpha = alwaysOnEnabled ? mAodFrontScrimAlpha : 1f;
-            mCurrentInFrontTint = Color.BLACK;
-            mCurrentBehindTint = Color.BLACK;
+
+            mFrontTint = Color.BLACK;
+            mFrontAlpha = alwaysOnEnabled ? mAodFrontScrimAlpha : 1f;
+
+            mBehindTint = Color.BLACK;
+            mBehindAlpha = ScrimController.TRANSPARENT;
+
+            mBubbleTint = Color.TRANSPARENT;
+            mBubbleAlpha = ScrimController.TRANSPARENT;
+
             mAnimationDuration = ScrimController.ANIMATION_DURATION_LONG;
             // DisplayPowerManager may blank the screen for us,
             // in this case we just need to set our state.
@@ -127,9 +139,10 @@
     PULSING(5) {
         @Override
         public void prepare(ScrimState previousState) {
-            mCurrentInFrontAlpha = 0f;
-            mCurrentBehindTint = Color.BLACK;
-            mCurrentInFrontTint = Color.BLACK;
+            mFrontAlpha = mAodFrontScrimAlpha;
+            mBubbleAlpha = 0f;
+            mBehindTint = Color.BLACK;
+            mFrontTint = Color.BLACK;
             mBlankScreen = mDisplayRequiresBlanking;
             mAnimationDuration = mWakeLockScreenSensorActive
                     ? ScrimController.ANIMATION_DURATION_LONG : ScrimController.ANIMATION_DURATION;
@@ -154,25 +167,33 @@
     UNLOCKED(6) {
         @Override
         public void prepare(ScrimState previousState) {
-            mCurrentBehindAlpha = 0;
-            mCurrentInFrontAlpha = 0;
+            // State that UI will sync to.
+            mBehindAlpha = 0;
+            mFrontAlpha = 0;
+            mBubbleAlpha = 0;
+
             mAnimationDuration = mKeyguardFadingAway
                     ? mKeyguardFadingAwayDuration
                     : StatusBar.FADE_KEYGUARD_DURATION;
+
             mAnimateChange = !mLaunchingAffordanceWithPreview;
 
+            mFrontTint = Color.TRANSPARENT;
+            mBehindTint = Color.TRANSPARENT;
+            mBubbleTint = Color.TRANSPARENT;
+            mBlankScreen = false;
+
             if (previousState == ScrimState.AOD) {
-                // Fade from black to transparent when coming directly from AOD
-                updateScrimColor(mScrimInFront, 1, Color.BLACK);
-                updateScrimColor(mScrimBehind, 1, Color.BLACK);
+                // Set all scrims black, before they fade transparent.
+                updateScrimColor(mScrimInFront, 1f /* alpha */, Color.BLACK /* tint */);
+                updateScrimColor(mScrimBehind, 1f /* alpha */, Color.BLACK /* tint */);
+                updateScrimColor(mScrimForBubble, 1f /* alpha */, Color.BLACK /* tint */);
+
                 // Scrims should still be black at the end of the transition.
-                mCurrentInFrontTint = Color.BLACK;
-                mCurrentBehindTint = Color.BLACK;
+                mFrontTint = Color.BLACK;
+                mBehindTint = Color.BLACK;
+                mBubbleTint = Color.BLACK;
                 mBlankScreen = true;
-            } else {
-                mCurrentInFrontTint = Color.TRANSPARENT;
-                mCurrentBehindTint = Color.TRANSPARENT;
-                mBlankScreen = false;
             }
         }
     },
@@ -183,25 +204,36 @@
     BUBBLE_EXPANDED(7) {
         @Override
         public void prepare(ScrimState previousState) {
-            mCurrentInFrontTint = Color.TRANSPARENT;
-            mCurrentBehindTint = Color.TRANSPARENT;
+            mFrontTint = Color.TRANSPARENT;
+            mBehindTint = Color.TRANSPARENT;
+            mBubbleTint = Color.TRANSPARENT;
+
+            mFrontAlpha = ScrimController.TRANSPARENT;
+            mBehindAlpha = ScrimController.GRADIENT_SCRIM_ALPHA_BUSY;
+            mBubbleAlpha = ScrimController.GRADIENT_SCRIM_ALPHA_BUSY;
+
             mAnimationDuration = ScrimController.ANIMATION_DURATION;
-            mCurrentBehindAlpha = ScrimController.GRADIENT_SCRIM_ALPHA_BUSY;
             mBlankScreen = false;
         }
     };
 
     boolean mBlankScreen = false;
     long mAnimationDuration = ScrimController.ANIMATION_DURATION;
-    int mCurrentInFrontTint = Color.TRANSPARENT;
-    int mCurrentBehindTint = Color.TRANSPARENT;
+    int mFrontTint = Color.TRANSPARENT;
+    int mBehindTint = Color.TRANSPARENT;
+    int mBubbleTint = Color.TRANSPARENT;
+
     boolean mAnimateChange = true;
-    float mCurrentInFrontAlpha;
-    float mCurrentBehindAlpha;
     float mAodFrontScrimAlpha;
+    float mFrontAlpha;
+    float mBehindAlpha;
+    float mBubbleAlpha;
+
     float mScrimBehindAlphaKeyguard;
     ScrimView mScrimInFront;
     ScrimView mScrimBehind;
+    ScrimView mScrimForBubble;
+
     DozeParameters mDozeParameters;
     boolean mDisplayRequiresBlanking;
     boolean mWallpaperSupportsAmbientMode;
@@ -216,13 +248,17 @@
         mIndex = index;
     }
 
-    public void init(ScrimView scrimInFront, ScrimView scrimBehind, DozeParameters dozeParameters) {
+    public void init(ScrimView scrimInFront, ScrimView scrimBehind, ScrimView scrimForBubble,
+            DozeParameters dozeParameters) {
         mScrimInFront = scrimInFront;
         mScrimBehind = scrimBehind;
+        mScrimForBubble = scrimForBubble;
+
         mDozeParameters = dozeParameters;
         mDisplayRequiresBlanking = dozeParameters.getDisplayNeedsBlanking();
     }
 
+    /** Prepare state for transition. */
     public void prepare(ScrimState previousState) {
     }
 
@@ -231,19 +267,27 @@
     }
 
     public float getFrontAlpha() {
-        return mCurrentInFrontAlpha;
+        return mFrontAlpha;
     }
 
     public float getBehindAlpha() {
-        return mCurrentBehindAlpha;
+        return mBehindAlpha;
+    }
+
+    public float getBubbleAlpha() {
+        return mBubbleAlpha;
     }
 
     public int getFrontTint() {
-        return mCurrentInFrontTint;
+        return mFrontTint;
     }
 
     public int getBehindTint() {
-        return mCurrentBehindTint;
+        return mBehindTint;
+    }
+
+    public int getBubbleTint() {
+        return mBubbleTint;
     }
 
     public long getAnimationDuration() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index d12bed9..fc20d83 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -25,6 +25,7 @@
 import static android.app.StatusBarManager.windowStateToString;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
 
+import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
 import static com.android.systemui.Dependency.BG_HANDLER;
 import static com.android.systemui.Dependency.MAIN_HANDLER;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
@@ -147,7 +148,6 @@
 import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.charging.WirelessChargingAnimation;
 import com.android.systemui.classifier.FalsingLog;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.doze.DozeHost;
 import com.android.systemui.doze.DozeLog;
@@ -239,6 +239,7 @@
 import java.util.Map;
 
 import javax.inject.Inject;
+import javax.inject.Named;
 
 import dagger.Subcomponent;
 
@@ -383,6 +384,9 @@
     @Nullable
     @Inject
     protected KeyguardLiftController mKeyguardLiftController;
+    @Inject
+    @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME)
+    boolean mAllowNotificationLongPress;
 
     // expanded notifications
     protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
@@ -701,6 +705,7 @@
         mRecents = getComponent(Recents.class);
 
         mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
+        mFalsingManager = Dependency.get(FalsingManager.class);
 
         // Connect in to the status bar manager service
         mCommandQueue = getComponent(CommandQueue.class);
@@ -776,7 +781,6 @@
         putComponent(DozeHost.class, mDozeServiceHost);
 
         mScreenPinningRequest = new ScreenPinningRequest(mContext);
-        mFalsingManager = FalsingManagerFactory.getInstance(mContext);
 
         Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(this);
 
@@ -807,6 +811,7 @@
         // TODO: Deal with the ugliness that comes from having some of the statusbar broken out
         // into fragments, but the rest here, it leaves some awkward lifecycle and whatnot.
         mNotificationPanel = mStatusBarWindow.findViewById(R.id.notification_panel);
+
         mStackScroller = mStatusBarWindow.findViewById(R.id.notification_stack_scroller);
         mZenController.addCallback(this);
         NotificationListContainer notifListContainer = (NotificationListContainer) mStackScroller;
@@ -927,8 +932,10 @@
 
         ScrimView scrimBehind = mStatusBarWindow.findViewById(R.id.scrim_behind);
         ScrimView scrimInFront = mStatusBarWindow.findViewById(R.id.scrim_in_front);
+        ScrimView scrimForBubble = mStatusBarWindow.findViewById(R.id.scrim_for_bubble);
+
         mScrimController = SystemUIFactory.getInstance().createScrimController(
-                scrimBehind, scrimInFront, mLockscreenWallpaper,
+                scrimBehind, scrimInFront, scrimForBubble, mLockscreenWallpaper,
                 (state, alpha, color) -> mLightBarController.setScrimState(state, alpha, color),
                 scrimsVisible -> {
                     if (mStatusBarWindowController != null) {
@@ -1065,7 +1072,7 @@
         final NotificationRowBinderImpl rowBinder =
                 new NotificationRowBinderImpl(
                         mContext,
-                        SystemUIFactory.getInstance().provideAllowNotificationLongPress(),
+                        mAllowNotificationLongPress,
                         mKeyguardBypassController,
                         mStatusBarStateController);
 
@@ -1243,7 +1250,7 @@
         mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
                 getBouncerContainer(), mNotificationPanel, mBiometricUnlockController,
                 mStatusBarWindow.findViewById(R.id.lock_icon_container), mStackScroller,
-                mKeyguardBypassController);
+                mKeyguardBypassController, mFalsingManager);
         mKeyguardIndicationController
                 .setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
         mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
@@ -2399,6 +2406,10 @@
             pw.println("  mGroupManager: null");
         }
 
+        if (mBubbleController != null) {
+            mBubbleController.dump(fd, pw, args);
+        }
+
         if (mLightBarController != null) {
             mLightBarController.dump(fd, pw, args);
         }
@@ -2415,7 +2426,7 @@
             mKeyguardUpdateMonitor.dump(fd, pw, args);
         }
 
-        FalsingManagerFactory.getInstance(mContext).dump(pw);
+        Dependency.get(FalsingManager.class).dump(pw);
         FalsingLog.dump(pw);
 
         pw.println("SharedPreferences:");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 7e86651..68ee8bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -44,6 +44,7 @@
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.CommandQueue;
@@ -61,6 +62,8 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 
+import androidx.annotation.VisibleForTesting;
+
 /**
  * Manages creating, showing, hiding and resetting the keyguard within the status bar. Calls back
  * via {@link ViewMediatorCallback} to poke the wake lock and report that the keyguard is done,
@@ -160,6 +163,7 @@
     private boolean mLastLockVisible;
 
     private OnDismissAction mAfterKeyguardGoneAction;
+    private Runnable mKeyguardGoneCancelAction;
     private final ArrayList<Runnable> mAfterKeyguardGoneRunnables = new ArrayList<>();
 
     // Dismiss action to be launched when we stop dozing or the keyguard is gone.
@@ -210,7 +214,7 @@
             BiometricUnlockController biometricUnlockController,
             DismissCallbackRegistry dismissCallbackRegistry,
             ViewGroup lockIconContainer, View notificationContainer,
-            KeyguardBypassController bypassController) {
+            KeyguardBypassController bypassController, FalsingManager falsingManager) {
         mStatusBar = statusBar;
         mContainer = container;
         mLockIconContainer = lockIconContainer;
@@ -220,7 +224,7 @@
         mBiometricUnlockController = biometricUnlockController;
         mBouncer = SystemUIFactory.getInstance().createKeyguardBouncer(mContext,
                 mViewMediatorCallback, mLockPatternUtils, container, dismissCallbackRegistry,
-                mExpansionCallback, bypassController);
+                mExpansionCallback, falsingManager, bypassController);
         mNotificationPanelView = notificationPanelView;
         notificationPanelView.addExpansionListener(this);
         mBypassController = bypassController;
@@ -327,10 +331,20 @@
         return false;
     }
 
-    private void hideBouncer(boolean destroyView) {
+    @VisibleForTesting
+    void hideBouncer(boolean destroyView) {
         if (mBouncer == null) {
             return;
         }
+        if (mShowing) {
+            // If we were showing the bouncer and then aborting, we need to also clear out any
+            // potential actions unless we actually unlocked.
+            mAfterKeyguardGoneAction = null;
+            if (mKeyguardGoneCancelAction != null) {
+                mKeyguardGoneCancelAction.run();
+                mKeyguardGoneCancelAction = null;
+            }
+        }
         mBouncer.hide(destroyView);
         cancelPendingWakeupAction();
     }
@@ -363,6 +377,7 @@
                 mBouncer.showWithDismissAction(r, cancelAction);
             } else {
                 mAfterKeyguardGoneAction = r;
+                mKeyguardGoneCancelAction = cancelAction;
                 mBouncer.show(false /* resetSecuritySelection */);
             }
         }
@@ -670,6 +685,7 @@
             mAfterKeyguardGoneAction.onDismiss();
             mAfterKeyguardGoneAction = null;
         }
+        mKeyguardGoneCancelAction = null;
         for (int i = 0; i < mAfterKeyguardGoneRunnables.size(); i++) {
             mAfterKeyguardGoneRunnables.get(i).run();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index 06921980..a870590 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -224,7 +224,7 @@
             mVisualStabilityManager.setUpWithPresenter(this);
             mGutsManager.setUpWithPresenter(this,
                     notifListContainer, mCheckSaveListener, mOnSettingsClickListener);
-            // ForegroundServiceNotificationListener adds its listener in its constructor
+            // ForegroundServiceControllerListener adds its listener in its constructor
             // but we need to request it here in order for it to be instantiated.
             // TODO: figure out how to do this correctly once Dependency.get() is gone.
             Dependency.get(ForegroundServiceNotificationListener.class);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
index 0ef981b..d3ae5cf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
@@ -39,9 +39,9 @@
 import android.view.WindowManager.LayoutParams;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.keyguard.R;
 import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
+import com.android.systemui.R;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -222,7 +222,7 @@
         }
 
         final boolean scrimsOccludingWallpaper =
-                state.scrimsVisibility == ScrimController.VISIBILITY_FULLY_OPAQUE;
+                state.scrimsVisibility == ScrimController.OPAQUE;
         final boolean keyguardOrAod = state.keyguardShowing
                 || (state.dozing && mDozeParameters.getAlwaysOn());
         if (keyguardOrAod && !state.backdropShowing && !scrimsOccludingWallpaper) {
@@ -308,7 +308,7 @@
         return !state.forceCollapsed && (state.isKeyguardShowingAndNotOccluded()
                 || state.panelVisible || state.keyguardFadingAway || state.bouncerShowing
                 || state.headsUpShowing || state.bubblesShowing
-                || state.scrimsVisibility != ScrimController.VISIBILITY_FULLY_TRANSPARENT);
+                || state.scrimsVisibility != ScrimController.TRANSPARENT);
     }
 
     private void applyFitsSystemWindows(State state) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 1081bad..6789930 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -62,7 +62,6 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.ExpandHelper;
 import com.android.systemui.R;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.DragDownHelper;
@@ -157,7 +156,7 @@
         setMotionEventSplittingEnabled(false);
         mTransparentSrcPaint.setColor(0);
         mTransparentSrcPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
-        mFalsingManager = FalsingManagerFactory.getInstance(context);
+        mFalsingManager = Dependency.get(FalsingManager.class);  // TODO: inject into a controller.
         mGestureDetector = new GestureDetector(context, mGestureListener);
         mStatusBarStateController = Dependency.get(StatusBarStateController.class);
         Dependency.get(TunerService.class).addTunable(mTunable,
@@ -291,7 +290,7 @@
         ExpandHelper.Callback expandHelperCallback = stackScrollLayout.getExpandHelperCallback();
         DragDownHelper.DragDownCallback dragDownCallback = stackScrollLayout.getDragDownCallback();
         setDragDownHelper(new DragDownHelper(getContext(), this, expandHelperCallback,
-                dragDownCallback));
+                dragDownCallback, mFalsingManager));
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index 111cdd2..738d076 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -45,9 +45,7 @@
     /**
      * Returns {@code true} if AOD was disabled by power saving policies.
      */
-    default boolean isAodPowerSave() {
-        return isPowerSave();
-    }
+    boolean isAodPowerSave();
 
     /**
      * A listener that will be notified whenever a change in battery level or power save mode has
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplies.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplies.java
index ee78a72..ea93193 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplies.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplies.java
@@ -80,6 +80,7 @@
      */
     public static InflatedSmartReplies inflate(
             Context context,
+            Context packageContext,
             NotificationEntry entry,
             SmartReplyConstants smartReplyConstants,
             SmartReplyController smartReplyController,
@@ -108,9 +109,9 @@
         }
         if (newSmartRepliesAndActions.smartActions != null) {
             suggestionButtons.addAll(
-                    smartReplyView.inflateSmartActions(newSmartRepliesAndActions.smartActions,
-                            smartReplyController, entry, headsUpManager,
-                            delayOnClickListener));
+                    smartReplyView.inflateSmartActions(packageContext,
+                            newSmartRepliesAndActions.smartActions, smartReplyController, entry,
+                            headsUpManager, delayOnClickListener));
         }
 
         return new InflatedSmartReplies(smartReplyView, suggestionButtons,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 94c2232..8ea09e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -21,6 +21,7 @@
 import android.net.NetworkCapabilities;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.Message;
 import android.provider.Settings.Global;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PhoneStateListener;
@@ -55,6 +56,10 @@
 
 public class MobileSignalController extends SignalController<
         MobileSignalController.MobileState, MobileSignalController.MobileIconGroup> {
+
+    // The message to display Nr5G icon gracfully by CarrierConfig timeout
+    private static final int MSG_DISPLAY_GRACE = 1;
+
     private final TelephonyManager mPhone;
     private final SubscriptionDefaults mDefaults;
     private final String mNetworkNameDefault;
@@ -77,8 +82,11 @@
     private SignalStrength mSignalStrength;
     private MobileIconGroup mDefaultIcons;
     private Config mConfig;
+    private final Handler mDisplayGraceHandler;
     @VisibleForTesting
     boolean mInflateSignalStrengths = false;
+    @VisibleForTesting
+    boolean mIsShowingIconGracefully = false;
     // Some specific carriers have 5GE network which is special LTE CA network.
     private static final int NETWORK_TYPE_LTE_CA_5GE = TelephonyManager.MAX_NETWORK_TYPE + 1;
 
@@ -118,6 +126,16 @@
                 updateTelephony();
             }
         };
+
+        mDisplayGraceHandler = new Handler(receiverLooper) {
+            @Override
+            public void handleMessage(Message msg) {
+                if (msg.what == MSG_DISPLAY_GRACE) {
+                    mIsShowingIconGracefully = false;
+                    updateTelephony();
+                }
+            }
+        };
     }
 
     public void setConfiguration(Config config) {
@@ -274,7 +292,8 @@
             }
             boolean dataDisabled = mCurrentState.userSetup
                     && (mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED
-                    || mCurrentState.iconGroup == TelephonyIcons.NOT_DEFAULT_DATA);
+                    || (mCurrentState.iconGroup == TelephonyIcons.NOT_DEFAULT_DATA
+                            && mCurrentState.defaultDataOff));
             boolean noInternet = mCurrentState.inetCondition == 0;
             boolean cutOut = dataDisabled || noInternet;
             return SignalDrawable.getState(level, getNumLevels(), cutOut);
@@ -306,7 +325,7 @@
             dataContentDescription = mContext.getString(R.string.data_connection_no_internet);
         }
         final boolean dataDisabled = (mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED
-                || mCurrentState.iconGroup == TelephonyIcons.NOT_DEFAULT_DATA)
+                || (mCurrentState.iconGroup == TelephonyIcons.NOT_DEFAULT_DATA))
                 && mCurrentState.userSetup;
 
         // Show icon in QS when we are connected or data is disabled.
@@ -471,6 +490,7 @@
             Log.d(mTag, "updateTelephonySignalStrength: hasService=" +
                     Utils.isInService(mServiceState) + " ss=" + mSignalStrength);
         }
+        checkDefaultData();
         mCurrentState.connected = Utils.isInService(mServiceState)
                 && mSignalStrength != null;
         if (mCurrentState.connected) {
@@ -484,6 +504,10 @@
         // When the device is camped on a 5G Non-Standalone network, the data network type is still
         // LTE. In this case, we first check which 5G icon should be shown.
         MobileIconGroup nr5GIconGroup = getNr5GIconGroup();
+        if (mConfig.nrIconDisplayGracePeriodMs > 0) {
+            nr5GIconGroup = adjustNr5GIconGroupByDisplayGraceTime(nr5GIconGroup);
+        }
+
         if (nr5GIconGroup != null) {
             mCurrentState.iconGroup = nr5GIconGroup;
         } else if (mNetworkToIconLookup.indexOfKey(mDataNetType) >= 0) {
@@ -524,6 +548,23 @@
         notifyListenersIfNecessary();
     }
 
+    /**
+     * If we are controlling the NOT_DEFAULT_DATA icon, check the status of the other one
+     */
+    private void checkDefaultData() {
+        if (mCurrentState.iconGroup != TelephonyIcons.NOT_DEFAULT_DATA) {
+            mCurrentState.defaultDataOff = false;
+            return;
+        }
+
+        mCurrentState.defaultDataOff = mNetworkController.isDataControllerDisabled();
+    }
+
+    void onMobileDataChanged() {
+        checkDefaultData();
+        notifyListenersIfNecessary();
+    }
+
     private MobileIconGroup getNr5GIconGroup() {
         if (mServiceState == null) return null;
 
@@ -542,8 +583,14 @@
                 return mConfig.nr5GIconMap.get(Config.NR_CONNECTED);
             }
         } else if (nrState == NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED) {
-            if (mConfig.nr5GIconMap.containsKey(Config.NR_NOT_RESTRICTED)) {
-                return mConfig.nr5GIconMap.get(Config.NR_NOT_RESTRICTED);
+            if (mCurrentState.activityDormant) {
+                if (mConfig.nr5GIconMap.containsKey(Config.NR_NOT_RESTRICTED_RRC_IDLE)) {
+                    return mConfig.nr5GIconMap.get(Config.NR_NOT_RESTRICTED_RRC_IDLE);
+                }
+            } else {
+                if (mConfig.nr5GIconMap.containsKey(Config.NR_NOT_RESTRICTED_RRC_CON)) {
+                    return mConfig.nr5GIconMap.get(Config.NR_NOT_RESTRICTED_RRC_CON);
+                }
             }
         } else if (nrState == NetworkRegistrationInfo.NR_STATE_RESTRICTED) {
             if (mConfig.nr5GIconMap.containsKey(Config.NR_RESTRICTED)) {
@@ -554,7 +601,47 @@
         return null;
     }
 
-    private boolean isDataDisabled() {
+    /**
+     * The function to adjust MobileIconGroup depend on CarrierConfig's time
+     * nextIconGroup == null imply next state could be 2G/3G/4G/4G+
+     * nextIconGroup != null imply next state will be 5G/5G+
+     * Flag : mIsShowingIconGracefully
+     * ---------------------------------------------------------------------------------
+     * |   Last state   |  Current state  | Flag |       Action                        |
+     * ---------------------------------------------------------------------------------
+     * |     5G/5G+     | 2G/3G/4G/4G+    | true | return previous IconGroup           |
+     * |     5G/5G+     |     5G/5G+      | true | Bypass                              |
+     * |  2G/3G/4G/4G+  |     5G/5G+      | true | Bypass                              |
+     * |  2G/3G/4G/4G+  | 2G/3G/4G/4G+    | true | Bypass                              |
+     * |  SS.connected  | SS.disconnect   |  T|F | Reset timer                         |
+     * |NETWORK_TYPE_LTE|!NETWORK_TYPE_LTE|  T|F | Reset timer                         |
+     * |     5G/5G+     | 2G/3G/4G/4G+    | false| Bypass                              |
+     * |     5G/5G+     |     5G/5G+      | false| Bypass                              |
+     * |  2G/3G/4G/4G+  |     5G/5G+      | false| SendMessageDelay(time), flag->true  |
+     * |  2G/3G/4G/4G+  | 2G/3G/4G/4G+    | false| Bypass                              |
+     * ---------------------------------------------------------------------------------
+     */
+    private MobileIconGroup adjustNr5GIconGroupByDisplayGraceTime(
+            MobileIconGroup candidateIconGroup) {
+        if (mIsShowingIconGracefully && candidateIconGroup == null) {
+            candidateIconGroup = (MobileIconGroup) mCurrentState.iconGroup;
+        } else if (!mIsShowingIconGracefully && candidateIconGroup != null
+                && mLastState.iconGroup != candidateIconGroup) {
+            mDisplayGraceHandler.sendMessageDelayed(
+                    mDisplayGraceHandler.obtainMessage(MSG_DISPLAY_GRACE),
+                    mConfig.nrIconDisplayGracePeriodMs);
+            mIsShowingIconGracefully = true;
+        } else if (!mCurrentState.connected || mDataState == TelephonyManager.DATA_DISCONNECTED
+                || candidateIconGroup == null) {
+            mDisplayGraceHandler.removeMessages(MSG_DISPLAY_GRACE);
+            mIsShowingIconGracefully = false;
+            candidateIconGroup = null;
+        }
+
+        return candidateIconGroup;
+    }
+
+    boolean isDataDisabled() {
         return !mPhone.isDataCapable();
     }
 
@@ -564,6 +651,8 @@
                 || activity == TelephonyManager.DATA_ACTIVITY_IN;
         mCurrentState.activityOut = activity == TelephonyManager.DATA_ACTIVITY_INOUT
                 || activity == TelephonyManager.DATA_ACTIVITY_OUT;
+        mCurrentState.activityDormant = activity == TelephonyManager.DATA_ACTIVITY_DORMANT;
+
         notifyListenersIfNecessary();
     }
 
@@ -577,6 +666,7 @@
         pw.println("  mDataNetType=" + mDataNetType + ",");
         pw.println("  mInflateSignalStrengths=" + mInflateSignalStrengths + ",");
         pw.println("  isDataDisabled=" + isDataDisabled() + ",");
+        pw.println("  mIsShowingIconGracefully=" + mIsShowingIconGracefully + ",");
     }
 
     class MobilePhoneStateListener extends PhoneStateListener {
@@ -684,6 +774,7 @@
         boolean isDefault;
         boolean userSetup;
         boolean roaming;
+        boolean defaultDataOff;  // Tracks the on/off state of the defaultDataSubscription
 
         @Override
         public void copyFrom(State s) {
@@ -699,6 +790,7 @@
             carrierNetworkChangeMode = state.carrierNetworkChangeMode;
             userSetup = state.userSetup;
             roaming = state.roaming;
+            defaultDataOff = state.defaultDataOff;
         }
 
         @Override
@@ -715,7 +807,8 @@
             builder.append("airplaneMode=").append(airplaneMode).append(',');
             builder.append("carrierNetworkChangeMode=").append(carrierNetworkChangeMode)
                     .append(',');
-            builder.append("userSetup=").append(userSetup);
+            builder.append("userSetup=").append(userSetup).append(',');
+            builder.append("defaultDataOff=").append(defaultDataOff);
         }
 
         @Override
@@ -730,7 +823,8 @@
                     && ((MobileState) o).carrierNetworkChangeMode == carrierNetworkChangeMode
                     && ((MobileState) o).userSetup == userSetup
                     && ((MobileState) o).isDefault == isDefault
-                    && ((MobileState) o).roaming == roaming;
+                    && ((MobileState) o).roaming == roaming
+                    && ((MobileState) o).defaultDataOff == defaultDataOff;
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 011dd85..7a09455 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -51,6 +51,7 @@
 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
+import android.text.format.DateUtils;
 import android.util.Log;
 import android.util.MathUtils;
 import android.util.SparseArray;
@@ -219,6 +220,7 @@
             @Override
             public void onMobileDataEnabled(boolean enabled) {
                 mCallbackHandler.setMobileDataEnabled(enabled);
+                notifyControllersMobileDataChanged();
             }
         });
         mWifiSignalController = new WifiSignalController(mContext, mHasMobileDataFeature,
@@ -384,6 +386,22 @@
         return mMobileSignalControllers.size();
     }
 
+    boolean isDataControllerDisabled() {
+        MobileSignalController dataController = getDataController();
+        if (dataController == null) {
+            return false;
+        }
+
+        return dataController.isDataDisabled();
+    }
+
+    private void notifyControllersMobileDataChanged() {
+        for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+            MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
+            mobileSignalController.onMobileDataChanged();
+        }
+    }
+
     public boolean isEmergencyOnly() {
         if (mMobileSignalControllers.size() == 0) {
             // When there are no active subscriptions, determine emengency state from last
@@ -829,6 +847,13 @@
         pw.print("  mEmergencySource=");
         pw.println(emergencyToString(mEmergencySource));
 
+        pw.println("  - config ------");
+        pw.print("  patternOfCarrierSpecificDataIcon=");
+        pw.println(mConfig.patternOfCarrierSpecificDataIcon);
+        pw.print("  nr5GIconMap=");
+        pw.println(mConfig.nr5GIconMap.toString());
+        pw.print("  nrIconDisplayGracePeriodMs=");
+        pw.println(mConfig.nrIconDisplayGracePeriodMs);
         for (int i = 0; i < mMobileSignalControllers.size(); i++) {
             MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
             mobileSignalController.dump(pw);
@@ -1111,8 +1136,9 @@
     static class Config {
         static final int NR_CONNECTED_MMWAVE = 1;
         static final int NR_CONNECTED = 2;
-        static final int NR_NOT_RESTRICTED = 3;
-        static final int NR_RESTRICTED = 4;
+        static final int NR_NOT_RESTRICTED_RRC_IDLE = 3;
+        static final int NR_NOT_RESTRICTED_RRC_CON = 4;
+        static final int NR_RESTRICTED = 5;
 
         Map<Integer, MobileIconGroup> nr5GIconMap = new HashMap<>();
 
@@ -1125,6 +1151,7 @@
         boolean inflateSignalStrengths = false;
         boolean alwaysShowDataRatIcon = false;
         public String patternOfCarrierSpecificDataIcon = "";
+        public long nrIconDisplayGracePeriodMs;
 
         /**
          * Mapping from NR 5G status string to an integer. The NR 5G status string should match
@@ -1132,10 +1159,11 @@
          */
         private static final Map<String, Integer> NR_STATUS_STRING_TO_INDEX;
         static {
-            NR_STATUS_STRING_TO_INDEX = new HashMap<>(4);
+            NR_STATUS_STRING_TO_INDEX = new HashMap<>(5);
             NR_STATUS_STRING_TO_INDEX.put("connected_mmwave", NR_CONNECTED_MMWAVE);
             NR_STATUS_STRING_TO_INDEX.put("connected", NR_CONNECTED);
-            NR_STATUS_STRING_TO_INDEX.put("not_restricted", NR_NOT_RESTRICTED);
+            NR_STATUS_STRING_TO_INDEX.put("not_restricted_rrc_idle", NR_NOT_RESTRICTED_RRC_IDLE);
+            NR_STATUS_STRING_TO_INDEX.put("not_restricted_rrc_con", NR_NOT_RESTRICTED_RRC_CON);
             NR_STATUS_STRING_TO_INDEX.put("restricted", NR_RESTRICTED);
         }
 
@@ -1176,6 +1204,9 @@
                         add5GIconMapping(pair, config);
                     }
                 }
+                setDisplayGraceTime(
+                        b.getInt(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT),
+                        config);
             }
 
             return config;
@@ -1209,5 +1240,18 @@
                         TelephonyIcons.ICON_NAME_TO_ICON.get(value));
             }
         }
+
+        /**
+         * Set display gracefully period time(MS) depend on carrierConfig KEY
+         * KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT, and this function will convert to ms.
+         * {@link CarrierConfigManager}.
+         *
+         * @param time   showing 5G icon gracefully in the period of the time(SECOND)
+         * @param config container that used to store the parsed configs.
+         */
+        @VisibleForTesting
+        static void setDisplayGraceTime(int time, Config config) {
+            config.nrIconDisplayGracePeriodMs = time * DateUtils.SECOND_IN_MILLIS;
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java
index 52f7ae0..952324c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java
@@ -259,6 +259,7 @@
         boolean enabled;
         boolean activityIn;
         boolean activityOut;
+        public boolean activityDormant;
         int level;
         IconGroup iconGroup;
         int inetCondition;
@@ -275,6 +276,7 @@
             inetCondition = state.inetCondition;
             activityIn = state.activityIn;
             activityOut = state.activityOut;
+            activityDormant = state.activityDormant;
             rssi = state.rssi;
             time = state.time;
         }
@@ -298,6 +300,7 @@
                     .append("iconGroup=").append(iconGroup).append(',')
                     .append("activityIn=").append(activityIn).append(',')
                     .append("activityOut=").append(activityOut).append(',')
+                    .append("activityDormant=").append(activityDormant).append(',')
                     .append("rssi=").append(rssi).append(',')
                     .append("lastModified=").append(DateFormat.format("MM-dd HH:mm:ss", time));
         }
@@ -315,6 +318,7 @@
                     && other.iconGroup == iconGroup
                     && other.activityIn == activityIn
                     && other.activityOut == activityOut
+                    && other.activityDormant == activityDormant
                     && other.rssi == rssi;
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
index 282d28c..ed0b9d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
@@ -235,17 +235,17 @@
      * Add smart actions to be shown next to smart replies. Only the actions that fit into the
      * notification are shown.
      */
-    public List<Button> inflateSmartActions(@NonNull SmartActions smartActions,
-            SmartReplyController smartReplyController, NotificationEntry entry,
-            HeadsUpManager headsUpManager, boolean delayOnClickListener) {
+    public List<Button> inflateSmartActions(Context packageContext,
+            @NonNull SmartActions smartActions, SmartReplyController smartReplyController,
+            NotificationEntry entry, HeadsUpManager headsUpManager, boolean delayOnClickListener) {
         List<Button> buttons = new ArrayList<>();
         int numSmartActions = smartActions.actions.size();
         for (int n = 0; n < numSmartActions; n++) {
             Notification.Action action = smartActions.actions.get(n);
             if (action.actionIntent != null) {
                 buttons.add(inflateActionButton(
-                        this, getContext(), n, smartActions, smartReplyController, entry,
-                        headsUpManager, delayOnClickListener));
+                        this, getContext(), packageContext, n, smartActions, smartReplyController,
+                        entry, headsUpManager, delayOnClickListener));
             }
         }
         return buttons;
@@ -327,7 +327,7 @@
 
     @VisibleForTesting
     static Button inflateActionButton(SmartReplyView smartReplyView, Context context,
-            int actionIndex, SmartActions smartActions,
+            Context packageContext, int actionIndex, SmartActions smartActions,
             SmartReplyController smartReplyController, NotificationEntry entry,
             HeadsUpManager headsUpManager, boolean useDelayedOnClickListener) {
         Notification.Action action = smartActions.actions.get(actionIndex);
@@ -335,7 +335,9 @@
                 R.layout.smart_action_button, smartReplyView, false);
         button.setText(action.title);
 
-        Drawable iconDrawable = action.getIcon().loadDrawable(context);
+        // We received the Icon from the application - so use the Context of the application to
+        // reference icon resources.
+        Drawable iconDrawable = action.getIcon().loadDrawable(packageContext);
         // Add the action icon to the Smart Action button.
         int newIconSize = context.getResources().getDimensionPixelSize(
                 R.dimen.smart_action_button_icon_size);
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
index 1d4f9b3..9750790 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
@@ -31,6 +31,7 @@
 
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.SystemUIFactory;
 import com.android.systemui.fragments.FragmentService;
 
 public class TunerActivity extends Activity implements
@@ -50,7 +51,7 @@
             setActionBar(toolbar);
         }
 
-        Dependency.initDependencies(this);
+        Dependency.initDependencies(SystemUIFactory.getInstance().getRootComponent());
 
         if (getFragmentManager().findFragmentByTag(TAG_TUNER) == null) {
             final String action = getIntent().getAction();
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index de86f3d..ff5bd03 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -628,6 +628,14 @@
             final int requestKey = vol.getId().hashCode();
             return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
                     PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
+        } else if (isAutomotive()) {
+            intent.setClassName("com.android.car.settings",
+                    "com.android.car.settings.storage.StorageUnmountReceiver");
+            intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
+
+            final int requestKey = vol.getId().hashCode();
+            return PendingIntent.getBroadcastAsUser(mContext, requestKey, intent,
+                    PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.CURRENT);
         } else {
             intent.setClassName("com.android.settings",
                     "com.android.settings.deviceinfo.StorageUnmountReceiver");
@@ -749,6 +757,11 @@
                 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
     }
 
+    private boolean isAutomotive() {
+        PackageManager packageManager = mContext.getPackageManager();
+        return packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+    }
+
     private boolean isTv() {
         PackageManager packageManager = mContext.getPackageManager();
         return packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
index ede3004..e44e58a 100644
--- a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
+++ b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
@@ -26,12 +26,13 @@
 import com.android.keyguard.KeyguardClockSwitch;
 import com.android.keyguard.KeyguardMessageArea;
 import com.android.keyguard.KeyguardSliceView;
-import com.android.systemui.SystemUIFactory;
+import com.android.systemui.SystemUIRootComponent;
 import com.android.systemui.qs.QSCarrierGroup;
 import com.android.systemui.qs.QSFooterImpl;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.qs.QuickQSPanel;
 import com.android.systemui.qs.QuickStatusBarHeader;
+import com.android.systemui.qs.customize.QSCustomizer;
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.phone.LockIcon;
@@ -62,7 +63,7 @@
     private final LayoutInflater.Factory2 mFactory = new InjectionFactory();
 
     @Inject
-    public InjectionInflationController(SystemUIFactory.SystemUIRootComponent rootComponent) {
+    public InjectionInflationController(SystemUIRootComponent rootComponent) {
         mViewCreator = rootComponent.createViewCreator();
         initInjectionMap();
     }
@@ -172,6 +173,11 @@
          * Creates the QuickQSPanel.
          */
         QuickQSPanel createQuickQSPanel();
+
+        /**
+         * Creates the QSCustomizer.
+         */
+        QSCustomizer createQSCustomizer();
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/util/ProximitySensor.java b/packages/SystemUI/src/com/android/systemui/util/ProximitySensor.java
new file mode 100644
index 0000000..a905eba
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/ProximitySensor.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2019 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.util;
+
+import android.content.Context;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.util.Log;
+
+import com.android.systemui.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+/**
+ * Simple wrapper around SensorManager customized for the Proximity sensor.
+ */
+public class ProximitySensor {
+    private static final String TAG = "ProxSensor";
+    private static final boolean DEBUG = false;
+
+    private final Sensor mSensor;
+    private final AsyncSensorManager mSensorManager;
+    private final boolean mUsingBrightnessSensor;
+    private final float mMaxRange;
+
+    private SensorEventListener mSensorEventListener = new SensorEventListener() {
+        @Override
+        public synchronized void onSensorChanged(SensorEvent event) {
+            onSensorEvent(event);
+        }
+
+        @Override
+        public void onAccuracyChanged(Sensor sensor, int accuracy) {
+        }
+    };
+    private boolean mNear;
+    private List<ProximitySensorListener> mListeners = new ArrayList<>();
+    private String mTag = null;
+
+    @Inject
+    public ProximitySensor(Context context, AsyncSensorManager sensorManager) {
+        mSensorManager = sensorManager;
+        Sensor sensor = findBrightnessSensor(context, sensorManager);
+
+        if (sensor == null) {
+            mUsingBrightnessSensor = false;
+            sensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
+        } else {
+            mUsingBrightnessSensor = true;
+        }
+        mSensor = sensor;
+        if (mSensor != null) {
+            mMaxRange = mSensor.getMaximumRange();
+        } else {
+            mMaxRange = 0;
+        }
+    }
+
+    public void setTag(String tag) {
+        mTag = tag;
+    }
+
+    private Sensor findBrightnessSensor(Context context, SensorManager sensorManager) {
+        String sensorType = context.getString(R.string.doze_brightness_sensor_type);
+        List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ALL);
+        Sensor sensor = null;
+        for (Sensor s : sensorList) {
+            if (sensorType.equals(s.getStringType())) {
+                sensor = s;
+                break;
+            }
+        }
+
+        return sensor;
+    }
+
+    /**
+     * Returns {@code false} if a Proximity sensor is not available.
+     */
+    public boolean getSensorAvailable() {
+        return mSensor != null;
+    }
+
+    /**
+     * Add a listener.
+     *
+     * Registers itself with the {@link SensorManager} if this is the first listener
+     * added.
+     */
+    public boolean register(ProximitySensorListener listener) {
+        if (!getSensorAvailable()) {
+            return false;
+        }
+
+        logDebug("using brightness sensor? " + mUsingBrightnessSensor);
+        mListeners.add(listener);
+        if (mListeners.size() == 1) {
+            logDebug("registering sensor listener");
+            mSensorManager.registerListener(
+                    mSensorEventListener, mSensor, SensorManager.SENSOR_DELAY_GAME);
+        }
+
+        return true;
+    }
+
+    /**
+     * Remove a listener.
+     *
+     * If all listeners are removed from an instance of this class,
+     * it will unregister itself with the SensorManager.
+     */
+    public void unregister(ProximitySensorListener listener) {
+        mListeners.remove(listener);
+        if (mListeners.size() == 0) {
+            logDebug("unregistering sensor listener");
+            mSensorManager.unregisterListener(mSensorEventListener);
+        }
+    }
+
+    public boolean isNear() {
+        return getSensorAvailable() && mNear;
+    }
+
+    private void onSensorEvent(SensorEvent event) {
+        boolean near = event.values[0] < mMaxRange;
+        if (mUsingBrightnessSensor) {
+            near = event.values[0] == 0;
+        }
+        mNear = near;
+        mListeners.forEach(proximitySensorListener ->
+                proximitySensorListener.onProximitySensorEvent(
+                        new ProximityEvent(mNear, event.timestamp)));
+    }
+
+    /** Implement to be notified of ProximityEvents. */
+    public interface ProximitySensorListener {
+        /** Called when the ProximitySensor changes. */
+        void onProximitySensorEvent(ProximityEvent proximityEvent);
+    }
+
+    /**
+     * Returned when the near/far state of a {@link ProximitySensor} changes.
+     */
+    public static class ProximityEvent {
+        private final boolean mNear;
+        private final long mTimestampNs;
+
+        public ProximityEvent(boolean near, long timestampNs) {
+            mNear = near;
+            mTimestampNs = timestampNs;
+        }
+
+        public boolean getNear() {
+            return mNear;
+        }
+
+        public long getTimestampNs() {
+            return mTimestampNs;
+        }
+    }
+
+    private void logDebug(String msg) {
+        if (DEBUG) {
+            Log.d(TAG, (mTag != null ? "[" + mTag + "] " : "") + msg);
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index 5412cde..81e2c22 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -39,7 +39,7 @@
     telephony-common \
     android.test.base \
 
-LOCAL_AAPT_FLAGS := --extra-packages com.android.systemui:com.android.keyguard
+LOCAL_AAPT_FLAGS := --extra-packages com.android.systemui
 
 # sign this with platform cert, so this test is allowed to inject key events into
 # UI it doesn't own. This is necessary to allow screenshots to be taken
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
index 0044ca7..728debd 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
@@ -22,11 +22,14 @@
 import static android.telephony.SubscriptionManager.NAME_SOURCE_DEFAULT_SOURCE;
 
 import static junit.framework.Assert.assertTrue;
+import static junit.framework.TestCase.assertFalse;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
@@ -34,18 +37,22 @@
 
 import android.content.Context;
 import android.net.ConnectivityManager;
+import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.os.Handler;
 import android.provider.Settings;
+import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
+import android.text.TextUtils;
 
 import com.android.internal.telephony.IccCardConstants;
 import com.android.systemui.Dependency;
+import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 
@@ -80,6 +87,9 @@
             TEST_CARRIER, TEST_CARRIER_2, NAME_SOURCE_DEFAULT_SOURCE, 0xFFFFFF, "",
             DATA_ROAMING_DISABLE, null, null, null, null, false, null, "", true, TEST_GROUP_UUID,
             TEST_CARRIER_ID, 0);
+    private static final SubscriptionInfo TEST_SUBSCRIPTION_NULL = new SubscriptionInfo(0, "", 0,
+            TEST_CARRIER, null, NAME_SOURCE_DEFAULT_SOURCE, 0xFFFFFF, "", DATA_ROAMING_DISABLE,
+            null, null, null, null, false, null, "");
     private static final SubscriptionInfo TEST_SUBSCRIPTION_ROAMING = new SubscriptionInfo(0, "", 0,
             TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_DEFAULT_SOURCE, 0xFFFFFF, "",
             DATA_ROAMING_ENABLE, null, null, null, null, false, null, "");
@@ -285,6 +295,65 @@
     }
 
     @Test
+    public void testCarrierText_noTextOnReadySimWhenNull() {
+        reset(mCarrierTextCallback);
+        List<SubscriptionInfo> list = new ArrayList<>();
+        list.add(TEST_SUBSCRIPTION_NULL);
+        when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(IccCardConstants.State.READY);
+        when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);
+
+        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
+
+        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
+                ArgumentCaptor.forClass(
+                        CarrierTextController.CarrierTextCallbackInfo.class);
+
+        mCarrierTextController.updateCarrierText();
+        mTestableLooper.processAllMessages();
+        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+
+        assertTrue("Carrier text should be empty, instead it's " + captor.getValue().carrierText,
+                TextUtils.isEmpty(captor.getValue().carrierText));
+        assertFalse("No SIM should be available", captor.getValue().anySimReady);
+    }
+
+    @Test
+    public void testCarrierText_noTextOnReadySimWhenNull_airplaneMode_wifiOn() {
+        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
+        reset(mCarrierTextCallback);
+        List<SubscriptionInfo> list = new ArrayList<>();
+        list.add(TEST_SUBSCRIPTION_NULL);
+        when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(IccCardConstants.State.READY);
+        when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(list);
+        mockWifi();
+
+        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
+        ServiceState ss = mock(ServiceState.class);
+        when(ss.getDataRegState()).thenReturn(ServiceState.STATE_IN_SERVICE);
+        mKeyguardUpdateMonitor.mServiceStates.put(TEST_SUBSCRIPTION_NULL.getSubscriptionId(), ss);
+
+        ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
+                ArgumentCaptor.forClass(
+                        CarrierTextController.CarrierTextCallbackInfo.class);
+
+        mCarrierTextController.updateCarrierText();
+        mTestableLooper.processAllMessages();
+        verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
+
+        assertFalse("No SIM should be available", captor.getValue().anySimReady);
+        // There's no airplane mode if at least one SIM is State.READY and there's wifi
+        assertFalse("Device should not be in airplane mode", captor.getValue().airplaneMode);
+        assertNotEquals(AIRPLANE_MODE_TEXT, captor.getValue().carrierText);
+    }
+
+    private void mockWifi() {
+        when(mWifiManager.isWifiEnabled()).thenReturn(true);
+        WifiInfo wifiInfo = mock(WifiInfo.class);
+        when(wifiInfo.getBSSID()).thenReturn("");
+        when(mWifiManager.getConnectionInfo()).thenReturn(wifiInfo);
+    }
+
+    @Test
     public void testCreateInfo_noSubscriptions() {
         reset(mCarrierTextCallback);
         when(mKeyguardUpdateMonitor.getSubscriptionInfo(anyBoolean())).thenReturn(
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java
index dcafa72..00f88bf 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java
@@ -27,6 +27,7 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
index f01c0b4..de7664c 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
@@ -39,6 +39,7 @@
 import android.widget.TextClock;
 
 import com.android.keyguard.clock.ClockManager;
+import com.android.systemui.R;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.ClockPlugin;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewTest.kt
index 5f03bdb..42a8950 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewTest.kt
@@ -21,6 +21,7 @@
 import android.testing.TestableLooper
 import android.view.LayoutInflater
 
+import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.google.common.truth.Truth.assertThat
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewTest.java
index eadb1b6..202fbd7 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewTest.java
@@ -28,6 +28,7 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
index 8db195a..d47fcee 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
@@ -23,6 +23,7 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Test;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
index b3accbc..116f8fc 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
@@ -27,6 +27,7 @@
 import androidx.slice.SliceSpecs;
 import androidx.slice.builders.ListBuilder;
 
+import com.android.systemui.R;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.keyguard.KeyguardSliceProvider;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
index 31ea39c..87f2ef5 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
@@ -24,6 +24,7 @@
 import android.testing.TestableLooper.RunWithLooper;
 import android.view.LayoutInflater;
 
+import com.android.systemui.R;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.util.Assert;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java b/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java
index b1ca169..b9d09ce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java
@@ -74,6 +74,6 @@
     @Test
     public void testInitDependency() {
         Dependency.clearDependencies();
-        Dependency.initDependencies(mContext);
+        Dependency.initDependencies(SystemUIFactory.getInstance().getRootComponent());
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceLifetimeExtenderTest.java b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceLifetimeExtenderTest.java
deleted file mode 100644
index b1dabdd..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceLifetimeExtenderTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2019 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;
-
-import static com.android.systemui.ForegroundServiceLifetimeExtender.MIN_FGS_TIME_MS;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.app.Notification;
-import android.service.notification.StatusBarNotification;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class ForegroundServiceLifetimeExtenderTest extends SysuiTestCase {
-    private ForegroundServiceLifetimeExtender mExtender = new ForegroundServiceLifetimeExtender();
-    private StatusBarNotification mSbn;
-    private NotificationEntry mEntry;
-    private Notification mNotif;
-
-    @Before
-    public void setup() {
-        mNotif = new Notification.Builder(mContext, "")
-                .setSmallIcon(R.drawable.ic_person)
-                .setContentTitle("Title")
-                .setContentText("Text")
-                .build();
-
-        mSbn = mock(StatusBarNotification.class);
-        when(mSbn.getNotification()).thenReturn(mNotif);
-
-        mEntry = new NotificationEntry(mSbn);
-    }
-
-    @Test
-    public void testShouldExtendLifetime_should_foreground() {
-        // Extend the lifetime of a FGS notification iff it has not been visible
-        // for the minimum time
-        mNotif.flags |= Notification.FLAG_FOREGROUND_SERVICE;
-        when(mSbn.getPostTime()).thenReturn(System.currentTimeMillis());
-        assertTrue(mExtender.shouldExtendLifetime(mEntry));
-    }
-
-    @Test
-    public void testShouldExtendLifetime_shouldNot_foreground() {
-        mNotif.flags |= Notification.FLAG_FOREGROUND_SERVICE;
-        when(mSbn.getPostTime()).thenReturn(System.currentTimeMillis() - MIN_FGS_TIME_MS - 1);
-        assertFalse(mExtender.shouldExtendLifetime(mEntry));
-    }
-
-    @Test
-    public void testShouldExtendLifetime_shouldNot_notForeground() {
-        mNotif.flags = 0;
-        when(mSbn.getPostTime()).thenReturn(System.currentTimeMillis() - MIN_FGS_TIME_MS - 1);
-        assertFalse(mExtender.shouldExtendLifetime(mEntry));
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/IconPackOverlayTest.java b/packages/SystemUI/tests/src/com/android/systemui/IconPackOverlayTest.java
index ccc9afc..0fa7443 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/IconPackOverlayTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/IconPackOverlayTest.java
@@ -32,6 +32,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.util.XmlUtils;
+import com.android.systemui.tests.R;
 
 import org.junit.After;
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/TestableDependency.java b/packages/SystemUI/tests/src/com/android/systemui/TestableDependency.java
index 18bf75e..0c53b03 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/TestableDependency.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/TestableDependency.java
@@ -25,10 +25,6 @@
     private final ArraySet<Object> mInstantiatedObjects = new ArraySet<>();
 
     public TestableDependency(Context context) {
-        if (context instanceof SysuiTestableContext) {
-            mComponents = ((SysuiTestableContext) context).getComponents();
-        }
-        mContext = context;
         SystemUIFactory.createFromConfig(context);
         SystemUIFactory.getInstance().getRootComponent()
                 .createDependency()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java
index a583b1c..20983fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java
@@ -37,10 +37,12 @@
 
 import com.android.internal.app.AssistUtils;
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
+import com.android.systemui.DumpController;
 import com.android.systemui.ScreenDecorations;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.recents.OverviewProxyService;
+import com.android.systemui.statusbar.phone.NavigationModeController;
 
 import org.junit.After;
 import org.junit.Before;
@@ -50,6 +52,9 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.EnumMap;
+import java.util.Map;
+
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
@@ -63,7 +68,12 @@
     @Mock private AssistUtils mMockAssistUtils;
     @Mock private Handler mMockHandler;
     @Mock private PhenotypeHelper mMockPhenotypeHelper;
-    @Mock private AssistHandleBehaviorController.BehaviorController mMockBehaviorController;
+    @Mock private AssistHandleOffBehavior mMockOffBehavior;
+    @Mock private AssistHandleLikeHomeBehavior mMockLikeHomeBehavior;
+    @Mock private AssistHandleReminderExpBehavior mMockReminderExpBehavior;
+    @Mock private AssistHandleBehaviorController.BehaviorController mMockTestBehavior;
+    @Mock private NavigationModeController mMockNavigationModeController;
+    @Mock private DumpController mMockDumpController;
 
     @Before
     public void setup() {
@@ -74,13 +84,23 @@
         doAnswer(answerVoid(Runnable::run)).when(mMockHandler)
                 .postDelayed(any(Runnable.class), anyLong());
 
+        Map<AssistHandleBehavior, AssistHandleBehaviorController.BehaviorController> behaviorMap =
+                new EnumMap<>(AssistHandleBehavior.class);
+        behaviorMap.put(AssistHandleBehavior.OFF, mMockOffBehavior);
+        behaviorMap.put(AssistHandleBehavior.LIKE_HOME, mMockLikeHomeBehavior);
+        behaviorMap.put(AssistHandleBehavior.REMINDER_EXP, mMockReminderExpBehavior);
+        behaviorMap.put(AssistHandleBehavior.TEST, mMockTestBehavior);
+
         mAssistHandleBehaviorController =
                 new AssistHandleBehaviorController(
                         mContext,
                         mMockAssistUtils,
-                        mMockHandler, () -> mMockScreenDecorations,
+                        mMockHandler,
+                        () -> mMockScreenDecorations,
                         mMockPhenotypeHelper,
-                        mMockBehaviorController);
+                        behaviorMap,
+                        mMockNavigationModeController,
+                        mMockDumpController);
     }
 
     @After
@@ -314,8 +334,8 @@
         mAssistHandleBehaviorController.setBehavior(AssistHandleBehavior.TEST);
 
         // Assert
-        verify(mMockBehaviorController).onModeActivated(mContext, mAssistHandleBehaviorController);
-        verifyNoMoreInteractions(mMockBehaviorController);
+        verify(mMockTestBehavior).onModeActivated(mContext, mAssistHandleBehaviorController);
+        verifyNoMoreInteractions(mMockTestBehavior);
     }
 
     @Test
@@ -324,14 +344,14 @@
         when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME);
         mAssistHandleBehaviorController.setBehavior(AssistHandleBehavior.TEST);
         mAssistHandleBehaviorController.setInGesturalModeForTest(true);
-        reset(mMockBehaviorController);
+        reset(mMockTestBehavior);
 
         // Act
         mAssistHandleBehaviorController.setBehavior(AssistHandleBehavior.OFF);
 
         // Assert
-        verify(mMockBehaviorController).onModeDeactivated();
-        verifyNoMoreInteractions(mMockBehaviorController);
+        verify(mMockTestBehavior).onModeDeactivated();
+        verifyNoMoreInteractions(mMockTestBehavior);
     }
 
     @Test
@@ -344,6 +364,6 @@
         mAssistHandleBehaviorController.setBehavior(AssistHandleBehavior.TEST);
 
         // Assert
-        verifyNoMoreInteractions(mMockBehaviorController);
+        verifyNoMoreInteractions(mMockTestBehavior);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleLikeHomeBehaviorTest.java b/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleLikeHomeBehaviorTest.java
new file mode 100644
index 0000000..21ef640
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleLikeHomeBehaviorTest.java
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2019 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.assist;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.recents.OverviewProxyService;
+import com.android.systemui.shared.system.QuickStepContract;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class AssistHandleLikeHomeBehaviorTest extends SysuiTestCase {
+
+    private AssistHandleLikeHomeBehavior mAssistHandleLikeHomeBehavior;
+
+    @Mock private StatusBarStateController mMockStatusBarStateController;
+    @Mock private WakefulnessLifecycle mMockWakefulnessLifecycle;
+    @Mock private OverviewProxyService mMockOverviewProxyService;
+    @Mock private AssistHandleCallbacks mMockAssistHandleCallbacks;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mAssistHandleLikeHomeBehavior = new AssistHandleLikeHomeBehavior(
+                () -> mMockStatusBarStateController,
+                () -> mMockWakefulnessLifecycle,
+                () -> mMockOverviewProxyService);
+    }
+
+    @Test
+    public void onModeActivated_beginsObserving() {
+        // Arrange
+
+        // Act
+        mAssistHandleLikeHomeBehavior.onModeActivated(mContext, mMockAssistHandleCallbacks);
+
+        // Assert
+        verify(mMockStatusBarStateController).isDozing();
+        verify(mMockStatusBarStateController).addCallback(
+                any(StatusBarStateController.StateListener.class));
+        verify(mMockWakefulnessLifecycle).getWakefulness();
+        verify(mMockWakefulnessLifecycle).addObserver(any(WakefulnessLifecycle.Observer.class));
+        verify(mMockOverviewProxyService).addCallback(any(
+                OverviewProxyService.OverviewProxyListener.class));
+        verifyNoMoreInteractions(mMockWakefulnessLifecycle, mMockOverviewProxyService);
+    }
+
+    @Test
+    public void onModeActivated_showsHandlesWhenFullyAwake() {
+        // Arrange
+        when(mMockStatusBarStateController.isDozing()).thenReturn(false);
+        when(mMockWakefulnessLifecycle.getWakefulness())
+                .thenReturn(WakefulnessLifecycle.WAKEFULNESS_AWAKE);
+
+        // Act
+        mAssistHandleLikeHomeBehavior.onModeActivated(mContext, mMockAssistHandleCallbacks);
+
+        // Assert
+        verify(mMockAssistHandleCallbacks).showAndStay();
+        verifyNoMoreInteractions(mMockAssistHandleCallbacks);
+    }
+
+    @Test
+    public void onModeActivated_hidesHandlesWhenNotAwake() {
+        // Arrange
+        when(mMockStatusBarStateController.isDozing()).thenReturn(true);
+        when(mMockWakefulnessLifecycle.getWakefulness())
+                .thenReturn(WakefulnessLifecycle.WAKEFULNESS_ASLEEP);
+
+        // Act
+        mAssistHandleLikeHomeBehavior.onModeActivated(mContext, mMockAssistHandleCallbacks);
+
+        // Assert
+        verify(mMockAssistHandleCallbacks).hide();
+        verifyNoMoreInteractions(mMockAssistHandleCallbacks);
+    }
+
+    @Test
+    public void onModeActivated_hidesHandlesWhenDozing() {
+        // Arrange
+        when(mMockStatusBarStateController.isDozing()).thenReturn(true);
+        when(mMockWakefulnessLifecycle.getWakefulness())
+                .thenReturn(WakefulnessLifecycle.WAKEFULNESS_AWAKE);
+
+        // Act
+        mAssistHandleLikeHomeBehavior.onModeActivated(mContext, mMockAssistHandleCallbacks);
+
+        // Assert
+        verify(mMockAssistHandleCallbacks).hide();
+        verifyNoMoreInteractions(mMockAssistHandleCallbacks);
+    }
+
+    @Test
+    public void onModeDeactivated_stopsObserving() {
+        // Arrange
+        mAssistHandleLikeHomeBehavior.onModeActivated(mContext, mMockAssistHandleCallbacks);
+        ArgumentCaptor<StatusBarStateController.StateListener> stateListener =
+                ArgumentCaptor.forClass(StatusBarStateController.StateListener.class);
+        ArgumentCaptor<WakefulnessLifecycle.Observer> observer =
+                ArgumentCaptor.forClass(WakefulnessLifecycle.Observer.class);
+        ArgumentCaptor<OverviewProxyService.OverviewProxyListener> overviewProxyListener =
+                ArgumentCaptor.forClass(OverviewProxyService.OverviewProxyListener.class);
+        verify(mMockStatusBarStateController).addCallback(stateListener.capture());
+        verify(mMockWakefulnessLifecycle).addObserver(observer.capture());
+        verify(mMockOverviewProxyService).addCallback(overviewProxyListener.capture());
+        reset(
+                mMockStatusBarStateController,
+                mMockWakefulnessLifecycle,
+                mMockOverviewProxyService,
+                mMockAssistHandleCallbacks);
+
+        // Act
+        mAssistHandleLikeHomeBehavior.onModeDeactivated();
+
+        // Assert
+        verify(mMockStatusBarStateController).removeCallback(eq(stateListener.getValue()));
+        verify(mMockWakefulnessLifecycle).removeObserver(eq(observer.getValue()));
+        verify(mMockOverviewProxyService).removeCallback(eq(overviewProxyListener.getValue()));
+        verifyNoMoreInteractions(
+                mMockStatusBarStateController,
+                mMockWakefulnessLifecycle,
+                mMockOverviewProxyService,
+                mMockAssistHandleCallbacks);
+    }
+
+    @Test
+    public void onAssistantGesturePerformed_doesNothing() {
+        // Arrange
+        mAssistHandleLikeHomeBehavior.onModeActivated(mContext, mMockAssistHandleCallbacks);
+        reset(
+                mMockStatusBarStateController,
+                mMockWakefulnessLifecycle,
+                mMockOverviewProxyService,
+                mMockAssistHandleCallbacks);
+
+        // Act
+        mAssistHandleLikeHomeBehavior.onAssistantGesturePerformed();
+
+        // Assert
+        verifyNoMoreInteractions(
+                mMockStatusBarStateController,
+                mMockWakefulnessLifecycle,
+                mMockOverviewProxyService,
+                mMockAssistHandleCallbacks);
+    }
+
+    @Test
+    public void onAssistHandlesRequested_doesNothing() {
+        // Arrange
+        mAssistHandleLikeHomeBehavior.onModeActivated(mContext, mMockAssistHandleCallbacks);
+        reset(
+                mMockStatusBarStateController,
+                mMockWakefulnessLifecycle,
+                mMockOverviewProxyService,
+                mMockAssistHandleCallbacks);
+
+        // Act
+        mAssistHandleLikeHomeBehavior.onAssistHandlesRequested();
+
+        // Assert
+        verifyNoMoreInteractions(
+                mMockStatusBarStateController,
+                mMockWakefulnessLifecycle,
+                mMockOverviewProxyService,
+                mMockAssistHandleCallbacks);
+    }
+
+    @Test
+    public void onBothAwakeAndUnDoze_handlesShow() {
+        // Arrange
+        when(mMockStatusBarStateController.isDozing()).thenReturn(true);
+        when(mMockWakefulnessLifecycle.getWakefulness())
+                .thenReturn(WakefulnessLifecycle.WAKEFULNESS_ASLEEP);
+        ArgumentCaptor<StatusBarStateController.StateListener> stateListener =
+                ArgumentCaptor.forClass(StatusBarStateController.StateListener.class);
+        ArgumentCaptor<WakefulnessLifecycle.Observer> observer =
+                ArgumentCaptor.forClass(WakefulnessLifecycle.Observer.class);
+        mAssistHandleLikeHomeBehavior.onModeActivated(mContext, mMockAssistHandleCallbacks);
+        verify(mMockStatusBarStateController).addCallback(stateListener.capture());
+        verify(mMockWakefulnessLifecycle).addObserver(observer.capture());
+        reset(
+                mMockStatusBarStateController,
+                mMockWakefulnessLifecycle,
+                mMockOverviewProxyService,
+                mMockAssistHandleCallbacks);
+
+        // Act
+        observer.getValue().onFinishedWakingUp();
+
+        // Assert
+        verify(mMockAssistHandleCallbacks).hide();
+        verifyNoMoreInteractions(
+                mMockStatusBarStateController,
+                mMockWakefulnessLifecycle,
+                mMockOverviewProxyService,
+                mMockAssistHandleCallbacks);
+
+        // Arrange
+        observer.getValue().onFinishedGoingToSleep();
+        reset(mMockAssistHandleCallbacks);
+
+        // Act
+        stateListener.getValue().onDozingChanged(false);
+
+        // Assert
+        verify(mMockAssistHandleCallbacks).hide();
+        verifyNoMoreInteractions(
+                mMockStatusBarStateController,
+                mMockWakefulnessLifecycle,
+                mMockOverviewProxyService,
+                mMockAssistHandleCallbacks);
+
+        // Act
+        observer.getValue().onFinishedWakingUp();
+
+        // Assert
+        verify(mMockAssistHandleCallbacks).showAndStay();
+        verifyNoMoreInteractions(
+                mMockStatusBarStateController,
+                mMockWakefulnessLifecycle,
+                mMockOverviewProxyService,
+                mMockAssistHandleCallbacks);
+    }
+
+    @Test
+    public void onSleepOrDoze_handlesHide() {
+        // Arrange
+        when(mMockStatusBarStateController.isDozing()).thenReturn(false);
+        when(mMockWakefulnessLifecycle.getWakefulness())
+                .thenReturn(WakefulnessLifecycle.WAKEFULNESS_AWAKE);
+        ArgumentCaptor<StatusBarStateController.StateListener> stateListener =
+                ArgumentCaptor.forClass(StatusBarStateController.StateListener.class);
+        ArgumentCaptor<WakefulnessLifecycle.Observer> observer =
+                ArgumentCaptor.forClass(WakefulnessLifecycle.Observer.class);
+        mAssistHandleLikeHomeBehavior.onModeActivated(mContext, mMockAssistHandleCallbacks);
+        verify(mMockStatusBarStateController).addCallback(stateListener.capture());
+        verify(mMockWakefulnessLifecycle).addObserver(observer.capture());
+        reset(
+                mMockStatusBarStateController,
+                mMockWakefulnessLifecycle,
+                mMockOverviewProxyService,
+                mMockAssistHandleCallbacks);
+
+        // Act
+        observer.getValue().onStartedGoingToSleep();
+
+        // Assert
+        verify(mMockAssistHandleCallbacks).hide();
+        verifyNoMoreInteractions(
+                mMockStatusBarStateController,
+                mMockWakefulnessLifecycle,
+                mMockOverviewProxyService,
+                mMockAssistHandleCallbacks);
+
+        // Arrange
+        observer.getValue().onFinishedWakingUp();
+        reset(mMockAssistHandleCallbacks);
+
+        // Act
+        stateListener.getValue().onDozingChanged(true);
+
+        // Assert
+        verify(mMockAssistHandleCallbacks).hide();
+        verifyNoMoreInteractions(
+                mMockStatusBarStateController,
+                mMockWakefulnessLifecycle,
+                mMockOverviewProxyService,
+                mMockAssistHandleCallbacks);
+    }
+
+    @Test
+    public void onHomeHandleHide_handlesHide() {
+        // Arrange
+        when(mMockStatusBarStateController.isDozing()).thenReturn(false);
+        when(mMockWakefulnessLifecycle.getWakefulness())
+                .thenReturn(WakefulnessLifecycle.WAKEFULNESS_AWAKE);
+        ArgumentCaptor<OverviewProxyService.OverviewProxyListener> sysUiStateCallback =
+                ArgumentCaptor.forClass(OverviewProxyService.OverviewProxyListener.class);
+        mAssistHandleLikeHomeBehavior.onModeActivated(mContext, mMockAssistHandleCallbacks);
+        verify(mMockOverviewProxyService).addCallback(sysUiStateCallback.capture());
+        reset(
+                mMockStatusBarStateController,
+                mMockWakefulnessLifecycle,
+                mMockOverviewProxyService,
+                mMockAssistHandleCallbacks);
+
+        // Act
+        sysUiStateCallback.getValue().onSystemUiStateChanged(
+                QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN);
+
+        // Assert
+        verify(mMockAssistHandleCallbacks).hide();
+        verifyNoMoreInteractions(
+                mMockStatusBarStateController,
+                mMockWakefulnessLifecycle,
+                mMockOverviewProxyService,
+                mMockAssistHandleCallbacks);
+    }
+
+    @Test
+    public void onHomeHandleUnhide_handlesShow() {
+        // Arrange
+        when(mMockStatusBarStateController.isDozing()).thenReturn(false);
+        when(mMockWakefulnessLifecycle.getWakefulness())
+                .thenReturn(WakefulnessLifecycle.WAKEFULNESS_AWAKE);
+        ArgumentCaptor<OverviewProxyService.OverviewProxyListener> sysUiStateCallback =
+                ArgumentCaptor.forClass(OverviewProxyService.OverviewProxyListener.class);
+        mAssistHandleLikeHomeBehavior.onModeActivated(mContext, mMockAssistHandleCallbacks);
+        verify(mMockOverviewProxyService).addCallback(sysUiStateCallback.capture());
+        sysUiStateCallback.getValue().onSystemUiStateChanged(
+                QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN);
+        reset(
+                mMockStatusBarStateController,
+                mMockWakefulnessLifecycle,
+                mMockOverviewProxyService,
+                mMockAssistHandleCallbacks);
+
+        // Act
+        sysUiStateCallback.getValue().onSystemUiStateChanged(
+                ~QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN);
+
+        // Assert
+        verify(mMockAssistHandleCallbacks).showAndStay();
+        verifyNoMoreInteractions(
+                mMockStatusBarStateController,
+                mMockWakefulnessLifecycle,
+                mMockOverviewProxyService,
+                mMockAssistHandleCallbacks);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleOffBehaviorTest.java b/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleOffBehaviorTest.java
new file mode 100644
index 0000000..15d4d5b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleOffBehaviorTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2019 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.assist;
+
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class AssistHandleOffBehaviorTest extends SysuiTestCase {
+
+    private AssistHandleOffBehavior mAssistHandleOffBehavior;
+
+    @Mock private AssistHandleCallbacks mMockAssistHandleCallbacks;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mAssistHandleOffBehavior = new AssistHandleOffBehavior();
+    }
+
+    @Test
+    public void onModeActivated_hidesHandles() {
+        // Arrange
+
+        // Act
+        mAssistHandleOffBehavior.onModeActivated(mContext, mMockAssistHandleCallbacks);
+
+        // Assert
+        verify(mMockAssistHandleCallbacks).hide();
+        verifyNoMoreInteractions(mMockAssistHandleCallbacks);
+    }
+
+    @Test
+    public void onModeDeactivated_doesNothing() {
+        // Arrange
+        mAssistHandleOffBehavior.onModeActivated(mContext, mMockAssistHandleCallbacks);
+        reset(mMockAssistHandleCallbacks);
+
+        // Act
+        mAssistHandleOffBehavior.onModeDeactivated();
+
+        // Assert
+        verifyNoMoreInteractions(mMockAssistHandleCallbacks);
+    }
+
+    @Test
+    public void onAssistantGesturePerformed_doesNothing() {
+        // Arrange
+        mAssistHandleOffBehavior.onModeActivated(mContext, mMockAssistHandleCallbacks);
+        reset(mMockAssistHandleCallbacks);
+
+        // Act
+        mAssistHandleOffBehavior.onAssistantGesturePerformed();
+
+        // Assert
+        verifyNoMoreInteractions(mMockAssistHandleCallbacks);
+    }
+
+    @Test
+    public void onAssistHandlesRequested_doesNothing() {
+        // Arrange
+        mAssistHandleOffBehavior.onModeActivated(mContext, mMockAssistHandleCallbacks);
+        reset(mMockAssistHandleCallbacks);
+
+        // Act
+        mAssistHandleOffBehavior.onAssistHandlesRequested();
+
+        // Assert
+        verifyNoMoreInteractions(mMockAssistHandleCallbacks);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
index 2221915..5a4e6c9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
@@ -17,7 +17,6 @@
 package com.android.systemui.bubbles;
 
 import static android.app.Notification.FLAG_BUBBLE;
-import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
 import static android.service.notification.NotificationListenerService.REASON_CANCEL;
 import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL;
@@ -28,6 +27,8 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -42,11 +43,10 @@
 import android.app.IActivityManager;
 import android.app.Notification;
 import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.graphics.drawable.Icon;
+import android.hardware.face.FaceManager;
 import android.service.notification.ZenModeConfig;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -57,19 +57,24 @@
 
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.NotificationRemoveInterceptor;
 import com.android.systemui.statusbar.NotificationTestHelper;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.notification.NotificationEntryListener;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationFilter;
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
 import com.android.systemui.statusbar.notification.collection.NotificationData;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.StatusBarWindowController;
+import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.policy.ZenModeController;
@@ -82,20 +87,16 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 public class BubbleControllerTest extends SysuiTestCase {
 
-    // Some APIs rely on the app being foreground, check is via pkg name
-    private static final String FOREGROUND_TEST_PKG_NAME = "com.android.systemui.tests";
-
     @Mock
     private NotificationEntryManager mNotificationEntryManager;
     @Mock
+    private NotificationGroupManager mNotificationGroupManager;
+    @Mock
     private WindowManager mWindowManager;
     @Mock
     private IActivityManager mActivityManager;
@@ -108,6 +109,10 @@
     @Mock
     private ZenModeConfig mZenModeConfig;
     @Mock
+    private FaceManager mFaceManager;
+    @Mock
+    private NotificationLockscreenUserManager mLockscreenUserManager;
+    @Mock
     private SysuiStatusBarStateController mStatusBarStateController;
     @Mock
     private KeyguardBypassController mKeyguardBypassController;
@@ -126,8 +131,6 @@
     private NotificationTestHelper mNotificationTestHelper;
     private ExpandableNotificationRow mRow;
     private ExpandableNotificationRow mRow2;
-    private ExpandableNotificationRow mAutoExpandRow;
-    private ExpandableNotificationRow mSuppressNotifRow;
     private ExpandableNotificationRow mNonBubbleNotifRow;
 
     @Mock
@@ -146,6 +149,7 @@
         MockitoAnnotations.initMocks(this);
         mStatusBarView = new FrameLayout(mContext);
         mDependency.injectTestDependency(NotificationEntryManager.class, mNotificationEntryManager);
+        mContext.addMockSystemService(FaceManager.class, mFaceManager);
 
         // Bubbles get added to status bar window view
         mStatusBarWindowController = new StatusBarWindowController(mContext, mWindowManager,
@@ -159,35 +163,32 @@
         mRow2 = mNotificationTestHelper.createBubble(mDeleteIntent);
         mNonBubbleNotifRow = mNotificationTestHelper.createRow();
 
-        // Some bubbles want to auto expand
-        Notification.BubbleMetadata autoExpandMetadata =
-                getBuilder().setAutoExpandBubble(true).build();
-        mAutoExpandRow = mNotificationTestHelper.createBubble(autoExpandMetadata,
-                FOREGROUND_TEST_PKG_NAME);
-
-        // Some bubbles want to suppress notifs
-        Notification.BubbleMetadata suppressNotifMetadata =
-                getBuilder().setSuppressNotification(true).build();
-        mSuppressNotifRow = mNotificationTestHelper.createBubble(suppressNotifMetadata,
-                FOREGROUND_TEST_PKG_NAME);
-
         // Return non-null notification data from the NEM
         when(mNotificationEntryManager.getNotificationData()).thenReturn(mNotificationData);
+        when(mNotificationData.get(mRow.getEntry().key)).thenReturn(mRow.getEntry());
         when(mNotificationData.getChannel(mRow.getEntry().key)).thenReturn(mRow.getEntry().channel);
 
         mZenModeConfig.suppressedVisualEffects = 0;
         when(mZenModeController.getConfig()).thenReturn(mZenModeConfig);
 
         TestableNotificationInterruptionStateProvider interruptionStateProvider =
-                new TestableNotificationInterruptionStateProvider(mContext);
+                new TestableNotificationInterruptionStateProvider(mContext,
+                        mock(NotificationFilter.class),
+                        mock(StatusBarStateController.class),
+                        mock(BatteryController.class));
         interruptionStateProvider.setUpWithPresenter(
                 mock(NotificationPresenter.class),
                 mock(HeadsUpManager.class),
                 mock(NotificationInterruptionStateProvider.HeadsUpSuppressor.class));
         mBubbleData = new BubbleData(mContext);
-        mBubbleController = new TestableBubbleController(mContext, mStatusBarWindowController,
-                mBubbleData, mConfigurationController, interruptionStateProvider,
-                mZenModeController);
+        mBubbleController = new TestableBubbleController(mContext,
+                mStatusBarWindowController,
+                mBubbleData,
+                mConfigurationController,
+                interruptionStateProvider,
+                mZenModeController,
+                mLockscreenUserManager,
+                mNotificationGroupManager);
         mBubbleController.setBubbleStateChangeListener(mBubbleStateChangeListener);
         mBubbleController.setExpandListener(mBubbleExpandListener);
 
@@ -219,13 +220,14 @@
     @Test
     public void testRemoveBubble() {
         mBubbleController.updateBubble(mRow.getEntry());
+        assertNotNull(mBubbleData.getBubbleWithKey(mRow.getEntry().key));
         assertTrue(mBubbleController.hasBubbles());
         verify(mNotificationEntryManager).updateNotifications();
         verify(mBubbleStateChangeListener).onHasBubblesChanged(true);
 
         mBubbleController.removeBubble(mRow.getEntry().key, BubbleController.DISMISS_USER_GESTURE);
         assertFalse(mStatusBarWindowController.getBubblesShowing());
-        assertTrue(mRow.getEntry().isBubbleDismissed());
+        assertNull(mBubbleData.getBubbleWithKey(mRow.getEntry().key));
         verify(mNotificationEntryManager, times(2)).updateNotifications();
         verify(mBubbleStateChangeListener).onHasBubblesChanged(false);
     }
@@ -236,10 +238,10 @@
         mBubbleController.updateBubble(mRow.getEntry());
 
         assertTrue(mBubbleController.hasBubbles());
-        assertTrue(mRow.getEntry().showInShadeWhenBubble());
+        assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
 
         // Make it look like dismissed notif
-        mRow.getEntry().setShowInShadeWhenBubble(false);
+        mBubbleData.getBubbleWithKey(mRow.getEntry().key).setShowInShadeWhenBubble(false);
 
         // Now remove the bubble
         mBubbleController.removeBubble(mRow.getEntry().key, BubbleController.DISMISS_USER_GESTURE);
@@ -255,15 +257,17 @@
     public void testDismissStack() {
         mBubbleController.updateBubble(mRow.getEntry());
         verify(mNotificationEntryManager, times(1)).updateNotifications();
+        assertNotNull(mBubbleData.getBubbleWithKey(mRow.getEntry().key));
         mBubbleController.updateBubble(mRow2.getEntry());
         verify(mNotificationEntryManager, times(2)).updateNotifications();
+        assertNotNull(mBubbleData.getBubbleWithKey(mRow2.getEntry().key));
         assertTrue(mBubbleController.hasBubbles());
 
         mBubbleController.dismissStack(BubbleController.DISMISS_USER_GESTURE);
         assertFalse(mStatusBarWindowController.getBubblesShowing());
         verify(mNotificationEntryManager, times(3)).updateNotifications();
-        assertTrue(mRow.getEntry().isBubbleDismissed());
-        assertTrue(mRow2.getEntry().isBubbleDismissed());
+        assertNull(mBubbleData.getBubbleWithKey(mRow.getEntry().key));
+        assertNull(mBubbleData.getBubbleWithKey(mRow2.getEntry().key));
     }
 
     @Test
@@ -274,9 +278,9 @@
         mEntryListener.onPendingEntryAdded(mRow.getEntry());
         mBubbleController.updateBubble(mRow.getEntry());
 
-        // We should have bubbles & their notifs should show in the shade
+        // We should have bubbles & their notifs should not be suppressed
         assertTrue(mBubbleController.hasBubbles());
-        assertTrue(mRow.getEntry().showInShadeWhenBubble());
+        assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
         assertFalse(mStatusBarWindowController.getBubbleExpanded());
 
         // Expand the stack
@@ -286,8 +290,8 @@
         verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().key);
         assertTrue(mStatusBarWindowController.getBubbleExpanded());
 
-        // Make sure it's no longer in the shade
-        assertFalse(mRow.getEntry().showInShadeWhenBubble());
+        // Make sure the notif is suppressed
+        assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
 
         // Collapse
         mBubbleController.collapseStack();
@@ -304,10 +308,11 @@
         mBubbleController.updateBubble(mRow.getEntry());
         mBubbleController.updateBubble(mRow2.getEntry());
 
-        // We should have bubbles & their notifs should show in the shade
+        // We should have bubbles & their notifs should not be suppressed
         assertTrue(mBubbleController.hasBubbles());
-        assertTrue(mRow.getEntry().showInShadeWhenBubble());
-        assertTrue(mRow2.getEntry().showInShadeWhenBubble());
+        assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
+        assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
+                mRow2.getEntry().key));
 
         // Expand
         BubbleStackView stackView = mBubbleController.getStackView();
@@ -317,13 +322,13 @@
 
         // Last added is the one that is expanded
         assertEquals(mRow2.getEntry(), stackView.getExpandedBubbleView().getEntry());
-        assertFalse(mRow2.getEntry().showInShadeWhenBubble());
+        assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow2.getEntry().key));
 
         // Switch which bubble is expanded
         mBubbleController.selectBubble(mRow.getEntry().key);
-        stackView.setExpandedBubble(mRow.getEntry());
+        stackView.setExpandedBubble(mRow.getEntry().key);
         assertEquals(mRow.getEntry(), stackView.getExpandedBubbleView().getEntry());
-        assertFalse(mRow.getEntry().showInShadeWhenBubble());
+        assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
 
         // collapse for previous bubble
         verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow2.getEntry().key);
@@ -336,14 +341,37 @@
     }
 
     @Test
-    public void testExpansionRemovesShowInShade() {
+    public void testExpansionRemovesShowInShadeAndDot() {
         // Mark it as a bubble and add it explicitly
         mEntryListener.onPendingEntryAdded(mRow.getEntry());
         mBubbleController.updateBubble(mRow.getEntry());
 
-        // We should have bubbles & their notifs should show in the shade
+        // We should have bubbles & their notifs should not be suppressed
         assertTrue(mBubbleController.hasBubbles());
-        assertTrue(mRow.getEntry().showInShadeWhenBubble());
+        assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
+        assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().key).showBubbleDot());
+
+        // Expand
+        mBubbleController.expandStack();
+        assertTrue(mBubbleController.isStackExpanded());
+        verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().key);
+
+        // Notif is suppressed after expansion
+        assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
+        // Notif shouldn't show dot after expansion
+        assertFalse(mBubbleData.getBubbleWithKey(mRow.getEntry().key).showBubbleDot());
+    }
+
+    @Test
+    public void testUpdateWhileExpanded_DoesntChangeShowInShadeAndDot() {
+        // Mark it as a bubble and add it explicitly
+        mEntryListener.onPendingEntryAdded(mRow.getEntry());
+        mBubbleController.updateBubble(mRow.getEntry());
+
+        // We should have bubbles & their notifs should not be suppressed
+        assertTrue(mBubbleController.hasBubbles());
+        assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
+        assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().key).showBubbleDot());
 
         // Expand
         BubbleStackView stackView = mBubbleController.getStackView();
@@ -351,8 +379,19 @@
         assertTrue(mBubbleController.isStackExpanded());
         verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().key);
 
-        // No longer show shade in notif after expansion
-        assertFalse(mRow.getEntry().showInShadeWhenBubble());
+        // Notif is suppressed after expansion
+        assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
+        // Notif shouldn't show dot after expansion
+        assertFalse(mBubbleData.getBubbleWithKey(mRow.getEntry().key).showBubbleDot());
+
+        // Send update
+        mEntryListener.onPreEntryUpdated(mRow.getEntry());
+
+        // Nothing should have changed
+        // Notif is suppressed after expansion
+        assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
+        // Notif shouldn't show dot after expansion
+        assertFalse(mBubbleData.getBubbleWithKey(mRow.getEntry().key).showBubbleDot());
     }
 
     @Test
@@ -373,7 +412,7 @@
 
         // Last added is the one that is expanded
         assertEquals(mRow2.getEntry(), stackView.getExpandedBubbleView().getEntry());
-        assertFalse(mRow2.getEntry().showInShadeWhenBubble());
+        assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow2.getEntry().key));
 
         // Dismiss currently expanded
         mBubbleController.removeBubble(stackView.getExpandedBubbleView().getKey(),
@@ -397,14 +436,16 @@
     @Test
     public void testAutoExpand_FailsNotForeground() {
         assertFalse(mBubbleController.isStackExpanded());
+        setMetadataFlags(mRow.getEntry(),
+                Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, false /* enableFlag */);
 
         // Add the auto expand bubble
-        mEntryListener.onPendingEntryAdded(mAutoExpandRow.getEntry());
-        mBubbleController.updateBubble(mAutoExpandRow.getEntry());
+        mEntryListener.onPendingEntryAdded(mRow.getEntry());
+        mBubbleController.updateBubble(mRow.getEntry());
 
         // Expansion shouldn't change
         verify(mBubbleExpandListener, never()).onBubbleExpandChanged(false /* expanded */,
-                mAutoExpandRow.getEntry().key);
+                mRow.getEntry().key);
         assertFalse(mBubbleController.isStackExpanded());
 
         // # of bubbles should change
@@ -413,91 +454,51 @@
 
     @Test
     public void testAutoExpand_SucceedsForeground() {
-        final CountDownLatch latch = new CountDownLatch(1);
-        BroadcastReceiver receiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                latch.countDown();
-            }
-        };
-        IntentFilter filter = new IntentFilter(BubblesTestActivity.BUBBLE_ACTIVITY_OPENED);
-        mContext.registerReceiver(receiver, filter);
-
-        assertFalse(mBubbleController.isStackExpanded());
-
-        // Make ourselves foreground
-        Intent i = new Intent(mContext, BubblesTestActivity.class);
-        i.setFlags(FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(i);
-
-        try {
-            latch.await(100, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-        }
+        setMetadataFlags(mRow.getEntry(),
+                Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, true /* enableFlag */);
 
         // Add the auto expand bubble
-        mEntryListener.onPendingEntryAdded(mAutoExpandRow.getEntry());
-        mBubbleController.updateBubble(mAutoExpandRow.getEntry());
+        mEntryListener.onPendingEntryAdded(mRow.getEntry());
+        mBubbleController.updateBubble(mRow.getEntry());
 
         // Expansion should change
         verify(mBubbleExpandListener).onBubbleExpandChanged(true /* expanded */,
-                mAutoExpandRow.getEntry().key);
+                mRow.getEntry().key);
         assertTrue(mBubbleController.isStackExpanded());
 
         // # of bubbles should change
         verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
-        mContext.unregisterReceiver(receiver);
     }
 
     @Test
     public void testSuppressNotif_FailsNotForeground() {
+        setMetadataFlags(mRow.getEntry(),
+                Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION, false /* enableFlag */);
+
         // Add the suppress notif bubble
-        mEntryListener.onPendingEntryAdded(mSuppressNotifRow.getEntry());
-        mBubbleController.updateBubble(mSuppressNotifRow.getEntry());
+        mEntryListener.onPendingEntryAdded(mRow.getEntry());
+        mBubbleController.updateBubble(mRow.getEntry());
 
-        // Should show in shade because we weren't forground
-        assertTrue(mSuppressNotifRow.getEntry().showInShadeWhenBubble());
-
+        // Should not be suppressed because we weren't forground
+        assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
         // # of bubbles should change
         verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
     }
 
     @Test
     public void testSuppressNotif_SucceedsForeground() {
-        final CountDownLatch latch = new CountDownLatch(1);
-        BroadcastReceiver receiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                latch.countDown();
-            }
-        };
-        IntentFilter filter = new IntentFilter(BubblesTestActivity.BUBBLE_ACTIVITY_OPENED);
-        mContext.registerReceiver(receiver, filter);
-
-        assertFalse(mBubbleController.isStackExpanded());
-
-        // Make ourselves foreground
-        Intent i = new Intent(mContext, BubblesTestActivity.class);
-        i.setFlags(FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(i);
-
-        try {
-            latch.await(100, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-        }
+        setMetadataFlags(mRow.getEntry(),
+                Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION, true /* enableFlag */);
 
         // Add the suppress notif bubble
-        mEntryListener.onPendingEntryAdded(mSuppressNotifRow.getEntry());
-        mBubbleController.updateBubble(mSuppressNotifRow.getEntry());
+        mEntryListener.onPendingEntryAdded(mRow.getEntry());
+        mBubbleController.updateBubble(mRow.getEntry());
 
-        // Should NOT show in shade because we were foreground
-        assertFalse(mSuppressNotifRow.getEntry().showInShadeWhenBubble());
+        // Notif should be suppressed because we were foreground
+        assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
 
         // # of bubbles should change
         verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
-        mContext.unregisterReceiver(receiver);
     }
 
     @Test
@@ -516,7 +517,8 @@
     @Test
     public void testMarkNewNotificationAsShowInShade() {
         mEntryListener.onPendingEntryAdded(mRow.getEntry());
-        assertTrue(mRow.getEntry().showInShadeWhenBubble());
+        assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
+        assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().key).showBubbleDot());
     }
 
     @Test
@@ -584,7 +586,7 @@
         mBubbleController.updateBubble(mRow.getEntry());
 
         assertTrue(mBubbleController.hasBubbles());
-        assertTrue(mRow.getEntry().showInShadeWhenBubble());
+        assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
 
         boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
                 mRow.getEntry().key, REASON_CANCEL_ALL);
@@ -592,7 +594,7 @@
         // Intercept!
         assertTrue(intercepted);
         // Should update show in shade state
-        assertFalse(mRow.getEntry().showInShadeWhenBubble());
+        assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
 
         verify(mNotificationEntryManager, never()).performRemoveNotification(
                 any(), anyInt());
@@ -605,7 +607,7 @@
         mBubbleController.updateBubble(mRow.getEntry());
 
         assertTrue(mBubbleController.hasBubbles());
-        assertTrue(mRow.getEntry().showInShadeWhenBubble());
+        assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
 
         boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
                 mRow.getEntry().key, REASON_CANCEL);
@@ -613,7 +615,7 @@
         // Intercept!
         assertTrue(intercepted);
         // Should update show in shade state
-        assertFalse(mRow.getEntry().showInShadeWhenBubble());
+        assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
 
         verify(mNotificationEntryManager, never()).performRemoveNotification(
                 any(), anyInt());
@@ -626,7 +628,7 @@
         mBubbleController.updateBubble(mRow.getEntry());
 
         assertTrue(mBubbleController.hasBubbles());
-        assertTrue(mRow.getEntry().showInShadeWhenBubble());
+        assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
 
         // Dismiss the bubble
         mBubbleController.removeBubble(mRow.getEntry().key, BubbleController.DISMISS_USER_GESTURE);
@@ -646,22 +648,22 @@
                 StatusBarWindowController statusBarWindowController, BubbleData data,
                 ConfigurationController configurationController,
                 NotificationInterruptionStateProvider interruptionStateProvider,
-                ZenModeController zenModeController) {
+                ZenModeController zenModeController,
+                NotificationLockscreenUserManager lockscreenUserManager,
+                NotificationGroupManager groupManager) {
             super(context, statusBarWindowController, data, Runnable::run,
-                    configurationController, interruptionStateProvider, zenModeController);
-        }
-
-        @Override
-        public boolean shouldAutoBubbleForFlags(Context c, NotificationEntry entry) {
-            return entry.notification.getNotification().getBubbleMetadata() != null;
+                    configurationController, interruptionStateProvider, zenModeController,
+                    lockscreenUserManager, groupManager);
         }
     }
 
-    public static class TestableNotificationInterruptionStateProvider extends
+    static class TestableNotificationInterruptionStateProvider extends
             NotificationInterruptionStateProvider {
 
-        public TestableNotificationInterruptionStateProvider(Context context) {
-            super(context);
+        TestableNotificationInterruptionStateProvider(Context context,
+                NotificationFilter filter, StatusBarStateController controller,
+                BatteryController batteryController) {
+            super(context, filter, controller, batteryController);
             mUseHeadsUp = true;
         }
     }
@@ -676,4 +678,21 @@
                 .setIntent(bubbleIntent)
                 .setIcon(Icon.createWithResource(mContext, R.drawable.android));
     }
+
+    /**
+     * Sets the bubble metadata flags for this entry. These flags are normally set by
+     * NotificationManagerService when the notification is sent, however, these tests do not
+     * go through that path so we set them explicitly when testing.
+     */
+    private void setMetadataFlags(NotificationEntry entry, int flag, boolean enableFlag) {
+        Notification.BubbleMetadata bubbleMetadata =
+                entry.notification.getNotification().getBubbleMetadata();
+        int flags = bubbleMetadata.getFlags();
+        if (enableFlag) {
+            flags |= flag;
+        } else {
+            flags &= ~flag;
+        }
+        bubbleMetadata.setFlags(flags);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
index 815a70a..f7d2743 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
@@ -887,7 +887,7 @@
 
     private void sendUpdatedEntryAtTime(NotificationEntry entry, long postTime) {
         setPostTime(entry, postTime);
-        mBubbleData.notificationEntryUpdated(entry);
+        mBubbleData.notificationEntryUpdated(entry, /* suppressFlyout=*/ false);
     }
 
     private void changeExpandedStateAtTime(boolean shouldBeExpanded, long time) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleFlyoutViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleFlyoutViewTest.java
index 173237f..a8961a8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleFlyoutViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleFlyoutViewTest.java
@@ -18,7 +18,6 @@
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotSame;
-import static junit.framework.Assert.assertTrue;
 
 import static org.mockito.Mockito.verify;
 
@@ -46,6 +45,7 @@
 public class BubbleFlyoutViewTest extends SysuiTestCase {
     private BubbleFlyoutView mFlyout;
     private TextView mFlyoutText;
+    private float[] mDotCenter = new float[2];
 
     @Before
     public void setUp() throws Exception {
@@ -53,20 +53,25 @@
         mFlyout = new BubbleFlyoutView(getContext());
 
         mFlyoutText = mFlyout.findViewById(R.id.bubble_flyout_text);
+        mDotCenter[0] = 30;
+        mDotCenter[1] = 30;
     }
 
     @Test
     public void testShowFlyout_isVisible() {
-        mFlyout.showFlyout("Hello", new PointF(100, 100), 500, true, Color.WHITE, null);
+        mFlyout.setupFlyoutStartingAsDot(
+                "Hello", new PointF(100, 100), 500, true, Color.WHITE, null, null, mDotCenter);
+        mFlyout.setVisibility(View.VISIBLE);
+
         assertEquals("Hello", mFlyoutText.getText());
         assertEquals(View.VISIBLE, mFlyout.getVisibility());
-        assertEquals(1f, mFlyoutText.getAlpha(), .01f);
     }
 
     @Test
     public void testFlyoutHide_runsCallback() {
         Runnable after = Mockito.mock(Runnable.class);
-        mFlyout.showFlyout("Hello", new PointF(100, 100), 500, true, Color.WHITE, after);
+        mFlyout.setupFlyoutStartingAsDot(
+                "Hello", new PointF(100, 100), 500, true, Color.WHITE, null, after, mDotCenter);
         mFlyout.hideFlyout();
 
         verify(after).run();
@@ -74,19 +79,16 @@
 
     @Test
     public void testSetCollapsePercent() {
-        mFlyout.showFlyout("Hello", new PointF(100, 100), 500, true, Color.WHITE, null);
-
-        float initialTranslationZ = mFlyout.getTranslationZ();
+        mFlyout.setupFlyoutStartingAsDot(
+                "Hello", new PointF(100, 100), 500, true, Color.WHITE, null, null, mDotCenter);
+        mFlyout.setVisibility(View.VISIBLE);
 
         mFlyout.setCollapsePercent(1f);
         assertEquals(0f, mFlyoutText.getAlpha(), 0.01f);
         assertNotSame(0f, mFlyoutText.getTranslationX()); // Should have moved to collapse.
-        assertTrue(mFlyout.getTranslationZ() < initialTranslationZ); // Should be descending.
 
         mFlyout.setCollapsePercent(0f);
         assertEquals(1f, mFlyoutText.getAlpha(), 0.01f);
         assertEquals(0f, mFlyoutText.getTranslationX());
-        assertEquals(initialTranslationZ, mFlyout.getTranslationZ());
-
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleTest.java
similarity index 83%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleTest.java
index cca9f28..e98662b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.notification.collection;
+package com.android.systemui.bubbles;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
@@ -23,6 +23,7 @@
 
 import android.app.Notification;
 import android.os.Bundle;
+import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -30,6 +31,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -40,13 +42,14 @@
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
-public class NotificationEntryTest extends SysuiTestCase {
+public class BubbleTest extends SysuiTestCase {
     @Mock
     private StatusBarNotification mStatusBarNotification;
     @Mock
     private Notification mNotif;
 
     private NotificationEntry mEntry;
+    private Bubble mBubble;
     private Bundle mExtras;
 
     @Before
@@ -55,11 +58,12 @@
 
         when(mStatusBarNotification.getKey()).thenReturn("key");
         when(mStatusBarNotification.getNotification()).thenReturn(mNotif);
-
+        when(mStatusBarNotification.getUser()).thenReturn(new UserHandle(0));
         mExtras = new Bundle();
         mNotif.extras = mExtras;
-
         mEntry = new NotificationEntry(mStatusBarNotification);
+
+        mBubble = new Bubble(mContext, mEntry);
     }
 
     @Test
@@ -67,7 +71,7 @@
         final String msg = "Hello there!";
         doReturn(Notification.Style.class).when(mNotif).getNotificationStyle();
         mExtras.putCharSequence(Notification.EXTRA_TEXT, msg);
-        assertEquals(msg, mEntry.getUpdateMessage(mContext));
+        assertEquals(msg, mBubble.getUpdateMessage(mContext));
     }
 
     @Test
@@ -78,7 +82,7 @@
         mExtras.putCharSequence(Notification.EXTRA_BIG_TEXT, msg);
 
         // Should be big text, not the small text.
-        assertEquals(msg, mEntry.getUpdateMessage(mContext));
+        assertEquals(msg, mBubble.getUpdateMessage(mContext));
     }
 
     @Test
@@ -86,7 +90,7 @@
         doReturn(Notification.MediaStyle.class).when(mNotif).getNotificationStyle();
 
         // Media notifs don't get update messages.
-        assertNull(mEntry.getUpdateMessage(mContext));
+        assertNull(mBubble.getUpdateMessage(mContext));
     }
 
     @Test
@@ -101,7 +105,7 @@
                         "Really? I prefer them that way."});
 
         // Should be the last one only.
-        assertEquals("Really? I prefer them that way.", mEntry.getUpdateMessage(mContext));
+        assertEquals("Really? I prefer them that way.", mBubble.getUpdateMessage(mContext));
     }
 
     @Test
@@ -116,6 +120,6 @@
                                 "Oh, hello!", 0, "Mady").toBundle()});
 
         // Should be the last one only.
-        assertEquals("Mady: Oh, hello!", mEntry.getUpdateMessage(mContext));
+        assertEquals("Mady: Oh, hello!", mBubble.getUpdateMessage(mContext));
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubblesTestActivity.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubblesTestActivity.java
index 43d2ad1..8bc2e2b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubblesTestActivity.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubblesTestActivity.java
@@ -20,7 +20,7 @@
 import android.content.Intent;
 import android.os.Bundle;
 
-import com.android.systemui.R;
+import com.android.systemui.tests.R;
 
 /**
  * Referenced by NotificationTestHelper#makeBubbleMetadata
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java
index b324235..1fbb443 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java
@@ -20,6 +20,7 @@
 import static org.junit.Assert.assertNotEquals;
 import static org.mockito.Mockito.verify;
 
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Point;
 import android.graphics.PointF;
@@ -45,14 +46,18 @@
 
     private int mDisplayWidth = 500;
     private int mDisplayHeight = 1000;
+    private int mExpandedViewPadding = 10;
+    private int mOrientation = Configuration.ORIENTATION_PORTRAIT;
+    private float mLauncherGridDiff = 30f;
 
     @Spy
     private ExpandedAnimationController mExpandedController =
             new ExpandedAnimationController(
                     new Point(mDisplayWidth, mDisplayHeight) /* displaySize */,
-                    0 /* expandedViewPadding */);
+                    mExpandedViewPadding, mOrientation);
+
     private int mStackOffset;
-    private float mBubblePadding;
+    private float mBubblePaddingTop;
     private float mBubbleSize;
 
     private PointF mExpansionPoint;
@@ -65,7 +70,7 @@
 
         Resources res = mLayout.getResources();
         mStackOffset = res.getDimensionPixelSize(R.dimen.bubble_stack_offset);
-        mBubblePadding = res.getDimensionPixelSize(R.dimen.bubble_padding);
+        mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
         mBubbleSize = res.getDimensionPixelSize(R.dimen.individual_bubble_size);
         mExpansionPoint = new PointF(100, 100);
     }
@@ -138,7 +143,6 @@
         assertEquals(500f, draggedBubble.getTranslationX(), 1f);
         assertEquals(500f, draggedBubble.getTranslationY(), 1f);
 
-        // Snap it back and make sure it made it back correctly.
         mLayout.removeView(draggedBubble);
         waitForLayoutMessageQueue();
         waitForPropertyAnimations(DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y);
@@ -174,7 +178,7 @@
 
         waitForPropertyAnimations(DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y);
 
-        assertEquals(mBubblePadding, mViews.get(1).getTranslationX(), 1f);
+        assertEquals(mBubblePaddingTop, mViews.get(1).getTranslationX(), 1f);
     }
 
     @Test
@@ -256,8 +260,8 @@
      * @return Bubble left x from left edge of screen.
      */
     public float getBubbleLeft(int index) {
-        float bubbleLeftFromRowLeft = index * (mBubbleSize + mBubblePadding);
-        return getRowLeft() + bubbleLeftFromRowLeft;
+        final float bubbleLeft = index * (mBubbleSize + getSpaceBetweenBubbles());
+        return getRowLeft() + bubbleLeft;
     }
 
     private float getRowLeft() {
@@ -265,16 +269,29 @@
             return 0;
         }
         int bubbleCount = mLayout.getChildCount();
+        final float totalBubbleWidth = bubbleCount * mBubbleSize;
+        final float totalGapWidth = (bubbleCount - 1) * getSpaceBetweenBubbles();
+        final float rowWidth = totalGapWidth + totalBubbleWidth;
 
-        // Width calculations.
-        double bubble = bubbleCount * mBubbleSize;
-        float gap = (bubbleCount - 1) * mBubblePadding;
-        float row = gap + (float) bubble;
+        final float centerScreen = mDisplayWidth / 2f;
+        final float halfRow = rowWidth / 2f;
+        final float rowLeft = centerScreen - halfRow;
 
-        float halfRow = row / 2f;
-        float centerScreen = mDisplayWidth / 2;
-        float rowLeftFromScreenLeft = centerScreen - halfRow;
+        return rowLeft;
+    }
 
-        return rowLeftFromScreenLeft;
+    /**
+     * @return Space between bubbles in row above expanded view.
+     */
+    private float getSpaceBetweenBubbles() {
+        final float rowMargins = (mExpandedViewPadding + mLauncherGridDiff) * 2;
+        final float maxRowWidth = mDisplayWidth - rowMargins;
+
+        final float totalBubbleWidth = mMaxBubbles * mBubbleSize;
+        final float totalGapWidth = maxRowWidth - totalBubbleWidth;
+
+        final int gapCount = mMaxBubbles - 1;
+        final float gapWidth = totalGapWidth / gapCount;
+        return gapWidth;
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java
index f8b32c2..86554b1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java
@@ -156,8 +156,8 @@
         });
 
         // Set end listeners for both x and y.
-        mLayout.setEndActionForProperty(xEndAction, DynamicAnimation.TRANSLATION_X);
-        mLayout.setEndActionForProperty(yEndAction, DynamicAnimation.TRANSLATION_Y);
+        mTestableController.setEndActionForProperty(xEndAction, DynamicAnimation.TRANSLATION_X);
+        mTestableController.setEndActionForProperty(yEndAction, DynamicAnimation.TRANSLATION_Y);
 
         // Animate x, and wait for it to finish.
         mTestableController.animationForChildAtIndex(0)
@@ -190,7 +190,7 @@
         });
 
         // Set the end listener.
-        mLayout.setEndActionForProperty(xEndListener, DynamicAnimation.TRANSLATION_X);
+        mTestableController.setEndActionForProperty(xEndListener, DynamicAnimation.TRANSLATION_X);
 
         // Animate x, and wait for it to finish.
         mTestableController.animationForChildAtIndex(0)
@@ -205,7 +205,7 @@
         mTestableController.animationForChildAtIndex(0)
                 .translationX(1000)
                 .start();
-        mLayout.removeEndActionForProperty(DynamicAnimation.TRANSLATION_X);
+        mTestableController.removeEndActionForProperty(DynamicAnimation.TRANSLATION_X);
         xLatch.await(1, TimeUnit.SECONDS);
 
         // Make sure the end listener was not called.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTestCase.java
index f633f39..a5f2e8b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTestCase.java
@@ -68,7 +68,7 @@
     @Mock
     private DisplayCutout mCutout;
 
-    private int mMaxBubbles;
+    protected int mMaxBubbles;
 
     @Before
     public void setUp() throws Exception {
@@ -195,14 +195,13 @@
         private void setTestEndActionForProperty(
                 Runnable action, DynamicAnimation.ViewProperty property) {
             final Runnable realEndAction = mEndActionForProperty.get(property);
-
-            setEndActionForProperty(() -> {
+            mLayout.mEndActionForProperty.put(property, () -> {
                 if (realEndAction != null) {
                     realEndAction.run();
                 }
 
                 action.run();
-            }, property);
+            });
         }
 
         /** PhysicsPropertyAnimator that posts its animations to the main thread. */
@@ -219,6 +218,11 @@
                         property, view, value, startVel, startDelay, stiffness, dampingRatio,
                         afterCallbacks));
             }
+
+            @Override
+            protected void startPathAnimation() {
+                mMainThreadHandler.post(super::startPathAnimation);
+            }
         }
 
         /**
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java
index 31a7d5a..d79128c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java
@@ -339,10 +339,10 @@
 
         @Override
         protected void springFirstBubbleWithStackFollowing(DynamicAnimation.ViewProperty property,
-                SpringForce spring, float vel, float finalPosition) {
+                SpringForce spring, float vel, float finalPosition, Runnable... after) {
             mMainThreadHandler.post(() ->
                     super.springFirstBubbleWithStackFollowing(
-                            property, spring, vel, finalPosition));
+                            property, spring, vel, finalPosition, after));
         }
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java
index 7ea6493..32cf842 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java
@@ -31,6 +31,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.brightline.BrightLineFalsingManager;
 import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.util.ProximitySensor;
 
 import org.junit.After;
 import org.junit.Before;
@@ -43,8 +44,10 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class FalsingManagerProxyTest extends SysuiTestCase {
-    @Mock
+    @Mock(stubOnly = true)
     PluginManager mPluginManager;
+    @Mock(stubOnly = true)
+    ProximitySensor mProximitySensor;
     private boolean mDefaultConfigValue;
     private Handler mHandler;
     private TestableLooper mTestableLooper;
@@ -69,7 +72,8 @@
 
     @Test
     public void test_brightLineFalsingManagerDisabled() {
-        FalsingManagerProxy proxy = new FalsingManagerProxy(getContext(), mPluginManager, mHandler);
+        FalsingManagerProxy proxy = new FalsingManagerProxy(
+                getContext(), mPluginManager, mHandler, mProximitySensor);
 
         assertThat(proxy.getInternalFalsingManager(), instanceOf(FalsingManagerImpl.class));
     }
@@ -78,14 +82,16 @@
     public void test_brightLineFalsingManagerEnabled() {
         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
                 BRIGHTLINE_FALSING_MANAGER_ENABLED, "true", false);
-        FalsingManagerProxy proxy = new FalsingManagerProxy(getContext(), mPluginManager, mHandler);
+        FalsingManagerProxy proxy = new FalsingManagerProxy(
+                getContext(), mPluginManager, mHandler, mProximitySensor);
 
         assertThat(proxy.getInternalFalsingManager(), instanceOf(BrightLineFalsingManager.class));
     }
 
     @Test
     public void test_brightLineFalsingManagerToggled() {
-        FalsingManagerProxy proxy = new FalsingManagerProxy(getContext(), mPluginManager, mHandler);
+        FalsingManagerProxy proxy = new FalsingManagerProxy(
+                getContext(), mPluginManager, mHandler, mProximitySensor);
         assertThat(proxy.getInternalFalsingManager(), instanceOf(FalsingManagerImpl.class));
 
         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java
index a6cabbf..49ba302 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java
@@ -23,24 +23,21 @@
 import static org.junit.Assert.assertThat;
 import static org.mockito.Mockito.when;
 
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.MotionEvent;
 
 import androidx.test.filters.SmallTest;
 
+import com.android.systemui.util.ProximitySensor;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
-import java.lang.reflect.Field;
-
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
@@ -78,8 +75,8 @@
     @Test
     public void testPass_mostlyUncovered() {
         touchDown();
-        mClassifier.onSensorEvent(createSensorEvent(true, 1));
-        mClassifier.onSensorEvent(createSensorEvent(false, 2));
+        mClassifier.onProximityEvent(createSensorEvent(true, 1));
+        mClassifier.onProximityEvent(createSensorEvent(false, 2));
         touchUp(20);
         assertThat(mClassifier.isFalseTouch(), is(false));
     }
@@ -88,8 +85,8 @@
     public void testPass_quickSettings() {
         touchDown();
         when(mDataProvider.getInteractionType()).thenReturn(QUICK_SETTINGS);
-        mClassifier.onSensorEvent(createSensorEvent(true, 1));
-        mClassifier.onSensorEvent(createSensorEvent(false, 11));
+        mClassifier.onProximityEvent(createSensorEvent(true, 1));
+        mClassifier.onProximityEvent(createSensorEvent(false, 11));
         touchUp(10);
         assertThat(mClassifier.isFalseTouch(), is(false));
     }
@@ -97,8 +94,8 @@
     @Test
     public void testFail_covered() {
         touchDown();
-        mClassifier.onSensorEvent(createSensorEvent(true, 1));
-        mClassifier.onSensorEvent(createSensorEvent(false, 11));
+        mClassifier.onProximityEvent(createSensorEvent(true, 1));
+        mClassifier.onProximityEvent(createSensorEvent(false, 11));
         touchUp(10);
         assertThat(mClassifier.isFalseTouch(), is(true));
     }
@@ -106,10 +103,10 @@
     @Test
     public void testFail_mostlyCovered() {
         touchDown();
-        mClassifier.onSensorEvent(createSensorEvent(true, 1));
-        mClassifier.onSensorEvent(createSensorEvent(true, 95));
-        mClassifier.onSensorEvent(createSensorEvent(true, 96));
-        mClassifier.onSensorEvent(createSensorEvent(false, 100));
+        mClassifier.onProximityEvent(createSensorEvent(true, 1));
+        mClassifier.onProximityEvent(createSensorEvent(true, 95));
+        mClassifier.onProximityEvent(createSensorEvent(true, 96));
+        mClassifier.onProximityEvent(createSensorEvent(false, 100));
         touchUp(100);
         assertThat(mClassifier.isFalseTouch(), is(true));
     }
@@ -117,8 +114,8 @@
     @Test
     public void testPass_coveredWithLongSwipe() {
         touchDown();
-        mClassifier.onSensorEvent(createSensorEvent(true, 1));
-        mClassifier.onSensorEvent(createSensorEvent(false, 11));
+        mClassifier.onProximityEvent(createSensorEvent(true, 1));
+        mClassifier.onProximityEvent(createSensorEvent(false, 11));
         touchUp(10);
         when(mDistanceClassifier.isLongSwipe()).thenReturn(true);
         assertThat(mClassifier.isFalseTouch(), is(false));
@@ -139,26 +136,7 @@
         motionEvent.recycle();
     }
 
-    private SensorEvent createSensorEvent(boolean covered, long timestampMs) {
-        SensorEvent sensorEvent = Mockito.mock(SensorEvent.class);
-        Sensor sensor = Mockito.mock(Sensor.class);
-        when(sensor.getType()).thenReturn(Sensor.TYPE_PROXIMITY);
-        when(sensor.getMaximumRange()).thenReturn(1f);
-        sensorEvent.sensor = sensor;
-        sensorEvent.timestamp = timestampMs * NS_PER_MS;
-        try {
-            Field valuesField = SensorEvent.class.getField("values");
-            valuesField.setAccessible(true);
-            float[] sensorValue = {covered ? 0 : 1};
-            try {
-                valuesField.set(sensorEvent, sensorValue);
-            } catch (IllegalAccessException e) {
-                e.printStackTrace();
-            }
-        } catch (NoSuchFieldException e) {
-            e.printStackTrace();
-        }
-
-        return sensorEvent;
+    private ProximitySensor.ProximityEvent createSensorEvent(boolean covered, long timestampMs) {
+        return new ProximitySensor.ProximityEvent(covered, timestampMs * NS_PER_MS);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
index 6dfb19e..1eb75aa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
@@ -45,11 +45,15 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.util.wakelock.WakeLockFake;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
@@ -58,6 +62,8 @@
 
     DozeMachine mMachine;
 
+    @Mock
+    private WakefulnessLifecycle mWakefulnessLifecycle;
     private DozeServiceFake mServiceFake;
     private WakeLockFake mWakeLockFake;
     private AmbientDisplayConfiguration mConfigMock;
@@ -65,13 +71,14 @@
 
     @Before
     public void setUp() {
+        MockitoAnnotations.initMocks(this);
         mServiceFake = new DozeServiceFake();
         mWakeLockFake = new WakeLockFake();
         mConfigMock = mock(AmbientDisplayConfiguration.class);
         mPartMock = mock(DozeMachine.Part.class);
 
-        mMachine = new DozeMachine(mServiceFake, mConfigMock, mWakeLockFake);
-
+        mMachine = new DozeMachine(mServiceFake, mConfigMock, mWakeLockFake,
+                mWakefulnessLifecycle, mock(BatteryController.class));
         mMachine.setParts(new DozeMachine.Part[]{mPartMock});
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt
new file mode 100644
index 0000000..b51e716
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2019 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.qs.tiles
+
+import android.content.Context
+import android.content.pm.UserInfo
+import android.graphics.Bitmap
+import android.testing.AndroidTestingRunner
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.policy.UserSwitcherController
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mock
+import org.mockito.Mockito.`when`
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class UserDetailViewAdapterTest : SysuiTestCase() {
+
+    @Mock private lateinit var mUserSwitcherController: UserSwitcherController
+    @Mock private lateinit var mParent: ViewGroup
+    @Mock private lateinit var mUserDetailItemView: UserDetailItemView
+    @Mock private lateinit var mOtherView: View
+    @Mock private lateinit var mInflatedUserDetailItemView: UserDetailItemView
+    @Mock private lateinit var mUserInfo: UserInfo
+    @Mock private lateinit var mPicture: Bitmap
+    @Mock private lateinit var mLayoutInflater: LayoutInflater
+    private lateinit var adapter: UserDetailView.Adapter
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        mContext.addMockSystemService(Context.LAYOUT_INFLATER_SERVICE, mLayoutInflater)
+        `when`(mLayoutInflater.inflate(anyInt(), any(ViewGroup::class.java), anyBoolean()))
+                .thenReturn(mInflatedUserDetailItemView)
+        adapter = UserDetailView.Adapter(mContext, mUserSwitcherController)
+    }
+
+    private fun clickableTest(
+        current: Boolean,
+        guest: Boolean,
+        convertView: View,
+        shouldBeClickable: Boolean
+    ) {
+        val user = createUserRecord(current, guest)
+        val v = adapter.createUserDetailItemView(convertView, mParent, user)
+        if (shouldBeClickable) {
+            verify(v).setOnClickListener(adapter)
+        } else {
+            verify(v).setOnClickListener(null)
+        }
+    }
+
+    @Test
+    fun testGuestIsClickable_differentViews_notCurrent() {
+        clickableTest(false, true, mOtherView, true)
+    }
+
+    @Test
+    fun testGuestIsClickable_differentViews_Current() {
+        clickableTest(true, true, mOtherView, true)
+    }
+
+    @Test
+    fun testGuestIsClickable_sameView_notCurrent() {
+        clickableTest(false, true, mUserDetailItemView, true)
+    }
+
+    @Test
+    fun testGuestIsClickable_sameView_Current() {
+        clickableTest(true, true, mUserDetailItemView, true)
+    }
+
+    @Test
+    fun testNotGuestCurrentUserIsNotClickable_otherView() {
+        clickableTest(true, false, mOtherView, false)
+    }
+
+    @Test
+    fun testNotGuestCurrentUserIsNotClickable_sameView() {
+        clickableTest(true, false, mUserDetailItemView, false)
+    }
+
+    @Test
+    fun testNotGuestNotCurrentUserIsClickable_otherView() {
+        clickableTest(false, false, mOtherView, true)
+    }
+
+    @Test
+    fun testNotGuestNotCurrentUserIsClickable_sameView() {
+        clickableTest(false, false, mUserDetailItemView, true)
+    }
+
+    private fun createUserRecord(current: Boolean, guest: Boolean) =
+            UserSwitcherController.UserRecord(
+                    mUserInfo,
+                    mPicture,
+                    guest,
+                    current,
+                    false /* isAddUser */,
+                    false /* isRestricted */,
+                    true /* isSwitchToEnabled */)
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotStubActivity.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotStubActivity.java
index 784d035..0b871e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotStubActivity.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotStubActivity.java
@@ -15,11 +15,11 @@
  */
 package com.android.systemui.screenshot;
 
-import com.android.systemui.R;
-
 import android.app.Activity;
 import android.os.Bundle;
 
+import com.android.systemui.tests.R;
+
 /**
  * A stub activity used in {@link ScreenshotTest}.
  */
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInterruptionStateProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInterruptionStateProviderTest.java
new file mode 100644
index 0000000..0db1f68
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInterruptionStateProviderTest.java
@@ -0,0 +1,593 @@
+/*
+ * Copyright (C) 2019 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.statusbar;
+
+
+import static android.app.Notification.FLAG_BUBBLE;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
+
+import static com.android.systemui.statusbar.StatusBarState.SHADE;
+
+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.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.Icon;
+import android.hardware.display.AmbientDisplayConfiguration;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.service.dreams.IDreamManager;
+import android.service.notification.StatusBarNotification;
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.notification.NotificationFilter;
+import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for the interruption state provider which understands whether the system & notification
+ * is in a state allowing a particular notification to hun, pulse, or bubble.
+ */
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class NotificationInterruptionStateProviderTest extends SysuiTestCase {
+
+    @Mock
+    PowerManager mPowerManager;
+    @Mock
+    IDreamManager mDreamManager;
+    @Mock
+    AmbientDisplayConfiguration mAmbientDisplayConfiguration;
+    @Mock
+    NotificationFilter mNotificationFilter;
+    @Mock
+    StatusBarStateController mStatusBarStateController;
+    @Mock
+    NotificationPresenter mPresenter;
+    @Mock
+    HeadsUpManager mHeadsUpManager;
+    @Mock
+    NotificationInterruptionStateProvider.HeadsUpSuppressor mHeadsUpSuppressor;
+    @Mock
+    BatteryController mBatteryController;
+
+    private NotificationInterruptionStateProvider mNotifInterruptionStateProvider;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+
+        mNotifInterruptionStateProvider =
+                new TestableNotificationInterruptionStateProvider(mContext,
+                        mPowerManager,
+                        mDreamManager,
+                        mAmbientDisplayConfiguration,
+                        mNotificationFilter,
+                        mStatusBarStateController,
+                        mBatteryController);
+
+        mNotifInterruptionStateProvider.setUpWithPresenter(
+                mPresenter,
+                mHeadsUpManager,
+                mHeadsUpSuppressor);
+    }
+
+    /**
+     * Sets up the state such that any requests to
+     * {@link NotificationInterruptionStateProvider#canAlertCommon(NotificationEntry)} will
+     * pass as long its provided NotificationEntry fulfills group suppression check.
+     */
+    private void ensureStateForAlertCommon() {
+        when(mNotificationFilter.shouldFilterOut(any())).thenReturn(false);
+    }
+
+    /**
+     * Sets up the state such that any requests to
+     * {@link NotificationInterruptionStateProvider#canAlertAwakeCommon(NotificationEntry)} will
+     * pass as long its provided NotificationEntry fulfills launch fullscreen check.
+     */
+    private void ensureStateForAlertAwakeCommon() {
+        when(mPresenter.isDeviceInVrMode()).thenReturn(false);
+        when(mHeadsUpManager.isSnoozed(any())).thenReturn(false);
+    }
+
+    /**
+     * Sets up the state such that any requests to
+     * {@link NotificationInterruptionStateProvider#shouldHeadsUp(NotificationEntry)} will
+     * pass as long its provided NotificationEntry fulfills importance & DND checks.
+     */
+    private void ensureStateForHeadsUpWhenAwake() throws RemoteException {
+        ensureStateForAlertCommon();
+        ensureStateForAlertAwakeCommon();
+
+        when(mStatusBarStateController.isDozing()).thenReturn(false);
+        when(mDreamManager.isDreaming()).thenReturn(false);
+        when(mPowerManager.isScreenOn()).thenReturn(true);
+        when(mHeadsUpSuppressor.canHeadsUp(any(), any())).thenReturn(true);
+    }
+
+    /**
+     * Sets up the state such that any requests to
+     * {@link NotificationInterruptionStateProvider#shouldHeadsUp(NotificationEntry)} will
+     * pass as long its provided NotificationEntry fulfills importance & DND checks.
+     */
+    private void ensureStateForHeadsUpWhenDozing() {
+        ensureStateForAlertCommon();
+
+        when(mStatusBarStateController.isDozing()).thenReturn(true);
+        when(mAmbientDisplayConfiguration.pulseOnNotificationEnabled(anyInt())).thenReturn(true);
+    }
+
+    /**
+     * Sets up the state such that any requests to
+     * {@link NotificationInterruptionStateProvider#shouldBubbleUp(NotificationEntry)} will
+     * pass as long its provided NotificationEntry fulfills importance & bubble checks.
+     */
+    private void ensureStateForBubbleUp() {
+        ensureStateForAlertCommon();
+        ensureStateForAlertAwakeCommon();
+    }
+
+    /**
+     * Ensure that the disabled state is set correctly.
+     */
+    @Test
+    public void testDisableNotificationAlerts() {
+        // Enabled by default
+        assertThat(mNotifInterruptionStateProvider.areNotificationAlertsDisabled()).isFalse();
+
+        // Disable alerts
+        mNotifInterruptionStateProvider.setDisableNotificationAlerts(true);
+        assertThat(mNotifInterruptionStateProvider.areNotificationAlertsDisabled()).isTrue();
+
+        // Enable alerts
+        mNotifInterruptionStateProvider.setDisableNotificationAlerts(false);
+        assertThat(mNotifInterruptionStateProvider.areNotificationAlertsDisabled()).isFalse();
+    }
+
+    /**
+     * Ensure that the disabled alert state effects whether HUNs are enabled.
+     */
+    @Test
+    public void testHunSettingsChange_enabled_butAlertsDisabled() {
+        // Set up but without a mock change observer
+        mNotifInterruptionStateProvider.setUpWithPresenter(
+                mPresenter,
+                mHeadsUpManager,
+                mHeadsUpSuppressor);
+
+        // HUNs enabled by default
+        assertThat(mNotifInterruptionStateProvider.getUseHeadsUp()).isTrue();
+
+        // Set alerts disabled
+        mNotifInterruptionStateProvider.setDisableNotificationAlerts(true);
+
+        // No more HUNs
+        assertThat(mNotifInterruptionStateProvider.getUseHeadsUp()).isFalse();
+    }
+
+    /**
+     * Alerts can happen.
+     */
+    @Test
+    public void testCanAlertCommon_true() {
+        ensureStateForAlertCommon();
+
+        NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
+        assertThat(mNotifInterruptionStateProvider.canAlertCommon(entry)).isTrue();
+    }
+
+    /**
+     * Filtered out notifications don't alert.
+     */
+    @Test
+    public void testCanAlertCommon_false_filteredOut() {
+        ensureStateForAlertCommon();
+        when(mNotificationFilter.shouldFilterOut(any())).thenReturn(true);
+
+        NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
+        assertThat(mNotifInterruptionStateProvider.canAlertCommon(entry)).isFalse();
+    }
+
+    /**
+     * Grouped notifications have different alerting behaviours, sometimes the alert for a
+     * grouped notification may be suppressed {@link android.app.Notification#GROUP_ALERT_CHILDREN}.
+     */
+    @Test
+    public void testCanAlertCommon_false_suppressedForGroups() {
+        ensureStateForAlertCommon();
+
+        Notification n = new Notification.Builder(getContext(), "a")
+                .setGroup("a")
+                .setGroupSummary(true)
+                .setGroupAlertBehavior(Notification.GROUP_ALERT_CHILDREN)
+                .build();
+        StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
+                UserHandle.of(0), null, 0);
+        NotificationEntry entry = new NotificationEntry(sbn);
+        entry.importance = IMPORTANCE_DEFAULT;
+
+        assertThat(mNotifInterruptionStateProvider.canAlertCommon(entry)).isFalse();
+    }
+
+    /**
+     * HUNs while dozing can happen.
+     */
+    @Test
+    public void testShouldHeadsUpWhenDozing_true() {
+        ensureStateForHeadsUpWhenDozing();
+
+        NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
+        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isTrue();
+    }
+
+    /**
+     * Ambient display can show HUNs for new notifications, this may be disabled.
+     */
+    @Test
+    public void testShouldHeadsUpWhenDozing_false_pulseDisabled() {
+        ensureStateForHeadsUpWhenDozing();
+        when(mAmbientDisplayConfiguration.pulseOnNotificationEnabled(anyInt())).thenReturn(false);
+
+        NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
+        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
+    }
+
+    /**
+     * If the device is not in ambient display or sleeping then we don't HUN.
+     */
+    @Test
+    public void testShouldHeadsUpWhenDozing_false_notDozing() {
+        ensureStateForHeadsUpWhenDozing();
+        when(mStatusBarStateController.isDozing()).thenReturn(false);
+
+        NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
+        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
+    }
+
+    /**
+     * In DND ambient effects can be suppressed
+     * {@link android.app.NotificationManager.Policy#SUPPRESSED_EFFECT_AMBIENT}.
+     */
+    @Test
+    public void testShouldHeadsUpWhenDozing_false_suppressingAmbient() {
+        ensureStateForHeadsUpWhenDozing();
+
+        NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
+        entry.suppressedVisualEffects = SUPPRESSED_EFFECT_AMBIENT;
+
+        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
+    }
+
+    /**
+     * Notifications that are < {@link android.app.NotificationManager#IMPORTANCE_DEFAULT} don't
+     * get to pulse.
+     */
+    @Test
+    public void testShouldHeadsUpWhenDozing_false_lessImportant() {
+        ensureStateForHeadsUpWhenDozing();
+
+        NotificationEntry entry = createNotification(IMPORTANCE_LOW);
+        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
+    }
+
+    /**
+     * Heads up can happen.
+     */
+    @Test
+    public void testShouldHeadsUp_true() throws RemoteException {
+        ensureStateForHeadsUpWhenAwake();
+
+        NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
+        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isTrue();
+    }
+
+    /**
+     * Heads up notifications can be disabled in general.
+     */
+    @Test
+    public void testShouldHeadsUp_false_noHunsAllowed() throws RemoteException {
+        ensureStateForHeadsUpWhenAwake();
+
+        // Set alerts disabled, this should cause heads up to be false
+        mNotifInterruptionStateProvider.setDisableNotificationAlerts(true);
+        assertThat(mNotifInterruptionStateProvider.getUseHeadsUp()).isFalse();
+
+        NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
+        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
+    }
+
+    /**
+     * If the device is dozing, we don't show as heads up.
+     */
+    @Test
+    public void testShouldHeadsUp_false_dozing() throws RemoteException {
+        ensureStateForHeadsUpWhenAwake();
+        when(mStatusBarStateController.isDozing()).thenReturn(true);
+
+        NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
+        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
+    }
+
+    /**
+     * If the notification is a bubble, and the user is not on AOD / lockscreen, then
+     * the bubble is shown rather than the heads up.
+     */
+    @Test
+    public void testShouldHeadsUp_false_bubble() throws RemoteException {
+        ensureStateForHeadsUpWhenAwake();
+
+        // Bubble bit only applies to interruption when we're in the shade
+        when(mStatusBarStateController.getState()).thenReturn(SHADE);
+
+        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(createBubble())).isFalse();
+    }
+
+    /**
+     * If we're not allowed to alert in general, we shouldn't be shown as heads up.
+     */
+    @Test
+    public void testShouldHeadsUp_false_alertCommonFalse() throws RemoteException {
+        ensureStateForHeadsUpWhenAwake();
+        // Make canAlertCommon false by saying it's filtered out
+        when(mNotificationFilter.shouldFilterOut(any())).thenReturn(true);
+
+        NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
+        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
+    }
+
+    /**
+     * In DND HUN peek effects can be suppressed
+     * {@link android.app.NotificationManager.Policy#SUPPRESSED_EFFECT_PEEK}.
+     */
+    @Test
+    public void testShouldHeadsUp_false_suppressPeek() throws RemoteException {
+        ensureStateForHeadsUpWhenAwake();
+
+        NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
+        entry.suppressedVisualEffects = SUPPRESSED_EFFECT_PEEK;
+
+        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
+    }
+
+    /**
+     * Notifications that are < {@link android.app.NotificationManager#IMPORTANCE_HIGH} don't get
+     * to show as a heads up.
+     */
+    @Test
+    public void testShouldHeadsUp_false_lessImportant() throws RemoteException {
+        ensureStateForHeadsUpWhenAwake();
+
+        NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
+        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
+    }
+
+    /**
+     * If the device is not in use then we shouldn't be shown as heads up.
+     */
+    @Test
+    public void testShouldHeadsUp_false_deviceNotInUse() throws RemoteException {
+        ensureStateForHeadsUpWhenAwake();
+        NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
+
+        // Device is not in use if screen is not on
+        when(mPowerManager.isScreenOn()).thenReturn(false);
+        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
+
+        // Also not in use if screen is on but we're showing screen saver / "dreaming"
+        when(mPowerManager.isDeviceIdleMode()).thenReturn(true);
+        when(mDreamManager.isDreaming()).thenReturn(true);
+        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
+    }
+
+    /**
+     * If something wants to suppress this heads up, then it shouldn't be shown as a heads up.
+     */
+    @Test
+    public void testShouldHeadsUp_false_suppressed() throws RemoteException {
+        ensureStateForHeadsUpWhenAwake();
+        when(mHeadsUpSuppressor.canHeadsUp(any(), any())).thenReturn(false);
+
+        NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
+        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
+        verify(mHeadsUpSuppressor).canHeadsUp(any(), any());
+    }
+
+    /**
+     * On screen alerts don't happen when the device is in VR Mode.
+     */
+    @Test
+    public void testCanAlertAwakeCommon__false_vrMode() {
+        ensureStateForAlertAwakeCommon();
+        when(mPresenter.isDeviceInVrMode()).thenReturn(true);
+
+        NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
+        assertThat(mNotifInterruptionStateProvider.canAlertAwakeCommon(entry)).isFalse();
+    }
+
+    /**
+     * On screen alerts don't happen when the notification is snoozed.
+     */
+    @Test
+    public void testCanAlertAwakeCommon_false_snoozedPackage() {
+        ensureStateForAlertAwakeCommon();
+        when(mHeadsUpManager.isSnoozed(any())).thenReturn(true);
+
+        NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
+        assertThat(mNotifInterruptionStateProvider.canAlertAwakeCommon(entry)).isFalse();
+    }
+
+    /**
+     * On screen alerts don't happen when that package has just launched fullscreen.
+     */
+    @Test
+    public void testCanAlertAwakeCommon_false_justLaunchedFullscreen() {
+        ensureStateForAlertAwakeCommon();
+
+        NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT);
+        entry.notifyFullScreenIntentLaunched();
+
+        assertThat(mNotifInterruptionStateProvider.canAlertAwakeCommon(entry)).isFalse();
+    }
+
+    /**
+     * Bubbles can happen.
+     */
+    @Test
+    public void testShouldBubbleUp_true() {
+        ensureStateForBubbleUp();
+        assertThat(mNotifInterruptionStateProvider.shouldBubbleUp(createBubble())).isTrue();
+    }
+
+    /**
+     * If the notification doesn't have permission to bubble, it shouldn't bubble.
+     */
+    @Test
+    public void shouldBubbleUp_false_notAllowedToBubble() {
+        ensureStateForBubbleUp();
+
+        NotificationEntry entry = createBubble();
+        entry.canBubble = false;
+
+        assertThat(mNotifInterruptionStateProvider.shouldBubbleUp(entry)).isFalse();
+    }
+
+    /**
+     * If the notification isn't a bubble, it should definitely not show as a bubble.
+     */
+    @Test
+    public void shouldBubbleUp_false_notABubble() {
+        ensureStateForBubbleUp();
+
+        NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
+        entry.canBubble = true;
+
+        assertThat(mNotifInterruptionStateProvider.shouldBubbleUp(entry)).isFalse();
+    }
+
+    /**
+     * If the notification doesn't have bubble metadata, it shouldn't bubble.
+     */
+    @Test
+    public void shouldBubbleUp_false_invalidMetadata() {
+        ensureStateForBubbleUp();
+
+        NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
+        entry.canBubble = true;
+        entry.notification.getNotification().flags |= FLAG_BUBBLE;
+
+        assertThat(mNotifInterruptionStateProvider.shouldBubbleUp(entry)).isFalse();
+    }
+
+    /**
+     * If the notification can't heads up in general, it shouldn't bubble.
+     */
+    @Test
+    public void shouldBubbleUp_false_alertAwakeCommonFalse() {
+        ensureStateForBubbleUp();
+
+        // Make alert common return false by pretending we're in VR mode
+        when(mPresenter.isDeviceInVrMode()).thenReturn(true);
+
+        assertThat(mNotifInterruptionStateProvider.shouldBubbleUp(createBubble())).isFalse();
+    }
+
+    /**
+     * If the notification can't heads up in general, it shouldn't bubble.
+     */
+    @Test
+    public void shouldBubbleUp_false_alertCommonFalse() {
+        ensureStateForBubbleUp();
+
+        // Make canAlertCommon false by saying it's filtered out
+        when(mNotificationFilter.shouldFilterOut(any())).thenReturn(true);
+
+        assertThat(mNotifInterruptionStateProvider.shouldBubbleUp(createBubble())).isFalse();
+    }
+
+    private NotificationEntry createBubble() {
+        Notification.BubbleMetadata data = new Notification.BubbleMetadata.Builder()
+                .setIntent(PendingIntent.getActivity(mContext, 0, new Intent(), 0))
+                .setIcon(Icon.createWithResource(mContext.getResources(), R.drawable.android))
+                .build();
+        Notification n = new Notification.Builder(getContext(), "a")
+                .setContentTitle("title")
+                .setContentText("content text")
+                .setBubbleMetadata(data)
+                .build();
+        StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
+                UserHandle.of(0), null, 0);
+        NotificationEntry entry = new NotificationEntry(sbn);
+        entry.notification.getNotification().flags |= FLAG_BUBBLE;
+        entry.importance = IMPORTANCE_HIGH;
+        entry.canBubble = true;
+        return entry;
+    }
+
+    private NotificationEntry createNotification(int importance) {
+        Notification n = new Notification.Builder(getContext(), "a")
+                .setContentTitle("title")
+                .setContentText("content text")
+                .build();
+        StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
+                UserHandle.of(0), null, 0);
+        NotificationEntry entry = new NotificationEntry(sbn);
+        entry.importance = importance;
+        return entry;
+    }
+
+    /**
+     * Testable class overriding constructor.
+     */
+    public static class TestableNotificationInterruptionStateProvider extends
+            NotificationInterruptionStateProvider {
+
+        TestableNotificationInterruptionStateProvider(Context context,
+                PowerManager powerManager, IDreamManager dreamManager,
+                AmbientDisplayConfiguration ambientDisplayConfiguration,
+                NotificationFilter notificationFilter,
+                StatusBarStateController statusBarStateController,
+                BatteryController batteryController) {
+            super(context, powerManager, dreamManager, ambientDisplayConfiguration,
+                    notificationFilter, batteryController, statusBarStateController);
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
index 7063ddf..ab207f8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -40,7 +40,6 @@
 
 import androidx.test.InstrumentationRegistry;
 
-import com.android.systemui.R;
 import com.android.systemui.bubbles.BubblesTestActivity;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -50,7 +49,7 @@
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.tests.R;
 
 /**
  * A helper class to create {@link ExpandableNotificationRow} (for both individual and group
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
index 58fb53a..0248dc5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -41,7 +41,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.InitController;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.bubbles.BubbleData;
+import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -110,8 +110,9 @@
         mViewHierarchyManager = new NotificationViewHierarchyManager(mContext,
                 mHandler, mLockscreenUserManager, mGroupManager, mVisualStabilityManager,
                 mock(StatusBarStateControllerImpl.class), mEntryManager,
-                () -> mShadeController, new BubbleData(mContext),
+                () -> mShadeController,
                 mock(KeyguardBypassController.class),
+                mock(BubbleController.class),
                 mock(DynamicPrivacyController.class));
         Dependency.get(InitController.class).executePostInitTasks();
         mViewHierarchyManager.setUpWithPresenter(mPresenter, mListContainer);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/MediaNotificationProcessorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/MediaNotificationProcessorTest.java
index 7eeae67..e6287e7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/MediaNotificationProcessorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/MediaNotificationProcessorTest.java
@@ -38,8 +38,8 @@
 import androidx.palette.graphics.Palette;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.tests.R;
 
 import org.junit.After;
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
index 2ec125e..ccadcc3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
@@ -23,7 +23,6 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
@@ -44,12 +43,12 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.InflationTask;
 import com.android.systemui.statusbar.NotificationTestHelper;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationCallback;
+import com.android.systemui.tests.R;
 
 import org.junit.Assert;
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapperTest.java
index 63e18ce..49a6410 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapperTest.java
@@ -24,10 +24,10 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.NotificationTestHelper;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.tests.R;
 
 import org.junit.Assert;
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index c851c91..31054260 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -53,6 +53,7 @@
 import com.android.systemui.InitController;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.EmptyShadeView;
@@ -80,7 +81,6 @@
 import com.android.systemui.statusbar.policy.ConfigurationController;
 
 import org.junit.After;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -165,7 +165,8 @@
                 mock(ActivityStarterDelegate.class),
                 mock(SysuiStatusBarStateController.class),
                 mHeadsUpManager,
-                mKeyguardBypassController);
+                mKeyguardBypassController,
+                new FalsingManagerFake());
         mStackScroller = spy(mStackScrollerInternal);
         mStackScroller.setShelf(notificationShelf);
         mStackScroller.setStatusBar(mBar);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
index b24c3dd..06a2eec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
@@ -40,6 +40,7 @@
 
 import com.android.systemui.SwipeHelper;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -76,7 +77,8 @@
     public void setUp() throws Exception {
         mCallback = mock(NotificationSwipeHelper.NotificationCallback.class);
         mListener = mock(NotificationMenuRowPlugin.OnMenuEventListener.class);
-        mSwipeHelper = spy(new NotificationSwipeHelper(SwipeHelper.X, mCallback, mContext, mListener));
+        mSwipeHelper = spy(new NotificationSwipeHelper(
+                SwipeHelper.X, mCallback, mContext, mListener, new FalsingManagerFake()));
         mView = mock(View.class);
         mEvent = mock(MotionEvent.class);
         mMenuRow = mock(NotificationMenuRowPlugin.class);
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 d14b460..f94779d 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
@@ -21,21 +21,26 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.StatusBarManager;
+import android.hardware.biometrics.BiometricSourceType;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.MotionEvent;
+import android.view.View;
 import android.view.ViewGroup;
 
 import androidx.test.filters.SmallTest;
 
 import com.android.keyguard.KeyguardStatusView;
+import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.KeyguardAffordanceView;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -49,7 +54,6 @@
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ZenModeController;
-import com.android.systemui.tuner.TunerService;
 import com.android.systemui.util.InjectionInflationController;
 
 import org.junit.Before;
@@ -98,6 +102,12 @@
     private PanelBar mPanelBar;
     @Mock
     private KeyguardAffordanceHelper mAffordanceHelper;
+    @Mock
+    private KeyguardUpdateMonitor mUpdateMonitor;
+    @Mock
+    private FalsingManager mFalsingManager;
+    @Mock
+    private KeyguardBypassController mKeyguardBypassController;
     private NotificationPanelView mNotificationPanelView;
 
     @Before
@@ -112,18 +122,16 @@
         mDependency.injectMockDependency(NotificationLockscreenUserManager.class);
         mDependency.injectMockDependency(ConfigurationController.class);
         mDependency.injectMockDependency(ZenModeController.class);
-        KeyguardBypassController bypassController = new KeyguardBypassController(mContext,
-                mock(TunerService.class), mStatusBarStateController,
-                mock(NotificationLockscreenUserManager.class));
         NotificationWakeUpCoordinator coordinator =
                 new NotificationWakeUpCoordinator(mContext,
                         mock(HeadsUpManagerPhone.class),
                         new StatusBarStateControllerImpl(),
-                        bypassController);
+                        mKeyguardBypassController);
         PulseExpansionHandler expansionHandler = new PulseExpansionHandler(mContext, coordinator,
-                bypassController, mHeadsUpManager, mock(NotificationRoundnessManager.class));
+                mKeyguardBypassController, mHeadsUpManager,
+                mock(NotificationRoundnessManager.class), mStatusBarStateController);
         mNotificationPanelView = new TestableNotificationPanelView(coordinator, expansionHandler,
-                bypassController);
+                mKeyguardBypassController);
         mNotificationPanelView.setHeadsUpManager(mHeadsUpManager);
         mNotificationPanelView.setBar(mPanelBar);
 
@@ -183,6 +191,20 @@
         assertThat(mNotificationPanelView.isTrackingBlocked()).isFalse();
     }
 
+    @Test
+    public void testKeyguardStatusBarVisibility_hiddenForBypass() {
+        when(mUpdateMonitor.shouldListenForFace()).thenReturn(true);
+        mNotificationPanelView.mKeyguardUpdateCallback.onBiometricRunningStateChanged(true,
+                BiometricSourceType.FACE);
+        verify(mKeyguardStatusBar, never()).setVisibility(View.VISIBLE);
+
+        when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
+        mNotificationPanelView.mKeyguardUpdateCallback.onFinishedGoingToSleep(0);
+        mNotificationPanelView.mKeyguardUpdateCallback.onBiometricRunningStateChanged(true,
+                BiometricSourceType.FACE);
+        verify(mKeyguardStatusBar, never()).setVisibility(View.VISIBLE);
+    }
+
     private class TestableNotificationPanelView extends NotificationPanelView {
         TestableNotificationPanelView(NotificationWakeUpCoordinator coordinator,
                 PulseExpansionHandler expansionHandler,
@@ -191,7 +213,8 @@
                     new InjectionInflationController(
                             SystemUIFactory.getInstance().getRootComponent()),
                     coordinator, expansionHandler, mock(DynamicPrivacyController.class),
-                    bypassController);
+                    bypassController,
+                    mFalsingManager);
             mNotificationStackScroller = mNotificationStackScrollLayout;
             mKeyguardStatusView = NotificationPanelViewTest.this.mKeyguardStatusView;
             mKeyguardStatusBar = NotificationPanelViewTest.this.mKeyguardStatusBar;
@@ -199,6 +222,7 @@
             mBigClockContainer = NotificationPanelViewTest.this.mBigClockContainer;
             mQsFrame = NotificationPanelViewTest.this.mQsFrame;
             mAffordanceHelper = NotificationPanelViewTest.this.mAffordanceHelper;
+            mUpdateMonitor = NotificationPanelViewTest.this.mUpdateMonitor;
             initDependencies(NotificationPanelViewTest.this.mStatusBar,
                     NotificationPanelViewTest.this.mGroupManager,
                     NotificationPanelViewTest.this.mNotificationShelf,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 97ad47e..d4ad4b6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -16,9 +16,9 @@
 
 package com.android.systemui.statusbar.phone;
 
-import static com.android.systemui.statusbar.phone.ScrimController.VISIBILITY_FULLY_OPAQUE;
-import static com.android.systemui.statusbar.phone.ScrimController.VISIBILITY_FULLY_TRANSPARENT;
-import static com.android.systemui.statusbar.phone.ScrimController.VISIBILITY_SEMI_TRANSPARENT;
+import static com.android.systemui.statusbar.phone.ScrimController.OPAQUE;
+import static com.android.systemui.statusbar.phone.ScrimController.SEMI_TRANSPARENT;
+import static com.android.systemui.statusbar.phone.ScrimController.TRANSPARENT;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -69,6 +69,7 @@
     private SynchronousScrimController mScrimController;
     private ScrimView mScrimBehind;
     private ScrimView mScrimInFront;
+    private ScrimView mScrimForBubble;
     private ScrimState mScrimState;
     private float mScrimBehindAlpha;
     private GradientColors mScrimInFrontColor;
@@ -84,6 +85,7 @@
     public void setup() {
         mScrimBehind = spy(new ScrimView(getContext()));
         mScrimInFront = new ScrimView(getContext());
+        mScrimForBubble = new ScrimView(getContext());
         mWakeLock = mock(WakeLock.class);
         mAlarmManager = mock(AlarmManager.class);
         mAlwaysOnEnabled = true;
@@ -92,6 +94,7 @@
         when(mDozeParamenters.getAlwaysOn()).thenAnswer(invocation -> mAlwaysOnEnabled);
         when(mDozeParamenters.getDisplayNeedsBlanking()).thenReturn(true);
         mScrimController = new SynchronousScrimController(mScrimBehind, mScrimInFront,
+                mScrimForBubble,
                 (scrimState, scrimBehindAlpha, scrimInFrontColor) -> {
                     mScrimState = scrimState;
                     mScrimBehindAlpha = scrimBehindAlpha;
@@ -114,21 +117,28 @@
     public void transitionToKeyguard() {
         mScrimController.transitionTo(ScrimState.KEYGUARD);
         mScrimController.finishAnimationsImmediately();
-        // Front scrim should be transparent
-        // Back scrim should be visible without tint
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT);
-        assertScrimTint(mScrimBehind, true /* tinted */);
+
+        assertScrimAlpha(TRANSPARENT /* front */,
+                SEMI_TRANSPARENT /* back */,
+                TRANSPARENT /* bubble */);
+
+        assertScrimTint(true /* front */,
+                true /* behind */,
+                false /* bubble */);
     }
 
     @Test
     public void transitionToAod_withRegularWallpaper() {
         mScrimController.transitionTo(ScrimState.AOD);
         mScrimController.finishAnimationsImmediately();
-        // Front scrim should be transparent
-        // Back scrim should be visible with tint
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
-        assertScrimTint(mScrimBehind, true /* tinted */);
-        assertScrimTint(mScrimInFront, true /* tinted */);
+
+        assertScrimAlpha(TRANSPARENT /* front */,
+                OPAQUE /* back */,
+                TRANSPARENT /* bubble */);
+
+        assertScrimTint(true /* front */,
+                true /* behind */,
+                false /* bubble */);
     }
 
     @Test
@@ -136,14 +146,18 @@
         mScrimController.setWallpaperSupportsAmbientMode(true);
         mScrimController.transitionTo(ScrimState.AOD);
         mScrimController.finishAnimationsImmediately();
-        // Front scrim should be transparent
-        // Back scrim should be transparent
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
+
+        assertScrimAlpha(TRANSPARENT /* front */,
+                TRANSPARENT /* back */,
+                TRANSPARENT /* bubble */);
 
         // Pulsing notification should conserve AOD wallpaper.
         mScrimController.transitionTo(ScrimState.PULSING);
         mScrimController.finishAnimationsImmediately();
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
+
+        assertScrimAlpha(TRANSPARENT /* front */,
+                TRANSPARENT /* back */,
+                TRANSPARENT /* bubble */);
     }
 
     @Test
@@ -152,11 +166,14 @@
         mScrimController.setWallpaperSupportsAmbientMode(true);
         mScrimController.transitionTo(ScrimState.AOD);
         mScrimController.finishAnimationsImmediately();
-        // Front scrim should be transparent
-        // Back scrim should be visible with tint
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
-        assertScrimTint(mScrimBehind, true /* tinted */);
-        assertScrimTint(mScrimInFront, true /* tinted */);
+
+        assertScrimAlpha(TRANSPARENT /* front */,
+                OPAQUE /* back */,
+                TRANSPARENT /* bubble */);
+
+        assertScrimTint(true /* front */,
+                true /* behind */,
+                false /* bubble */);
     }
 
     @Test
@@ -166,11 +183,14 @@
         mScrimController.finishAnimationsImmediately();
         mScrimController.setHasBackdrop(true);
         mScrimController.finishAnimationsImmediately();
-        // Front scrim should be transparent
-        // Back scrim should be visible with tint
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
-        assertScrimTint(mScrimBehind, true /* tinted */);
-        assertScrimTint(mScrimInFront, true /* tinted */);
+
+        assertScrimAlpha(TRANSPARENT /* front */,
+                OPAQUE /* back */,
+                TRANSPARENT /* bubble */);
+
+        assertScrimTint(true /* front */,
+                true /* behind */,
+                false /* bubble */);
     }
 
     @Test
@@ -179,27 +199,32 @@
         mScrimController.transitionTo(ScrimState.KEYGUARD);
         mScrimController.setAodFrontScrimAlpha(0.5f);
         mScrimController.finishAnimationsImmediately();
-        // Front scrim should be transparent
-        // Back scrim should be visible without tint
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT);
+
+        assertScrimAlpha(TRANSPARENT /* front */,
+                SEMI_TRANSPARENT /* back */,
+                TRANSPARENT /* bubble */);
 
         // ... but that it does take effect once we enter the AOD state.
         mScrimController.transitionTo(ScrimState.AOD);
         mScrimController.finishAnimationsImmediately();
-        // Front scrim should be semi-transparent
-        // Back scrim should be visible
-        assertScrimVisibility(VISIBILITY_SEMI_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
+        assertScrimAlpha(SEMI_TRANSPARENT /* front */,
+                OPAQUE /* back */,
+                TRANSPARENT /* bubble */);
 
         // ... and that if we set it while we're in AOD, it does take immediate effect.
         mScrimController.setAodFrontScrimAlpha(1f);
-        assertScrimVisibility(VISIBILITY_FULLY_OPAQUE, VISIBILITY_FULLY_OPAQUE);
+        assertScrimAlpha(OPAQUE /* front */,
+                OPAQUE /* back */,
+                TRANSPARENT /* bubble */);
 
         // ... and make sure we recall the previous front scrim alpha even if we transition away
         // for a bit.
         mScrimController.transitionTo(ScrimState.UNLOCKED);
         mScrimController.transitionTo(ScrimState.AOD);
         mScrimController.finishAnimationsImmediately();
-        assertScrimVisibility(VISIBILITY_FULLY_OPAQUE, VISIBILITY_FULLY_OPAQUE);
+        assertScrimAlpha(OPAQUE /* front */,
+                OPAQUE /* back */,
+                TRANSPARENT /* bubble */);
 
         // ... and alpha updates should be completely ignored if always_on is off.
         // Passing it forward would mess up the wake-up transition.
@@ -216,27 +241,46 @@
     }
 
     @Test
-    public void transitionToPulsing() {
+    public void transitionToPulsing_withFrontAlphaUpdates() {
         // Pre-condition
         // Need to go to AoD first because PULSING doesn't change
         // the back scrim opacity - otherwise it would hide AoD wallpapers.
         mScrimController.setWallpaperSupportsAmbientMode(false);
         mScrimController.transitionTo(ScrimState.AOD);
         mScrimController.finishAnimationsImmediately();
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
+        assertScrimAlpha(TRANSPARENT /* front */,
+                OPAQUE /* back */,
+                TRANSPARENT /* bubble */);
 
         mScrimController.transitionTo(ScrimState.PULSING);
         mScrimController.finishAnimationsImmediately();
         // Front scrim should be transparent, but tinted
         // Back scrim should be semi-transparent so the user can see the wallpaper
         // Pulse callback should have been invoked
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
-        assertScrimTint(mScrimBehind, true /* tinted */);
-        assertScrimTint(mScrimInFront, true /* tinted */);
+        assertScrimAlpha(TRANSPARENT /* front */,
+                OPAQUE /* back */,
+                TRANSPARENT /* bubble */);
+
+        assertScrimTint(true /* front */,
+                true /* behind */,
+                false /* bubble */);
+
+        // ... and when ambient goes dark, front scrim should be semi-transparent
+        mScrimController.setAodFrontScrimAlpha(0.5f);
+        mScrimController.finishAnimationsImmediately();
+        // Front scrim should be semi-transparent
+        assertScrimAlpha(SEMI_TRANSPARENT /* front */,
+                OPAQUE /* back */,
+                TRANSPARENT /* bubble */);
 
         mScrimController.setWakeLockScreenSensorActive(true);
         mScrimController.finishAnimationsImmediately();
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT);
+        assertScrimAlpha(SEMI_TRANSPARENT /* front */,
+                SEMI_TRANSPARENT /* back */,
+                TRANSPARENT /* bubble */);
+
+        // Reset value since enums are static.
+        mScrimController.setAodFrontScrimAlpha(0f);
     }
 
     @Test
@@ -245,8 +289,13 @@
         mScrimController.finishAnimationsImmediately();
         // Front scrim should be transparent
         // Back scrim should be visible without tint
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT);
-        assertScrimTint(mScrimBehind, false /* tinted */);
+        assertScrimAlpha(TRANSPARENT /* front */,
+                SEMI_TRANSPARENT /* back */,
+                TRANSPARENT /* bubble */);
+
+        assertScrimTint(false /* front */,
+                false /* behind */,
+                false /* bubble */);
     }
 
     @Test
@@ -255,8 +304,12 @@
         mScrimController.finishAnimationsImmediately();
         // Front scrim should be transparent
         // Back scrim should be visible without tint
-        assertScrimVisibility(VISIBILITY_SEMI_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
-        assertScrimTint(mScrimBehind, false /* tinted */);
+        assertScrimAlpha(SEMI_TRANSPARENT /* front */,
+                TRANSPARENT /* back */,
+                TRANSPARENT /* bubble */);
+        assertScrimTint(false /* front */,
+                false /* behind */,
+                false /* bubble */);
     }
 
     @Test
@@ -264,15 +317,19 @@
         mScrimController.setPanelExpansion(0f);
         mScrimController.transitionTo(ScrimState.UNLOCKED);
         mScrimController.finishAnimationsImmediately();
-        // Front scrim should be transparent
-        // Back scrim should be transparent
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
-        assertScrimTint(mScrimBehind, false /* tinted */);
-        assertScrimTint(mScrimInFront, false /* tinted */);
+        assertScrimAlpha(TRANSPARENT /* front */,
+                TRANSPARENT /* back */,
+                TRANSPARENT /* bubble */);
+
+        assertScrimTint(false /* front */,
+                false /* behind */,
+                false /* bubble */);
 
         // Back scrim should be visible after start dragging
         mScrimController.setPanelExpansion(0.5f);
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT);
+        assertScrimAlpha(TRANSPARENT /* front */,
+                SEMI_TRANSPARENT /* back */,
+                TRANSPARENT /* bubble */);
     }
 
     @Test
@@ -280,12 +337,19 @@
         mScrimController.transitionTo(ScrimState.BUBBLE_EXPANDED);
         mScrimController.finishAnimationsImmediately();
 
+        assertScrimTint(false /* front */,
+                false /* behind */,
+                false /* bubble */);
+
         // Front scrim should be transparent
-        Assert.assertEquals(ScrimController.VISIBILITY_FULLY_TRANSPARENT,
+        Assert.assertEquals(ScrimController.TRANSPARENT,
                 mScrimInFront.getViewAlpha(), 0.0f);
         // Back scrim should be visible
         Assert.assertEquals(ScrimController.GRADIENT_SCRIM_ALPHA_BUSY,
                 mScrimBehind.getViewAlpha(), 0.0f);
+        // Bubble scrim should be visible
+        Assert.assertEquals(ScrimController.GRADIENT_SCRIM_ALPHA_BUSY,
+                mScrimBehind.getViewAlpha(), 0.0f);
     }
 
     @Test
@@ -354,16 +418,23 @@
         mScrimController.setPanelExpansion(0f);
         mScrimController.finishAnimationsImmediately();
         mScrimController.transitionTo(ScrimState.UNLOCKED);
-        // Immediately tinted after the transition starts
-        assertScrimTint(mScrimInFront, true /* tinted */);
-        assertScrimTint(mScrimBehind, true /* tinted */);
+
+        // Immediately tinted black after the transition starts
+        assertScrimTint(true /* front */,
+                true /* behind */,
+                true  /* bubble */);
+
         mScrimController.finishAnimationsImmediately();
-        // Front scrim should be transparent
-        // Back scrim should be transparent
-        // Neither scrims should be tinted anymore after the animation.
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
-        assertScrimTint(mScrimInFront, false /* tinted */);
-        assertScrimTint(mScrimBehind, false /* tinted */);
+
+        // All scrims should be transparent at the end of fade transition.
+        assertScrimAlpha(TRANSPARENT /* front */,
+                TRANSPARENT /* behind */,
+                TRANSPARENT /* bubble */);
+
+        // Make sure at the very end of the animation, we're reset to transparent
+        assertScrimTint(false /* front */,
+                false /* behind */,
+                false  /* bubble */);
     }
 
     @Test
@@ -378,9 +449,11 @@
                         // Front scrim should be black in the middle of the transition
                         Assert.assertTrue("Scrim should be visible during transition. Alpha: "
                                 + mScrimInFront.getViewAlpha(), mScrimInFront.getViewAlpha() > 0);
-                        assertScrimTint(mScrimInFront, true /* tinted */);
+                        assertScrimTint(true /* front */,
+                                true /* behind */,
+                                true /* bubble */);
                         Assert.assertSame("Scrim should be visible during transition.",
-                                mScrimVisibility, VISIBILITY_FULLY_OPAQUE);
+                                mScrimVisibility, OPAQUE);
                     }
                 });
         mScrimController.finishAnimationsImmediately();
@@ -588,11 +661,15 @@
         mScrimController.setKeyguardOccluded(true);
         mScrimController.transitionTo(ScrimState.AOD);
         mScrimController.finishAnimationsImmediately();
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
+        assertScrimAlpha(TRANSPARENT /* front */,
+                OPAQUE /* behind */,
+                TRANSPARENT /* bubble */);
 
         mScrimController.transitionTo(ScrimState.PULSING);
         mScrimController.finishAnimationsImmediately();
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
+        assertScrimAlpha(TRANSPARENT /* front */,
+                OPAQUE /* behind */,
+                TRANSPARENT /* bubble */);
     }
 
     @Test
@@ -600,11 +677,15 @@
         mScrimController.setWallpaperSupportsAmbientMode(true);
         mScrimController.transitionTo(ScrimState.AOD);
         mScrimController.finishAnimationsImmediately();
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
+        assertScrimAlpha(TRANSPARENT /* front */,
+                TRANSPARENT /* behind */,
+                TRANSPARENT /* bubble */);
 
         mScrimController.setKeyguardOccluded(true);
         mScrimController.finishAnimationsImmediately();
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
+        assertScrimAlpha(TRANSPARENT /* front */,
+                OPAQUE /* behind */,
+                TRANSPARENT /* bubble */);
     }
 
     @Test
@@ -643,33 +724,68 @@
                 mScrimInFront.getDefaultFocusHighlightEnabled());
         Assert.assertFalse("Scrim shouldn't have focus highlight",
                 mScrimBehind.getDefaultFocusHighlightEnabled());
+        Assert.assertFalse("Scrim shouldn't have focus highlight",
+                mScrimForBubble.getDefaultFocusHighlightEnabled());
     }
 
-    private void assertScrimTint(ScrimView scrimView, boolean tinted) {
-        final boolean viewIsTinted = scrimView.getTint() != Color.TRANSPARENT;
-        final String name = scrimView == mScrimInFront ? "front" : "back";
+    private void assertScrimTint(boolean front, boolean behind, boolean bubble) {
         Assert.assertEquals("Tint test failed at state " + mScrimController.getState()
-                +" with scrim: " + name + " and tint: " + Integer.toHexString(scrimView.getTint()),
-                tinted, viewIsTinted);
+                        + " with scrim: " + getScrimName(mScrimInFront) + " and tint: "
+                        + Integer.toHexString(mScrimInFront.getTint()),
+                front, mScrimInFront.getTint() != Color.TRANSPARENT);
+
+        Assert.assertEquals("Tint test failed at state " + mScrimController.getState()
+                        + " with scrim: " + getScrimName(mScrimBehind) + " and tint: "
+                        + Integer.toHexString(mScrimBehind.getTint()),
+                behind, mScrimBehind.getTint() != Color.TRANSPARENT);
+
+        Assert.assertEquals("Tint test failed at state " + mScrimController.getState()
+                        + " with scrim: " + getScrimName(mScrimForBubble) + " and tint: "
+                        + Integer.toHexString(mScrimForBubble.getTint()),
+                bubble, mScrimForBubble.getTint() != Color.TRANSPARENT);
     }
 
-    private void assertScrimVisibility(int inFront, int behind) {
-        boolean inFrontVisible = inFront != ScrimController.VISIBILITY_FULLY_TRANSPARENT;
-        boolean behindVisible = behind != ScrimController.VISIBILITY_FULLY_TRANSPARENT;
-        Assert.assertEquals("Unexpected front scrim visibility. Alpha is "
-                + mScrimInFront.getViewAlpha(), inFrontVisible, mScrimInFront.getViewAlpha() > 0);
-        Assert.assertEquals("Unexpected back scrim visibility. Alpha is "
-                + mScrimBehind.getViewAlpha(), behindVisible, mScrimBehind.getViewAlpha() > 0);
-
-        final int visibility;
-        if (inFront == VISIBILITY_FULLY_OPAQUE || behind == VISIBILITY_FULLY_OPAQUE) {
-            visibility = VISIBILITY_FULLY_OPAQUE;
-        } else if (inFront > VISIBILITY_FULLY_TRANSPARENT || behind > VISIBILITY_FULLY_TRANSPARENT) {
-            visibility = VISIBILITY_SEMI_TRANSPARENT;
-        } else {
-            visibility = VISIBILITY_FULLY_TRANSPARENT;
+    private String getScrimName(ScrimView scrim) {
+        if (scrim == mScrimInFront) {
+            return "front";
+        } else if (scrim == mScrimBehind) {
+            return "back";
+        } else if (scrim == mScrimForBubble) {
+            return "bubble";
         }
-        Assert.assertEquals("Invalid visibility.", visibility, mScrimVisibility);
+        return "unknown_scrim";
+    }
+
+    private void assertScrimAlpha(int front, int behind, int bubble) {
+        // Check single scrim visibility.
+        Assert.assertEquals("Unexpected front scrim alpha: "
+                        + mScrimInFront.getViewAlpha(),
+                front != TRANSPARENT /* expected */,
+                mScrimInFront.getViewAlpha() > TRANSPARENT /* actual */);
+
+        Assert.assertEquals("Unexpected back scrim alpha: "
+                        + mScrimBehind.getViewAlpha(),
+                behind != TRANSPARENT /* expected */,
+                mScrimBehind.getViewAlpha() > TRANSPARENT /* actual */);
+
+        Assert.assertEquals(
+                "Unexpected bubble scrim alpha: "
+                        + mScrimForBubble.getViewAlpha(), /* message */
+                bubble != TRANSPARENT /* expected */,
+                mScrimForBubble.getViewAlpha() > TRANSPARENT /* actual */);
+
+        // Check combined scrim visibility.
+        final int visibility;
+        if (front == OPAQUE || behind == OPAQUE || bubble == OPAQUE) {
+            visibility = OPAQUE;
+        } else if (front > TRANSPARENT || behind > TRANSPARENT || bubble > TRANSPARENT) {
+            visibility = SEMI_TRANSPARENT;
+        } else {
+            visibility = TRANSPARENT;
+        }
+        Assert.assertEquals("Invalid visibility.",
+                visibility /* expected */,
+                mScrimVisibility);
     }
 
     /**
@@ -681,11 +797,12 @@
         boolean mOnPreDrawCalled;
 
         SynchronousScrimController(ScrimView scrimBehind, ScrimView scrimInFront,
+                ScrimView scrimForBubble,
                 TriConsumer<ScrimState, Float, GradientColors> scrimStateListener,
                 Consumer<Integer> scrimVisibleListener, DozeParameters dozeParameters,
                 AlarmManager alarmManager, KeyguardMonitor keyguardMonitor) {
-            super(scrimBehind, scrimInFront, scrimStateListener, scrimVisibleListener,
-                    dozeParameters, alarmManager, keyguardMonitor);
+            super(scrimBehind, scrimInFront, scrimForBubble, scrimStateListener,
+                    scrimVisibleListener, dozeParameters, alarmManager, keyguardMonitor);
         }
 
         @Override
@@ -696,13 +813,14 @@
 
         void finishAnimationsImmediately() {
             boolean[] animationFinished = {false};
-            setOnAnimationFinished(()-> animationFinished[0] = true);
+            setOnAnimationFinished(() -> animationFinished[0] = true);
             // Execute code that will trigger animations.
             onPreDraw();
             // Force finish all animations.
             mLooper.processAllMessages();
             endAnimation(mScrimBehind, TAG_KEY_ANIM);
             endAnimation(mScrimInFront, TAG_KEY_ANIM);
+            endAnimation(mScrimForBubble, TAG_KEY_ANIM);
 
             if (!animationFinished[0]) {
                 throw new IllegalStateException("Animation never finished");
@@ -740,6 +858,7 @@
 
         /**
          * Do not wait for a frame since we're in a test environment.
+         *
          * @param callback What to execute.
          */
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index da2e8dc..0da0e76 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -39,8 +39,10 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 
@@ -93,7 +95,8 @@
                 mViewMediatorCallback, mLockPatternUtils);
         mStatusBarKeyguardViewManager.registerStatusBar(mStatusBar, mContainer,
                 mNotificationPanelView, mBiometrucUnlockController, mDismissCallbackRegistry,
-                mLockIconContainer, mNotificationContainer, mBypassController);
+                mLockIconContainer, mNotificationContainer, mBypassController,
+                new FalsingManagerFake());
         mStatusBarKeyguardViewManager.show(null);
     }
 
@@ -218,6 +221,31 @@
         verify(mStatusBar, never()).animateKeyguardUnoccluding();
     }
 
+    @Test
+    public void testHiding_cancelsGoneRunnable() {
+        OnDismissAction action = mock(OnDismissAction.class);
+        Runnable cancelAction = mock(Runnable.class);
+        mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
+                true /* afterKeyguardGone */);
+
+        mStatusBarKeyguardViewManager.hideBouncer(true);
+        mStatusBarKeyguardViewManager.hide(0, 30);
+        verify(action, never()).onDismiss();
+        verify(cancelAction).run();
+    }
+
+    @Test
+    public void testHiding_doesntCancelWhenShowing() {
+        OnDismissAction action = mock(OnDismissAction.class);
+        Runnable cancelAction = mock(Runnable.class);
+        mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
+                true /* afterKeyguardGone */);
+
+        mStatusBarKeyguardViewManager.hide(0, 30);
+        verify(action).onDismiss();
+        verify(cancelAction, never()).run();
+    }
+
     private class TestableStatusBarKeyguardViewManager extends StatusBarKeyguardViewManager {
 
         public TestableStatusBarKeyguardViewManager(Context context,
@@ -232,11 +260,11 @@
                 BiometricUnlockController fingerprintUnlockController,
                 DismissCallbackRegistry dismissCallbackRegistry,
                 ViewGroup lockIconContainer, View notificationContainer,
-                KeyguardBypassController bypassController) {
+                KeyguardBypassController bypassController, FalsingManager falsingManager) {
             super.registerStatusBar(statusBar, container, notificationPanelView,
                     fingerprintUnlockController, dismissCallbackRegistry, lockIconContainer,
-                    notificationContainer, bypassController);
+                    notificationContainer, bypassController, falsingManager);
             mBouncer = StatusBarKeyguardViewManagerTest.this.mBouncer;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index 06d76eb..5a6f27d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -153,8 +153,6 @@
         StatusBarNotification bubbleSbn = mBubbleNotificationRow.getStatusBarNotification();
         bubbleSbn.getNotification().contentIntent = mContentIntent;
         bubbleSbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
-        // Do what BubbleController's NotificationEntryListener#onPendingEntryAdded does:
-        mBubbleNotificationRow.getEntry().setShowInShadeWhenBubble(true);
 
         mActiveNotifications = new ArrayList<>();
         mActiveNotifications.add(mNotificationRow.getEntry());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
index a97832f..4b6ca56 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
@@ -68,7 +68,7 @@
         mDependency.injectTestDependency(ShadeController.class, mShadeController);
         mDependency.injectTestDependency(NotificationLockscreenUserManager.class,
                 mNotificationLockscreenUserManager);
-        mDependency.putComponent(CommandQueue.class, mock(CommandQueue.class));
+        mContext.putComponent(CommandQueue.class, mock(CommandQueue.class));
 
         mRemoteInputCallback = spy(new StatusBarRemoteInputCallback(mContext,
                 mock(NotificationGroupManager.class)));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index fa235bd..02215a9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -110,6 +110,7 @@
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
@@ -156,6 +157,7 @@
     @Mock private NotificationRemoteInputManager mRemoteInputManager;
     @Mock private RemoteInputController mRemoteInputController;
     @Mock private StatusBarStateControllerImpl mStatusBarStateController;
+    @Mock private BatteryController mBatteryController;
     @Mock private DeviceProvisionedController mDeviceProvisionedController;
     @Mock private StatusBarNotificationPresenter mNotificationPresenter;
     @Mock
@@ -208,7 +210,8 @@
 
         mNotificationInterruptionStateProvider =
                 new TestableNotificationInterruptionStateProvider(mContext, mPowerManager,
-                        mDreamManager, mAmbientDisplayConfiguration);
+                        mDreamManager, mAmbientDisplayConfiguration, mNotificationFilter,
+                        mStatusBarStateController, mBatteryController);
         mDependency.injectTestDependency(NotificationInterruptionStateProvider.class,
                 mNotificationInterruptionStateProvider);
         mDependency.injectMockDependency(NavigationBarController.class);
@@ -870,8 +873,12 @@
                 Context context,
                 PowerManager powerManager,
                 IDreamManager dreamManager,
-                AmbientDisplayConfiguration ambientDisplayConfiguration) {
-            super(context, powerManager, dreamManager, ambientDisplayConfiguration);
+                AmbientDisplayConfiguration ambientDisplayConfiguration,
+                NotificationFilter filter,
+                StatusBarStateController controller,
+                BatteryController batteryController) {
+            super(context, powerManager, dreamManager, ambientDisplayConfiguration, filter,
+                    batteryController, controller);
             mUseHeadsUp = true;
         }
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index edc513b..354aa83 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -30,6 +30,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import android.app.Instrumentation;
 import android.content.Intent;
 import android.net.ConnectivityManager;
 import android.net.Network;
@@ -48,6 +49,8 @@
 import android.testing.TestableResources;
 import android.util.Log;
 
+import androidx.test.InstrumentationRegistry;
+
 import com.android.internal.telephony.cdma.EriInfo;
 import com.android.settingslib.graph.SignalDrawable;
 import com.android.settingslib.net.DataUsageController;
@@ -95,6 +98,7 @@
     protected SubscriptionDefaults mMockSubDefaults;
     protected DeviceProvisionedController mMockProvisionController;
     protected DeviceProvisionedListener mUserCallback;
+    protected Instrumentation mInstrumentation;
 
     protected int mSubId;
 
@@ -116,6 +120,7 @@
 
     @Before
     public void setUp() throws Exception {
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
         Settings.Global.putInt(mContext.getContentResolver(), Global.AIRPLANE_MODE_ON, 0);
         TestableResources res = mContext.getOrCreateTestableResources();
         res.addOverride(R.string.cell_data_off_content_description, NO_DATA_STRING);
@@ -228,6 +233,28 @@
         NetworkControllerImpl.Config.add5GIconMapping("connected:5g", mConfig);
     }
 
+    public void setupNr5GIconConfigurationForNotRestrictedRrcCon() {
+        NetworkControllerImpl.Config.add5GIconMapping("connected_mmwave:5g_plus", mConfig);
+        NetworkControllerImpl.Config.add5GIconMapping("connected:5g_plus", mConfig);
+        NetworkControllerImpl.Config.add5GIconMapping("not_restricted_rrc_con:5g", mConfig);
+    }
+
+    public void setupNr5GIconConfigurationForNotRestrictedRrcIdle() {
+        NetworkControllerImpl.Config.add5GIconMapping("connected_mmwave:5g_plus", mConfig);
+        NetworkControllerImpl.Config.add5GIconMapping("connected:5g_plus", mConfig);
+        NetworkControllerImpl.Config.add5GIconMapping("not_restricted_rrc_idle:5g", mConfig);
+    }
+
+    public void setupDefaultNr5GIconDisplayGracePeriodTime_enableThirtySeconds() {
+        final int enableDisplayGraceTimeSec = 30;
+        NetworkControllerImpl.Config.setDisplayGraceTime(enableDisplayGraceTimeSec, mConfig);
+    }
+
+    public void setupDefaultNr5GIconDisplayGracePeriodTime_disabled() {
+        final int disableDisplayGraceTimeSec = 0;
+        NetworkControllerImpl.Config.setDisplayGraceTime(disableDisplayGraceTimeSec, mConfig);
+    }
+
     public void setConnectivityViaBroadcast(
         int networkType, boolean validated, boolean isConnected) {
         setConnectivityCommon(networkType, validated, isConnected);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index 5128675..aa4723a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -1,5 +1,7 @@
 package com.android.systemui.statusbar.policy;
 
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
@@ -145,7 +147,7 @@
     }
 
     @Test
-    public void testNoInternetIcon_withoutDefaultSub() {
+    public void testNonDefaultSIM_showsFullSignal_connected() {
         setupNetworkController();
         when(mMockTm.isDataCapable()).thenReturn(false);
         setupDefaultSignal();
@@ -156,11 +158,11 @@
         // Verify that a SignalDrawable with a cut out is used to display data disabled.
         verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, 0,
                 true, DEFAULT_QS_SIGNAL_STRENGTH, 0, false,
-                false, true, NOT_DEFAULT_DATA_STRING);
+                false, false, NOT_DEFAULT_DATA_STRING);
     }
 
     @Test
-    public void testDataDisabledIcon_withoutDefaultSub() {
+    public void testNonDefaultSIM_showsFullSignal_disconnected() {
         setupNetworkController();
         when(mMockTm.isDataCapable()).thenReturn(false);
         setupDefaultSignal();
@@ -171,7 +173,36 @@
         // Verify that a SignalDrawable with a cut out is used to display data disabled.
         verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, 0,
                 true, DEFAULT_QS_SIGNAL_STRENGTH, 0, false,
-                false, true, NOT_DEFAULT_DATA_STRING);
+                false, false, NOT_DEFAULT_DATA_STRING);
+    }
+
+    @Test
+    public void testNr5GIcon_NrNotRestrictedRrcCon_show5GIcon() {
+        setupNr5GIconConfigurationForNotRestrictedRrcCon();
+        setupDefaultSignal();
+        updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_LTE);
+        updateDataActivity(TelephonyManager.DATA_ACTIVITY_INOUT);
+        ServiceState ss = Mockito.mock(ServiceState.class);
+        doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(ss).getNrState();
+        mPhoneStateListener.onServiceStateChanged(ss);
+
+        verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, TelephonyIcons.ICON_5G,
+                true, DEFAULT_QS_SIGNAL_STRENGTH, TelephonyIcons.ICON_5G, true, true);
+    }
+
+    @Test
+    public void testNr5GIcon_NrNotRestrictedRrcIdle_show5GIcon() {
+        setupNr5GIconConfigurationForNotRestrictedRrcIdle();
+        setupDefaultSignal();
+        updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_LTE);
+        updateDataActivity(TelephonyManager.DATA_ACTIVITY_DORMANT);
+        ServiceState ss = Mockito.mock(ServiceState.class);
+        doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(ss).getNrState();
+        mPhoneStateListener.onServiceStateChanged(ss);
+
+        verifyDataIndicators(TelephonyIcons.ICON_5G);
     }
 
     @Test
@@ -216,6 +247,186 @@
     }
 
     @Test
+    public void testNr5GIcon_displayGracePeriodTime_enabled() {
+        setupDefaultNr5GIconConfiguration();
+        setupDefaultNr5GIconDisplayGracePeriodTime_enableThirtySeconds();
+        setupDefaultSignal();
+        mNetworkController.handleConfigurationChanged();
+        mPhoneStateListener.onServiceStateChanged(mServiceState);
+
+        ServiceState ss = Mockito.mock(ServiceState.class);
+        // While nrIconDisplayGracePeriodMs > 0 & is Nr5G, mIsShowingIconGracefully should be true
+        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss).getNrState();
+        doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss).getNrFrequencyRange();
+        mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_LTE);
+        mPhoneStateListener.onServiceStateChanged(ss);
+
+        assertTrue(mConfig.nrIconDisplayGracePeriodMs > 0);
+        assertTrue(mMobileSignalController.mIsShowingIconGracefully);
+    }
+
+    @Test
+    public void testNr5GIcon_displayGracePeriodTime_disabled() {
+        setupDefaultNr5GIconConfiguration();
+        setupDefaultNr5GIconDisplayGracePeriodTime_disabled();
+        setupDefaultSignal();
+
+        assertTrue(mConfig.nrIconDisplayGracePeriodMs == 0);
+
+        // While nrIconDisplayGracePeriodMs <= 0, mIsShowingIconGracefully should be false
+        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
+        doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(mServiceState).getNrFrequencyRange();
+        mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_LTE);
+
+        assertFalse(mMobileSignalController.mIsShowingIconGracefully);
+    }
+
+    @Test
+    public void testNr5GIcon_enableDisplayGracePeriodTime_showIconGracefully() {
+        setupDefaultNr5GIconConfiguration();
+        setupDefaultNr5GIconDisplayGracePeriodTime_enableThirtySeconds();
+        setupDefaultSignal();
+        mNetworkController.handleConfigurationChanged();
+        mPhoneStateListener.onServiceStateChanged(mServiceState);
+
+        ServiceState ss = Mockito.mock(ServiceState.class);
+        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss).getNrState();
+        doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss).getNrFrequencyRange();
+        mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_LTE);
+        mPhoneStateListener.onServiceStateChanged(ss);
+
+        verifyDataIndicators(TelephonyIcons.ICON_5G);
+
+        // Enabled timer Nr5G switch to None Nr5G, showing 5G icon gracefully
+        ServiceState ssLte = Mockito.mock(ServiceState.class);
+        doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(ssLte).getNrState();
+        doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(ssLte).getNrFrequencyRange();
+        mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_LTE);
+        mPhoneStateListener.onServiceStateChanged(ssLte);
+
+        verifyDataIndicators(TelephonyIcons.ICON_5G);
+    }
+
+    @Test
+    public void testNr5GIcon_disableDisplayGracePeriodTime_showLatestIconImmediately() {
+        setupDefaultNr5GIconConfiguration();
+        setupDefaultNr5GIconDisplayGracePeriodTime_disabled();
+        setupDefaultSignal();
+        mNetworkController.handleConfigurationChanged();
+
+        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
+        doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(mServiceState).getNrFrequencyRange();
+        mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_LTE);
+
+        verifyDataIndicators(TelephonyIcons.ICON_5G);
+
+        doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
+        doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(mServiceState).getNrFrequencyRange();
+        mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_LTE);
+
+        verifyDataIndicators(TelephonyIcons.ICON_LTE);
+    }
+
+    @Test
+    public void testNr5GIcon_resetDisplayGracePeriodTime_whenDataDisconnected() {
+        setupDefaultNr5GIconConfiguration();
+        setupDefaultNr5GIconDisplayGracePeriodTime_enableThirtySeconds();
+        setupDefaultSignal();
+        mNetworkController.handleConfigurationChanged();
+        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
+        doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(mServiceState).getNrFrequencyRange();
+        mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_LTE);
+
+        verifyDataIndicators(TelephonyIcons.ICON_5G);
+
+        // Disabled timer, when out of service, reset timer to display latest state
+        updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
+        doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(mServiceState).getNrFrequencyRange();
+        mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_DISCONNECTED,
+                TelephonyManager.NETWORK_TYPE_UMTS);
+
+        verifyDataIndicators(0);
+    }
+
+    @Test
+    public void testNr5GIcon_enableDisplayGracePeriodTime_show5G_switching_5GPlus() {
+        setupDefaultNr5GIconConfiguration();
+        setupDefaultNr5GIconDisplayGracePeriodTime_enableThirtySeconds();
+        setupDefaultSignal();
+        mNetworkController.handleConfigurationChanged();
+        mPhoneStateListener.onServiceStateChanged(mServiceState);
+
+        ServiceState ss5G = Mockito.mock(ServiceState.class);
+        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss5G).getNrState();
+        doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss5G).getNrFrequencyRange();
+        mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_LTE);
+        mPhoneStateListener.onServiceStateChanged(ss5G);
+
+        verifyDataIndicators(TelephonyIcons.ICON_5G);
+
+        // When timeout enabled, 5G/5G+ switching should be updated immediately
+        ServiceState ss5GPlus = Mockito.mock(ServiceState.class);
+        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss5GPlus).getNrState();
+        doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(ss5GPlus).getNrFrequencyRange();
+        mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_LTE);
+        mPhoneStateListener.onServiceStateChanged(ss5GPlus);
+
+        verifyDataIndicators(TelephonyIcons.ICON_5G_PLUS);
+    }
+
+    @Test
+    public void testNr5GIcon_carrierDisabledDisplayGracePeriodTime_shouldUpdateIconImmediately() {
+        setupDefaultNr5GIconConfiguration();
+        setupDefaultNr5GIconDisplayGracePeriodTime_enableThirtySeconds();
+        setupDefaultSignal();
+        mNetworkController.handleConfigurationChanged();
+        mPhoneStateListener.onServiceStateChanged(mServiceState);
+
+        ServiceState ss5G = Mockito.mock(ServiceState.class);
+        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss5G).getNrState();
+        doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss5G).getNrFrequencyRange();
+        mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_LTE);
+        mPhoneStateListener.onServiceStateChanged(ss5G);
+
+        verifyDataIndicators(TelephonyIcons.ICON_5G);
+
+        // State from NR_5G to NONE NR_5G with timeout, should show previous 5G icon
+        ServiceState ssLte = Mockito.mock(ServiceState.class);
+        doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(ssLte).getNrState();
+        doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(ssLte).getNrFrequencyRange();
+        mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_LTE);
+        mPhoneStateListener.onServiceStateChanged(ssLte);
+
+        verifyDataIndicators(TelephonyIcons.ICON_5G);
+
+        // Update nrIconDisplayGracePeriodMs to 0
+        setupDefaultNr5GIconDisplayGracePeriodTime_disabled();
+        mNetworkController.handleConfigurationChanged();
+
+        // State from NR_5G to NONE NR_STATE_RESTRICTED, showing corresponding icon
+        doReturn(NetworkRegistrationInfo.NR_STATE_RESTRICTED).when(mServiceState).getNrState();
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
+        mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_LTE);
+
+        assertTrue(mConfig.nrIconDisplayGracePeriodMs == 0);
+        verifyDataIndicators(TelephonyIcons.ICON_LTE);
+    }
+
+    @Test
     public void testDataDisabledIcon_UserNotSetup() {
         setupNetworkController();
         when(mMockTm.isDataCapable()).thenReturn(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
index 6e3d906..3451183 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
@@ -1,5 +1,12 @@
 package com.android.systemui.statusbar.policy;
 
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import android.content.Intent;
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
@@ -16,13 +23,6 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
 
-import static junit.framework.Assert.assertEquals;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
index 0cb5754..6be7081 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
@@ -494,6 +494,7 @@
     private void setSmartActions(String[] actionTitles, boolean useDelayedOnClickListener) {
         mView.resetSmartSuggestions(mContainer);
         List<Button> actions = mView.inflateSmartActions(
+                getContext(),
                 new SmartReplyView.SmartActions(createActions(actionTitles), false),
                 mLogger,
                 mEntry,
@@ -514,6 +515,7 @@
         List<Button> smartSuggestions = inflateSmartReplies(choices, fromAssistant,
                 useDelayedOnClickListener);
         smartSuggestions.addAll(mView.inflateSmartActions(
+                getContext(),
                 new SmartReplyView.SmartActions(createActions(actionTitles), fromAssistant),
                 mLogger,
                 mEntry,
@@ -860,7 +862,7 @@
     }
 
     private Button inflateActionButton(Notification.Action action) {
-        return SmartReplyView.inflateActionButton(mView, getContext(), 0,
+        return SmartReplyView.inflateActionButton(mView, getContext(), getContext(), 0,
                 new SmartReplyView.SmartActions(Collections.singletonList(action), false),
                 mLogger, mEntry, mHeadsUpManager, true /* useDelayedOnClickListener */);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeBatteryController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeBatteryController.java
index a843cca..df76f01 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeBatteryController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeBatteryController.java
@@ -48,4 +48,9 @@
     public boolean isPowerSave() {
         return false;
     }
+
+    @Override
+    public boolean isAodPowerSave() {
+        return false;
+    }
 }
diff --git a/packages/SystemUI/tools/lint/baseline.xml b/packages/SystemUI/tools/lint/baseline.xml
index 8c43222..096a639 100644
--- a/packages/SystemUI/tools/lint/baseline.xml
+++ b/packages/SystemUI/tools/lint/baseline.xml
@@ -2685,39 +2685,6 @@
 
     <issue
         id="UnusedResources"
-        message="The resource `R.dimen.volume_dialog_base_margin` appears to be unused"
-        errorLine1="    &lt;dimen name=&quot;volume_dialog_base_margin&quot;>8dp&lt;/dimen>"
-        errorLine2="           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/dimens.xml"
-            line="308"
-            column="12"/>
-    </issue>
-
-    <issue
-        id="UnusedResources"
-        message="The resource `R.dimen.volume_dialog_row_height` appears to be unused"
-        errorLine1="    &lt;dimen name=&quot;volume_dialog_row_height&quot;>252dp&lt;/dimen>"
-        errorLine2="           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/dimens.xml"
-            line="314"
-            column="12"/>
-    </issue>
-
-    <issue
-        id="UnusedResources"
-        message="The resource `R.dimen.volume_dialog_settings_icon_size` appears to be unused"
-        errorLine1="    &lt;dimen name=&quot;volume_dialog_settings_icon_size&quot;>16dp&lt;/dimen>"
-        errorLine2="           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/dimens.xml"
-            line="328"
-            column="12"/>
-    </issue>
-
-    <issue
-        id="UnusedResources"
         message="The resource `R.dimen.carrier_label_height` appears to be unused"
         errorLine1="    &lt;dimen name=&quot;carrier_label_height&quot;>24dp&lt;/dimen>"
         errorLine2="           ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
diff --git a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-ru/strings.xml b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-ru/strings.xml
index dc77981..0ff85fe 100644
--- a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-ru/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-ru/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_cutout_emulation_overlay" msgid="1677693377327336341">"Сделать вырез в углу"</string>
+    <string name="display_cutout_emulation_overlay" msgid="1677693377327336341">"В правом углу"</string>
 </resources>
diff --git a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-ru/strings.xml b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-ru/strings.xml
index a02eaf7..2493da3 100644
--- a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-ru/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-ru/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_cutout_emulation_overlay" msgid="5323179900047630217">"Увеличить вырез вдвое"</string>
+    <string name="display_cutout_emulation_overlay" msgid="5323179900047630217">"Сверху и снизу"</string>
 </resources>
diff --git a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-ru/strings.xml b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-ru/strings.xml
index 1d1656d..89ac1c3 100644
--- a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-ru/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-ru/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_cutout_emulation_overlay" msgid="6424539415439220018">"Сделать вырез выше"</string>
+    <string name="display_cutout_emulation_overlay" msgid="6424539415439220018">"Сверху"</string>
 </resources>
diff --git a/proto/src/gnss.proto b/proto/src/gnss.proto
index 1509fc0..33dbb26 100644
--- a/proto/src/gnss.proto
+++ b/proto/src/gnss.proto
@@ -48,6 +48,27 @@
 
   // Hardware revision (EVT, DVT, PVT etc.)
   optional string hardware_revision = 13;
+
+  // Total number of sv status messages processed
+  optional int32 num_sv_status_processed = 14;
+
+  // Total number of L5 sv status messages processed
+  optional int32 num_l5_sv_status_processed = 15;
+
+  // Total number of sv status messages processed, where sv is used in fix
+  optional int32 num_sv_status_used_in_fix = 16;
+
+  // Total number of L5 sv status messages processed, where sv is used in fix
+  optional int32 num_l5_sv_status_used_in_fix = 17;
+
+  // Number of l5 top 4 average CN0 processed
+  optional int32 num_l5_top_four_average_cn0_processed = 18;
+
+  // Mean of l5 top 4 average CN0 (dB-Hz)
+  optional double mean_l5_top_four_average_cn0_db_hz = 19;
+
+  // Standard deviation of l5 top 4 average CN0 (dB-Hz)
+  optional double standard_deviation_l5_top_four_average_cn0_db_hz = 20;
 }
 
 // Power metrics
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index 5a4892c..38154cb 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -7414,6 +7414,18 @@
     // Note: Gear icon is shown next to gesture navigation preference and opens sensitivity dialog
     SETTINGS_GESTURE_NAV_BACK_SENSITIVITY_DLG = 1748;
 
+
+
+    // ACTION: Chooser > User taps a system-provided target such as copy
+    //   SUBTYPE: Index of target
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: Q - QPR1
+    ACTION_ACTIVITY_CHOOSER_PICKED_SYSTEM_TARGET = 1749;
+
+    // OPEN: Settings > System > Aware > Aware Display
+    // CATEGORY: SETTINGS
+    // OS: Q
+    SETTINGS_AWARE_DISPLAY = 1750;
     // ---- End Q Constants, all Q constants go above this line ----
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto
index 8ad2489..353a187 100644
--- a/proto/src/wifi.proto
+++ b/proto/src/wifi.proto
@@ -1792,6 +1792,25 @@
 
   // Indicates if we are logging LinkSpeedCount in metrics
   optional bool link_speed_counts_logging_enabled = 4;
+
+  // Duration for evaluating Wifi condition to trigger a data stall
+  // measured in milliseconds
+  optional int32 data_stall_duration_ms = 5;
+
+  // Threshold of Tx throughput below which to trigger a data stall
+  // measured in Mbps
+  optional int32 data_stall_tx_tput_thr_mbps = 6;
+
+  // Threshold of Rx throughput below which to trigger a data stall
+  // measured in Mbps
+  optional int32 data_stall_rx_tput_thr_mbps = 7;
+
+  // Threshold of Tx packet error rate above which to trigger a data stall
+  // in percentage
+  optional int32 data_stall_tx_per_thr = 8;
+
+  // Threshold of CCA level above which to trigger a data stall in percentage
+  optional int32 data_stall_cca_level_thr = 9;
 }
 
 message WifiIsUnusableEvent {
diff --git a/services/accessibility/java/com/android/server/accessibility/GlobalActionPerformer.java b/services/accessibility/java/com/android/server/accessibility/GlobalActionPerformer.java
index 672518c..b9b2654 100644
--- a/services/accessibility/java/com/android/server/accessibility/GlobalActionPerformer.java
+++ b/services/accessibility/java/com/android/server/accessibility/GlobalActionPerformer.java
@@ -24,10 +24,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.SystemClock;
-import android.view.IWindowManager;
 import android.view.InputDevice;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
@@ -191,7 +188,7 @@
         ScreenshotHelper screenshotHelper = (mScreenshotHelperSupplier != null)
                 ? mScreenshotHelperSupplier.get() : new ScreenshotHelper(mContext);
         screenshotHelper.takeScreenshot(android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN,
-                true, true, new Handler(Looper.getMainLooper()));
+                true, true, new Handler(Looper.getMainLooper()), null);
         return true;
     }
 }
diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java
index d7e68f8..5844f98 100644
--- a/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java
+++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java
@@ -23,6 +23,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.app.prediction.AppPredictionContext;
 import android.app.prediction.AppPredictionSessionId;
 import android.app.prediction.AppTargetEvent;
@@ -61,7 +62,8 @@
 
     public AppPredictionManagerService(Context context) {
         super(context, new FrameworkResourcesServiceNameResolver(context,
-                com.android.internal.R.string.config_defaultAppPredictionService), null);
+                com.android.internal.R.string.config_defaultAppPredictionService), null,
+                PACKAGE_UPDATE_POLICY_NO_REFRESH | PACKAGE_RESTART_POLICY_NO_REFRESH);
         mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
     }
 
@@ -80,6 +82,22 @@
         getContext().enforceCallingPermission(MANAGE_APP_PREDICTIONS, TAG);
     }
 
+    @Override // from AbstractMasterSystemService
+    protected void onServicePackageUpdatedLocked(@UserIdInt int userId) {
+        final AppPredictionPerUserService service = peekServiceForUserLocked(userId);
+        if (service != null) {
+            service.onPackageUpdatedLocked();
+        }
+    }
+
+    @Override // from AbstractMasterSystemService
+    protected void onServicePackageRestartedLocked(@UserIdInt int userId) {
+        final AppPredictionPerUserService service = peekServiceForUserLocked(userId);
+        if (service != null) {
+            service.onPackageRestartedLocked();
+        }
+    }
+
     @Override
     protected int getMaximumTemporaryServiceDurationMs() {
         return MAX_TEMP_SERVICE_DURATION_MS;
diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
index 03c4542..4f49fb7 100644
--- a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
+++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
@@ -251,6 +251,40 @@
         // Do nothing, eventually the system will bind to the remote service again...
     }
 
+    void onPackageUpdatedLocked() {
+        if (isDebug()) {
+            Slog.v(TAG, "onPackageUpdatedLocked()");
+        }
+        destroyAndRebindRemoteService();
+    }
+
+    void onPackageRestartedLocked() {
+        if (isDebug()) {
+            Slog.v(TAG, "onPackageRestartedLocked()");
+        }
+        destroyAndRebindRemoteService();
+    }
+
+    private void destroyAndRebindRemoteService() {
+        if (mRemoteService == null) {
+            return;
+        }
+
+        if (isDebug()) {
+            Slog.d(TAG, "Destroying the old remote service.");
+        }
+        mRemoteService.destroy();
+        mRemoteService = null;
+
+        mRemoteService = getRemoteServiceLocked();
+        if (mRemoteService != null) {
+            if (isDebug()) {
+                Slog.d(TAG, "Rebinding to the new remote service.");
+            }
+            mRemoteService.reconnect();
+        }
+    }
+
     /**
      * Called after the remote service connected, it's used to restore state from a 'zombie'
      * service (i.e., after it died).
diff --git a/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java b/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java
index c82e7a0..04e0e7f 100644
--- a/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java
+++ b/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java
@@ -135,6 +135,13 @@
     }
 
     /**
+     * Schedules a request to bind to the remote service.
+     */
+    public void reconnect() {
+        super.scheduleBind();
+    }
+
+    /**
      * Failure callback
      */
     public interface RemoteAppPredictionServiceCallbacks
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index d260985..87991be 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -2407,7 +2407,9 @@
 
                 // Update the view states first...
                 mCurrentViewId = viewState.id;
-                viewState.setCurrentValue(value);
+                if (value != null) {
+                    viewState.setCurrentValue(value);
+                }
 
                 if (mCompatMode && (viewState.getState() & ViewState.STATE_URL_BAR) != 0) {
                     if (sDebug) Slog.d(TAG, "Ignoring VIEW_ENTERED on URL BAR (id=" + id + ")");
diff --git a/services/core/java/com/android/server/BluetoothService.java b/services/core/java/com/android/server/BluetoothService.java
index 5c5b477..6a6ddc8 100644
--- a/services/core/java/com/android/server/BluetoothService.java
+++ b/services/core/java/com/android/server/BluetoothService.java
@@ -54,8 +54,11 @@
 
     @Override
     public void onSwitchUser(int userHandle) {
-        initialize();
-        mBluetoothManagerService.handleOnSwitchUser(userHandle);
+        if (!mInitialized) {
+            initialize();
+        } else {
+            mBluetoothManagerService.handleOnSwitchUser(userHandle);
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 52a4218..2ab46e6 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -2737,7 +2737,9 @@
                 resetIdleManagementLocked();
                 // Wait a small amount of time in case something (eg: background service from
                 // recently closed app) needs to finish running.
-                scheduleAlarmLocked(mConstants.QUICK_DOZE_DELAY_TIMEOUT, false);
+                // Use a non-wakeup alarm for going into quick doze in case an AlarmClock alarm
+                // is scheduled soon. The non-wakeup alarm will be delayed by at most 2 minutes.
+                scheduleAlarmLocked(mConstants.QUICK_DOZE_DELAY_TIMEOUT, false, false);
                 EventLogTags.writeDeviceIdle(mState, "no activity");
             } else if (mState == STATE_ACTIVE) {
                 mState = STATE_INACTIVE;
@@ -3362,6 +3364,10 @@
     }
 
     void scheduleAlarmLocked(long delay, boolean idleUntil) {
+        scheduleAlarmLocked(delay, idleUntil, true);
+    }
+
+    private void scheduleAlarmLocked(long delay, boolean idleUntil, boolean useWakeupAlarm) {
         if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")");
 
         if (mUseMotionSensor && mMotionSensor == null
@@ -3377,12 +3383,14 @@
             // can continue until the user interacts with the device.
             return;
         }
+        final int alarmType = useWakeupAlarm
+                ? AlarmManager.ELAPSED_REALTIME_WAKEUP : AlarmManager.ELAPSED_REALTIME;
         mNextAlarmTime = SystemClock.elapsedRealtime() + delay;
         if (idleUntil) {
-            mAlarmManager.setIdleUntil(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+            mAlarmManager.setIdleUntil(alarmType,
                     mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
         } else {
-            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+            mAlarmManager.set(alarmType,
                     mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
         }
     }
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index 4d39f9a..bec08f4 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -39,6 +39,12 @@
 27391 user_activity_timeout_override (override|2|3)
 27392 battery_saver_setting (threshold|1)
 
+
+# ---------------------------
+# ThermalManagerService.java
+# ---------------------------
+2737 thermal_changed (name|3),(type|1|5),(temperature|5),(sensor_status|1|5),(previous_system_status|1|5)
+
 #
 # Leave IDs through 2740 for more power logs (2730 used by battery_discharge above)
 #
diff --git a/services/core/java/com/android/server/MountServiceIdler.java b/services/core/java/com/android/server/MountServiceIdler.java
index 1891ba9..6bc1a57 100644
--- a/services/core/java/com/android/server/MountServiceIdler.java
+++ b/services/core/java/com/android/server/MountServiceIdler.java
@@ -27,6 +27,7 @@
 import android.content.Context;
 import android.os.RemoteException;
 import android.util.Slog;
+import java.util.concurrent.TimeUnit;
 
 public class MountServiceIdler extends JobService {
     private static final String TAG = "MountServiceIdler";
@@ -48,7 +49,7 @@
                     mStarted = false;
                 }
             }
-            // ... and try again tomorrow
+            // ... and try again right away or tomorrow
             scheduleIdlePass(MountServiceIdler.this);
         }
     };
@@ -98,24 +99,32 @@
     public static void scheduleIdlePass(Context context) {
         JobScheduler tm = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
 
-        Calendar calendar = tomorrowMidnight();
-        final long timeToMidnight = calendar.getTimeInMillis() - System.currentTimeMillis();
+        final long today3AM = offsetFromTodayMidnight(0, 3).getTimeInMillis();
+        final long today4AM = offsetFromTodayMidnight(0, 4).getTimeInMillis();
+        final long tomorrow3AM = offsetFromTodayMidnight(1, 3).getTimeInMillis();
+
+        long nextScheduleTime;
+        if (System.currentTimeMillis() > today3AM && System.currentTimeMillis() < today4AM) {
+            nextScheduleTime = TimeUnit.SECONDS.toMillis(10);
+        } else {
+            nextScheduleTime = tomorrow3AM - System.currentTimeMillis(); // 3AM tomorrow
+        }
 
         JobInfo.Builder builder = new JobInfo.Builder(MOUNT_JOB_ID, sIdleService);
         builder.setRequiresDeviceIdle(true);
-        builder.setRequiresCharging(true);
-        builder.setMinimumLatency(timeToMidnight);
+        builder.setRequiresBatteryNotLow(true);
+        builder.setMinimumLatency(nextScheduleTime);
         tm.schedule(builder.build());
     }
 
-    private static Calendar tomorrowMidnight() {
+    private static Calendar offsetFromTodayMidnight(int nDays, int nHours) {
         Calendar calendar = Calendar.getInstance();
         calendar.setTimeInMillis(System.currentTimeMillis());
-        calendar.set(Calendar.HOUR_OF_DAY, 3);
+        calendar.set(Calendar.HOUR_OF_DAY, nHours);
         calendar.set(Calendar.MINUTE, 0);
         calendar.set(Calendar.SECOND, 0);
         calendar.set(Calendar.MILLISECOND, 0);
-        calendar.add(Calendar.DAY_OF_MONTH, 1);
+        calendar.add(Calendar.DAY_OF_MONTH, nDays);
         return calendar;
     }
 }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index e66e596..f7e825e 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -1027,7 +1027,12 @@
                 log(str);
             }
             mLocalLog.log(str);
-            if (validatePhoneId(phoneId)) {
+            // for service state updates, don't notify clients when subId is invalid. This prevents
+            // us from sending incorrect notifications like b/133140128
+            // In the future, we can remove this logic for every notification here and add a
+            // callback so listeners know when their PhoneStateListener's subId becomes invalid, but
+            // for now we use the simplest fix.
+            if (validatePhoneId(phoneId) && SubscriptionManager.isValidSubscriptionId(subId)) {
                 mServiceState[phoneId] = state;
 
                 for (Record r : mRecords) {
@@ -1059,7 +1064,8 @@
                     }
                 }
             } else {
-                log("notifyServiceStateForSubscriber: INVALID phoneId=" + phoneId);
+                log("notifyServiceStateForSubscriber: INVALID phoneId=" + phoneId
+                        + " or subId=" + subId);
             }
             handleRemoveListLocked();
         }
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 30a3563..6b03897 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -48,7 +48,6 @@
 import android.os.ShellCommand;
 import android.os.SystemProperties;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.provider.Settings.Secure;
 import android.service.dreams.Sandman;
 import android.service.vr.IVrManager;
@@ -218,6 +217,15 @@
         }
     };
 
+    private final ContentObserver mDarkThemeObserver = new ContentObserver(mHandler) {
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            final int mode = Secure.getIntForUser(getContext().getContentResolver(),
+                    Secure.UI_NIGHT_MODE, mNightMode, 0);
+            SystemProperties.set(SYSTEM_PROPERTY_DEVICE_THEME, Integer.toString(mode));
+        }
+    };
+
     @Override
     public void onSwitchUser(int userHandle) {
         super.onSwitchUser(userHandle);
@@ -293,6 +301,9 @@
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_USER_SWITCHED);
         context.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);
+
+        context.getContentResolver().registerContentObserver(Secure.getUriFor(Secure.UI_NIGHT_MODE),
+                false, mDarkThemeObserver, 0);
     }
 
     // Records whether setup wizard has happened or not and adds an observer for this user if not.
@@ -417,11 +428,6 @@
                         if (!mCarModeEnabled) {
                             Secure.putIntForUser(getContext().getContentResolver(),
                                     Secure.UI_NIGHT_MODE, mode, user);
-
-                            if (UserManager.get(getContext()).isPrimaryUser()) {
-                                SystemProperties.set(SYSTEM_PROPERTY_DEVICE_THEME,
-                                        Integer.toString(mode));
-                            }
                         }
 
                         mNightMode = mode;
diff --git a/services/core/java/com/android/server/accounts/AccountManagerServiceShellCommand.java b/services/core/java/com/android/server/accounts/AccountManagerServiceShellCommand.java
index 9e5f722..9bf0bd3 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerServiceShellCommand.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerServiceShellCommand.java
@@ -17,6 +17,7 @@
 package com.android.server.accounts;
 
 import android.annotation.NonNull;
+import android.app.ActivityManager;
 import android.os.ShellCommand;
 import android.os.UserHandle;
 
@@ -83,7 +84,7 @@
                 return null;
             }
         }
-        return UserHandle.USER_SYSTEM;
+        return ActivityManager.getCurrentUser();
     }
 
     @Override
@@ -92,9 +93,11 @@
         pw.println("Account manager service commands:");
         pw.println("  help");
         pw.println("    Print this help text.");
-        pw.println("  set-bind-instant-service-allowed [--user <USER_ID>] true|false ");
+        pw.println("  set-bind-instant-service-allowed "
+                + "[--user <USER_ID> (current user if not specified)] true|false ");
         pw.println("    Set whether binding to services provided by instant apps is allowed.");
-        pw.println("  get-bind-instant-service-allowed [--user <USER_ID>]");
+        pw.println("  get-bind-instant-service-allowed "
+                + "[--user <USER_ID> (current user if not specified)]");
         pw.println("    Get whether binding to services provided by instant apps is allowed.");
     }
 }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 60bc9ae..54192a9 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5255,11 +5255,14 @@
 
         // Inform checkpointing systems of success
         try {
+            // This line is needed to CTS test for the correct exception handling
+            // See b/138952436#comment36 for context
+            Slog.i(TAG, "About to commit checkpoint");
             IStorageManager storageManager = PackageHelper.getStorageManager();
             storageManager.commitChanges();
         } catch (Exception e) {
             PowerManager pm = (PowerManager)
-                     mContext.getSystemService(Context.POWER_SERVICE);
+                     mInjector.getContext().getSystemService(Context.POWER_SERVICE);
             pm.reboot("Checkpoint commit failed");
         }
 
@@ -9023,7 +9026,16 @@
                 Integer.toString(currentUserId), currentUserId);
         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
                 Integer.toString(currentUserId), currentUserId);
-        mSystemServiceManager.startUser(currentUserId);
+
+        // On Automotive, at this point the system user has already been started and unlocked,
+        // and some of the tasks we do here have already been done. So skip those in that case.
+        // TODO(b/132262830): this workdound shouldn't be necessary once we move the
+        // headless-user start logic to UserManager-land
+        final boolean bootingSystemUser = currentUserId == UserHandle.USER_SYSTEM;
+
+        if (bootingSystemUser) {
+            mSystemServiceManager.startUser(currentUserId);
+        }
 
         synchronized (this) {
             // Only start up encryption-aware persistent apps; once user is
@@ -9047,43 +9059,53 @@
                     throw e.rethrowAsRuntimeException();
                 }
             }
-            mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
+
+            if (bootingSystemUser) {
+                mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
+            }
 
             mAtmInternal.showSystemReadyErrorDialogsIfNeeded();
 
-            final int callingUid = Binder.getCallingUid();
-            final int callingPid = Binder.getCallingPid();
-            long ident = Binder.clearCallingIdentity();
-            try {
-                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
-                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
-                        | Intent.FLAG_RECEIVER_FOREGROUND);
-                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
-                broadcastIntentLocked(null, null, intent,
-                        null, null, 0, null, null, null, OP_NONE,
-                        null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid,
-                        currentUserId);
-                intent = new Intent(Intent.ACTION_USER_STARTING);
-                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
-                broadcastIntentLocked(null, null, intent,
-                        null, new IIntentReceiver.Stub() {
-                            @Override
-                            public void performReceive(Intent intent, int resultCode, String data,
-                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
-                                    throws RemoteException {
-                            }
-                        }, 0, null, null,
-                        new String[] {INTERACT_ACROSS_USERS}, OP_NONE,
-                        null, true, false, MY_PID, SYSTEM_UID, callingUid, callingPid,
-                        UserHandle.USER_ALL);
-            } catch (Throwable t) {
-                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
-            } finally {
-                Binder.restoreCallingIdentity(ident);
+            if (bootingSystemUser) {
+                final int callingUid = Binder.getCallingUid();
+                final int callingPid = Binder.getCallingPid();
+                long ident = Binder.clearCallingIdentity();
+                try {
+                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
+                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
+                            | Intent.FLAG_RECEIVER_FOREGROUND);
+                    intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
+                    broadcastIntentLocked(null, null, intent,
+                            null, null, 0, null, null, null, OP_NONE,
+                            null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid,
+                            currentUserId);
+                    intent = new Intent(Intent.ACTION_USER_STARTING);
+                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+                    intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
+                    broadcastIntentLocked(null, null, intent,
+                            null, new IIntentReceiver.Stub() {
+                                @Override
+                                public void performReceive(Intent intent, int resultCode, String data,
+                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
+                                        throws RemoteException {
+                                }
+                            }, 0, null, null,
+                            new String[] {INTERACT_ACROSS_USERS}, OP_NONE,
+                            null, true, false, MY_PID, SYSTEM_UID, callingUid, callingPid,
+                            UserHandle.USER_ALL);
+                } catch (Throwable t) {
+                    Slog.wtf(TAG, "Failed sending first user broadcasts", t);
+                } finally {
+                    Binder.restoreCallingIdentity(ident);
+                }
+            } else {
+                Slog.i(TAG, "Not sending multi-user broadcasts for non-system user "
+                        + currentUserId);
             }
             mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
-            mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
+            if (bootingSystemUser) {
+                mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
+            }
 
             BinderInternal.nSetBinderProxyCountWatermarks(BINDER_PROXY_HIGH_WATERMARK,
                     BINDER_PROXY_LOW_WATERMARK);
@@ -14975,7 +14997,12 @@
                             final int uid = getUidFromIntent(intent);
                             if (uid >= 0) {
                                 mBatteryStatsService.removeUid(uid);
-                                mAppOpsService.uidRemoved(uid);
+                                if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+                                    mAppOpsService.resetAllModes(UserHandle.getUserId(uid),
+                                            intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME));
+                                } else {
+                                    mAppOpsService.uidRemoved(uid);
+                                }
                             }
                             break;
                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
@@ -17971,7 +17998,7 @@
 
         @Override
         public int getCurrentUserId() {
-            return mUserController.getCurrentUserIdLU();
+            return mUserController.getCurrentUserId();
         }
 
         @Override
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index c2f4529..a47ea4f 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -722,10 +722,10 @@
         }
     }
 
-    public void notePhoneDataConnectionState(int dataType, boolean hasData) {
+    public void notePhoneDataConnectionState(int dataType, boolean hasData, int serviceType) {
         enforceCallingPermission();
         synchronized (mStats) {
-            mStats.notePhoneDataConnectionStateLocked(dataType, hasData);
+            mStats.notePhoneDataConnectionStateLocked(dataType, hasData, serviceType);
         }
     }
 
@@ -756,7 +756,7 @@
     }
 
     public void noteStartAudio(int uid) {
-        enforceSelfOrCallingPermission(uid);
+        enforceCallingPermission();
         synchronized (mStats) {
             mStats.noteAudioOnLocked(uid);
             StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, uid, null,
@@ -765,7 +765,7 @@
     }
 
     public void noteStopAudio(int uid) {
-        enforceSelfOrCallingPermission(uid);
+        enforceCallingPermission();
         synchronized (mStats) {
             mStats.noteAudioOffLocked(uid);
             StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, uid, null,
@@ -774,7 +774,7 @@
     }
 
     public void noteStartVideo(int uid) {
-        enforceSelfOrCallingPermission(uid);
+        enforceCallingPermission();
         synchronized (mStats) {
             mStats.noteVideoOnLocked(uid);
             StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_STATE_CHANGED, uid, null,
@@ -783,7 +783,7 @@
     }
 
     public void noteStopVideo(int uid) {
-        enforceSelfOrCallingPermission(uid);
+        enforceCallingPermission();
         synchronized (mStats) {
             mStats.noteVideoOffLocked(uid);
             StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_STATE_CHANGED, uid,
@@ -1184,13 +1184,6 @@
                 Binder.getCallingPid(), Binder.getCallingUid(), null);
     }
 
-    private void enforceSelfOrCallingPermission(int uid) {
-        if (Binder.getCallingUid() == uid) {
-            return;
-        }
-        enforceCallingPermission();
-    }
-
     final class WakeupReasonThread extends Thread {
         private static final int MAX_REASON_SIZE = 512;
         private CharsetDecoder mDecoder;
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index b399971..838e7d3 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -2094,10 +2094,10 @@
                     }
                 }
             }
-            if (lrui <= mLruProcessActivityStart) {
+            if (lrui < mLruProcessActivityStart) {
                 mLruProcessActivityStart--;
             }
-            if (lrui <= mLruProcessServiceStart) {
+            if (lrui < mLruProcessServiceStart) {
                 mLruProcessServiceStart--;
             }
             mLruProcesses.remove(lrui);
@@ -2629,7 +2629,7 @@
                         if (!moved) {
                             // Goes to the end of the group.
                             mLruProcesses.remove(i);
-                            mLruProcesses.add(endIndex - 1, subProc);
+                            mLruProcesses.add(endIndex, subProc);
                             if (DEBUG_LRU) Slog.d(TAG_LRU,
                                     "Moving " + subProc
                                             + " from position " + i + " to end of group @ "
@@ -2874,15 +2874,6 @@
                     pos--;
                 }
                 mLruProcesses.add(pos, app);
-                if (pos == mLruProcessActivityStart) {
-                    mLruProcessActivityStart++;
-                }
-                if (pos == mLruProcessServiceStart) {
-                    // Unless {@code #hasService} is implemented, currently the starting position
-                    // for activity and service are the same, so the incoming position may equal to
-                    // the starting position of service.
-                    mLruProcessServiceStart++;
-                }
                 // If this process is part of a group, need to pull up any other processes
                 // in that group to be with it.
                 int endIndex = pos - 1;
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index f0fac67..3ba31e9 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -518,6 +518,10 @@
 
         private void updateProxyState(long key, int proxyUid,
             @Nullable String proxyPackageName) {
+            if (proxyUid == Process.INVALID_UID) {
+                return;
+            }
+
             if (mProxyUids == null) {
                 mProxyUids = new LongSparseLongArray();
             }
@@ -3000,17 +3004,40 @@
                 out.startTag(null, "app-ops");
                 out.attribute(null, "v", String.valueOf(CURRENT_VERSION));
 
-                final int uidStateCount = mUidStates.size();
-                for (int i = 0; i < uidStateCount; i++) {
-                    UidState uidState = mUidStates.valueAt(i);
-                    if (uidState.opModes != null && uidState.opModes.size() > 0) {
+                SparseArray<SparseIntArray> uidStatesClone;
+                synchronized (this) {
+                    uidStatesClone = new SparseArray<>(mUidStates.size());
+
+                    final int uidStateCount = mUidStates.size();
+                    for (int uidStateNum = 0; uidStateNum < uidStateCount; uidStateNum++) {
+                        UidState uidState = mUidStates.valueAt(uidStateNum);
+                        int uid = mUidStates.keyAt(uidStateNum);
+
+                        SparseIntArray opModes = uidState.opModes;
+                        if (opModes != null && opModes.size() > 0) {
+                            uidStatesClone.put(uid, new SparseIntArray(opModes.size()));
+
+                            final int opCount = opModes.size();
+                            for (int opCountNum = 0; opCountNum < opCount; opCountNum++) {
+                                uidStatesClone.get(uid).put(
+                                        opModes.keyAt(opCountNum),
+                                        opModes.valueAt(opCountNum));
+                            }
+                        }
+                    }
+                }
+
+                final int uidStateCount = uidStatesClone.size();
+                for (int uidStateNum = 0; uidStateNum < uidStateCount; uidStateNum++) {
+                    SparseIntArray opModes = uidStatesClone.valueAt(uidStateNum);
+                    if (opModes != null && opModes.size() > 0) {
                         out.startTag(null, "uid");
-                        out.attribute(null, "n", Integer.toString(uidState.uid));
-                        SparseIntArray uidOpModes = uidState.opModes;
-                        final int opCount = uidOpModes.size();
-                        for (int j = 0; j < opCount; j++) {
-                            final int op = uidOpModes.keyAt(j);
-                            final int mode = uidOpModes.valueAt(j);
+                        out.attribute(null, "n",
+                                Integer.toString(uidStatesClone.keyAt(uidStateNum)));
+                        final int opCount = opModes.size();
+                        for (int opCountNum = 0; opCountNum < opCount; opCountNum++) {
+                            final int op = opModes.keyAt(opCountNum);
+                            final int mode = opModes.valueAt(opCountNum);
                             out.startTag(null, "op");
                             out.attribute(null, "n", Integer.toString(op));
                             out.attribute(null, "m", Integer.toString(mode));
diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java
index ee49f58..387d7a8 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -53,6 +53,7 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.provider.Settings;
 import android.util.Slog;
 
 import com.android.internal.R;
@@ -926,7 +927,8 @@
                     final Face face = new Face("", 0 /* identifier */, deviceId);
                     FaceService.super.handleRemoved(face, 0 /* remaining */);
                 }
-
+                Settings.Secure.putIntForUser(getContext().getContentResolver(),
+                        Settings.Secure.FACE_UNLOCK_RE_ENROLL, 0, UserHandle.USER_CURRENT);
             });
         }
 
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
index acb0207..85ca627 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
@@ -35,6 +35,8 @@
 import android.hardware.broadcastradio.V2_0.VendorKeyValue;
 import android.hardware.radio.RadioManager;
 import android.os.DeadObjectException;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.RemoteException;
 import android.util.MutableInt;
 import android.util.Slog;
@@ -44,6 +46,7 @@
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -55,6 +58,7 @@
     @NonNull public final RadioManager.ModuleProperties mProperties;
 
     private final Object mLock = new Object();
+    @NonNull private final Handler mHandler;
 
     @GuardedBy("mLock")
     private ITunerSession mHalTunerSession;
@@ -70,38 +74,46 @@
     private final ITunerCallback mHalTunerCallback = new ITunerCallback.Stub() {
         @Override
         public void onTuneFailed(int result, ProgramSelector programSelector) {
-            fanoutAidlCallback(cb -> cb.onTuneFailed(result, Convert.programSelectorFromHal(
-                    programSelector)));
+            lockAndFireLater(() -> {
+                android.hardware.radio.ProgramSelector csel =
+                        Convert.programSelectorFromHal(programSelector);
+                fanoutAidlCallbackLocked(cb -> cb.onTuneFailed(result, csel));
+            });
         }
 
         @Override
         public void onCurrentProgramInfoChanged(ProgramInfo halProgramInfo) {
-            RadioManager.ProgramInfo programInfo = Convert.programInfoFromHal(halProgramInfo);
-            synchronized (mLock) {
-                mProgramInfo = programInfo;
-                fanoutAidlCallbackLocked(cb -> cb.onCurrentProgramInfoChanged(programInfo));
-            }
+            lockAndFireLater(() -> {
+                mProgramInfo = Convert.programInfoFromHal(halProgramInfo);
+                fanoutAidlCallbackLocked(cb -> cb.onCurrentProgramInfoChanged(mProgramInfo));
+            });
         }
 
         @Override
         public void onProgramListUpdated(ProgramListChunk programListChunk) {
             // TODO: Cache per-AIDL client filters, send union of filters to HAL, use filters to fan
             // back out to clients.
-            fanoutAidlCallback(cb -> cb.onProgramListUpdated(Convert.programListChunkFromHal(
-                    programListChunk)));
+            lockAndFireLater(() -> {
+                android.hardware.radio.ProgramList.Chunk chunk =
+                        Convert.programListChunkFromHal(programListChunk);
+                fanoutAidlCallbackLocked(cb -> cb.onProgramListUpdated(chunk));
+            });
         }
 
         @Override
         public void onAntennaStateChange(boolean connected) {
-            synchronized (mLock) {
+            lockAndFireLater(() -> {
                 mAntennaConnected = connected;
                 fanoutAidlCallbackLocked(cb -> cb.onAntennaState(connected));
-            }
+            });
         }
 
         @Override
         public void onParametersUpdated(ArrayList<VendorKeyValue> parameters) {
-            fanoutAidlCallback(cb -> cb.onParametersUpdated(Convert.vendorInfoFromHal(parameters)));
+            lockAndFireLater(() -> {
+                Map<String, String> cparam = Convert.vendorInfoFromHal(parameters);
+                fanoutAidlCallbackLocked(cb -> cb.onParametersUpdated(cparam));
+            });
         }
     };
 
@@ -113,6 +125,7 @@
             @NonNull RadioManager.ModuleProperties properties) throws RemoteException {
         mProperties = Objects.requireNonNull(properties);
         mService = Objects.requireNonNull(service);
+        mHandler = new Handler(Looper.getMainLooper());
     }
 
     public static @Nullable RadioModule tryLoadingModule(int idx, @NonNull String fqName) {
@@ -201,15 +214,22 @@
         }
     }
 
+    // add to mHandler queue, but ensure the runnable holds mLock when it gets executed
+    private void lockAndFireLater(Runnable r) {
+        mHandler.post(() -> {
+            synchronized (mLock) {
+                r.run();
+            }
+        });
+    }
+
     interface AidlCallbackRunnable {
         void run(android.hardware.radio.ITunerCallback callback) throws RemoteException;
     }
 
     // Invokes runnable with each TunerSession currently open.
     void fanoutAidlCallback(AidlCallbackRunnable runnable) {
-        synchronized (mLock) {
-            fanoutAidlCallbackLocked(runnable);
-        }
+        lockAndFireLater(() -> fanoutAidlCallbackLocked(runnable));
     }
 
     private void fanoutAidlCallbackLocked(AidlCallbackRunnable runnable) {
diff --git a/services/core/java/com/android/server/connectivity/DataConnectionStats.java b/services/core/java/com/android/server/connectivity/DataConnectionStats.java
index 227ab23..4990ea1 100644
--- a/services/core/java/com/android/server/connectivity/DataConnectionStats.java
+++ b/services/core/java/com/android/server/connectivity/DataConnectionStats.java
@@ -91,7 +91,8 @@
         if (DEBUG) Log.d(TAG, String.format("Noting data connection for network type %s: %svisible",
                 networkType, visible ? "" : "not "));
         try {
-            mBatteryStats.notePhoneDataConnectionState(networkType, visible);
+            mBatteryStats.notePhoneDataConnectionState(networkType, visible,
+                    mServiceState.getState());
         } catch (RemoteException e) {
             Log.w(TAG, "Error noting data connection state", e);
         }
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index fbe2589..29c4bad 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -130,6 +130,11 @@
         }
 
         @Override
+        public void onPackageChanged(@NonNull String packageName, int uid) {
+            sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
+        }
+
+        @Override
         public void onPackageRemoved(String packageName, int uid) {
             sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
         }
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 73d160d..24581a2 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -455,7 +455,20 @@
 
             @Override
             public void onServiceConnected(int profile, BluetoothProfile proxy) {
-                ((BluetoothPan) proxy).setBluetoothTethering(enable);
+                // Clear identify is fine because caller already pass tethering permission at
+                // ConnectivityService#startTethering()(or stopTethering) before the control comes
+                // here. Bluetooth will check tethering permission again that there is
+                // Context#getOpPackageName() under BluetoothPan#setBluetoothTethering() to get
+                // caller's package name for permission check.
+                // Calling BluetoothPan#setBluetoothTethering() here means the package name always
+                // be system server. If calling identity is not cleared, that package's uid might
+                // not match calling uid and end up in permission denied.
+                final long identityToken = Binder.clearCallingIdentity();
+                try {
+                    ((BluetoothPan) proxy).setBluetoothTethering(enable);
+                } finally {
+                    Binder.restoreCallingIdentity(identityToken);
+                }
                 // TODO: Enabling bluetooth tethering can fail asynchronously here.
                 // We should figure out a way to bubble up that failure instead of sending success.
                 final int result = (((BluetoothPan) proxy).isTetheringOn() == enable)
diff --git a/services/core/java/com/android/server/display/ColorFade.java b/services/core/java/com/android/server/display/ColorFade.java
index f613064..c46fc20 100644
--- a/services/core/java/com/android/server/display/ColorFade.java
+++ b/services/core/java/com/android/server/display/ColorFade.java
@@ -649,13 +649,8 @@
         if (mSurfaceControl != null) {
             mSurfaceLayout.dispose();
             mSurfaceLayout = null;
-            SurfaceControl.openTransaction();
-            try {
-                mSurfaceControl.remove();
-                mSurface.release();
-            } finally {
-                SurfaceControl.closeTransaction();
-            }
+            new Transaction().remove(mSurfaceControl).apply();
+            mSurface.release();
             mSurfaceControl = null;
             mSurfaceVisible = false;
             mSurfaceAlpha = 0f;
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index 500a242..1fc0db3 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -766,6 +766,7 @@
         @Override
         public void onDisplayChanged(int displayId) {
             updateDisplayModes(displayId);
+            mBrightnessObserver.onDisplayChanged(displayId);
         }
 
         private void updateDisplayModes(int displayId) {
@@ -820,7 +821,6 @@
         private AmbientFilter mAmbientFilter;
 
         private final Context mContext;
-        private final ScreenStateReceiver mScreenStateReceiver;
 
         // Enable light sensor only when mShouldObserveAmbientChange is true, screen is on, peak
         // refresh rate changeable and low power mode off. After initialization, these states will
@@ -834,7 +834,6 @@
         BrightnessObserver(Context context, Handler handler) {
             super(handler);
             mContext = context;
-            mScreenStateReceiver = new ScreenStateReceiver(mContext);
             mDisplayBrightnessThresholds = context.getResources().getIntArray(
                     R.array.config_brightnessThresholdsOfPeakRefreshRate);
             mAmbientBrightnessThresholds = context.getResources().getIntArray(
@@ -919,12 +918,16 @@
             }
         }
 
+        public void onDisplayChanged(int displayId) {
+            if (displayId == Display.DEFAULT_DISPLAY) {
+                onScreenOn(isDefaultDisplayOn());
+            }
+        }
+
         @Override
         public void onChange(boolean selfChange, Uri uri, int userId) {
             synchronized (mLock) {
-                if (mRefreshRateChangeable) {
-                    onBrightnessChangedLocked();
-                }
+                onBrightnessChangedLocked();
             }
         }
 
@@ -970,16 +973,11 @@
                     mAmbientFilter = DisplayWhiteBalanceFactory.createBrightnessFilter(res);
                     mLightSensor = lightSensor;
 
-                    // Intent.ACTION_SCREEN_ON is not sticky. Check current screen status.
-                    if (mContext.getSystemService(PowerManager.class).isInteractive()) {
-                        onScreenOn(true);
-                    }
-                    mScreenStateReceiver.register();
+                    onScreenOn(isDefaultDisplayOn());
                 }
             } else {
                 mAmbientFilter = null;
                 mLightSensor = null;
-                mScreenStateReceiver.unregister();
             }
 
             if (mRefreshRateChangeable) {
@@ -1049,8 +1047,6 @@
         }
 
         private void onScreenOn(boolean on) {
-            // Not check mShouldObserveAmbientChange because Screen status receiver is registered
-            // only when it is true.
             if (mScreenOn != on) {
                 mScreenOn = on;
                 updateSensorStatus();
@@ -1072,6 +1068,13 @@
             }
         }
 
+        private boolean isDefaultDisplayOn() {
+            final Display display = mContext.getSystemService(DisplayManager.class)
+                    .getDisplay(Display.DEFAULT_DISPLAY);
+            return display.getState() != Display.STATE_OFF
+                    && mContext.getSystemService(PowerManager.class).isInteractive();
+        }
+
         private final class LightSensorEventListener implements SensorEventListener {
             final private static int INJECT_EVENTS_INTERVAL_MS = LIGHT_SENSOR_RATE_MS;
             private float mLastSensorData;
@@ -1149,38 +1152,6 @@
                     }
                 }
             };
-        };
-
-        private final class ScreenStateReceiver extends BroadcastReceiver {
-            final Context mContext;
-            boolean mRegistered;
-
-            public ScreenStateReceiver(Context context) {
-                mContext = context;
-            }
-
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                onScreenOn(Intent.ACTION_SCREEN_ON.equals(intent.getAction()));
-            }
-
-            public void register() {
-                if (!mRegistered) {
-                    IntentFilter filter = new IntentFilter();
-                    filter.addAction(Intent.ACTION_SCREEN_OFF);
-                    filter.addAction(Intent.ACTION_SCREEN_ON);
-                    filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
-                    mContext.registerReceiver(this, filter, null, mHandler);
-                    mRegistered = true;
-                }
-            }
-
-            public void unregister() {
-                if (mRegistered) {
-                    mContext.unregisterReceiver(this);
-                    mRegistered = false;
-                }
-            }
         }
     }
 
diff --git a/services/core/java/com/android/server/display/color/ColorDisplayService.java b/services/core/java/com/android/server/display/color/ColorDisplayService.java
index 7fb5b19..0bf43b6 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -609,6 +609,9 @@
 
                 @Override
                 public void onAnimationEnd(Animator animator) {
+                    Slog.d(TAG, tintController.getClass().getSimpleName()
+                            + " Animation cancelled: " + mIsCancelled
+                            + " to matrix: " + TintController.matrixToString(to, 16));
                     if (!mIsCancelled) {
                         // Ensure final color matrix is set at the end of the animation. If the
                         // animation is cancelled then don't set the final color matrix so the new
@@ -1314,8 +1317,10 @@
          * Reset the CCT value for the display white balance transform to its default value.
          */
         public boolean resetDisplayWhiteBalanceColorTemperature() {
-            return setDisplayWhiteBalanceColorTemperature(getContext().getResources()
-                    .getInteger(R.integer.config_displayWhiteBalanceColorTemperatureDefault));
+            int temperatureDefault = getContext().getResources()
+                    .getInteger(R.integer.config_displayWhiteBalanceColorTemperatureDefault);
+            Slog.d(TAG, "resetDisplayWhiteBalanceColorTemperature: " + temperatureDefault);
+            return setDisplayWhiteBalanceColorTemperature(temperatureDefault);
         }
 
         /**
diff --git a/services/core/java/com/android/server/display/color/DisplayWhiteBalanceTintController.java b/services/core/java/com/android/server/display/color/DisplayWhiteBalanceTintController.java
index d2c6cd9..3f1c222 100644
--- a/services/core/java/com/android/server/display/color/DisplayWhiteBalanceTintController.java
+++ b/services/core/java/com/android/server/display/color/DisplayWhiteBalanceTintController.java
@@ -149,8 +149,6 @@
             cct = mTemperatureMax;
         }
 
-        Slog.d(ColorDisplayService.TAG, "setDisplayWhiteBalanceTemperatureMatrix: cct = " + cct);
-
         synchronized (mLock) {
             mCurrentColorTemperature = cct;
 
@@ -185,6 +183,9 @@
             java.lang.System.arraycopy(result, 3, mMatrixDisplayWhiteBalance, 4, 3);
             java.lang.System.arraycopy(result, 6, mMatrixDisplayWhiteBalance, 8, 3);
         }
+
+        Slog.d(ColorDisplayService.TAG, "setDisplayWhiteBalanceTemperatureMatrix: cct = " + cct
+                + " matrix = " + matrixToString(mMatrixDisplayWhiteBalance, 16));
     }
 
     @Override
@@ -225,28 +226,6 @@
         }
     }
 
-    /**
-     * Format a given matrix into a string.
-     *
-     * @param matrix the matrix to format
-     * @param columns number of columns in the matrix
-     */
-    private String matrixToString(float[] matrix, int columns) {
-        if (matrix == null || columns <= 0) {
-            Slog.e(ColorDisplayService.TAG, "Invalid arguments when formatting matrix to string");
-            return "";
-        }
-
-        final StringBuilder sb = new StringBuilder("");
-        for (int i = 0; i < matrix.length; i++) {
-            if (i % columns == 0) {
-                sb.append("\n      ");
-            }
-            sb.append(String.format("%9.6f", matrix[i]));
-        }
-        return sb.toString();
-    }
-
     private ColorSpace.Rgb makeRgbColorSpaceFromXYZ(float[] redGreenBlueXYZ, float[] whiteXYZ) {
         return new ColorSpace.Rgb(
                 "Display Color Space",
diff --git a/services/core/java/com/android/server/display/color/TintController.java b/services/core/java/com/android/server/display/color/TintController.java
index b291c64..8d8b9b2 100644
--- a/services/core/java/com/android/server/display/color/TintController.java
+++ b/services/core/java/com/android/server/display/color/TintController.java
@@ -18,6 +18,7 @@
 
 import android.animation.ValueAnimator;
 import android.content.Context;
+import android.util.Slog;
 
 import java.io.PrintWriter;
 
@@ -95,4 +96,29 @@
      * Returns whether or not this transform type is available on this device.
      */
     public abstract boolean isAvailable(Context context);
+
+    /**
+     * Format a given matrix into a string.
+     *
+     * @param matrix the matrix to format
+     * @param columns number of columns in the matrix
+     */
+    static String matrixToString(float[] matrix, int columns) {
+        if (matrix == null || columns <= 0) {
+            Slog.e(ColorDisplayService.TAG, "Invalid arguments when formatting matrix to string,"
+                    + " matrix is null: " + (matrix == null)
+                    + " columns: " + columns);
+            return "";
+        }
+
+        final StringBuilder sb = new StringBuilder("");
+        for (int i = 0; i < matrix.length; i++) {
+            if (i % columns == 0) {
+                sb.append("\n      ");
+            }
+            sb.append(String.format("%9.6f", matrix[i]));
+        }
+        return sb.toString();
+    }
+
 }
diff --git a/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java b/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java
index 02ec10e..7b1f4c3 100644
--- a/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java
+++ b/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java
@@ -95,6 +95,11 @@
     // A piecewise linear relationship between high light brightness and high light bias.
     private Spline.LinearSpline mHighLightAmbientBrightnessToBiasSpline;
 
+    private float mLatestAmbientColorTemperature;
+    private float mLatestAmbientBrightness;
+    private float mLatestLowLightBias;
+    private float mLatestHighLightBias;
+
     /**
      * @param brightnessSensor
      *      The sensor used to detect changes in the ambient brightness.
@@ -348,6 +353,7 @@
     public void updateAmbientColorTemperature() {
         final long time = System.currentTimeMillis();
         float ambientColorTemperature = mColorTemperatureFilter.getEstimate(time);
+        mLatestAmbientColorTemperature = ambientColorTemperature;
 
         if (mAmbientToDisplayColorTemperatureSpline != null && ambientColorTemperature != -1.0f) {
             ambientColorTemperature =
@@ -355,6 +361,7 @@
         }
 
         float ambientBrightness = mBrightnessFilter.getEstimate(time);
+        mLatestAmbientBrightness = ambientBrightness;
 
         if (ambientColorTemperature != -1.0f &&
                 mLowLightAmbientBrightnessToBiasSpline != null) {
@@ -362,6 +369,7 @@
             ambientColorTemperature =
                     bias * ambientColorTemperature + (1.0f - bias)
                     * mLowLightAmbientColorTemperature;
+            mLatestLowLightBias = bias;
         }
         if (ambientColorTemperature != -1.0f &&
                 mHighLightAmbientBrightnessToBiasSpline != null) {
@@ -369,6 +377,7 @@
             ambientColorTemperature =
                     (1.0f - bias) * ambientColorTemperature + bias
                     * mHighLightAmbientColorTemperature;
+            mLatestHighLightBias = bias;
         }
 
         if (mAmbientColorTemperatureOverride != -1.0f) {
@@ -426,6 +435,11 @@
         }
         mPendingAmbientColorTemperature = -1.0f;
         mAmbientColorTemperatureHistory.add(mAmbientColorTemperature);
+        Slog.d(TAG, "Display cct: " + mAmbientColorTemperature
+                + " Latest ambient cct: " + mLatestAmbientColorTemperature
+                + " Latest ambient lux: " + mLatestAmbientBrightness
+                + " Latest low light bias: " + mLatestLowLightBias
+                + " Latest high light bias: " + mLatestHighLightBias);
         mColorDisplayServiceInternal.setDisplayWhiteBalanceColorTemperature(
                 (int) mAmbientColorTemperature);
         mLastAmbientColorTemperature = mAmbientColorTemperature;
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index 9782f30..259527a 100644
--- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
@@ -79,7 +79,7 @@
         S extends AbstractPerUserSystemService<S, M>> extends SystemService {
 
     /** On a package update, does not refresh the per-user service in the cache. */
-    public static final int PACKAGE_UPDATE_POLICY_NO_REFRESH = 0;
+    public static final int PACKAGE_UPDATE_POLICY_NO_REFRESH = 0x00000001;
 
     /**
      * On a package update, removes any existing per-user services in the cache.
@@ -87,20 +87,40 @@
      * <p>This does not immediately recreate these services. It is assumed they will be recreated
      * for the next user request.
      */
-    public static final int PACKAGE_UPDATE_POLICY_REFRESH_LAZY = 1;
+    public static final int PACKAGE_UPDATE_POLICY_REFRESH_LAZY = 0x00000002;
 
     /**
      * On a package update, removes and recreates any existing per-user services in the cache.
      */
-    public static final int PACKAGE_UPDATE_POLICY_REFRESH_EAGER = 2;
+    public static final int PACKAGE_UPDATE_POLICY_REFRESH_EAGER = 0x00000004;
 
-    @IntDef(flag = true, prefix = { "PACKAGE_UPDATE_POLICY_" }, value = {
+    /** On a package restart, does not refresh the per-user service in the cache. */
+    public static final int PACKAGE_RESTART_POLICY_NO_REFRESH = 0x00000010;
+
+    /**
+     * On a package restart, removes any existing per-user services in the cache.
+     *
+     * <p>This does not immediately recreate these services. It is assumed they will be recreated
+     * for the next user request.
+     */
+    public static final int PACKAGE_RESTART_POLICY_REFRESH_LAZY = 0x00000020;
+
+    /**
+     * On a package restart, removes and recreates any existing per-user services in the cache.
+     */
+    public static final int PACKAGE_RESTART_POLICY_REFRESH_EAGER = 0x00000040;
+
+    @IntDef(flag = true, prefix = { "PACKAGE_" }, value = {
             PACKAGE_UPDATE_POLICY_NO_REFRESH,
             PACKAGE_UPDATE_POLICY_REFRESH_LAZY,
-            PACKAGE_UPDATE_POLICY_REFRESH_EAGER
+            PACKAGE_UPDATE_POLICY_REFRESH_EAGER,
+            PACKAGE_RESTART_POLICY_NO_REFRESH,
+            PACKAGE_RESTART_POLICY_REFRESH_LAZY,
+            PACKAGE_RESTART_POLICY_REFRESH_EAGER
     })
+
     @Retention(RetentionPolicy.SOURCE)
-    public @interface PackageUpdatePolicy {}
+    public @interface ServicePackagePolicyFlags {}
 
     /**
      * Log tag
@@ -153,12 +173,10 @@
     private final SparseArray<S> mServicesCache = new SparseArray<>();
 
     /**
-     * Whether the per-user service should be removed from the cache when its apk is updated.
-     *
-     * <p>One of {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH},
-     * {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY} or {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER}.
+     * Value that determines whether the per-user service should be removed from the cache when its
+     * apk is updated or restarted.
      */
-    private final @PackageUpdatePolicy int mPackageUpdatePolicy;
+    private final @ServicePackagePolicyFlags int mServicePackagePolicyFlags;
 
     /**
      * Name of the service packages whose APK are being updated, keyed by user id.
@@ -184,11 +202,11 @@
             @Nullable ServiceNameResolver serviceNameResolver,
             @Nullable String disallowProperty) {
         this(context, serviceNameResolver, disallowProperty,
-                /*packageUpdatePolicy=*/ PACKAGE_UPDATE_POLICY_REFRESH_LAZY);
+                PACKAGE_UPDATE_POLICY_REFRESH_LAZY | PACKAGE_RESTART_POLICY_REFRESH_LAZY);
     }
 
     /**
-     * Full constructor.
+     * Full Constructor.
      *
      * @param context system context.
      * @param serviceNameResolver resolver for
@@ -197,19 +215,32 @@
      * @param disallowProperty when not {@code null}, defines a {@link UserManager} restriction that
      *        disables the service. <b>NOTE: </b> you'll also need to add it to
      *        {@code UserRestrictionsUtils.USER_RESTRICTIONS}.
-     * @param packageUpdatePolicy when {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY}, the
-     *        {@link AbstractPerUserSystemService} is removed from the cache when the service
-     *        package is updated; when {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER}, the
-     *        {@link AbstractPerUserSystemService} is removed from the cache and immediately
-     *        re-added when the service package is updated; when
-     *        {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH}, the service is untouched during the update.
+     * @param servicePackagePolicyFlags a combination of
+     *        {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH},
+     *        {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY},
+     *        {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER},
+     *        {@link #PACKAGE_RESTART_POLICY_NO_REFRESH},
+     *        {@link #PACKAGE_RESTART_POLICY_REFRESH_LAZY} or
+     *        {@link #PACKAGE_RESTART_POLICY_REFRESH_EAGER}
      */
     protected AbstractMasterSystemService(@NonNull Context context,
-            @Nullable ServiceNameResolver serviceNameResolver,
-            @Nullable String disallowProperty, @PackageUpdatePolicy int packageUpdatePolicy) {
+            @Nullable ServiceNameResolver serviceNameResolver, @Nullable String disallowProperty,
+            @ServicePackagePolicyFlags int servicePackagePolicyFlags) {
         super(context);
 
-        mPackageUpdatePolicy = packageUpdatePolicy;
+        final int updatePolicyMask = PACKAGE_UPDATE_POLICY_NO_REFRESH
+                | PACKAGE_UPDATE_POLICY_REFRESH_LAZY | PACKAGE_UPDATE_POLICY_REFRESH_EAGER;
+        if ((servicePackagePolicyFlags & updatePolicyMask) == 0) {
+            // If the package update policy is not set, add the default flag
+            servicePackagePolicyFlags |= PACKAGE_UPDATE_POLICY_REFRESH_LAZY;
+        }
+        final int restartPolicyMask = PACKAGE_RESTART_POLICY_NO_REFRESH
+                | PACKAGE_RESTART_POLICY_REFRESH_LAZY | PACKAGE_RESTART_POLICY_REFRESH_EAGER;
+        if ((servicePackagePolicyFlags & restartPolicyMask) == 0) {
+            // If the package restart policy is not set, add the default flag
+            servicePackagePolicyFlags |= PACKAGE_RESTART_POLICY_REFRESH_LAZY;
+        }
+        mServicePackagePolicyFlags = servicePackagePolicyFlags;
 
         mServiceNameResolver = serviceNameResolver;
         if (mServiceNameResolver != null) {
@@ -606,6 +637,20 @@
     }
 
     /**
+     * Called after the package data that provides the service for the given user is cleared.
+     */
+    protected void onServicePackageDataClearedLocked(@UserIdInt int userId) {
+        if (verbose) Slog.v(mTag, "onServicePackageDataCleared(" + userId + ")");
+    }
+
+    /**
+     * Called after the package that provides the service for the given user is restarted.
+     */
+    protected void onServicePackageRestartedLocked(@UserIdInt int userId) {
+        if (verbose) Slog.v(mTag, "onServicePackageRestarted(" + userId + ")");
+    }
+
+    /**
      * Called after the service is removed from the cache.
      */
     @SuppressWarnings("unused")
@@ -677,7 +722,7 @@
             final int size = mServicesCache.size();
             pw.print(prefix); pw.print("Debug: "); pw.print(realDebug);
             pw.print(" Verbose: "); pw.println(realVerbose);
-            pw.print("Refresh on package update: "); pw.println(mPackageUpdatePolicy);
+            pw.print("Package policy flags: "); pw.println(mServicePackagePolicyFlags);
             if (mUpdatingPackageNames != null) {
                 pw.print("Packages being updated: "); pw.println(mUpdatingPackageNames);
             }
@@ -733,7 +778,12 @@
                     }
                     mUpdatingPackageNames.put(userId, packageName);
                     onServicePackageUpdatingLocked(userId);
-                    if (mPackageUpdatePolicy != PACKAGE_UPDATE_POLICY_NO_REFRESH) {
+                    if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_NO_REFRESH) != 0) {
+                        if (debug) {
+                            Slog.d(mTag, "Holding service for user " + userId + " while package "
+                                    + activePackageName + " is being updated");
+                        }
+                    } else {
                         if (debug) {
                             Slog.d(mTag, "Removing service for user " + userId
                                     + " because package " + activePackageName
@@ -741,18 +791,14 @@
                         }
                         removeCachedServiceLocked(userId);
 
-                        if (mPackageUpdatePolicy == PACKAGE_UPDATE_POLICY_REFRESH_EAGER) {
+                        if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_REFRESH_EAGER)
+                                != 0) {
                             if (debug) {
                                 Slog.d(mTag, "Eagerly recreating service for user "
                                         + userId);
                             }
                             getServiceForUserLocked(userId);
                         }
-                    } else {
-                        if (debug) {
-                            Slog.d(mTag, "Holding service for user " + userId + " while package "
-                                    + activePackageName + " is being updated");
-                        }
                     }
                 }
             }
@@ -804,7 +850,13 @@
                             if (!doit) {
                                 return true;
                             }
-                            removeCachedServiceLocked(getChangingUserId());
+                            final String action = intent.getAction();
+                            final int userId = getChangingUserId();
+                            if (Intent.ACTION_PACKAGE_RESTARTED.equals(action)) {
+                                handleActiveServiceRestartedLocked(activePackageName, userId);
+                            } else {
+                                removeCachedServiceLocked(userId);
+                            }
                         } else {
                             handlePackageUpdateLocked(pkg);
                         }
@@ -813,6 +865,23 @@
                 return false;
             }
 
+            @Override
+            public void onPackageDataCleared(String packageName, int uid) {
+                if (verbose) Slog.v(mTag, "onPackageDataCleared(): " + packageName);
+                final int userId = getChangingUserId();
+                synchronized (mLock) {
+                    final S service = peekServiceForUserLocked(userId);
+                    if (service != null) {
+                        final ComponentName componentName = service.getServiceComponentName();
+                        if (componentName != null) {
+                            if (packageName.equals(componentName.getPackageName())) {
+                                onServicePackageDataClearedLocked(userId);
+                            }
+                        }
+                    }
+                }
+            }
+
             private void handleActiveServiceRemoved(@UserIdInt int userId) {
                 synchronized (mLock) {
                     removeCachedServiceLocked(userId);
@@ -824,6 +893,31 @@
                 }
             }
 
+            private void handleActiveServiceRestartedLocked(String activePackageName,
+                    @UserIdInt int userId) {
+                if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_NO_REFRESH) != 0) {
+                    if (debug) {
+                        Slog.d(mTag, "Holding service for user " + userId + " while package "
+                                + activePackageName + " is being restarted");
+                    }
+                } else {
+                    if (debug) {
+                        Slog.d(mTag, "Removing service for user " + userId
+                                + " because package " + activePackageName
+                                + " is being restarted");
+                    }
+                    removeCachedServiceLocked(userId);
+
+                    if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_REFRESH_EAGER) != 0) {
+                        if (debug) {
+                            Slog.d(mTag, "Eagerly recreating service for user " + userId);
+                        }
+                        getServiceForUserLocked(userId);
+                    }
+                }
+                onServicePackageRestartedLocked(userId);
+            }
+
             private String getActiveServicePackageNameLocked() {
                 final int userId = getChangingUserId();
                 final S service = peekServiceForUserLocked(userId);
diff --git a/services/core/java/com/android/server/job/controllers/QuotaController.java b/services/core/java/com/android/server/job/controllers/QuotaController.java
index 18d193a..c6b082a 100644
--- a/services/core/java/com/android/server/job/controllers/QuotaController.java
+++ b/services/core/java/com/android/server/job/controllers/QuotaController.java
@@ -2034,10 +2034,10 @@
         private static final long DEFAULT_MAX_EXECUTION_TIME_MS =
                 4 * HOUR_IN_MILLIS;
         private static final long DEFAULT_RATE_LIMITING_WINDOW_MS =
-                10 * MINUTE_IN_MILLIS;
+                MINUTE_IN_MILLIS;
         private static final int DEFAULT_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW = 20;
-        private static final int DEFAULT_MAX_JOB_COUNT_ACTIVE = // 20/window = 120/hr = 1/session
-                DEFAULT_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW;
+        private static final int DEFAULT_MAX_JOB_COUNT_ACTIVE =
+                75; // 75/window = 450/hr = 1/session
         private static final int DEFAULT_MAX_JOB_COUNT_WORKING = // 120/window = 60/hr = 12/session
                 (int) (60.0 * DEFAULT_WINDOW_SIZE_WORKING_MS / HOUR_IN_MILLIS);
         private static final int DEFAULT_MAX_JOB_COUNT_FREQUENT = // 200/window = 25/hr = 25/session
@@ -2045,7 +2045,7 @@
         private static final int DEFAULT_MAX_JOB_COUNT_RARE = // 48/window = 2/hr = 16/session
                 (int) (2.0 * DEFAULT_WINDOW_SIZE_RARE_MS / HOUR_IN_MILLIS);
         private static final int DEFAULT_MAX_SESSION_COUNT_ACTIVE =
-                20; // 120/hr
+                75; // 450/hr
         private static final int DEFAULT_MAX_SESSION_COUNT_WORKING =
                 10; // 5/hr
         private static final int DEFAULT_MAX_SESSION_COUNT_FREQUENT =
@@ -2199,7 +2199,7 @@
             mResolver = resolver;
             mResolver.registerContentObserver(Settings.Global.getUriFor(
                     Settings.Global.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS), false, this);
-            updateConstants();
+            onChange(true, null);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index c312b76..181a435 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -1459,7 +1459,7 @@
                 info.mSvCarrierFreqs);
 
         // Log CN0 as part of GNSS metrics
-        mGnssMetrics.logCn0(info.mCn0s, info.mSvCount);
+        mGnssMetrics.logCn0(info.mCn0s, info.mSvCount, info.mSvCarrierFreqs);
 
         if (VERBOSE) {
             Log.v(TAG, "SV count: " + info.mSvCount);
@@ -1510,6 +1510,8 @@
                 SystemClock.elapsedRealtime() - mLastFixTime > RECENT_FIX_TIMEOUT) {
             updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
         }
+
+        mGnssMetrics.logSvStatus(info.mSvCount, info.mSvidWithFlags, info.mSvCarrierFreqs);
     }
 
     @NativeEntryPoint
diff --git a/services/core/java/com/android/server/notification/BubbleExtractor.java b/services/core/java/com/android/server/notification/BubbleExtractor.java
index 358bdb9..e59bf16 100644
--- a/services/core/java/com/android/server/notification/BubbleExtractor.java
+++ b/services/core/java/com/android/server/notification/BubbleExtractor.java
@@ -41,10 +41,9 @@
             if (DBG) Slog.d(TAG, "missing config");
             return null;
         }
-        boolean userWantsBubbles = mConfig.bubblesEnabled(record.sbn.getUser());
         boolean appCanShowBubble =
                 mConfig.areBubblesAllowed(record.sbn.getPackageName(), record.sbn.getUid());
-        if (!userWantsBubbles || !appCanShowBubble) {
+        if (!mConfig.bubblesEnabled() || !appCanShowBubble) {
             record.setAllowBubble(false);
         } else {
             if (record.getChannel() != null) {
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 4a6eb27..4828bbf 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -196,18 +196,20 @@
 
     public void dump(PrintWriter pw, DumpFilter filter) {
         pw.println("    Allowed " + getCaption() + "s:");
-        final int N = mApproved.size();
-        for (int i = 0 ; i < N; i++) {
-            final int userId = mApproved.keyAt(i);
-            final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
-            if (approvedByType != null) {
-                final int M = approvedByType.size();
-                for (int j = 0; j < M; j++) {
-                    final boolean isPrimary = approvedByType.keyAt(j);
-                    final ArraySet<String> approved = approvedByType.valueAt(j);
-                    if (approvedByType != null && approvedByType.size() > 0) {
-                        pw.println("      " + String.join(ENABLED_SERVICES_SEPARATOR, approved)
-                                + " (user: " + userId + " isPrimary: " + isPrimary + ")");
+        synchronized (mApproved) {
+            final int N = mApproved.size();
+            for (int i = 0; i < N; i++) {
+                final int userId = mApproved.keyAt(i);
+                final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
+                if (approvedByType != null) {
+                    final int M = approvedByType.size();
+                    for (int j = 0; j < M; j++) {
+                        final boolean isPrimary = approvedByType.keyAt(j);
+                        final ArraySet<String> approved = approvedByType.valueAt(j);
+                        if (approvedByType != null && approvedByType.size() > 0) {
+                            pw.println("      " + String.join(ENABLED_SERVICES_SEPARATOR, approved)
+                                    + " (user: " + userId + " isPrimary: " + isPrimary + ")");
+                        }
                     }
                 }
             }
@@ -240,23 +242,25 @@
 
     public void dump(ProtoOutputStream proto, DumpFilter filter) {
         proto.write(ManagedServicesProto.CAPTION, getCaption());
-        final int N = mApproved.size();
-        for (int i = 0 ; i < N; i++) {
-            final int userId = mApproved.keyAt(i);
-            final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
-            if (approvedByType != null) {
-                final int M = approvedByType.size();
-                for (int j = 0; j < M; j++) {
-                    final boolean isPrimary = approvedByType.keyAt(j);
-                    final ArraySet<String> approved = approvedByType.valueAt(j);
-                    if (approvedByType != null && approvedByType.size() > 0) {
-                        final long sToken = proto.start(ManagedServicesProto.APPROVED);
-                        for (String s : approved) {
-                            proto.write(ServiceProto.NAME, s);
+        synchronized (mApproved) {
+            final int N = mApproved.size();
+            for (int i = 0; i < N; i++) {
+                final int userId = mApproved.keyAt(i);
+                final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
+                if (approvedByType != null) {
+                    final int M = approvedByType.size();
+                    for (int j = 0; j < M; j++) {
+                        final boolean isPrimary = approvedByType.keyAt(j);
+                        final ArraySet<String> approved = approvedByType.valueAt(j);
+                        if (approvedByType != null && approvedByType.size() > 0) {
+                            final long sToken = proto.start(ManagedServicesProto.APPROVED);
+                            for (String s : approved) {
+                                proto.write(ServiceProto.NAME, s);
+                            }
+                            proto.write(ServiceProto.USER_ID, userId);
+                            proto.write(ServiceProto.IS_PRIMARY, isPrimary);
+                            proto.end(sToken);
                         }
-                        proto.write(ServiceProto.USER_ID, userId);
-                        proto.write(ServiceProto.IS_PRIMARY, isPrimary);
-                        proto.end(sToken);
                     }
                 }
             }
@@ -315,33 +319,36 @@
             trimApprovedListsAccordingToInstalledServices(userId);
         }
 
-        final int N = mApproved.size();
-        for (int i = 0 ; i < N; i++) {
-            final int approvedUserId = mApproved.keyAt(i);
-            if (forBackup && approvedUserId != userId) {
-                continue;
-            }
-            final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
-            if (approvedByType != null) {
-                final int M = approvedByType.size();
-                for (int j = 0; j < M; j++) {
-                    final boolean isPrimary = approvedByType.keyAt(j);
-                    final Set<String> approved = approvedByType.valueAt(j);
-                    if (approved != null) {
-                        String allowedItems = String.join(ENABLED_SERVICES_SEPARATOR, approved);
-                        out.startTag(null, TAG_MANAGED_SERVICES);
-                        out.attribute(null, ATT_APPROVED_LIST, allowedItems);
-                        out.attribute(null, ATT_USER_ID, Integer.toString(approvedUserId));
-                        out.attribute(null, ATT_IS_PRIMARY, Boolean.toString(isPrimary));
-                        writeExtraAttributes(out, approvedUserId);
-                        out.endTag(null, TAG_MANAGED_SERVICES);
+        synchronized (mApproved) {
+            final int N = mApproved.size();
+            for (int i = 0; i < N; i++) {
+                final int approvedUserId = mApproved.keyAt(i);
+                if (forBackup && approvedUserId != userId) {
+                    continue;
+                }
+                final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
+                if (approvedByType != null) {
+                    final int M = approvedByType.size();
+                    for (int j = 0; j < M; j++) {
+                        final boolean isPrimary = approvedByType.keyAt(j);
+                        final Set<String> approved = approvedByType.valueAt(j);
+                        if (approved != null) {
+                            String allowedItems = String.join(ENABLED_SERVICES_SEPARATOR, approved);
+                            out.startTag(null, TAG_MANAGED_SERVICES);
+                            out.attribute(null, ATT_APPROVED_LIST, allowedItems);
+                            out.attribute(null, ATT_USER_ID, Integer.toString(approvedUserId));
+                            out.attribute(null, ATT_IS_PRIMARY, Boolean.toString(isPrimary));
+                            writeExtraAttributes(out, approvedUserId);
+                            out.endTag(null, TAG_MANAGED_SERVICES);
 
-                        if (!forBackup && isPrimary) {
-                            // Also write values to settings, for observers who haven't migrated yet
-                            Settings.Secure.putStringForUser(mContext.getContentResolver(),
-                                    getConfig().secureSettingName, allowedItems, approvedUserId);
+                            if (!forBackup && isPrimary) {
+                                // Also write values to settings, for observers who haven't migrated yet
+                                Settings.Secure.putStringForUser(mContext.getContentResolver(),
+                                        getConfig().secureSettingName, allowedItems,
+                                        approvedUserId);
+                            }
+
                         }
-
                     }
                 }
             }
@@ -440,23 +447,25 @@
         if (TextUtils.isEmpty(approved)) {
             approved = "";
         }
-        ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(userId);
-        if (approvedByType == null) {
-            approvedByType = new ArrayMap<>();
-            mApproved.put(userId, approvedByType);
-        }
+        synchronized (mApproved) {
+            ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(userId);
+            if (approvedByType == null) {
+                approvedByType = new ArrayMap<>();
+                mApproved.put(userId, approvedByType);
+            }
 
-        ArraySet<String> approvedList = approvedByType.get(isPrimary);
-        if (approvedList == null) {
-            approvedList = new ArraySet<>();
-            approvedByType.put(isPrimary, approvedList);
-        }
+            ArraySet<String> approvedList = approvedByType.get(isPrimary);
+            if (approvedList == null) {
+                approvedList = new ArraySet<>();
+                approvedByType.put(isPrimary, approvedList);
+            }
 
-        String[] approvedArray = approved.split(ENABLED_SERVICES_SEPARATOR);
-        for (String pkgOrComponent : approvedArray) {
-            String approvedItem = getApprovedValue(pkgOrComponent);
-            if (approvedItem != null) {
-                approvedList.add(approvedItem);
+            String[] approvedArray = approved.split(ENABLED_SERVICES_SEPARATOR);
+            for (String pkgOrComponent : approvedArray) {
+                String approvedItem = getApprovedValue(pkgOrComponent);
+                if (approvedItem != null) {
+                    approvedList.add(approvedItem);
+                }
             }
         }
     }
@@ -469,23 +478,25 @@
             boolean isPrimary, boolean enabled) {
         Slog.i(TAG,
                 (enabled ? " Allowing " : "Disallowing ") + mConfig.caption + " " + pkgOrComponent);
-        ArrayMap<Boolean, ArraySet<String>> allowedByType = mApproved.get(userId);
-        if (allowedByType == null) {
-            allowedByType = new ArrayMap<>();
-            mApproved.put(userId, allowedByType);
-        }
-        ArraySet<String> approved = allowedByType.get(isPrimary);
-        if (approved == null) {
-            approved = new ArraySet<>();
-            allowedByType.put(isPrimary, approved);
-        }
-        String approvedItem = getApprovedValue(pkgOrComponent);
+        synchronized (mApproved) {
+            ArrayMap<Boolean, ArraySet<String>> allowedByType = mApproved.get(userId);
+            if (allowedByType == null) {
+                allowedByType = new ArrayMap<>();
+                mApproved.put(userId, allowedByType);
+            }
+            ArraySet<String> approved = allowedByType.get(isPrimary);
+            if (approved == null) {
+                approved = new ArraySet<>();
+                allowedByType.put(isPrimary, approved);
+            }
+            String approvedItem = getApprovedValue(pkgOrComponent);
 
-        if (approvedItem != null) {
-            if (enabled) {
-                approved.add(approvedItem);
-            } else {
-                approved.remove(approvedItem);
+            if (approvedItem != null) {
+                if (enabled) {
+                    approved.add(approvedItem);
+                } else {
+                    approved.remove(approvedItem);
+                }
             }
         }
 
@@ -504,22 +515,26 @@
     }
 
     protected String getApproved(int userId, boolean primary) {
-        final ArrayMap<Boolean, ArraySet<String>> allowedByType =
-                mApproved.getOrDefault(userId, new ArrayMap<>());
-        ArraySet<String> approved = allowedByType.getOrDefault(primary, new ArraySet<>());
-        return String.join(ENABLED_SERVICES_SEPARATOR, approved);
+        synchronized (mApproved) {
+            final ArrayMap<Boolean, ArraySet<String>> allowedByType =
+                    mApproved.getOrDefault(userId, new ArrayMap<>());
+            ArraySet<String> approved = allowedByType.getOrDefault(primary, new ArraySet<>());
+            return String.join(ENABLED_SERVICES_SEPARATOR, approved);
+        }
     }
 
     protected List<ComponentName> getAllowedComponents(int userId) {
         final List<ComponentName> allowedComponents = new ArrayList<>();
-        final ArrayMap<Boolean, ArraySet<String>> allowedByType =
-                mApproved.getOrDefault(userId, new ArrayMap<>());
-        for (int i = 0; i < allowedByType.size(); i++) {
-            final ArraySet<String> allowed = allowedByType.valueAt(i);
-            for (int j = 0; j < allowed.size(); j++) {
-                ComponentName cn = ComponentName.unflattenFromString(allowed.valueAt(j));
-                if (cn != null) {
-                    allowedComponents.add(cn);
+        synchronized (mApproved) {
+            final ArrayMap<Boolean, ArraySet<String>> allowedByType =
+                    mApproved.getOrDefault(userId, new ArrayMap<>());
+            for (int i = 0; i < allowedByType.size(); i++) {
+                final ArraySet<String> allowed = allowedByType.valueAt(i);
+                for (int j = 0; j < allowed.size(); j++) {
+                    ComponentName cn = ComponentName.unflattenFromString(allowed.valueAt(j));
+                    if (cn != null) {
+                        allowedComponents.add(cn);
+                    }
                 }
             }
         }
@@ -528,14 +543,16 @@
 
     protected List<String> getAllowedPackages(int userId) {
         final List<String> allowedPackages = new ArrayList<>();
-        final ArrayMap<Boolean, ArraySet<String>> allowedByType =
-                mApproved.getOrDefault(userId, new ArrayMap<>());
-        for (int i = 0; i < allowedByType.size(); i++) {
-            final ArraySet<String> allowed = allowedByType.valueAt(i);
-            for (int j = 0; j < allowed.size(); j++) {
-                String pkgName = getPackageName(allowed.valueAt(j));
-                if (!TextUtils.isEmpty(pkgName)) {
-                    allowedPackages.add(pkgName);
+        synchronized (mApproved) {
+            final ArrayMap<Boolean, ArraySet<String>> allowedByType =
+                    mApproved.getOrDefault(userId, new ArrayMap<>());
+            for (int i = 0; i < allowedByType.size(); i++) {
+                final ArraySet<String> allowed = allowedByType.valueAt(i);
+                for (int j = 0; j < allowed.size(); j++) {
+                    String pkgName = getPackageName(allowed.valueAt(j));
+                    if (!TextUtils.isEmpty(pkgName)) {
+                        allowedPackages.add(pkgName);
+                    }
                 }
             }
         }
@@ -543,12 +560,14 @@
     }
 
     protected boolean isPackageOrComponentAllowed(String pkgOrComponent, int userId) {
-        ArrayMap<Boolean, ArraySet<String>> allowedByType =
-                mApproved.getOrDefault(userId, new ArrayMap<>());
-        for (int i = 0; i < allowedByType.size(); i++) {
-            ArraySet<String> allowed = allowedByType.valueAt(i);
-            if (allowed.contains(pkgOrComponent)) {
-                return true;
+        synchronized (mApproved) {
+            ArrayMap<Boolean, ArraySet<String>> allowedByType =
+                    mApproved.getOrDefault(userId, new ArrayMap<>());
+            for (int i = 0; i < allowedByType.size(); i++) {
+                ArraySet<String> allowed = allowedByType.valueAt(i);
+                if (allowed.contains(pkgOrComponent)) {
+                    return true;
+                }
             }
         }
         return false;
@@ -558,19 +577,21 @@
         if (pkg == null) {
             return false;
         }
-        ArrayMap<Boolean, ArraySet<String>> allowedByType =
-                mApproved.getOrDefault(userId, new ArrayMap<>());
-        for (int i = 0; i < allowedByType.size(); i++) {
-            ArraySet<String> allowed = allowedByType.valueAt(i);
-            for (String allowedEntry : allowed) {
-                ComponentName component = ComponentName.unflattenFromString(allowedEntry);
-                if (component != null) {
-                    if (pkg.equals(component.getPackageName())) {
-                        return true;
-                    }
-                } else {
-                    if (pkg.equals(allowedEntry)) {
-                        return true;
+        synchronized (mApproved) {
+            ArrayMap<Boolean, ArraySet<String>> allowedByType =
+                    mApproved.getOrDefault(userId, new ArrayMap<>());
+            for (int i = 0; i < allowedByType.size(); i++) {
+                ArraySet<String> allowed = allowedByType.valueAt(i);
+                for (String allowedEntry : allowed) {
+                    ComponentName component = ComponentName.unflattenFromString(allowedEntry);
+                    if (component != null) {
+                        if (pkg.equals(component.getPackageName())) {
+                            return true;
+                        }
+                    } else {
+                        if (pkg.equals(allowedEntry)) {
+                            return true;
+                        }
                     }
                 }
             }
@@ -616,7 +637,9 @@
 
     public void onUserRemoved(int user) {
         Slog.i(TAG, "Removing approved services for removed user " + user);
-        mApproved.remove(user);
+        synchronized (mApproved) {
+            mApproved.remove(user);
+        }
         rebindServices(true, user);
     }
 
@@ -797,14 +820,16 @@
 
     protected Set<String> getAllowedPackages() {
         final Set<String> allowedPackages = new ArraySet<>();
-        for (int k = 0; k < mApproved.size(); k++) {
-            ArrayMap<Boolean, ArraySet<String>> allowedByType = mApproved.valueAt(k);
-            for (int i = 0; i < allowedByType.size(); i++) {
-                final ArraySet<String> allowed = allowedByType.valueAt(i);
-                for (int j = 0; j < allowed.size(); j++) {
-                    String pkgName = getPackageName(allowed.valueAt(j));
-                    if (!TextUtils.isEmpty(pkgName)) {
-                        allowedPackages.add(pkgName);
+        synchronized (mApproved) {
+            for (int k = 0; k < mApproved.size(); k++) {
+                ArrayMap<Boolean, ArraySet<String>> allowedByType = mApproved.valueAt(k);
+                for (int i = 0; i < allowedByType.size(); i++) {
+                    final ArraySet<String> allowed = allowedByType.valueAt(i);
+                    for (int j = 0; j < allowed.size(); j++) {
+                        String pkgName = getPackageName(allowed.valueAt(j));
+                        if (!TextUtils.isEmpty(pkgName)) {
+                            allowedPackages.add(pkgName);
+                        }
                     }
                 }
             }
@@ -813,22 +838,24 @@
     }
 
     private void trimApprovedListsAccordingToInstalledServices(int userId) {
-        final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(userId);
-        if (approvedByType == null) {
-            return;
-        }
-        for (int i = 0; i < approvedByType.size(); i++) {
-            final ArraySet<String> approved = approvedByType.valueAt(i);
-            for (int j = approved.size() - 1; j >= 0; j--) {
-                final String approvedPackageOrComponent = approved.valueAt(j);
-                if (!isValidEntry(approvedPackageOrComponent, userId)){
-                    approved.removeAt(j);
-                    Slog.v(TAG, "Removing " + approvedPackageOrComponent
-                            + " from approved list; no matching services found");
-                } else {
-                    if (DEBUG) {
-                        Slog.v(TAG, "Keeping " + approvedPackageOrComponent
-                                + " on approved list; matching services found");
+        synchronized (mApproved) {
+            final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(userId);
+            if (approvedByType == null) {
+                return;
+            }
+            for (int i = 0; i < approvedByType.size(); i++) {
+                final ArraySet<String> approved = approvedByType.valueAt(i);
+                for (int j = approved.size() - 1; j >= 0; j--) {
+                    final String approvedPackageOrComponent = approved.valueAt(j);
+                    if (!isValidEntry(approvedPackageOrComponent, userId)) {
+                        approved.removeAt(j);
+                        Slog.v(TAG, "Removing " + approvedPackageOrComponent
+                                + " from approved list; no matching services found");
+                    } else {
+                        if (DEBUG) {
+                            Slog.v(TAG, "Keeping " + approvedPackageOrComponent
+                                    + " on approved list; matching services found");
+                        }
                     }
                 }
             }
@@ -837,20 +864,23 @@
 
     private boolean removeUninstalledItemsFromApprovedLists(int uninstalledUserId, String pkg) {
         boolean removed = false;
-        final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(uninstalledUserId);
-        if (approvedByType != null) {
-            int M = approvedByType.size();
-            for (int j = 0; j < M; j++) {
-                final ArraySet<String> approved = approvedByType.valueAt(j);
-                int O = approved.size();
-                for (int k = O - 1; k >= 0; k--) {
-                    final String packageOrComponent = approved.valueAt(k);
-                    final String packageName = getPackageName(packageOrComponent);
-                    if (TextUtils.equals(pkg, packageName)) {
-                        approved.removeAt(k);
-                        if (DEBUG) {
-                            Slog.v(TAG, "Removing " + packageOrComponent
-                                    + " from approved list; uninstalled");
+        synchronized (mApproved) {
+            final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(
+                    uninstalledUserId);
+            if (approvedByType != null) {
+                int M = approvedByType.size();
+                for (int j = 0; j < M; j++) {
+                    final ArraySet<String> approved = approvedByType.valueAt(j);
+                    int O = approved.size();
+                    for (int k = O - 1; k >= 0; k--) {
+                        final String packageOrComponent = approved.valueAt(k);
+                        final String packageName = getPackageName(packageOrComponent);
+                        if (TextUtils.equals(pkg, packageName)) {
+                            approved.removeAt(k);
+                            if (DEBUG) {
+                                Slog.v(TAG, "Removing " + packageOrComponent
+                                        + " from approved list; uninstalled");
+                            }
                         }
                     }
                 }
@@ -887,17 +917,19 @@
 
         for (int i = 0; i < nUserIds; ++i) {
             final int userId = userIds.get(i);
-            final ArrayMap<Boolean, ArraySet<String>> approvedLists = mApproved.get(userId);
-            if (approvedLists != null) {
-                final int N = approvedLists.size();
-                for (int j = 0; j < N; j++) {
-                    ArraySet<ComponentName> approvedByUser = componentsByUser.get(userId);
-                    if (approvedByUser == null) {
-                        approvedByUser = new ArraySet<>();
-                        componentsByUser.put(userId, approvedByUser);
+            synchronized (mApproved) {
+                final ArrayMap<Boolean, ArraySet<String>> approvedLists = mApproved.get(userId);
+                if (approvedLists != null) {
+                    final int N = approvedLists.size();
+                    for (int j = 0; j < N; j++) {
+                        ArraySet<ComponentName> approvedByUser = componentsByUser.get(userId);
+                        if (approvedByUser == null) {
+                            approvedByUser = new ArraySet<>();
+                            componentsByUser.put(userId, approvedByUser);
+                        }
+                        approvedByUser.addAll(
+                                loadComponentNamesFromValues(approvedLists.valueAt(j), userId));
                     }
-                    approvedByUser.addAll(
-                            loadComponentNamesFromValues(approvedLists.valueAt(j), userId));
                 }
             }
         }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index cf3065b..3105207 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -91,6 +91,7 @@
 import static com.android.server.am.PendingIntentRecord.FLAG_ACTIVITY_SENDER;
 import static com.android.server.am.PendingIntentRecord.FLAG_BROADCAST_SENDER;
 import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER;
+import static com.android.server.notification.PreferencesHelper.DEFAULT_ALLOW_BUBBLE;
 import static com.android.server.utils.PriorityDump.PRIORITY_ARG;
 import static com.android.server.utils.PriorityDump.PRIORITY_ARG_CRITICAL;
 import static com.android.server.utils.PriorityDump.PRIORITY_ARG_NORMAL;
@@ -466,6 +467,8 @@
     private MetricsLogger mMetricsLogger;
     private TriPredicate<String, Integer, String> mAllowedManagedServicePackages;
 
+    private final SavePolicyFileRunnable mSavePolicyFile = new SavePolicyFileRunnable();
+
     private static class Archive {
         final int mBufferSize;
         final ArrayDeque<StatusBarNotification> mBuffer;
@@ -659,7 +662,14 @@
 
     @VisibleForTesting
     protected void handleSavePolicyFile() {
-        IoThread.getHandler().post(() -> {
+        if (!IoThread.getHandler().hasCallbacks(mSavePolicyFile)) {
+            IoThread.getHandler().post(mSavePolicyFile);
+        }
+    }
+
+    private final class SavePolicyFileRunnable implements Runnable {
+        @Override
+        public void run() {
             if (DBG) Slog.d(TAG, "handleSavePolicyFile");
             synchronized (mPolicyFile) {
                 final FileOutputStream stream;
@@ -679,7 +689,7 @@
                 }
             }
             BackupManager.dataChanged(getContext().getPackageName());
-        });
+        }
     }
 
     private void writePolicyXml(OutputStream stream, boolean forBackup, int userId)
@@ -1358,7 +1368,9 @@
     private final class SettingsObserver extends ContentObserver {
         private final Uri NOTIFICATION_BADGING_URI
                 = Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_BADGING);
-        private final Uri NOTIFICATION_BUBBLES_URI
+        private final Uri NOTIFICATION_BUBBLES_URI_GLOBAL
+                = Settings.Global.getUriFor(Settings.Global.NOTIFICATION_BUBBLES);
+        private final Uri NOTIFICATION_BUBBLES_URI_SECURE
                 = Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_BUBBLES);
         private final Uri NOTIFICATION_LIGHT_PULSE_URI
                 = Settings.System.getUriFor(Settings.System.NOTIFICATION_LIGHT_PULSE);
@@ -1377,7 +1389,9 @@
                     false, this, UserHandle.USER_ALL);
             resolver.registerContentObserver(NOTIFICATION_RATE_LIMIT_URI,
                     false, this, UserHandle.USER_ALL);
-            resolver.registerContentObserver(NOTIFICATION_BUBBLES_URI,
+            resolver.registerContentObserver(NOTIFICATION_BUBBLES_URI_GLOBAL,
+                    false, this, UserHandle.USER_ALL);
+            resolver.registerContentObserver(NOTIFICATION_BUBBLES_URI_SECURE,
                     false, this, UserHandle.USER_ALL);
             update(null);
         }
@@ -1404,9 +1418,41 @@
             if (uri == null || NOTIFICATION_BADGING_URI.equals(uri)) {
                 mPreferencesHelper.updateBadgingEnabled();
             }
-            if (uri == null || NOTIFICATION_BUBBLES_URI.equals(uri)) {
+            // In QPR we moved the setting to Global rather than Secure so that the setting
+            // applied to work profiles. Unfortunately we need to maintain both to pass CTS without
+            // a change to CTS outside of a normal letter release.
+            if (uri == null || NOTIFICATION_BUBBLES_URI_GLOBAL.equals(uri)) {
+                syncBubbleSettings(resolver, NOTIFICATION_BUBBLES_URI_GLOBAL);
                 mPreferencesHelper.updateBubblesEnabled();
             }
+            if (NOTIFICATION_BUBBLES_URI_SECURE.equals(uri)) {
+                syncBubbleSettings(resolver, NOTIFICATION_BUBBLES_URI_SECURE);
+            }
+        }
+
+        private void syncBubbleSettings(ContentResolver resolver, Uri settingToFollow) {
+            boolean followSecureSetting = settingToFollow.equals(NOTIFICATION_BUBBLES_URI_SECURE);
+
+            int secureSettingValue = Settings.Secure.getInt(resolver,
+                    Settings.Secure.NOTIFICATION_BUBBLES, DEFAULT_ALLOW_BUBBLE ? 1 : 0);
+            int globalSettingValue = Settings.Global.getInt(resolver,
+                    Settings.Global.NOTIFICATION_BUBBLES, DEFAULT_ALLOW_BUBBLE ? 1 : 0);
+
+            if (globalSettingValue == secureSettingValue) {
+                return;
+            }
+
+            if (followSecureSetting) {
+                // Global => secure
+                Settings.Global.putInt(resolver,
+                        Settings.Global.NOTIFICATION_BUBBLES,
+                        secureSettingValue);
+            } else {
+                // Secure => Global
+                Settings.Secure.putInt(resolver,
+                        Settings.Secure.NOTIFICATION_BUBBLES,
+                        globalSettingValue);
+            }
         }
     }
 
@@ -1824,6 +1870,7 @@
                     }
                     if (properties.getKeyset()
                             .contains(SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE)) {
+                        mAssistants.allowAdjustmentType(Adjustment.KEY_IMPORTANCE);
                         mAssistants.resetDefaultAssistantsIfNecessary();
                     }
                 });
@@ -2256,7 +2303,7 @@
             final int callingUid = Binder.getCallingUid();
             final boolean isSystemToast = isCallerSystemOrPhone()
                     || PackageManagerService.PLATFORM_PACKAGE_NAME.equals(pkg);
-            final boolean isPackageSuspended = isPackageSuspendedForUser(pkg, callingUid);
+            final boolean isPackageSuspended = isPackagePaused(pkg);
             final boolean notificationsDisabledForPackage = !areNotificationsEnabledForPackage(pkg,
                     callingUid);
 
@@ -2405,9 +2452,25 @@
         }
 
         @Override
+        public void silenceNotificationSound() {
+            checkCallerIsSystem();
+
+            mNotificationDelegate.clearEffects();
+        }
+
+        @Override
         public void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled) {
             enforceSystemOrSystemUI("setNotificationsEnabledForPackage");
 
+            synchronized (mNotificationLock) {
+                boolean wasEnabled = mPreferencesHelper.getImportance(pkg, uid)
+                        != NotificationManager.IMPORTANCE_NONE;
+
+                if (wasEnabled == enabled) {
+                    return;
+                }
+            }
+
             mPreferencesHelper.setEnabled(pkg, uid, enabled);
             mMetricsLogger.write(new LogMaker(MetricsEvent.ACTION_BAN_APP_NOTES)
                     .setType(MetricsEvent.TYPE_ACTION)
@@ -4094,17 +4157,7 @@
             Preconditions.checkNotNull(pkg);
             checkCallerIsSameApp(pkg);
 
-            boolean isPaused;
-
-            final PackageManagerInternal pmi = LocalServices.getService(
-                    PackageManagerInternal.class);
-            int flags = pmi.getDistractingPackageRestrictions(
-                    pkg, Binder.getCallingUserHandle().getIdentifier());
-            isPaused = ((flags & PackageManager.RESTRICTION_HIDE_NOTIFICATIONS) != 0);
-
-            isPaused |= isPackageSuspendedForUser(pkg, Binder.getCallingUid());
-
-            return isPaused;
+            return isPackagePausedOrSuspended(pkg, Binder.getCallingUid());
         }
 
         private void verifyPrivilegedListener(INotificationListener token, UserHandle user,
@@ -4817,47 +4870,112 @@
         } else {
             notification.flags &= ~FLAG_BUBBLE;
         }
+        // Is the app in the foreground?
+        final boolean appIsForeground =
+                mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
+        Notification.BubbleMetadata metadata = notification.getBubbleMetadata();
+        if (!appIsForeground && metadata != null) {
+            // Remove any flags that only work when foregrounded
+            int flags = metadata.getFlags();
+            flags &= ~Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE;
+            flags &= ~Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION;
+            metadata.setFlags(flags);
+        }
     }
 
     /**
-     * @return whether the provided notification record is allowed to be represented as a bubble.
+     * @return whether the provided notification record is allowed to be represented as a bubble,
+     * accounting for user choice & policy.
      */
     private boolean isNotificationAppropriateToBubble(NotificationRecord r, String pkg, int userId,
             NotificationRecord oldRecord) {
         Notification notification = r.getNotification();
-        Notification.BubbleMetadata metadata = notification.getBubbleMetadata();
-        boolean intentCanBubble = metadata != null
-                && canLaunchInActivityView(getContext(), metadata.getIntent(), pkg);
+        if (!canBubble(r, pkg, userId)) {
+            // no log: canBubble has its own
+            return false;
+        }
 
-        // Does the app want to bubble & is able to bubble
-        boolean canBubble = intentCanBubble
-                && mPreferencesHelper.areBubblesAllowed(pkg, userId)
-                && mPreferencesHelper.bubblesEnabled(r.sbn.getUser())
-                && r.getChannel().canBubble()
-                && !mActivityManager.isLowRamDevice();
+        if (mActivityManager.isLowRamDevice()) {
+            logBubbleError(r.getKey(), "low ram device");
+            return false;
+        }
 
-        // Is the app in the foreground?
-        final boolean appIsForeground =
-                mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
+        if (mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND) {
+            // If the app is foreground it always gets to bubble
+            return true;
+        }
 
-        // Is the notification something we'd allow to bubble?
-        // A call with a foreground service + person
+        if (oldRecord != null && (oldRecord.getNotification().flags & FLAG_BUBBLE) != 0) {
+            // This is an update to an active bubble
+            return true;
+        }
+
+        // At this point the bubble must fulfill communication policy
+
+        // Communication always needs a person
         ArrayList<Person> peopleList = notification.extras != null
                 ? notification.extras.getParcelableArrayList(Notification.EXTRA_PEOPLE_LIST)
                 : null;
-        boolean isForegroundCall = CATEGORY_CALL.equals(notification.category)
-                && (notification.flags & FLAG_FOREGROUND_SERVICE) != 0;
-        // OR message style (which always has a person) with any remote input
-        Class<? extends Notification.Style> style = notification.getNotificationStyle();
-        boolean isMessageStyle = Notification.MessagingStyle.class.equals(style);
-        boolean notificationAppropriateToBubble =
-                (isMessageStyle && hasValidRemoteInput(notification))
-                || (peopleList != null && !peopleList.isEmpty() && isForegroundCall);
+        // Message style requires a person & it's not included in the list
+        boolean isMessageStyle = Notification.MessagingStyle.class.equals(
+                notification.getNotificationStyle());
+        if (!isMessageStyle && (peopleList == null || peopleList.isEmpty())) {
+            logBubbleError(r.getKey(), "if not foreground, must have a person and be "
+                    + "Notification.MessageStyle or Notification.CATEGORY_CALL");
+            return false;
+        }
 
-        // OR something that was previously a bubble & still exists
-        boolean bubbleUpdate = oldRecord != null
-                && (oldRecord.getNotification().flags & FLAG_BUBBLE) != 0;
-        return canBubble && (notificationAppropriateToBubble || appIsForeground || bubbleUpdate);
+        // Communication is a message or a call
+        boolean isCall = CATEGORY_CALL.equals(notification.category);
+        boolean hasForegroundService = (notification.flags & FLAG_FOREGROUND_SERVICE) != 0;
+        if (isMessageStyle) {
+            if (hasValidRemoteInput(notification)) {
+                return true;
+            }
+            logBubbleError(r.getKey(), "messages require valid remote input");
+            return false;
+        } else if (isCall) {
+            if (hasForegroundService) {
+                return true;
+            }
+            logBubbleError(r.getKey(), "calls require foreground service");
+            return false;
+        }
+        logBubbleError(r.getKey(), "if not foreground, must be "
+                + "Notification.MessageStyle or Notification.CATEGORY_CALL");
+        return false;
+    }
+
+    /**
+     * @return whether the user has enabled the provided notification to bubble, does not account
+     * for policy.
+     */
+    private boolean canBubble(NotificationRecord r, String pkg, int userId) {
+        Notification notification = r.getNotification();
+        Notification.BubbleMetadata metadata = notification.getBubbleMetadata();
+        if (metadata == null) {
+            // no log: no need to inform dev if they didn't attach bubble metadata
+            return false;
+        }
+        if (!canLaunchInActivityView(getContext(), metadata.getIntent(), pkg)) {
+            // no log: method has the failure log
+            return false;
+        }
+        if (!mPreferencesHelper.bubblesEnabled()) {
+            logBubbleError(r.getKey(), "bubbles disabled for user: " + userId);
+            return false;
+        }
+        if (!mPreferencesHelper.areBubblesAllowed(pkg, userId)) {
+            logBubbleError(r.getKey(),
+                    "bubbles for package: " + pkg + " disabled for user: " + userId);
+            return false;
+        }
+        if (!r.getChannel().canBubble()) {
+            logBubbleError(r.getKey(),
+                    "bubbles for channel " + r.getChannel().getId() + " disabled");
+            return false;
+        }
+        return true;
     }
 
     private boolean hasValidRemoteInput(Notification n) {
@@ -4876,6 +4994,11 @@
         return false;
     }
 
+    private void logBubbleError(String key, String failureMessage) {
+        if (DBG) {
+            Log.w(TAG, "Bubble notification: " + key + " failed: " + failureMessage);
+        }
+    }
     /**
      * Whether an intent is properly configured to display in an {@link android.app.ActivityView}.
      *
@@ -5220,16 +5343,8 @@
             }
 
             synchronized (mNotificationLock) {
-                // If the notification is currently enqueued, repost this runnable so it has a
-                // chance to notify listeners
-                if ((findNotificationByListLocked(mEnqueuedNotifications, mPkg, mTag, mId, mUserId))
-                        != null) {
-                    mHandler.post(this);
-                    return;
-                }
-                // Look for the notification in the posted list, since we already checked enqueued.
-                NotificationRecord r =
-                        findNotificationByListLocked(mNotificationList, mPkg, mTag, mId, mUserId);
+                // Look for the notification, searching both the posted and enqueued lists.
+                NotificationRecord r = findNotificationLocked(mPkg, mTag, mId, mUserId);
                 if (r != null) {
                     // The notification was found, check if it should be removed.
 
@@ -5246,12 +5361,26 @@
                         return;
                     }
 
+                    // Bubbled children get to stick around if the summary was manually cancelled
+                    // (user removed) from systemui.
+                    FlagChecker childrenFlagChecker = null;
+                    if (mReason == REASON_CANCEL
+                            || mReason == REASON_CLICK
+                            || mReason == REASON_CANCEL_ALL) {
+                        childrenFlagChecker = (flags) -> {
+                            if ((flags & FLAG_BUBBLE) != 0) {
+                                return false;
+                            }
+                            return true;
+                        };
+                    }
+
                     // Cancel the notification.
                     boolean wasPosted = removeFromNotificationListsLocked(r);
                     cancelNotificationLocked(
                             r, mSendDelete, mReason, mRank, mCount, wasPosted, listenerName);
                     cancelGroupChildrenLocked(r, mCallingUid, mCallingPid, listenerName,
-                            mSendDelete, null);
+                            mSendDelete, childrenFlagChecker);
                     updateLightsLocked();
                 } else {
                     // No notification was found, assume that it is snoozed and cancel it.
@@ -5334,11 +5463,18 @@
     }
 
     @GuardedBy("mNotificationLock")
-    private boolean isPackageSuspendedLocked(NotificationRecord r) {
-        final String pkg = r.sbn.getPackageName();
-        final int callingUid = r.sbn.getUid();
+    boolean isPackagePausedOrSuspended(String pkg, int uid) {
+        boolean isPaused;
 
-        return isPackageSuspendedForUser(pkg, callingUid);
+        final PackageManagerInternal pmi = LocalServices.getService(
+                PackageManagerInternal.class);
+        int flags = pmi.getDistractingPackageRestrictions(
+                pkg, Binder.getCallingUserHandle().getIdentifier());
+        isPaused = ((flags & PackageManager.RESTRICTION_HIDE_NOTIFICATIONS) != 0);
+
+        isPaused |= isPackageSuspendedForUser(pkg, uid);
+
+        return isPaused;
     }
 
     protected class PostNotificationRunnable implements Runnable {
@@ -5371,7 +5507,8 @@
                         return;
                     }
 
-                    final boolean isPackageSuspended = isPackageSuspendedLocked(r);
+                    final boolean isPackageSuspended =
+                            isPackagePausedOrSuspended(r.sbn.getPackageName(), r.getUid());
                     r.setHidden(isPackageSuspended);
                     if (isPackageSuspended) {
                         mUsageStats.registerSuspendedByAdmin(r);
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 7b45a1b..4835c97 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -73,6 +73,9 @@
     private static final String NON_BLOCKABLE_CHANNEL_DELIM = ":";
 
     @VisibleForTesting
+    static final int NOTIFICATION_CHANNEL_COUNT_LIMIT = 50000;
+
+    @VisibleForTesting
     static final String TAG_RANKING = "ranking";
     private static final String TAG_PACKAGE = "package";
     private static final String TAG_CHANNEL = "channel";
@@ -100,7 +103,7 @@
     @VisibleForTesting
     static final boolean DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS = false;
     private static final boolean DEFAULT_SHOW_BADGE = true;
-    private static final boolean DEFAULT_ALLOW_BUBBLE = true;
+    static final boolean DEFAULT_ALLOW_BUBBLE = true;
     private static final boolean DEFAULT_OEM_LOCKED_IMPORTANCE  = false;
     private static final boolean DEFAULT_APP_LOCKED_IMPORTANCE  = false;
 
@@ -130,7 +133,7 @@
     private final ZenModeHelper mZenModeHelper;
 
     private SparseBooleanArray mBadgingEnabled;
-    private SparseBooleanArray mBubblesEnabled;
+    private boolean mBubblesEnabled = DEFAULT_ALLOW_BUBBLE;
     private boolean mAreChannelsBypassingDnd;
     private boolean mHideSilentStatusBarIcons = DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS;
 
@@ -179,6 +182,7 @@
                                     // noop
                                 }
                             }
+                            boolean skipWarningLogged = false;
 
                             PackagePreferences r = getOrCreatePackagePreferencesLocked(name, uid,
                                     XmlUtils.readIntAttribute(
@@ -225,6 +229,14 @@
                                 }
                                 // Channels
                                 if (TAG_CHANNEL.equals(tagName)) {
+                                    if (r.channels.size() >= NOTIFICATION_CHANNEL_COUNT_LIMIT) {
+                                        if (!skipWarningLogged) {
+                                            Slog.w(TAG, "Skipping further channels for " + r.pkg
+                                                    + "; app has too many");
+                                            skipWarningLogged = true;
+                                        }
+                                        continue;
+                                    }
                                     String id = parser.getAttributeValue(null, ATT_ID);
                                     String channelName = parser.getAttributeValue(null, ATT_NAME);
                                     int channelImportance = XmlUtils.readIntAttribute(
@@ -690,6 +702,10 @@
                 return needsPolicyFileChange;
             }
 
+            if (r.channels.size() >= NOTIFICATION_CHANNEL_COUNT_LIMIT) {
+                throw new IllegalStateException("Limit exceed; cannot create more channels");
+            }
+
             needsPolicyFileChange = true;
 
             if (channel.getImportance() < IMPORTANCE_NONE
@@ -1818,40 +1834,19 @@
     }
 
     public void updateBubblesEnabled() {
-        if (mBubblesEnabled == null) {
-            mBubblesEnabled = new SparseBooleanArray();
-        }
-        boolean changed = false;
-        // update the cached values
-        for (int index = 0; index < mBubblesEnabled.size(); index++) {
-            int userId = mBubblesEnabled.keyAt(index);
-            final boolean oldValue = mBubblesEnabled.get(userId);
-            final boolean newValue = Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                    Settings.Secure.NOTIFICATION_BUBBLES,
-                    DEFAULT_ALLOW_BUBBLE ? 1 : 0, userId) != 0;
-            mBubblesEnabled.put(userId, newValue);
-            changed |= oldValue != newValue;
-        }
-        if (changed) {
+        final boolean newValue = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.NOTIFICATION_BUBBLES,
+                DEFAULT_ALLOW_BUBBLE ? 1 : 0) == 1;
+        if (newValue != mBubblesEnabled) {
+            mBubblesEnabled = newValue;
             updateConfig();
         }
     }
 
-    public boolean bubblesEnabled(UserHandle userHandle) {
-        int userId = userHandle.getIdentifier();
-        if (userId == UserHandle.USER_ALL) {
-            return false;
-        }
-        if (mBubblesEnabled.indexOfKey(userId) < 0) {
-            mBubblesEnabled.put(userId,
-                    Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                            Settings.Secure.NOTIFICATION_BUBBLES,
-                            DEFAULT_ALLOW_BUBBLE ? 1 : 0, userId) != 0);
-        }
-        return mBubblesEnabled.get(userId, DEFAULT_ALLOW_BUBBLE);
+    public boolean bubblesEnabled() {
+        return mBubblesEnabled;
     }
 
-
     public void updateBadgingEnabled() {
         if (mBadgingEnabled == null) {
             mBadgingEnabled = new SparseBooleanArray();
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index 5de00e4..7816f36 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -30,7 +30,7 @@
     boolean canShowBadge(String packageName, int uid);
     boolean badgingEnabled(UserHandle userHandle);
     boolean areBubblesAllowed(String packageName, int uid);
-    boolean bubblesEnabled(UserHandle userHandle);
+    boolean bubblesEnabled();
     boolean isGroupBlocked(String packageName, int uid, String groupId);
 
     Collection<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
diff --git a/services/core/java/com/android/server/notification/ZenLog.java b/services/core/java/com/android/server/notification/ZenLog.java
index c6af756..8f05636 100644
--- a/services/core/java/com/android/server/notification/ZenLog.java
+++ b/services/core/java/com/android/server/notification/ZenLog.java
@@ -179,6 +179,7 @@
             case TYPE_SUPPRESSOR_CHANGED: return "suppressor_changed";
             case TYPE_LISTENER_HINTS_CHANGED: return "listener_hints_changed";
             case TYPE_SET_NOTIFICATION_POLICY: return "set_notification_policy";
+            case TYPE_SET_CONSOLIDATED_ZEN_POLICY: return "set_consolidated_policy";
             default: return "unknown";
         }
     }
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index f81015d..ebc4191 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -942,12 +942,11 @@
     }
 
     private void applyCustomPolicy(ZenPolicy policy, ZenRule rule) {
-        if (rule.zenMode == NotificationManager.INTERRUPTION_FILTER_NONE) {
+        if (rule.zenMode == Global.ZEN_MODE_NO_INTERRUPTIONS) {
             policy.apply(new ZenPolicy.Builder()
                     .disallowAllSounds()
                     .build());
-        } else if (rule.zenMode
-                == NotificationManager.INTERRUPTION_FILTER_ALARMS) {
+        } else if (rule.zenMode == Global.ZEN_MODE_ALARMS) {
             policy.apply(new ZenPolicy.Builder()
                     .disallowAllSounds()
                     .allowAlarms(true)
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index da69986..965ddc9 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -751,7 +751,7 @@
         @Override
         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             final DumpState dumpState = new DumpState();
-            dumpState.setUserId(UserHandle.getUserId(Binder.getCallingUid()));
+            dumpState.setUserId(UserHandle.USER_ALL);
 
             int opti = 0;
             while (opti < args.length) {
@@ -771,13 +771,13 @@
                     pw.println("  so the following are equivalent: mState, mstate, State, state.");
                     return;
                 } else if ("--user".equals(opt)) {
-                    opti++;
                     if (opti >= args.length) {
                         pw.println("Error: user missing argument");
                         return;
                     }
                     try {
                         dumpState.setUserId(Integer.parseInt(args[opti]));
+                        opti++;
                     } catch (NumberFormatException e) {
                         pw.println("Error: user argument is not a number: " + args[opti]);
                         return;
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 9b6333d..3464cab 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -443,45 +443,39 @@
             if (isManagedProfileAdmin(user, appInfo.packageName)) {
                 return false;
             }
-            // If app does not have any components or any permissions, the app can legitimately
-            // have no icon so we do not show the synthetic activity.
-            return hasComponentsAndRequestsPermissions(appInfo.packageName);
-        }
-
-        private boolean hasComponentsAndRequestsPermissions(@NonNull String packageName) {
             final PackageManagerInternal pmInt =
                     LocalServices.getService(PackageManagerInternal.class);
-            final PackageParser.Package pkg = pmInt.getPackage(packageName);
+            final PackageParser.Package pkg = pmInt.getPackage(appInfo.packageName);
             if (pkg == null) {
                 // Should not happen, but we shouldn't be failing if it does
                 return false;
             }
-            if (ArrayUtils.isEmpty(pkg.requestedPermissions)) {
-                return false;
-            }
-            if (!hasApplicationDeclaredActivities(pkg)
-                    && ArrayUtils.isEmpty(pkg.receivers)
-                    && ArrayUtils.isEmpty(pkg.providers)
-                    && ArrayUtils.isEmpty(pkg.services)) {
-                return false;
-            }
-            return true;
+            // If app does not have any default enabled launcher activity or any permissions,
+            // the app can legitimately have no icon so we do not show the synthetic activity.
+            return requestsPermissions(pkg) && hasDefaultEnableLauncherActivity(
+                    appInfo.packageName);
         }
 
-        private boolean hasApplicationDeclaredActivities(@NonNull PackageParser.Package pkg) {
-            if (pkg.activities == null) {
-                return false;
+        private boolean requestsPermissions(@NonNull PackageParser.Package pkg) {
+            return !ArrayUtils.isEmpty(pkg.requestedPermissions);
+        }
+
+        private boolean hasDefaultEnableLauncherActivity(@NonNull String packageName) {
+            final PackageManagerInternal pmInt =
+                    LocalServices.getService(PackageManagerInternal.class);
+            final Intent matchIntent = new Intent(Intent.ACTION_MAIN);
+            matchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+            matchIntent.setPackage(packageName);
+            final List<ResolveInfo> infoList = pmInt.queryIntentActivities(matchIntent,
+                    PackageManager.MATCH_DISABLED_COMPONENTS, Binder.getCallingUid(),
+                    getCallingUserId());
+            final int size = infoList.size();
+            for (int i = 0; i < size; i++) {
+                if (infoList.get(i).activityInfo.enabled) {
+                    return true;
+                }
             }
-            if (ArrayUtils.isEmpty(pkg.activities)) {
-                return false;
-            }
-            // If it only contains synthetic AppDetailsActivity only, it means application does
-            // not have actual activity declared in manifest.
-            if (pkg.activities.size() == 1 && PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(
-                    pkg.activities.get(0).className)) {
-                return false;
-            }
-            return true;
+            return false;
         }
 
         private boolean isManagedProfileAdmin(UserHandle user, String packageName) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a7d436a..aae4823 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -198,6 +198,7 @@
 import android.content.pm.dex.ArtManager;
 import android.content.pm.dex.DexMetadataHelper;
 import android.content.pm.dex.IArtManager;
+import android.content.pm.permission.SplitPermissionInfoParcelable;
 import android.content.res.Resources;
 import android.content.rollback.IRollbackManager;
 import android.database.ContentObserver;
@@ -238,6 +239,7 @@
 import android.os.storage.StorageManagerInternal;
 import android.os.storage.VolumeInfo;
 import android.os.storage.VolumeRecord;
+import android.permission.PermissionManager;
 import android.provider.DeviceConfig;
 import android.provider.MediaStore;
 import android.provider.Settings.Global;
@@ -2023,6 +2025,14 @@
                     pkgList.add(packageName);
                     sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
                 }
+            } else if (!ArrayUtils.isEmpty(res.libraryConsumers)) { // if static shared lib
+                for (int i = 0; i < res.libraryConsumers.size(); i++) {
+                    PackageParser.Package pkg = res.libraryConsumers.get(i);
+                    // send broadcast that all consumers of the static shared library have changed
+                    sendPackageChangedBroadcast(pkg.packageName, false /*killFlag*/,
+                            new ArrayList<>(Collections.singletonList(pkg.packageName)),
+                            pkg.applicationInfo.uid);
+                }
             }
 
             // Work that needs to happen on first install within each user
@@ -2121,6 +2131,12 @@
         }
     }
 
+    @Override
+    public List<SplitPermissionInfoParcelable> getSplitPermissions() {
+        return PermissionManager.splitPermissionInfoListToParcelableList(
+                SystemConfig.getInstance().getSplitPermissions());
+    }
+
     private void notifyInstallObserver(String packageName) {
         Pair<PackageInstalledInfo, IPackageInstallObserver2> pair =
                 mNoKillInstallObservers.remove(packageName);
@@ -12193,6 +12209,9 @@
                 }
             }
         }
+        if (reconciledPkg.installResult != null) {
+            reconciledPkg.installResult.libraryConsumers = clientLibPkgs;
+        }
 
         if ((scanFlags & SCAN_BOOTING) != 0) {
             // No apps can run during boot scan, so they don't need to be frozen
@@ -16046,6 +16065,8 @@
         String installerPackageName;
         PackageRemovedInfo removedInfo;
         ArrayMap<String, PackageInstalledInfo> addedChildPackages;
+        // The set of packages consuming this shared library or null if no consumers exist.
+        ArrayList<PackageParser.Package> libraryConsumers;
 
         public void setError(int code, String msg) {
             setReturnCode(code);
@@ -18800,8 +18821,14 @@
                 }
             }
             if (removedAppId >= 0) {
+                // If a system app's updates are uninstalled the UID is not actually removed. Some
+                // services need to know the package name affected.
+                if (extras.getBoolean(Intent.EXTRA_REPLACING, false)) {
+                    extras.putString(Intent.EXTRA_PACKAGE_NAME, removedPackage);
+                }
+
                 packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
-                    null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
+                        null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
                     null, null, broadcastUsers, instantUserIds);
             }
         }
@@ -18890,19 +18917,20 @@
                         // or packages running under the shared user of the removed
                         // package if revoking the permissions requested only by the removed
                         // package is successful and this causes a change in gids.
+                        boolean shouldKill = false;
                         for (int userId : UserManagerService.getInstance().getUserIds()) {
                             final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
                                     userId);
-                            if (userIdToKill == UserHandle.USER_ALL
-                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
-                                // If gids changed for this user, kill all affected packages.
-                                mHandler.post(() -> {
-                                    // This has to happen with no lock held.
-                                    killApplication(deletedPs.name, deletedPs.appId,
-                                            KILL_APP_REASON_GIDS_CHANGED);
-                                });
-                                break;
-                            }
+                            shouldKill |= userIdToKill == UserHandle.USER_ALL
+                                    || userIdToKill >= UserHandle.USER_SYSTEM;
+                        }
+                        // If gids changed, kill all affected packages.
+                        if (shouldKill) {
+                            mHandler.post(() -> {
+                                // This has to happen with no lock held.
+                                killApplication(deletedPs.name, deletedPs.appId,
+                                        KILL_APP_REASON_GIDS_CHANGED);
+                            });
                         }
                     }
                     clearPackagePreferredActivitiesLPw(
@@ -20859,7 +20887,7 @@
 
     public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
         UserManagerService ums = UserManagerService.getInstance();
-        if (ums != null) {
+        if (ums != null && !sessionInfo.isStaged()) {
             final UserInfo parent = ums.getProfileParent(userId);
             final int launcherUid = (parent != null) ? parent.id : userId;
             final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
diff --git a/services/core/java/com/android/server/pm/ProtectedPackages.java b/services/core/java/com/android/server/pm/ProtectedPackages.java
index a374e14..231168e 100644
--- a/services/core/java/com/android/server/pm/ProtectedPackages.java
+++ b/services/core/java/com/android/server/pm/ProtectedPackages.java
@@ -92,6 +92,9 @@
         if (mDeviceOwnerUserId == userId) {
             return mDeviceOwnerPackage;
         }
+        if (mProfileOwnerPackages == null) {
+            return null;
+        }
         return mProfileOwnerPackages.get(userId);
     }
 
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 4550446..ecf6686 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -190,6 +190,7 @@
     static {
         STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
         STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
+        STORAGE_PERMISSIONS.add(Manifest.permission.ACCESS_MEDIA_LOCATION);
     }
 
     private static final int MSG_READ_DEFAULT_PERMISSION_EXCEPTIONS = 1;
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 899f802..4c33bec 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -967,10 +967,12 @@
                         // or has updated its target SDK and AR is no longer implicit to it.
                         // This is a compatibility workaround for apps when AR permission was
                         // split in Q.
-                        int numSplitPerms = PermissionManager.SPLIT_PERMISSIONS.size();
+                        final List<PermissionManager.SplitPermissionInfo> permissionList =
+                                getSplitPermissions();
+                        int numSplitPerms = permissionList.size();
                         for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
                             PermissionManager.SplitPermissionInfo sp =
-                                    PermissionManager.SPLIT_PERMISSIONS.get(splitPermNum);
+                                    permissionList.get(splitPermNum);
                             String splitPermName = sp.getSplitPermission();
                             if (sp.getNewPermissions().contains(permName)
                                     && origPermissions.hasInstallPermission(splitPermName)) {
@@ -1537,10 +1539,10 @@
         String pkgName = pkg.packageName;
         ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();
 
-        int numSplitPerms = PermissionManager.SPLIT_PERMISSIONS.size();
+        final List<PermissionManager.SplitPermissionInfo> permissionList = getSplitPermissions();
+        int numSplitPerms = permissionList.size();
         for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
-            PermissionManager.SplitPermissionInfo spi =
-                    PermissionManager.SPLIT_PERMISSIONS.get(splitPermNum);
+            PermissionManager.SplitPermissionInfo spi = permissionList.get(splitPermNum);
 
             List<String> newPerms = spi.getNewPermissions();
             int numNewPerms = newPerms.size();
@@ -1595,8 +1597,6 @@
                                 Slog.i(TAG, newPerm + " does not inherit from " + sourcePerms
                                         + " for " + pkgName + " as split permission is also new");
                             }
-
-                            break;
                         } else {
                             // Inherit from new install or existing runtime permissions
                             inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms,
@@ -1610,6 +1610,10 @@
         return updatedUserIds;
     }
 
+    private List<PermissionManager.SplitPermissionInfo> getSplitPermissions() {
+        return SystemConfig.getInstance().getSplitPermissions();
+    }
+
     private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
         boolean allowed = false;
         final int NP = PackageParser.NEW_PERMISSIONS.length;
@@ -2022,16 +2026,6 @@
         return whitelistedPermissions;
     }
 
-    private void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg,
-            @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
-            @PackageManager.PermissionWhitelistFlags int whitelistFlags,
-            @NonNull PermissionCallback callback) {
-        for (int userId : userIds) {
-            setWhitelistedRestrictedPermissionsForUser(pkg, userId, permissions,
-                    callingUid, whitelistFlags, callback);
-        }
-    }
-
     private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
             String[] grantedPermissions, int callingUid, PermissionCallback callback) {
         PackageSetting ps = (PackageSetting) pkg.mExtras;
@@ -2312,109 +2306,122 @@
         }
     }
 
-    private void setWhitelistedRestrictedPermissionsForUser(@NonNull PackageParser.Package pkg,
-            @UserIdInt int userId, @Nullable List<String> permissions, int callingUid,
-            @PermissionWhitelistFlags int whitelistFlags, PermissionCallback callback) {
+    private void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg,
+            @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
+            @PackageManager.PermissionWhitelistFlags int whitelistFlags,
+            @NonNull PermissionCallback callback) {
+
         final PackageSetting ps = (PackageSetting) pkg.mExtras;
         if (ps == null) {
             return;
         }
 
         final PermissionsState permissionsState = ps.getPermissionsState();
-
-        ArraySet<String> oldGrantedRestrictedPermissions = null;
+        SparseArray<ArraySet<String>> oldGrantedRestrictedPermissionsByUser = new SparseArray<>();
         boolean updatePermissions = false;
 
         final int permissionCount = pkg.requestedPermissions.size();
-        for (int i = 0; i < permissionCount; i++) {
-            final String permissionName = pkg.requestedPermissions.get(i);
+        for (int userId : userIds) {
+            for (int i = 0; i < permissionCount; i++) {
+                final String permissionName = pkg.requestedPermissions.get(i);
 
-            final BasePermission bp = mSettings.getPermissionLocked(permissionName);
-            if (bp == null) {
-                Slog.w(TAG, "Cannot whitelist unknown permission: " + permissionName);
-                continue;
-            }
-
-            if (!bp.isHardOrSoftRestricted()) {
-                continue;
-            }
-
-            if (permissionsState.hasPermission(permissionName, userId)) {
-                if (oldGrantedRestrictedPermissions == null) {
-                    oldGrantedRestrictedPermissions = new ArraySet<>();
+                final BasePermission bp = mSettings.getPermissionLocked(permissionName);
+                if (bp == null) {
+                    Slog.w(TAG, "Cannot whitelist unknown permission: " + permissionName);
+                    continue;
                 }
-                oldGrantedRestrictedPermissions.add(permissionName);
-            }
 
-            final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);
-
-            int newFlags = oldFlags;
-            int mask = 0;
-            int whitelistFlagsCopy = whitelistFlags;
-            while (whitelistFlagsCopy != 0) {
-                final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy);
-                whitelistFlagsCopy &= ~flag;
-                switch (flag) {
-                    case FLAG_PERMISSION_WHITELIST_SYSTEM: {
-                        mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
-                        if (permissions != null && permissions.contains(permissionName)) {
-                            newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
-                        } else {
-                            newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
-                        }
-                    } break;
-                    case FLAG_PERMISSION_WHITELIST_UPGRADE: {
-                        mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
-                        if (permissions != null && permissions.contains(permissionName)) {
-                            newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
-                        } else {
-                            newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
-                        }
-                    } break;
-                    case FLAG_PERMISSION_WHITELIST_INSTALLER: {
-                        mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
-                        if (permissions != null && permissions.contains(permissionName)) {
-                            newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
-                        } else {
-                            newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
-                        }
-                    } break;
+                if (!bp.isHardOrSoftRestricted()) {
+                    continue;
                 }
-            }
 
-            if (oldFlags == newFlags) {
-                continue;
-            }
-
-            updatePermissions = true;
-
-            final boolean wasWhitelisted = (oldFlags
-                    & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
-            final boolean isWhitelisted = (newFlags
-                    & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
-
-            // If the permission is policy fixed as granted but it is no longer
-            // on any of the whitelists we need to clear the policy fixed flag
-            // as whitelisting trumps policy i.e. policy cannot grant a non
-            // grantable permission.
-            if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
-                final boolean isGranted = permissionsState.hasPermission(permissionName, userId);
-                if (!isWhitelisted && isGranted) {
-                    mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
-                    newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
+                if (permissionsState.hasPermission(permissionName, userId)) {
+                    if (oldGrantedRestrictedPermissionsByUser.get(userId) == null) {
+                        oldGrantedRestrictedPermissionsByUser.put(userId, new ArraySet<>());
+                    }
+                    oldGrantedRestrictedPermissionsByUser.get(userId).add(permissionName);
                 }
-            }
 
-            // If we are whitelisting an app that does not support runtime permissions
-            // we need to make sure it goes through the permission review UI at launch.
-            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
-                    && !wasWhitelisted && isWhitelisted) {
-                mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
-                newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
-            }
+                final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);
 
-            updatePermissionFlags(permissionName, pkg.packageName, mask, newFlags,
-                    callingUid, userId, false, null /*callback*/);
+                int newFlags = oldFlags;
+                int mask = 0;
+                int whitelistFlagsCopy = whitelistFlags;
+                while (whitelistFlagsCopy != 0) {
+                    final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy);
+                    whitelistFlagsCopy &= ~flag;
+                    switch (flag) {
+                        case FLAG_PERMISSION_WHITELIST_SYSTEM: {
+                            mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
+                            if (permissions != null && permissions.contains(permissionName)) {
+                                newFlags |=
+                                        PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
+                            } else {
+                                newFlags &=
+                                        ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
+                            }
+                        }
+                        break;
+                        case FLAG_PERMISSION_WHITELIST_UPGRADE: {
+                            mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
+                            if (permissions != null && permissions.contains(permissionName)) {
+                                newFlags |=
+                                        PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
+                            } else {
+                                newFlags &=
+                                        ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
+                            }
+                        }
+                        break;
+                        case FLAG_PERMISSION_WHITELIST_INSTALLER: {
+                            mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
+                            if (permissions != null && permissions.contains(permissionName)) {
+                                newFlags |=
+                                        PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
+                            } else {
+                                newFlags &= ~PackageManager
+                                        .FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
+                            }
+                        }
+                        break;
+                    }
+                }
+
+                if (oldFlags == newFlags) {
+                    continue;
+                }
+
+                updatePermissions = true;
+
+                final boolean wasWhitelisted = (oldFlags
+                        & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
+                final boolean isWhitelisted = (newFlags
+                        & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
+
+                // If the permission is policy fixed as granted but it is no longer
+                // on any of the whitelists we need to clear the policy fixed flag
+                // as whitelisting trumps policy i.e. policy cannot grant a non
+                // grantable permission.
+                if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
+                    final boolean isGranted = permissionsState.hasPermission(permissionName,
+                            userId);
+                    if (!isWhitelisted && isGranted) {
+                        mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
+                        newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
+                    }
+                }
+
+                // If we are whitelisting an app that does not support runtime permissions
+                // we need to make sure it goes through the permission review UI at launch.
+                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
+                        && !wasWhitelisted && isWhitelisted) {
+                    mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
+                    newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
+                }
+
+                updatePermissionFlags(permissionName, pkg.packageName, mask, newFlags,
+                        callingUid, userId, false, null /*callback*/);
+            }
         }
 
         if (updatePermissions) {
@@ -2422,7 +2429,12 @@
             restorePermissionState(pkg, false, pkg.packageName, callback);
 
             // If this resulted in losing a permission we need to kill the app.
-            if (oldGrantedRestrictedPermissions != null) {
+            int oldGrantedRestrictedPermissionsByUserCount =
+                    oldGrantedRestrictedPermissionsByUser.size();
+            for (int j = 0; j < oldGrantedRestrictedPermissionsByUserCount; j++) {
+                final int userId = oldGrantedRestrictedPermissionsByUser.keyAt(j);
+                final ArraySet<String> oldGrantedRestrictedPermissions =
+                        oldGrantedRestrictedPermissionsByUser.valueAt(j);
                 final int oldGrantedCount = oldGrantedRestrictedPermissions.size();
                 for (int i = 0; i < oldGrantedCount; i++) {
                     final String permission = oldGrantedRestrictedPermissions.valueAt(i);
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index eba4fb6..cd72c8f 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -23,6 +23,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.content.Context.CONTEXT_RESTRICTED;
 import static android.content.Context.WINDOW_SERVICE;
+import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE;
 import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
 import static android.content.pm.PackageManager.FEATURE_LEANBACK;
 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
@@ -107,6 +108,7 @@
 import android.app.ActivityTaskManager;
 import android.app.AppOpsManager;
 import android.app.IUiModeManager;
+import android.app.NotificationManager;
 import android.app.ProgressDialog;
 import android.app.SearchManager;
 import android.app.UiModeManager;
@@ -383,6 +385,7 @@
     BurnInProtectionHelper mBurnInProtectionHelper;
     private DisplayFoldController mDisplayFoldController;
     AppOpsManager mAppOpsManager;
+    private boolean mHasFeatureAuto;
     private boolean mHasFeatureWatch;
     private boolean mHasFeatureLeanback;
     private boolean mHasFeatureHdmiCec;
@@ -1751,6 +1754,7 @@
         mDisplayManager = mContext.getSystemService(DisplayManager.class);
         mHasFeatureWatch = mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH);
         mHasFeatureLeanback = mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK);
+        mHasFeatureAuto = mContext.getPackageManager().hasSystemFeature(FEATURE_AUTOMOTIVE);
         mHasFeatureHdmiCec = mContext.getPackageManager().hasSystemFeature(FEATURE_HDMI_CEC);
         mAccessibilityShortcutController =
                 new AccessibilityShortcutController(mContext, new Handler(), mCurrentUserId);
@@ -2572,6 +2576,10 @@
         return (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
     }
 
+    NotificationManager getNotificationService() {
+        return mContext.getSystemService(NotificationManager.class);
+    }
+
     static IAudioService getAudioService() {
         IAudioService audioService = IAudioService.Stub.asInterface(
                 ServiceManager.checkService(Context.AUDIO_SERVICE));
@@ -3806,6 +3814,11 @@
                 if (down) {
                     sendSystemKeyToStatusBarAsync(event.getKeyCode());
 
+                    NotificationManager nm = getNotificationService();
+                    if (nm != null && !mHandleVolumeKeysInWM) {
+                        nm.silenceNotificationSound();
+                    }
+
                     TelecomManager telecomManager = getTelecommService();
                     if (telecomManager != null && !mHandleVolumeKeysInWM) {
                         // When {@link #mHandleVolumeKeysInWM} is set, volume key events
@@ -5206,7 +5219,7 @@
             awakenDreams();
         }
 
-        if (!isUserSetupComplete()) {
+        if (!mHasFeatureAuto && !isUserSetupComplete()) {
             Slog.i(TAG, "Not going home because user setup is in progress.");
             return;
         }
diff --git a/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java b/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java
index 77bf930..712012d 100644
--- a/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java
+++ b/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java
@@ -24,20 +24,17 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.ResolveInfo;
-import android.os.Debug;
 import android.provider.Settings;
-import android.telecom.TelecomManager;
 import android.text.TextUtils;
-import android.util.Log;
 import android.util.Slog;
 
+import com.android.internal.R;
 import com.android.internal.telephony.SmsApplication;
 import com.android.internal.util.CollectionUtils;
 import com.android.server.LocalServices;
 import com.android.server.role.RoleManagerService;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 
@@ -67,14 +64,25 @@
     public List<String> getRoleHolders(@NonNull String roleName, @UserIdInt int userId) {
         switch (roleName) {
             case RoleManager.ROLE_ASSISTANT: {
-                String legacyAssistant = Settings.Secure.getStringForUser(
-                        mContext.getContentResolver(), Settings.Secure.ASSISTANT, userId);
-                if (legacyAssistant == null || legacyAssistant.isEmpty()) {
-                    return Collections.emptyList();
+                String packageName;
+                String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
+                        Settings.Secure.ASSISTANT, userId);
+                // AssistUtils was using the default assistant app if Settings.Secure.ASSISTANT is
+                // null, while only an empty string means user selected "None".
+                if (setting != null) {
+                    if (!setting.isEmpty()) {
+                        ComponentName componentName = ComponentName.unflattenFromString(setting);
+                        packageName = componentName != null ? componentName.getPackageName() : null;
+                    } else {
+                        packageName = null;
+                    }
+                } else if (mContext.getPackageManager().isDeviceUpgrading()) {
+                    String defaultAssistant = mContext.getString(R.string.config_defaultAssistant);
+                    packageName = !TextUtils.isEmpty(defaultAssistant) ? defaultAssistant : null;
                 } else {
-                    return Collections.singletonList(
-                            ComponentName.unflattenFromString(legacyAssistant).getPackageName());
+                    packageName = null;
                 }
+                return CollectionUtils.singletonOrEmpty(packageName);
             }
             case RoleManager.ROLE_BROWSER: {
                 PackageManagerInternal packageManagerInternal = LocalServices.getService(
@@ -84,44 +92,36 @@
                 return CollectionUtils.singletonOrEmpty(packageName);
             }
             case RoleManager.ROLE_DIALER: {
-                String setting = Settings.Secure.getStringForUser(
-                        mContext.getContentResolver(),
+                String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
                         Settings.Secure.DIALER_DEFAULT_APPLICATION, userId);
-                return CollectionUtils.singletonOrEmpty(!TextUtils.isEmpty(setting)
-                        ? setting
-                        : mContext.getSystemService(TelecomManager.class).getSystemDialerPackage());
+                String packageName;
+                if (!TextUtils.isEmpty(setting)) {
+                    packageName = setting;
+                } else if (mContext.getPackageManager().isDeviceUpgrading()) {
+                    // DefaultDialerManager was using the default dialer app if
+                    // Settings.Secure.DIALER_DEFAULT_APPLICATION is invalid.
+                    // TelecomManager.getSystemDialerPackage() won't work because it might not
+                    // be ready.
+                    packageName = mContext.getString(R.string.config_defaultDialer);
+                } else {
+                    packageName = null;
+                }
+                return CollectionUtils.singletonOrEmpty(packageName);
             }
             case RoleManager.ROLE_SMS: {
-                // Moved over from SmsApplication#getApplication
-                String result = Settings.Secure.getStringForUser(
-                        mContext.getContentResolver(),
+                String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
                         Settings.Secure.SMS_DEFAULT_APPLICATION, userId);
-                // TODO: STOPSHIP: Remove the following code once we read the value of
-                //  config_defaultSms in RoleControllerService.
-                if (result == null) {
-                    Collection<SmsApplication.SmsApplicationData> applications =
-                            SmsApplication.getApplicationCollectionAsUser(mContext, userId);
-                    SmsApplication.SmsApplicationData applicationData;
-                    String defaultPackage = mContext.getResources()
-                            .getString(com.android.internal.R.string.default_sms_application);
-                    applicationData =
-                            SmsApplication.getApplicationForPackage(applications, defaultPackage);
-
-                    if (applicationData == null) {
-                        // Are there any applications?
-                        if (applications.size() != 0) {
-                            applicationData =
-                                    (SmsApplication.SmsApplicationData) applications.toArray()[0];
-                        }
-                    }
-                    if (DEBUG) {
-                        Log.i(LOG_TAG, "Found default sms app: " + applicationData
-                                + " among: " + applications + " from " + Debug.getCallers(4));
-                    }
-                    SmsApplication.SmsApplicationData app = applicationData;
-                    result = app == null ? null : app.mPackageName;
+                String packageName;
+                if (!TextUtils.isEmpty(setting)) {
+                    packageName = setting;
+                } else if (mContext.getPackageManager().isDeviceUpgrading()) {
+                    // SmsApplication was using the default SMS app if
+                    // Settings.Secure.DIALER_DEFAULT_APPLICATION is invalid.
+                    packageName = mContext.getString(R.string.config_defaultSms);
+                } else {
+                    packageName = null;
                 }
-                return CollectionUtils.singletonOrEmpty(result);
+                return CollectionUtils.singletonOrEmpty(packageName);
             }
             case RoleManager.ROLE_HOME: {
                 PackageManager packageManager = mContext.getPackageManager();
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index aa49ba6..e1b3e4d 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -542,6 +542,10 @@
     // True if we in the process of performing a forceSuspend
     private boolean mForceSuspendActive;
 
+    // Transition to Doze is in progress.  We have transitioned to WAKEFULNESS_DOZING,
+    // but the DreamService has not yet been told to start (it's an async process).
+    private boolean mDozeStartInProgress;
+
     private final class ForegroundProfileObserver extends SynchronousUserSwitchObserver {
         @Override
         public void onUserSwitching(int newUserId) throws RemoteException {}
@@ -1514,6 +1518,7 @@
             mLastSleepTime = eventTime;
             mLastSleepReason = reason;
             mSandmanSummoned = true;
+            mDozeStartInProgress = true;
             setWakefulnessLocked(WAKEFULNESS_DOZING, reason, eventTime);
 
             // Report the number of wake locks that will be cleared by going to sleep.
@@ -1601,6 +1606,10 @@
             mWakefulness = wakefulness;
             mWakefulnessChanging = true;
             mDirty |= DIRTY_WAKEFULNESS;
+
+            // This is only valid while we are in wakefulness dozing. Set to false otherwise.
+            mDozeStartInProgress &= (mWakefulness == WAKEFULNESS_DOZING);
+
             if (mNotifier != null) {
                 mNotifier.onWakefulnessChangeStarted(wakefulness, reason, eventTime);
             }
@@ -1631,6 +1640,9 @@
             if (mWakefulness == WAKEFULNESS_DOZING
                     && (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) {
                 return; // wait until dream has enabled dozing
+            } else {
+                // Doze wakelock acquired (doze started) or device is no longer dozing.
+                mDozeStartInProgress = false;
             }
             if (mWakefulness == WAKEFULNESS_DOZING || mWakefulness == WAKEFULNESS_ASLEEP) {
                 logSleepTimeoutRecapturedLocked();
@@ -2309,6 +2321,10 @@
             isDreaming = false;
         }
 
+        // At this point, we either attempted to start the dream or no attempt will be made,
+        // so stop holding the display suspend blocker for Doze.
+        mDozeStartInProgress = false;
+
         // Update dream state.
         synchronized (mLock) {
             // Remember the initial battery level when the dream started.
@@ -2735,6 +2751,16 @@
         if (mScreenBrightnessBoostInProgress) {
             return true;
         }
+
+        // When we transition to DOZING, we have to keep the display suspend blocker
+        // up until the Doze service has a change to acquire the DOZE wakelock.
+        // Here we wait for mWakefulnessChanging to become false since the wakefulness
+        // transition to DOZING isn't considered "changed" until the doze wake lock is
+        // acquired.
+        if (mWakefulness == WAKEFULNESS_DOZING && mDozeStartInProgress) {
+            return true;
+        }
+
         // Let the system suspend if the screen is off or dozing.
         return false;
     }
diff --git a/services/core/java/com/android/server/power/ThermalManagerService.java b/services/core/java/com/android/server/power/ThermalManagerService.java
index 1552fd5..491c5ab 100644
--- a/services/core/java/com/android/server/power/ThermalManagerService.java
+++ b/services/core/java/com/android/server/power/ThermalManagerService.java
@@ -38,11 +38,13 @@
 import android.os.ShellCommand;
 import android.os.Temperature;
 import android.util.ArrayMap;
+import android.util.EventLog;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.DumpUtils;
+import com.android.server.EventLogTags;
 import com.android.server.FgThread;
 import com.android.server.SystemService;
 
@@ -250,6 +252,8 @@
         } finally {
             mThermalEventListeners.finishBroadcast();
         }
+        EventLog.writeEvent(EventLogTags.THERMAL_CHANGED, temperature.getName(),
+                temperature.getType(), temperature.getValue(), temperature.getStatus(), mStatus);
     }
 
     private void shutdownIfNeeded(Temperature temperature) {
@@ -860,10 +864,10 @@
                     mThermalHal11.linkToDeath(new DeathRecipient(),
                             THERMAL_HAL_DEATH_COOKIE);
                     mThermalHal11.registerThermalCallback(mThermalCallback11);
+                    Slog.i(TAG, "Thermal HAL 1.1 service connected, limited thermal functions "
+                            + "due to legacy API.");
                 } catch (NoSuchElementException | RemoteException e) {
-                    Slog.e(TAG,
-                            "Thermal HAL 1.1 service not connected, no thermal call back will be "
-                                    + "called.");
+                    Slog.e(TAG, "Thermal HAL 1.1 service not connected.");
                     mThermalHal11 = null;
                 }
                 return (mThermalHal11 != null);
@@ -978,8 +982,9 @@
                     mThermalHal20.linkToDeath(new DeathRecipient(), THERMAL_HAL_DEATH_COOKIE);
                     mThermalHal20.registerThermalChangedCallback(mThermalCallback20, false,
                             0 /* not used */);
+                    Slog.i(TAG, "Thermal HAL 2.0 service connected.");
                 } catch (NoSuchElementException | RemoteException e) {
-                    Slog.e(TAG, "Thermal HAL 2.0 service not connected, trying 1.1.");
+                    Slog.e(TAG, "Thermal HAL 2.0 service not connected.");
                     mThermalHal20 = null;
                 }
                 return (mThermalHal20 != null);
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdater.java b/services/core/java/com/android/server/webkit/WebViewUpdater.java
index a460040..3b58af2 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdater.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdater.java
@@ -87,19 +87,6 @@
                         newPackage = findPreferredWebViewPackage();
                         if (mCurrentWebViewPackage != null) {
                             oldProviderName = mCurrentWebViewPackage.packageName;
-                            if (changedState == WebViewUpdateService.PACKAGE_CHANGED
-                                    && newPackage.packageName.equals(oldProviderName)) {
-                                // If we don't change package name we should only rerun the
-                                // preparation phase if the current package has been replaced
-                                // (not if it has been enabled/disabled).
-                                return;
-                            }
-                            if (newPackage.packageName.equals(oldProviderName)
-                                    && (newPackage.lastUpdateTime
-                                        == mCurrentWebViewPackage.lastUpdateTime)) {
-                                // If the chosen package hasn't been updated, then early-out
-                                return;
-                            }
                         }
                         // Only trigger update actions if the updated package is the one
                         // that will be used, or the one that was in use before the
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 4cfc1d1..afd6674 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -907,7 +907,7 @@
                 }
 
                 public void releaseSurface() {
-                    mSurfaceControl.remove();
+                    mService.mTransactionFactory.make().remove(mSurfaceControl).apply();
                     mSurface.release();
                 }
 
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index c5c53d8..56be335 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -5227,18 +5227,28 @@
      *         then skip running tasks that match those types.
      */
     void getRunningTasks(List<TaskRecord> tasksOut, @ActivityType int ignoreActivityType,
-            @WindowingMode int ignoreWindowingMode, int callingUid, boolean allowed) {
+            @WindowingMode int ignoreWindowingMode, int callingUid, boolean allowed,
+            boolean crossUser, ArraySet<Integer> profileIds) {
         boolean focusedStack = mRootActivityContainer.getTopDisplayFocusedStack() == this;
         boolean topTask = true;
+        int userId = UserHandle.getUserId(callingUid);
         for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
             final TaskRecord task = mTaskHistory.get(taskNdx);
             if (task.getTopActivity() == null) {
                 // Skip if there are no activities in the task
                 continue;
             }
-            if (!allowed && !task.isActivityTypeHome() && task.effectiveUid != callingUid) {
-                // Skip if the caller can't fetch this task
-                continue;
+            if (task.effectiveUid != callingUid) {
+                if (task.userId != userId && !crossUser && !profileIds.contains(task.userId)) {
+                    // Skip if the caller does not have cross user permission or cannot access
+                    // the task's profile
+                    continue;
+                }
+                if (!allowed && !task.isActivityTypeHome()) {
+                    // Skip if the caller isn't allowed to fetch this task, except for the home
+                    // task which we always return.
+                    continue;
+                }
             }
             if (ignoreActivityType != ACTIVITY_TYPE_UNDEFINED
                     && task.getActivityType() == ignoreActivityType) {
@@ -5454,6 +5464,7 @@
             task.cleanUpResourcesForDestroy();
         }
 
+        final ActivityDisplay display = getDisplay();
         if (mTaskHistory.isEmpty()) {
             if (DEBUG_STACK) Slog.i(TAG_STACK, "removeTask: removing stack=" + this);
             // We only need to adjust focused stack if this stack is in focus and we are not in the
@@ -5462,11 +5473,11 @@
                     && mRootActivityContainer.isTopDisplayFocusedStack(this)) {
                 String myReason = reason + " leftTaskHistoryEmpty";
                 if (!inMultiWindowMode() || adjustFocusToNextFocusableStack(myReason) == null) {
-                    getDisplay().moveHomeStackToFront(myReason);
+                    display.moveHomeStackToFront(myReason);
                 }
             }
             if (isAttached()) {
-                getDisplay().positionChildAtBottom(this);
+                display.positionChildAtBottom(this);
             }
             if (!isActivityTypeHome() || !isAttached()) {
                 remove();
@@ -5479,6 +5490,9 @@
         if (inPinnedWindowingMode()) {
             mService.getTaskChangeNotificationController().notifyActivityUnpinned();
         }
+        if (display.isSingleTaskInstance()) {
+            mService.notifySingleTaskDisplayEmpty(display.mDisplayId);
+        }
     }
 
     TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 5a1eed8..5b697ee 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2700,7 +2700,8 @@
                  || mPreferredDisplayId != DEFAULT_DISPLAY) {
             final boolean onTop = aOptions == null || !aOptions.getAvoidMoveToFront();
             final ActivityStack stack =
-                    mRootActivityContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams);
+                    mRootActivityContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams,
+                            mRequest.realCallingPid, mRequest.realCallingUid);
             return stack;
         }
         // Otherwise handle adjacent launch.
@@ -2818,11 +2819,24 @@
         return this;
     }
 
+    /**
+     * Sets the pid of the caller who originally started the activity.
+     *
+     * Normally, the pid/uid would be the calling pid from the binder call.
+     * However, in case of a {@link PendingIntent}, the pid/uid pair of the caller is considered
+     * the original entity that created the pending intent, in contrast to setRealCallingPid/Uid,
+     * which represents the entity who invoked pending intent via {@link PendingIntent#send}.
+     */
     ActivityStarter setCallingPid(int pid) {
         mRequest.callingPid = pid;
         return this;
     }
 
+    /**
+     * Sets the uid of the caller who originally started the activity.
+     *
+     * @see #setCallingPid
+     */
     ActivityStarter setCallingUid(int uid) {
         mRequest.callingUid = uid;
         return this;
@@ -2833,11 +2847,25 @@
         return this;
     }
 
+    /**
+     * Sets the pid of the caller who requested to launch the activity.
+     *
+     * The pid/uid represents the caller who launches the activity in this request.
+     * It will almost same as setCallingPid/Uid except when processing {@link PendingIntent}:
+     * the pid/uid will be the caller who called {@link PendingIntent#send()}.
+     *
+     * @see #setCallingPid
+     */
     ActivityStarter setRealCallingPid(int pid) {
         mRequest.realCallingPid = pid;
         return this;
     }
 
+    /**
+     * Sets the uid of the caller who requested to launch the activity.
+     *
+     * @see #setRealCallingPid
+     */
     ActivityStarter setRealCallingUid(int uid) {
         mRequest.realCallingUid = uid;
         return this;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 747837b..2232053 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -19,6 +19,8 @@
 import static android.Manifest.permission.BIND_VOICE_INTERACTION;
 import static android.Manifest.permission.CHANGE_CONFIGURATION;
 import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
+import static android.Manifest.permission.INTERACT_ACROSS_USERS;
+import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
 import static android.Manifest.permission.READ_FRAME_BUFFER;
@@ -213,6 +215,7 @@
 import android.text.TextUtils;
 import android.text.format.Time;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
@@ -2522,15 +2525,22 @@
             @WindowConfiguration.ActivityType int ignoreActivityType,
             @WindowConfiguration.WindowingMode int ignoreWindowingMode) {
         final int callingUid = Binder.getCallingUid();
+        final int callingPid = Binder.getCallingPid();
+        final boolean crossUser = isCrossUserAllowed(callingPid, callingUid);
+        final int[] profileIds = getUserManager().getProfileIds(
+                UserHandle.getUserId(callingUid), true);
+        ArraySet<Integer> callingProfileIds = new ArraySet<>();
+        for (int i = 0; i < profileIds.length; i++) {
+            callingProfileIds.add(profileIds[i]);
+        }
         ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>();
 
         synchronized (mGlobalLock) {
             if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
 
-            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
-                    callingUid);
+            final boolean allowed = isGetTasksAllowed("getTasks", callingPid, callingUid);
             mRootActivityContainer.getRunningTasks(maxNum, list, ignoreActivityType,
-                    ignoreWindowingMode, callingUid, allowed);
+                    ignoreWindowingMode, callingUid, allowed, crossUser, callingProfileIds);
         }
 
         return list;
@@ -3587,6 +3597,11 @@
         return allowed;
     }
 
+    boolean isCrossUserAllowed(int pid, int uid) {
+        return checkPermission(INTERACT_ACROSS_USERS, pid, uid) == PERMISSION_GRANTED
+                || checkPermission(INTERACT_ACROSS_USERS_FULL, pid, uid) == PERMISSION_GRANTED;
+    }
+
     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
             IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
@@ -6048,6 +6063,10 @@
         return allUids.contains(uid);
     }
 
+    void notifySingleTaskDisplayEmpty(int displayId) {
+        mTaskChangeNotificationController.notifySingleTaskDisplayEmpty(displayId);
+    }
+
     final class H extends Handler {
         static final int REPORT_TIME_TRACKER_MSG = 1;
 
diff --git a/services/core/java/com/android/server/wm/BlackFrame.java b/services/core/java/com/android/server/wm/BlackFrame.java
index 84ba5ca9..7fc17e1 100644
--- a/services/core/java/com/android/server/wm/BlackFrame.java
+++ b/services/core/java/com/android/server/wm/BlackFrame.java
@@ -97,6 +97,7 @@
     final BlackSurface[] mBlackSurfaces = new BlackSurface[4];
 
     final boolean mForceDefaultOrientation;
+    private final TransactionFactory mTransactionFactory;
 
     public void printTo(String prefix, PrintWriter pw) {
         pw.print(prefix); pw.print("Outer: "); mOuterRect.printShortString(pw);
@@ -111,11 +112,12 @@
         }
     }
 
-    public BlackFrame(SurfaceControl.Transaction t,
-            Rect outer, Rect inner, int layer, DisplayContent dc,
-            boolean forceDefaultOrientation) throws OutOfResourcesException {
+    public BlackFrame(TransactionFactory factory, SurfaceControl.Transaction t, Rect outer,
+            Rect inner, int layer, DisplayContent dc, boolean forceDefaultOrientation)
+            throws OutOfResourcesException {
         boolean success = false;
 
+        mTransactionFactory = factory;
         mForceDefaultOrientation = forceDefaultOrientation;
 
         // TODO: Why do we use 4 surfaces instead of just one big one behind the screenshot?
@@ -149,14 +151,16 @@
 
     public void kill() {
         if (mBlackSurfaces != null) {
+            SurfaceControl.Transaction t = mTransactionFactory.make();
             for (int i=0; i<mBlackSurfaces.length; i++) {
                 if (mBlackSurfaces[i] != null) {
                     if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
                             "  BLACK " + mBlackSurfaces[i].surface + ": DESTROY");
-                    mBlackSurfaces[i].surface.remove();
+                    t.remove(mBlackSurfaces[i].surface);
                     mBlackSurfaces[i] = null;
                 }
             }
+            t.apply();
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index e099a4f..3e7fea2 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1072,9 +1072,10 @@
                 // removing from parent.
                 token.getParent().removeChild(token);
             }
-            if (prevDc.mLastFocus == mCurrentFocus) {
-                // The window has become the focus of this display, so it should not be notified
-                // that it lost focus from the previous display.
+            if (token.hasChild(prevDc.mLastFocus)) {
+                // If the reparent window token contains previous display's last focus window, means
+                // it will end up to gain window focus on the target display, so it should not be
+                // notified that it lost focus from the previous display.
                 prevDc.mLastFocus = null;
             }
         }
@@ -4589,13 +4590,15 @@
                         .show(mSplitScreenDividerAnchor);
                 scheduleAnimation();
             } else {
-                mAppAnimationLayer.remove();
+                mWmService.mTransactionFactory.make()
+                        .remove(mAppAnimationLayer)
+                        .remove(mBoostedAppAnimationLayer)
+                        .remove(mHomeAppAnimationLayer)
+                        .remove(mSplitScreenDividerAnchor)
+                        .apply();
                 mAppAnimationLayer = null;
-                mBoostedAppAnimationLayer.remove();
                 mBoostedAppAnimationLayer = null;
-                mHomeAppAnimationLayer.remove();
                 mHomeAppAnimationLayer = null;
-                mSplitScreenDividerAnchor.remove();
                 mSplitScreenDividerAnchor = null;
             }
         }
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index ed7dbd0..99a9db3 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -3622,7 +3622,8 @@
         if (mScreenshotHelper != null) {
             mScreenshotHelper.takeScreenshot(screenshotType,
                     mStatusBar != null && mStatusBar.isVisibleLw(),
-                    mNavigationBar != null && mNavigationBar.isVisibleLw(), mHandler);
+                    mNavigationBar != null && mNavigationBar.isVisibleLw(),
+                    mHandler, null /* completionConsumer */);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
index a46fa13..207e8ef 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
@@ -30,6 +30,7 @@
 import android.annotation.Nullable;
 import android.app.WindowConfiguration;
 import android.os.Environment;
+import android.os.FileUtils;
 import android.provider.Settings;
 import android.util.AtomicFile;
 import android.util.Slog;
@@ -64,6 +65,11 @@
 class DisplayWindowSettings {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayWindowSettings" : TAG_WM;
 
+    private static final String SYSTEM_DIRECTORY = "system";
+    private static final String DISPLAY_SETTINGS_FILE_NAME = "display_settings.xml";
+    private static final String VENDOR_DISPLAY_SETTINGS_PATH = "etc/" + DISPLAY_SETTINGS_FILE_NAME;
+    private static final String WM_DISPLAY_COMMIT_TAG = "wm-displays";
+
     private static final int IDENTIFIER_UNIQUE_ID = 0;
     private static final int IDENTIFIER_PORT = 1;
     @IntDef(prefix = { "IDENTIFIER_" }, value = {
@@ -688,8 +694,26 @@
         private final AtomicFile mAtomicFile;
 
         AtomicFileStorage() {
-            final File folder = new File(Environment.getDataDirectory(), "system");
-            mAtomicFile = new AtomicFile(new File(folder, "display_settings.xml"), "wm-displays");
+            final File folder = new File(Environment.getDataDirectory(), SYSTEM_DIRECTORY);
+            final File settingsFile = new File(folder, DISPLAY_SETTINGS_FILE_NAME);
+            // If display_settings.xml doesn't exist, try to copy the vendor's one instead
+            // in order to provide the vendor specific initialization.
+            if (!settingsFile.exists()) {
+                copyVendorSettings(settingsFile);
+            }
+            mAtomicFile = new AtomicFile(settingsFile, WM_DISPLAY_COMMIT_TAG);
+        }
+
+        private static void copyVendorSettings(File target) {
+            final File vendorFile = new File(Environment.getVendorDirectory(),
+                    VENDOR_DISPLAY_SETTINGS_PATH);
+            if (vendorFile.canRead()) {
+                try {
+                    FileUtils.copy(vendorFile, target);
+                } catch (IOException e) {
+                    Slog.e(TAG, "Failed to copy vendor display_settings.xml");
+                }
+            }
         }
 
         @Override
diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java
index c3ea72f..bb035d5 100644
--- a/services/core/java/com/android/server/wm/Letterbox.java
+++ b/services/core/java/com/android/server/wm/Letterbox.java
@@ -261,7 +261,7 @@
 
         public void remove() {
             if (mSurface != null) {
-                mSurface.remove();
+                new SurfaceControl.Transaction().remove(mSurface).apply();
                 mSurface = null;
             }
             if (mInputInterceptor != null) {
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index d58c613..ffbf688 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -1667,7 +1667,8 @@
 
     <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r,
             @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop) {
-        return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */);
+        return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */,
+                -1 /* no realCallingPid */, -1 /* no realCallingUid */);
     }
 
     /**
@@ -1676,13 +1677,16 @@
      * @param r The activity we are trying to launch. Can be null.
      * @param options The activity options used to the launch. Can be null.
      * @param candidateTask The possible task the activity might be launched in. Can be null.
-     * @params launchParams The resolved launch params to use.
+     * @param launchParams The resolved launch params to use.
+     * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid}
+     * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid}
      *
      * @return The stack to use for the launch or INVALID_STACK_ID.
      */
     <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r,
             @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop,
-            @Nullable LaunchParamsController.LaunchParams launchParams) {
+            @Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid,
+            int realCallingUid) {
         int taskId = INVALID_TASK_ID;
         int displayId = INVALID_DISPLAY;
         //Rect bounds = null;
@@ -1713,7 +1717,14 @@
         if (launchParams != null && launchParams.mPreferredDisplayId != INVALID_DISPLAY) {
             displayId = launchParams.mPreferredDisplayId;
         }
-        if (displayId != INVALID_DISPLAY && canLaunchOnDisplay(r, displayId)) {
+        final boolean canLaunchOnDisplayFromStartRequest =
+                realCallingPid != 0 && realCallingUid > 0 && r != null
+                        && mStackSupervisor.canPlaceEntityOnDisplay(displayId, realCallingPid,
+                        realCallingUid, r.info);
+        // Checking if the activity's launch caller, or the realCallerId of the activity from
+        // start request (i.e. PendingIntent caller) is allowed to launch on the display.
+        if (displayId != INVALID_DISPLAY && (canLaunchOnDisplay(r, displayId)
+                || canLaunchOnDisplayFromStartRequest)) {
             if (r != null) {
                 stack = (T) getValidLaunchStackOnDisplay(displayId, r, candidateTask, options,
                         launchParams);
@@ -2266,9 +2277,9 @@
     void getRunningTasks(int maxNum, List<ActivityManager.RunningTaskInfo> list,
             @WindowConfiguration.ActivityType int ignoreActivityType,
             @WindowConfiguration.WindowingMode int ignoreWindowingMode, int callingUid,
-            boolean allowed) {
+            boolean allowed, boolean crossUser, ArraySet<Integer> profileIds) {
         mStackSupervisor.mRunningTasks.getTasks(maxNum, list, ignoreActivityType,
-                ignoreWindowingMode, mActivityDisplays, callingUid, allowed);
+                ignoreWindowingMode, mActivityDisplays, callingUid, allowed, crossUser, profileIds);
     }
 
     void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
diff --git a/services/core/java/com/android/server/wm/RunningTasks.java b/services/core/java/com/android/server/wm/RunningTasks.java
index 3bf437d..81a8547 100644
--- a/services/core/java/com/android/server/wm/RunningTasks.java
+++ b/services/core/java/com/android/server/wm/RunningTasks.java
@@ -19,6 +19,7 @@
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.WindowConfiguration.ActivityType;
 import android.app.WindowConfiguration.WindowingMode;
+import android.util.ArraySet;
 
 import java.util.ArrayList;
 import java.util.Comparator;
@@ -40,7 +41,7 @@
 
     void getTasks(int maxNum, List<RunningTaskInfo> list, @ActivityType int ignoreActivityType,
             @WindowingMode int ignoreWindowingMode, ArrayList<ActivityDisplay> activityDisplays,
-            int callingUid, boolean allowed) {
+            int callingUid, boolean allowed, boolean crossUser, ArraySet<Integer> profileIds) {
         // Return early if there are no tasks to fetch
         if (maxNum <= 0) {
             return;
@@ -55,7 +56,7 @@
                 final ActivityStack stack = display.getChildAt(stackNdx);
                 mTmpStackTasks.clear();
                 stack.getRunningTasks(mTmpStackTasks, ignoreActivityType, ignoreWindowingMode,
-                        callingUid, allowed);
+                        callingUid, allowed, crossUser, profileIds);
                 mTmpSortedSet.addAll(mTmpStackTasks);
             }
         }
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index 0be9736..b94a7dc 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -558,7 +558,7 @@
                 Rect outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
                         mOriginalWidth*2, mOriginalHeight*2);
                 Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
-                mCustomBlackFrame = new BlackFrame(t, outer, inner,
+                mCustomBlackFrame = new BlackFrame(mService.mTransactionFactory, t, outer, inner,
                         SCREEN_FREEZE_LAYER_CUSTOM, mDisplayContent, false);
                 mCustomBlackFrame.setMatrix(t, mFrameInitialMatrix);
             } catch (OutOfResourcesException e) {
@@ -589,7 +589,7 @@
                             mOriginalWidth*2, mOriginalHeight*2);
                     inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
                 }
-                mExitingBlackFrame = new BlackFrame(t, outer, inner,
+                mExitingBlackFrame = new BlackFrame(mService.mTransactionFactory, t, outer, inner,
                         SCREEN_FREEZE_LAYER_EXIT, mDisplayContent, mForceDefaultOrientation);
                 mExitingBlackFrame.setMatrix(t, mFrameInitialMatrix);
             } catch (OutOfResourcesException e) {
@@ -602,7 +602,7 @@
                 Rect outer = new Rect(-finalWidth*1, -finalHeight*1,
                         finalWidth*2, finalHeight*2);
                 Rect inner = new Rect(0, 0, finalWidth, finalHeight);
-                mEnteringBlackFrame = new BlackFrame(t, outer, inner,
+                mEnteringBlackFrame = new BlackFrame(mService.mTransactionFactory, t, outer, inner,
                         SCREEN_FREEZE_LAYER_ENTER, mDisplayContent, false);
             } catch (OutOfResourcesException e) {
                 Slog.w(TAG, "Unable to allocate black surface", e);
@@ -640,7 +640,7 @@
             if (SHOW_TRANSACTIONS ||
                     SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
                             "  FREEZE " + mSurfaceControl + ": DESTROY");
-            mSurfaceControl.remove();
+            mService.mTransactionFactory.make().remove(mSurfaceControl).apply();
             mSurfaceControl = null;
         }
         if (mCustomBlackFrame != null) {
diff --git a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
index f776062..4c50527 100644
--- a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
@@ -55,7 +55,8 @@
     private static final int NOTIFY_SIZE_COMPAT_MODE_ACTIVITY_CHANGED_MSG = 20;
     private static final int NOTIFY_BACK_PRESSED_ON_TASK_ROOT = 21;
     private static final int NOTIFY_SINGLE_TASK_DISPLAY_DRAWN = 22;
-    private static final int NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG = 23;
+    private static final int NOTIFY_SINGLE_TASK_DISPLAY_EMPTY = 23;
+    private static final int NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG = 24;
 
     // Delay in notifying task stack change listeners (in millis)
     private static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
@@ -160,6 +161,10 @@
         l.onSingleTaskDisplayDrawn(m.arg1);
     };
 
+    private final TaskStackConsumer mNotifySingleTaskDisplayEmpty = (l, m) -> {
+        l.onSingleTaskDisplayEmpty(m.arg1);
+    };
+
     private final TaskStackConsumer mNotifyTaskDisplayChanged = (l, m) -> {
         l.onTaskDisplayChanged(m.arg1, m.arg2);
     };
@@ -246,6 +251,9 @@
                 case NOTIFY_SINGLE_TASK_DISPLAY_DRAWN:
                     forAllRemoteListeners(mNotifySingleTaskDisplayDrawn, msg);
                     break;
+                case NOTIFY_SINGLE_TASK_DISPLAY_EMPTY:
+                    forAllRemoteListeners(mNotifySingleTaskDisplayEmpty, msg);
+                    break;
                 case NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG:
                     forAllRemoteListeners(mNotifyTaskDisplayChanged, msg);
                     break;
@@ -505,6 +513,17 @@
     }
 
     /**
+     * Notify listeners that the last task is removed from a single task display.
+     */
+    void notifySingleTaskDisplayEmpty(int displayId) {
+        final Message msg = mHandler.obtainMessage(
+                NOTIFY_SINGLE_TASK_DISPLAY_EMPTY,
+                displayId, 0 /* unused */);
+        forAllLocalListeners(mNotifySingleTaskDisplayEmpty, msg);
+        msg.sendToTarget();
+    }
+
+    /**
      * Notify listeners that a task is reparented to another display.
      */
     void notifyTaskDisplayChanged(int taskId, int newDisplayId) {
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 114a56f..343a972 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -1012,7 +1012,7 @@
         EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId);
 
         if (mAnimationBackgroundSurface != null) {
-            mAnimationBackgroundSurface.remove();
+            mWmService.mTransactionFactory.make().remove(mAnimationBackgroundSurface).apply();
             mAnimationBackgroundSurface = null;
         }
 
@@ -1747,6 +1747,11 @@
             if (toBounds.width() == fromBounds.width()
                     && toBounds.height() == fromBounds.height()) {
                 intendedAnimationType = BoundsAnimationController.BOUNDS;
+            } else if (!fromFullscreen && !toBounds.equals(fromBounds)) {
+                // intendedAnimationType may have been reset at the end of RecentsAnimation,
+                // force it to BOUNDS type if we know for certain we're animating to
+                // a different bounds, especially for expand and collapse of PiP window.
+                intendedAnimationType = BoundsAnimationController.BOUNDS;
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c108752..f67b4fe 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1167,7 +1167,8 @@
                 new HandlerExecutor(mH), properties -> {
                     synchronized (mGlobalLock) {
                         final int exclusionLimitDp = Math.max(MIN_GESTURE_EXCLUSION_LIMIT_DP,
-                                properties.getInt(KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, 0));
+                                DeviceConfig.getInt(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                                        KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, 0));
                         final boolean excludedByPreQSticky = DeviceConfig.getBoolean(
                                 DeviceConfig.NAMESPACE_WINDOW_MANAGER,
                                 KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE, false);
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 53bbd70..f37209b 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -162,7 +162,7 @@
         }
         try {
             if (mSurfaceControl != null) {
-                mSurfaceControl.remove();
+                mTmpTransaction.remove(mSurfaceControl).apply();
             }
         } catch (RuntimeException e) {
             Slog.w(TAG, "Error destroying surface in: " + this, e);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 133b82f..97e003c 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -23,6 +23,7 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 
 import android.annotation.NonNull;
+import android.annotation.StringRes;
 import android.app.ActivityThread;
 import android.app.INotificationManager;
 import android.app.usage.UsageStatsManagerInternal;
@@ -1251,14 +1252,22 @@
             startSystemCaptionsManagerService(context);
 
             // App prediction manager service
-            traceBeginAndSlog("StartAppPredictionService");
-            mSystemServiceManager.startService(APP_PREDICTION_MANAGER_SERVICE_CLASS);
-            traceEnd();
+            if (deviceHasConfigString(context, R.string.config_defaultAppPredictionService)) {
+                traceBeginAndSlog("StartAppPredictionService");
+                mSystemServiceManager.startService(APP_PREDICTION_MANAGER_SERVICE_CLASS);
+                traceEnd();
+            } else {
+                Slog.d(TAG, "AppPredictionService not defined by OEM");
+            }
 
             // Content suggestions manager service
-            traceBeginAndSlog("StartContentSuggestionsService");
-            mSystemServiceManager.startService(CONTENT_SUGGESTIONS_SERVICE_CLASS);
-            traceEnd();
+            if (deviceHasConfigString(context, R.string.config_defaultContentSuggestionsService)) {
+                traceBeginAndSlog("StartContentSuggestionsService");
+                mSystemServiceManager.startService(CONTENT_SUGGESTIONS_SERVICE_CLASS);
+                traceEnd();
+            } else {
+                Slog.d(TAG, "ContentSuggestionsService not defined by OEM");
+            }
 
             traceBeginAndSlog("InitNetworkStackClient");
             try {
@@ -2249,10 +2258,13 @@
         }, BOOT_TIMINGS_TRACE_LOG);
     }
 
+    private boolean deviceHasConfigString(@NonNull Context context, @StringRes int resId) {
+        String serviceName = context.getString(resId);
+        return !TextUtils.isEmpty(serviceName);
+    }
+
     private void startSystemCaptionsManagerService(@NonNull Context context) {
-        String serviceName = context.getString(
-                com.android.internal.R.string.config_defaultSystemCaptionsManagerService);
-        if (TextUtils.isEmpty(serviceName)) {
+        if (!deviceHasConfigString(context, R.string.config_defaultSystemCaptionsManagerService)) {
             Slog.d(TAG, "SystemCaptionsManagerService disabled because resource is not overlaid");
             return;
         }
@@ -2279,9 +2291,7 @@
 
         // Then check if OEM overlaid the resource that defines the service.
         if (!explicitlyEnabled) {
-            final String serviceName = context
-                    .getString(com.android.internal.R.string.config_defaultContentCaptureService);
-            if (TextUtils.isEmpty(serviceName)) {
+            if (!deviceHasConfigString(context, R.string.config_defaultContentCaptureService)) {
                 Slog.d(TAG, "ContentCaptureService disabled because resource is not overlaid");
                 return;
             }
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/GlobalActionPerformerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/GlobalActionPerformerTest.java
index e72e460..c73be6f 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/GlobalActionPerformerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/GlobalActionPerformerTest.java
@@ -35,6 +35,8 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.function.Consumer;
+
 /**
  * Tests for GlobalActionPerformer
  */
@@ -84,6 +86,6 @@
                 AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT);
         verify(mMockScreenshotHelper).takeScreenshot(
                 eq(android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN), anyBoolean(),
-                anyBoolean(), any(Handler.class));
+                anyBoolean(), any(Handler.class), any());
     }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java
index 273a9e6..7459c4b 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java
@@ -86,7 +86,7 @@
         BubbleExtractor extractor = new BubbleExtractor();
         extractor.setConfig(mConfig);
 
-        when(mConfig.bubblesEnabled(mUser)).thenReturn(true);
+        when(mConfig.bubblesEnabled()).thenReturn(true);
         when(mConfig.areBubblesAllowed(mPkg, mUid)).thenReturn(true);
         NotificationRecord r = getNotificationRecord(false, IMPORTANCE_UNSPECIFIED);
 
@@ -100,7 +100,7 @@
         BubbleExtractor extractor = new BubbleExtractor();
         extractor.setConfig(mConfig);
 
-        when(mConfig.bubblesEnabled(mUser)).thenReturn(true);
+        when(mConfig.bubblesEnabled()).thenReturn(true);
         when(mConfig.areBubblesAllowed(mPkg, mUid)).thenReturn(false);
         NotificationRecord r = getNotificationRecord(true, IMPORTANCE_HIGH);
 
@@ -114,7 +114,7 @@
         BubbleExtractor extractor = new BubbleExtractor();
         extractor.setConfig(mConfig);
 
-        when(mConfig.bubblesEnabled(mUser)).thenReturn(true);
+        when(mConfig.bubblesEnabled()).thenReturn(true);
         when(mConfig.areBubblesAllowed(mPkg, mUid)).thenReturn(true);
         NotificationRecord r = getNotificationRecord(true, IMPORTANCE_UNSPECIFIED);
 
@@ -128,7 +128,7 @@
         BubbleExtractor extractor = new BubbleExtractor();
         extractor.setConfig(mConfig);
 
-        when(mConfig.bubblesEnabled(mUser)).thenReturn(true);
+        when(mConfig.bubblesEnabled()).thenReturn(true);
         when(mConfig.areBubblesAllowed(mPkg, mUid)).thenReturn(false);
         NotificationRecord r = getNotificationRecord(false, IMPORTANCE_UNSPECIFIED);
 
@@ -142,7 +142,7 @@
         BubbleExtractor extractor = new BubbleExtractor();
         extractor.setConfig(mConfig);
 
-        when(mConfig.bubblesEnabled(mUser)).thenReturn(false);
+        when(mConfig.bubblesEnabled()).thenReturn(false);
         when(mConfig.areBubblesAllowed(mPkg, mUid)).thenReturn(true);
         NotificationRecord r = getNotificationRecord(true, IMPORTANCE_HIGH);
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 504e531..dc5edcd 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -20,6 +20,7 @@
 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
 import static android.app.Notification.CATEGORY_CALL;
+import static android.app.Notification.FLAG_AUTO_CANCEL;
 import static android.app.Notification.FLAG_BUBBLE;
 import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
 import static android.app.NotificationManager.EXTRA_BLOCKED_STATE;
@@ -420,7 +421,7 @@
     private void setUpPrefsForBubbles(boolean globalEnabled, boolean pkgEnabled,
             boolean channelEnabled) {
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mPreferencesHelper.bubblesEnabled(any())).thenReturn(globalEnabled);
+        when(mPreferencesHelper.bubblesEnabled()).thenReturn(globalEnabled);
         when(mPreferencesHelper.areBubblesAllowed(anyString(), anyInt())).thenReturn(pkgEnabled);
         when(mPreferencesHelper.getNotificationChannel(
                 anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
@@ -439,14 +440,22 @@
         return sbn;
     }
 
+
     private NotificationRecord generateNotificationRecord(NotificationChannel channel, int id,
             String groupKey, boolean isSummary) {
+        return generateNotificationRecord(channel, id, groupKey, isSummary, false /* isBubble */);
+    }
+
+    private NotificationRecord generateNotificationRecord(NotificationChannel channel, int id,
+            String groupKey, boolean isSummary, boolean isBubble) {
         Notification.Builder nb = new Notification.Builder(mContext, channel.getId())
                 .setContentTitle("foo")
                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
                 .setGroup(groupKey)
                 .setGroupSummary(isSummary);
-
+        if (isBubble) {
+            nb.setBubbleMetadata(getBasicBubbleMetadataBuilder().build());
+        }
         StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, id, "tag", mUid, 0,
                 nb.build(), new UserHandle(mUid), null, 0);
         return new NotificationRecord(mContext, sbn, channel);
@@ -542,6 +551,52 @@
                 .setIcon(Icon.createWithResource(mContext, android.R.drawable.sym_def_app_icon));
     }
 
+    private NotificationRecord addGroupWithBubblesAndValidateAdded(boolean summaryAutoCancel)
+            throws RemoteException {
+
+        // Notification that has bubble metadata
+        NotificationRecord nrBubble = generateNotificationRecord(mTestNotificationChannel, 1,
+                "BUBBLE_GROUP", false /* isSummary */, true /* isBubble */);
+
+        // Make the package foreground so that we're allowed to be a bubble
+        when(mActivityManager.getPackageImportance(nrBubble.sbn.getPackageName())).thenReturn(
+                IMPORTANCE_FOREGROUND);
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+                nrBubble.sbn.getId(), nrBubble.sbn.getNotification(), nrBubble.sbn.getUserId());
+        waitForIdle();
+
+        // Make sure we are a bubble
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        assertEquals(1, notifsAfter.length);
+        assertTrue((notifsAfter[0].getNotification().flags & FLAG_BUBBLE) != 0);
+
+        // Plain notification without bubble metadata
+        NotificationRecord nrPlain = generateNotificationRecord(mTestNotificationChannel, 2,
+                "BUBBLE_GROUP", false /* isSummary */, false /* isBubble */);
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+                nrPlain.sbn.getId(), nrPlain.sbn.getNotification(), nrPlain.sbn.getUserId());
+        waitForIdle();
+
+        notifsAfter = mBinderService.getActiveNotifications(PKG);
+        assertEquals(2, notifsAfter.length);
+
+        // Summary notification for both of those
+        NotificationRecord nrSummary = generateNotificationRecord(mTestNotificationChannel, 3,
+                "BUBBLE_GROUP", true /* isSummary */, false /* isBubble */);
+        if (summaryAutoCancel) {
+            nrSummary.getNotification().flags |= FLAG_AUTO_CANCEL;
+        }
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+                nrSummary.sbn.getId(), nrSummary.sbn.getNotification(), nrSummary.sbn.getUserId());
+        waitForIdle();
+
+        notifsAfter = mBinderService.getActiveNotifications(PKG);
+        assertEquals(3, notifsAfter.length);
+
+        return nrSummary;
+    }
+
     @Test
     public void testCreateNotificationChannels_SingleChannel() throws Exception {
         final NotificationChannel channel =
@@ -962,20 +1017,6 @@
     }
 
     @Test
-    public void testCancelImmediatelyAfterEnqueueNotifiesListeners_ForegroundServiceFlag()
-            throws Exception {
-        final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
-        sbn.getNotification().flags =
-                Notification.FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
-                sbn.getId(), sbn.getNotification(), sbn.getUserId());
-        mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId());
-        waitForIdle();
-        verify(mListeners, times(1)).notifyPostedLocked(any(), any());
-        verify(mListeners, times(1)).notifyRemovedLocked(any(), anyInt(), any());
-    }
-
-    @Test
     public void testUserInitiatedClearAll_noLeak() throws Exception {
         final NotificationRecord n = generateNotificationRecord(
                 mTestNotificationChannel, 1, "group", true);
@@ -1522,14 +1563,22 @@
     public void testUpdateAppNotifyCreatorBlock() throws Exception {
         mService.setPreferencesHelper(mPreferencesHelper);
 
-        mBinderService.setNotificationsEnabledForPackage(PKG, 0, false);
+        mBinderService.setNotificationsEnabledForPackage(PKG, 0, true);
         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
         verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
 
         assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED,
                 captor.getValue().getAction());
         assertEquals(PKG, captor.getValue().getPackage());
-        assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
+        assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true));
+    }
+
+    @Test
+    public void testUpdateAppNotifyCreatorBlock_notIfMatchesExistingSetting() throws Exception {
+        mService.setPreferencesHelper(mPreferencesHelper);
+
+        mBinderService.setNotificationsEnabledForPackage(PKG, 0, false);
+        verify(mContext, never()).sendBroadcastAsUser(any(), any(), eq(null));
     }
 
     @Test
@@ -5092,4 +5141,162 @@
         assertEquals(1, notifsAfter.length);
         assertEquals((notifsAfter[0].getNotification().flags & FLAG_BUBBLE), 0);
     }
+
+    @Test
+    public void testNotificationBubbles_flagAutoExpandForeground_fails_notForeground()
+            throws Exception {
+        // Bubbles are allowed!
+        setUpPrefsForBubbles(true /* global */, true /* app */, true /* channel */);
+
+        // Give it bubble metadata
+        Notification.BubbleMetadata data = getBasicBubbleMetadataBuilder()
+                .setSuppressNotification(true)
+                .setAutoExpandBubble(true).build();
+        // Give it a person
+        Person person = new Person.Builder()
+                .setName("bubblebot")
+                .build();
+        // It needs remote input to be bubble-able
+        RemoteInput remoteInput = new RemoteInput.Builder("reply_key").setLabel("reply").build();
+        PendingIntent inputIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+        Icon icon = Icon.createWithResource(mContext, android.R.drawable.sym_def_app_icon);
+        Notification.Action replyAction = new Notification.Action.Builder(icon, "Reply",
+                inputIntent).addRemoteInput(remoteInput)
+                .build();
+        // Make it messaging style
+        Notification.Builder nb = new Notification.Builder(mContext,
+                mTestNotificationChannel.getId())
+                .setContentTitle("foo")
+                .setBubbleMetadata(data)
+                .setStyle(new Notification.MessagingStyle(person)
+                        .setConversationTitle("Bubble Chat")
+                        .addMessage("Hello?",
+                                SystemClock.currentThreadTimeMillis() - 300000, person)
+                        .addMessage("Is it me you're looking for?",
+                                SystemClock.currentThreadTimeMillis(), person)
+                )
+                .setActions(replyAction)
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
+
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0,
+                nb.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+        // Ensure we're not foreground
+        when(mActivityManager.getPackageImportance(nr.sbn.getPackageName())).thenReturn(
+                IMPORTANCE_VISIBLE);
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        waitForIdle();
+
+        // yes allowed, yes messaging, yes bubble
+        Notification notif = mService.getNotificationRecord(sbn.getKey()).getNotification();
+        assertTrue(notif.isBubbleNotification());
+
+        // Our flags should have failed since we're not foreground
+        assertFalse(notif.getBubbleMetadata().getAutoExpandBubble());
+        assertFalse(notif.getBubbleMetadata().isNotificationSuppressed());
+    }
+
+    @Test
+    public void testNotificationBubbles_flagAutoExpandForeground_succeeds_foreground()
+            throws RemoteException {
+        // Bubbles are allowed!
+        setUpPrefsForBubbles(true /* global */, true /* app */, true /* channel */);
+
+        // Give it bubble metadata
+        Notification.BubbleMetadata data = getBasicBubbleMetadataBuilder()
+                .setSuppressNotification(true)
+                .setAutoExpandBubble(true).build();
+        // Give it a person
+        Person person = new Person.Builder()
+                .setName("bubblebot")
+                .build();
+        // It needs remote input to be bubble-able
+        RemoteInput remoteInput = new RemoteInput.Builder("reply_key").setLabel("reply").build();
+        PendingIntent inputIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+        Icon icon = Icon.createWithResource(mContext, android.R.drawable.sym_def_app_icon);
+        Notification.Action replyAction = new Notification.Action.Builder(icon, "Reply",
+                inputIntent).addRemoteInput(remoteInput)
+                .build();
+        // Make it messaging style
+        Notification.Builder nb = new Notification.Builder(mContext,
+                mTestNotificationChannel.getId())
+                .setContentTitle("foo")
+                .setBubbleMetadata(data)
+                .setStyle(new Notification.MessagingStyle(person)
+                        .setConversationTitle("Bubble Chat")
+                        .addMessage("Hello?",
+                                SystemClock.currentThreadTimeMillis() - 300000, person)
+                        .addMessage("Is it me you're looking for?",
+                                SystemClock.currentThreadTimeMillis(), person)
+                )
+                .setActions(replyAction)
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
+
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0,
+                nb.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+        // Ensure we are in the foreground
+        when(mActivityManager.getPackageImportance(nr.sbn.getPackageName())).thenReturn(
+                IMPORTANCE_FOREGROUND);
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        waitForIdle();
+
+        // yes allowed, yes messaging, yes bubble
+        Notification notif = mService.getNotificationRecord(sbn.getKey()).getNotification();
+        assertTrue(notif.isBubbleNotification());
+
+        // Our flags should have failed since we are foreground
+        assertTrue(notif.getBubbleMetadata().getAutoExpandBubble());
+        assertTrue(notif.getBubbleMetadata().isNotificationSuppressed());
+    }
+
+    @Test
+    public void testNotificationBubbles_bubbleChildrenStay_whenGroupSummaryDismissed()
+            throws Exception {
+        // Bubbles are allowed!
+        setUpPrefsForBubbles(true /* global */, true /* app */, true /* channel */);
+
+        NotificationRecord nrSummary = addGroupWithBubblesAndValidateAdded(
+                true /* summaryAutoCancel */);
+
+        // Dismiss summary
+        final NotificationVisibility nv = NotificationVisibility.obtain(nrSummary.getKey(), 1, 2,
+                true);
+        mService.mNotificationDelegate.onNotificationClear(mUid, 0, PKG, nrSummary.sbn.getTag(),
+                nrSummary.sbn.getId(), nrSummary.getUserId(), nrSummary.getKey(),
+                NotificationStats.DISMISSAL_SHADE,
+                NotificationStats.DISMISS_SENTIMENT_NEUTRAL, nv);
+        waitForIdle();
+
+        // The bubble should still exist
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        assertEquals(1, notifsAfter.length);
+    }
+
+    @Test
+    public void testNotificationBubbles_bubbleChildrenStay_whenGroupSummaryClicked()
+            throws Exception {
+        // Bubbles are allowed!
+        setUpPrefsForBubbles(true /* global */, true /* app */, true /* channel */);
+
+        NotificationRecord nrSummary = addGroupWithBubblesAndValidateAdded(
+                true /* summaryAutoCancel */);
+
+        // Click summary
+        final NotificationVisibility nv = NotificationVisibility.obtain(nrSummary.getKey(), 1, 2,
+                true);
+        mService.mNotificationDelegate.onNotificationClick(mUid, Binder.getCallingPid(),
+                nrSummary.getKey(), nv);
+        waitForIdle();
+
+        // The bubble should still exist
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        assertEquals(1, notifsAfter.length);
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 8f8b746..80439cf 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -22,6 +22,8 @@
 import static android.app.NotificationManager.IMPORTANCE_NONE;
 import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
 
+import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_COUNT_LIMIT;
+
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.fail;
 
@@ -58,7 +60,9 @@
 import android.os.Build;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.provider.Settings.Global;
 import android.provider.Settings.Secure;
+
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.TestableContentResolver;
 import android.util.ArrayMap;
@@ -152,8 +156,7 @@
         contentResolver.setFallbackToExisting(false);
         Secure.putIntForUser(contentResolver,
                 Secure.NOTIFICATION_BADGING, 1, UserHandle.getUserId(UID_N_MR1));
-        Secure.putIntForUser(contentResolver,
-                Secure.NOTIFICATION_BUBBLES, 1, UserHandle.getUserId(UID_N_MR1));
+        Global.putInt(contentResolver, Global.NOTIFICATION_BUBBLES, 1);
 
         ContentProvider testContentProvider = mock(ContentProvider.class);
         when(testContentProvider.getIContentProvider()).thenReturn(mTestIContentProvider);
@@ -1948,42 +1951,18 @@
 
     @Test
     public void testBubblesOverrideTrue() {
-        Secure.putIntForUser(getContext().getContentResolver(),
-                Secure.NOTIFICATION_BUBBLES, 1,
-                USER.getIdentifier());
+        Global.putInt(getContext().getContentResolver(),
+                Global.NOTIFICATION_BUBBLES, 1);
         mHelper.updateBubblesEnabled(); // would be called by settings observer
-        assertTrue(mHelper.bubblesEnabled(USER));
+        assertTrue(mHelper.bubblesEnabled());
     }
 
     @Test
     public void testBubblesOverrideFalse() {
-        Secure.putIntForUser(getContext().getContentResolver(),
-                Secure.NOTIFICATION_BUBBLES, 0,
-                USER.getIdentifier());
+        Global.putInt(getContext().getContentResolver(),
+                Global.NOTIFICATION_BUBBLES, 0);
         mHelper.updateBubblesEnabled(); // would be called by settings observer
-        assertFalse(mHelper.bubblesEnabled(USER));
-    }
-
-    @Test
-    public void testBubblesForUserAll() {
-        try {
-            mHelper.bubblesEnabled(UserHandle.ALL);
-        } catch (Exception e) {
-            fail("just don't throw");
-        }
-    }
-
-    @Test
-    public void testBubblesOverrideUserIsolation() {
-        Secure.putIntForUser(getContext().getContentResolver(),
-                Secure.NOTIFICATION_BUBBLES, 0,
-                USER.getIdentifier());
-        Secure.putIntForUser(getContext().getContentResolver(),
-                Secure.NOTIFICATION_BUBBLES, 1,
-                USER2.getIdentifier());
-        mHelper.updateBubblesEnabled(); // would be called by settings observer
-        assertFalse(mHelper.bubblesEnabled(USER));
-        assertTrue(mHelper.bubblesEnabled(USER2));
+        assertFalse(mHelper.bubblesEnabled());
     }
 
     @Test
@@ -2690,4 +2669,51 @@
         assertFalse(mHelper.areBubblesAllowed(PKG_O, UID_O));
         verify(mHandler, times(1)).requestSort();
     }
+
+    @Test
+    public void testTooManyChannels() {
+        for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) {
+            NotificationChannel channel = new NotificationChannel(String.valueOf(i),
+                    String.valueOf(i), NotificationManager.IMPORTANCE_HIGH);
+            mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
+        }
+        try {
+            NotificationChannel channel = new NotificationChannel(
+                    String.valueOf(NOTIFICATION_CHANNEL_COUNT_LIMIT),
+                    String.valueOf(NOTIFICATION_CHANNEL_COUNT_LIMIT),
+                    NotificationManager.IMPORTANCE_HIGH);
+            mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
+            fail("Allowed to create too many notification channels");
+        } catch (IllegalStateException e) {
+            // great
+        }
+    }
+
+    @Test
+    public void testTooManyChannels_xml() throws Exception {
+        String extraChannel = "EXTRA";
+        String extraChannel1 = "EXTRA1";
+
+        // create first... many... directly so we don't need a big xml blob in this test
+        for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) {
+            NotificationChannel channel = new NotificationChannel(String.valueOf(i),
+                    String.valueOf(i), NotificationManager.IMPORTANCE_HIGH);
+            mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
+        }
+
+        final String xml = "<ranking version=\"1\">\n"
+                + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
+                + "<channel id=\"" + extraChannel + "\" name=\"hi\" importance=\"3\"/>"
+                + "<channel id=\"" + extraChannel1 + "\" name=\"hi\" importance=\"3\"/>"
+                + "</package>"
+                + "</ranking>";
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
+                null);
+        parser.nextTag();
+        mHelper.readXml(parser, false, UserHandle.USER_ALL);
+
+        assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel, true));
+        assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel1, true));
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 3d94467..07d9f80 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -341,7 +341,7 @@
             doReturn(stack).when(mRootActivityContainer)
                     .getLaunchStack(any(), any(), any(), anyBoolean());
             doReturn(stack).when(mRootActivityContainer)
-                    .getLaunchStack(any(), any(), any(), anyBoolean(), any());
+                    .getLaunchStack(any(), any(), any(), anyBoolean(), any(), anyInt(), anyInt());
         }
 
         // Set up mock package manager internal and make sure no unmocked methods are called
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
index ecf3acd..84bdecb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -40,6 +40,8 @@
 import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
 import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
 
+import static org.mockito.ArgumentMatchers.eq;
+
 import android.app.ActivityManagerInternal;
 import android.app.ActivityOptions;
 import android.app.AppOpsManager;
@@ -72,6 +74,7 @@
 import com.android.server.am.PendingIntentController;
 import com.android.server.appop.AppOpsService;
 import com.android.server.firewall.IntentFirewall;
+import com.android.server.pm.UserManagerService;
 import com.android.server.policy.PermissionPolicyInternal;
 import com.android.server.uri.UriGrantsManagerInternal;
 import com.android.server.wm.TaskRecord.TaskRecordFactory;
@@ -92,6 +95,7 @@
  */
 class ActivityTestsBase {
     private static int sNextDisplayId = DEFAULT_DISPLAY + 1;
+    private static final int[] TEST_USER_PROFILE_IDS = {};
 
     @Rule
     public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
@@ -204,6 +208,8 @@
         private ActivityStack mStack;
         private int mActivityFlags;
         private int mLaunchMode;
+        private int mLaunchedFromPid;
+        private int mLaunchedFromUid;
 
         ActivityBuilder(ActivityTaskManagerService service) {
             mService = service;
@@ -254,6 +260,16 @@
             return this;
         }
 
+        ActivityBuilder setLaunchedFromPid(int pid) {
+            mLaunchedFromPid = pid;
+            return this;
+        }
+
+        ActivityBuilder setLaunchedFromUid(int uid) {
+            mLaunchedFromUid = uid;
+            return this;
+        }
+
         ActivityRecord build() {
             if (mComponent == null) {
                 final int id = sCurrentActivityId++;
@@ -281,10 +297,11 @@
             aInfo.launchMode = mLaunchMode;
 
             final ActivityRecord activity = new ActivityRecord(mService, null /* caller */,
-                    0 /* launchedFromPid */, 0, null, intent, null,
-                    aInfo /*aInfo*/, new Configuration(), null /* resultTo */, null /* resultWho */,
-                    0 /* reqCode */, false /*componentSpecified*/, false /* rootVoiceInteraction */,
-                    mService.mStackSupervisor, null /* options */, null /* sourceRecord */);
+                    mLaunchedFromPid /* launchedFromPid */, mLaunchedFromUid /* launchedFromUid */,
+                    null, intent, null, aInfo /*aInfo*/, new Configuration(), null /* resultTo */,
+                    null /* resultWho */, 0 /* reqCode */, false /*componentSpecified*/,
+                    false /* rootVoiceInteraction */, mService.mStackSupervisor,
+                    null /* options */, null /* sourceRecord */);
             spyOn(activity);
             activity.mAppWindowToken = mock(AppWindowToken.class);
             doCallRealMethod().when(activity.mAppWindowToken).getOrientationIgnoreVisibility();
@@ -471,6 +488,11 @@
             // allow background activity starts by default
             doReturn(true).when(this).isBackgroundActivityStartsEnabled();
             doNothing().when(this).updateCpuStats();
+
+            // UserManager
+            final UserManagerService ums = mock(UserManagerService.class);
+            doReturn(ums).when(this).getUserManager();
+            doReturn(TEST_USER_PROFILE_IDS).when(ums).getProfileIds(anyInt(), eq(true));
         }
 
         void setup(IntentFirewall intentFirewall, PendingIntentController intentController,
diff --git a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
index 292a05b..a98f79c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
@@ -169,7 +169,7 @@
 
         mDimmer.updateDims(mTransaction, new Rect());
         verify(mTransaction).show(getDimLayer());
-        verify(dimLayer, never()).remove();
+        verify(mTransaction, never()).remove(dimLayer);
     }
 
     @Test
@@ -231,7 +231,7 @@
 
         mDimmer.updateDims(mTransaction, new Rect());
         verify(mTransaction).show(dimLayer);
-        verify(dimLayer, never()).remove();
+        verify(mTransaction, never()).remove(dimLayer);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index a1999c90..e4f614d3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -62,6 +62,7 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
+import android.util.ArraySet;
 import android.util.MutableLong;
 import android.util.SparseBooleanArray;
 
@@ -952,7 +953,6 @@
     public void testRecentsComponent_allowApiAccessWithoutPermissions() {
         doReturn(PackageManager.PERMISSION_DENIED).when(mTestService)
                 .checkGetTasksPermission(anyString(), anyInt(), anyInt());
-
         // Set the recents component and ensure that the following calls do not fail
         mRecentTasks.setIsCallerRecentsOverride(TestRecentTasks.GRANT);
         doTestRecentTasksApis(true /* expectNoSecurityException */);
@@ -1301,10 +1301,10 @@
         @Override
         void getTasks(int maxNum, List<RunningTaskInfo> list, int ignoreActivityType,
                 int ignoreWindowingMode, ArrayList<ActivityDisplay> activityDisplays,
-                int callingUid, boolean allowed) {
+                int callingUid, boolean allowed, boolean crossUser, ArraySet<Integer> profileIds) {
             mLastAllowed = allowed;
             super.getTasks(maxNum, list, ignoreActivityType, ignoreWindowingMode, activityDisplays,
-                    callingUid, allowed);
+                    callingUid, allowed, crossUser, profileIds);
         }
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index 8d2c3dd..baf1b08 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -25,6 +25,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.TYPE_VIRTUAL;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
@@ -61,6 +62,7 @@
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.util.Pair;
+import android.view.DisplayInfo;
 
 import androidx.test.filters.MediumTest;
 
@@ -817,6 +819,41 @@
     }
 
     /**
+     * Test that {@link RootActivityContainer#getLaunchStack} with the real caller id will get the
+     * expected stack when requesting the activity launch on the secondary display.
+     */
+    @Test
+    public void testGetLaunchStackWithRealCallerId() {
+        // Create a non-system owned virtual display.
+        final DisplayInfo info = new DisplayInfo();
+        mSupervisor.mService.mContext.getDisplay().getDisplayInfo(info);
+        info.type = TYPE_VIRTUAL;
+        info.ownerUid = 100;
+        final TestActivityDisplay secondaryDisplay = createNewActivityDisplay(info);
+        mRootActivityContainer.addChild(secondaryDisplay, POSITION_TOP);
+
+        // Create an activity with specify the original launch pid / uid.
+        final ActivityRecord r = new ActivityBuilder(mService).setLaunchedFromPid(200)
+                .setLaunchedFromUid(200).build();
+
+        // Simulate ActivityStarter to find a launch stack for requesting the activity to launch
+        // on the secondary display with realCallerId.
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(secondaryDisplay.mDisplayId);
+        options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        doReturn(true).when(mSupervisor).canPlaceEntityOnDisplay(secondaryDisplay.mDisplayId,
+                300 /* test realCallerPid */, 300 /* test realCallerUid */, r.info);
+        final ActivityStack result = mRootActivityContainer.getLaunchStack(r, options,
+                null /* task */, true /* onTop */, null, 300 /* test realCallerPid */,
+                300 /* test realCallerUid */);
+
+        // Assert that the stack is returned as expected.
+        assertNotNull(result);
+        assertEquals("The display ID of the stack should same as secondary display ",
+                secondaryDisplay.mDisplayId, result.mDisplayId);
+    }
+
+    /**
      * Mock {@link RootActivityContainerTests#resolveHomeActivity} for returning consistent activity
      * info for test cases (the original implementation will resolve from the real package manager).
      */
diff --git a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
index dc96480..3e316f6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
@@ -29,6 +29,7 @@
 import android.app.ActivityManager.RunningTaskInfo;
 import android.content.ComponentName;
 import android.platform.test.annotations.Presubmit;
+import android.util.ArraySet;
 
 import androidx.test.filters.MediumTest;
 
@@ -45,6 +46,8 @@
 @Presubmit
 public class RunningTasksTest extends ActivityTestsBase {
 
+    private static final ArraySet<Integer> PROFILE_IDS = new ArraySet<>();
+
     private RunningTasks mRunningTasks;
 
     @Before
@@ -77,7 +80,8 @@
         final int numFetchTasks = 5;
         ArrayList<RunningTaskInfo> tasks = new ArrayList<>();
         mRunningTasks.getTasks(5, tasks, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED,
-                displays, -1 /* callingUid */, true /* allowed */);
+                displays, -1 /* callingUid */, true /* allowed */, true /*crossUser */,
+                PROFILE_IDS);
         assertThat(tasks).hasSize(numFetchTasks);
         for (int i = 0; i < numFetchTasks; i++) {
             assertEquals(numTasks - i - 1, tasks.get(i).id);
@@ -87,7 +91,8 @@
         // and does not crash
         tasks.clear();
         mRunningTasks.getTasks(100, tasks, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED,
-                displays, -1 /* callingUid */, true /* allowed */);
+                displays, -1 /* callingUid */, true /* allowed */, true /* crossUser */,
+                PROFILE_IDS);
         assertThat(tasks).hasSize(numTasks);
         for (int i = 0; i < numTasks; i++) {
             assertEquals(numTasks - i - 1, tasks.get(i).id);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
index 19fd93fe..6e41118 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
@@ -271,6 +271,54 @@
         waitForCallback(singleTaskDisplayDrawnLatch);
     }
 
+    @Test
+    public void testSingleTaskDisplayEmpty() throws Exception {
+        final Instrumentation instrumentation = getInstrumentation();
+
+        final CountDownLatch activityViewReadyLatch = new CountDownLatch(1);
+        final CountDownLatch activityViewDestroyedLatch = new CountDownLatch(1);
+        final CountDownLatch singleTaskDisplayDrawnLatch = new CountDownLatch(1);
+        final CountDownLatch singleTaskDisplayEmptyLatch = new CountDownLatch(1);
+
+        registerTaskStackChangedListener(new TaskStackListener() {
+            @Override
+            public void onSingleTaskDisplayDrawn(int displayId) throws RemoteException {
+                singleTaskDisplayDrawnLatch.countDown();
+            }
+            @Override
+            public void onSingleTaskDisplayEmpty(int displayId)
+                    throws RemoteException {
+                singleTaskDisplayEmptyLatch.countDown();
+            }
+        });
+        final ActivityViewTestActivity activity =
+                (ActivityViewTestActivity) startTestActivity(ActivityViewTestActivity.class);
+        final ActivityView activityView = activity.getActivityView();
+        activityView.setCallback(new ActivityView.StateCallback() {
+            @Override
+            public void onActivityViewReady(ActivityView view) {
+                activityViewReadyLatch.countDown();
+            }
+
+            @Override
+            public void onActivityViewDestroyed(ActivityView view) {
+                activityViewDestroyedLatch.countDown();
+            }
+        });
+        waitForCallback(activityViewReadyLatch);
+
+        final Context context = instrumentation.getContext();
+        Intent intent = new Intent(context, ActivityInActivityView.class);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
+        activityView.startActivity(intent);
+        waitForCallback(singleTaskDisplayDrawnLatch);
+        assertEquals(1, singleTaskDisplayEmptyLatch.getCount());
+
+        activityView.release();
+        waitForCallback(activityViewDestroyedLatch);
+        waitForCallback(singleTaskDisplayEmptyLatch);
+    }
+
     /**
      * Starts the provided activity and returns the started instance.
      */
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index b93c994..acfc2ea 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -114,16 +114,12 @@
     @Test
     public void testAddChildSetsSurfacePosition() {
         try (MockSurfaceBuildingContainer top = new MockSurfaceBuildingContainer(mWm)) {
-
-            final SurfaceControl.Transaction transaction = mock(SurfaceControl.Transaction.class);
-            mWm.mTransactionFactory = () -> transaction;
-
             WindowContainer child = new WindowContainer(mWm);
             child.setBounds(1, 1, 10, 10);
 
-            verify(transaction, never()).setPosition(any(), anyFloat(), anyFloat());
+            verify(mTransaction, never()).setPosition(any(), anyFloat(), anyFloat());
             top.addChild(child, 0);
-            verify(transaction, times(1)).setPosition(any(), eq(1.f), eq(1.f));
+            verify(mTransaction, times(1)).setPosition(any(), eq(1.f), eq(1.f));
         }
     }
 
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index 9933756..735b9a1 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -325,9 +325,8 @@
                     false /* Don't notify for synchronous calls */);
 
                                 // Initialize power save, call active state monitoring logic.
-            if (status == STATUS_OK && !mRecognitionRequested) {
+            if (status == STATUS_OK) {
                 initializeTelephonyAndPowerStateListeners();
-                mRecognitionRequested = true;
             }
 
             return status;
@@ -481,6 +480,9 @@
 
         if (unloadModel && modelData.isModelLoaded()) {
             Slog.d(TAG, "Unloading previously loaded stale model.");
+            if (mModule == null) {
+                return STATUS_ERROR;
+            }
             status = mModule.unloadSoundModel(modelData.getHandle());
             MetricsLogger.count(mContext, "sth_unloading_stale_model", 1);
             if (status != SoundTrigger.STATUS_OK) {
@@ -550,6 +552,9 @@
                 }
             }
 
+            if (mModule == null) {
+                return STATUS_ERROR;
+            }
             int status = mModule.unloadSoundModel(modelData.getHandle());
             if (status != SoundTrigger.STATUS_OK) {
                 Slog.w(TAG, "unloadGenericSoundModel() call failed with " + status);
@@ -878,6 +883,7 @@
             mContext.unregisterReceiver(mPowerSaveModeListener);
             mPowerSaveModeListener = null;
         }
+        mRecognitionRequested = false;
     }
 
     // Clears state for all models (generic and keyphrase).
@@ -924,6 +930,9 @@
     }
 
     private void initializeTelephonyAndPowerStateListeners() {
+        if (mRecognitionRequested) {
+            return;
+        }
         long token = Binder.clearCallingIdentity();
         try {
             // Get the current call state synchronously for the first recognition.
@@ -941,6 +950,8 @@
             }
             mIsPowerSaveMode = mPowerManager.getPowerSaveState(ServiceType.SOUND)
                     .batterySaverEnabled;
+
+            mRecognitionRequested = true;
         } finally {
             Binder.restoreCallingIdentity(token);
         }
@@ -987,6 +998,9 @@
         if (exception != null) {
           Slog.e(TAG, "forceStopAndUnloadModel", exception);
         }
+        if (mModule == null) {
+            return;
+        }
         if (modelData.isModelStarted()) {
             Slog.d(TAG, "Stopping previously started dangling model " + modelData.getHandle());
             if (mModule.stopRecognition(modelData.getHandle()) != STATUS_OK) {
@@ -1093,6 +1107,13 @@
     // a recognition include: no active phone call or not being in a power save mode. Also,
     // the native service should be enabled.
     private boolean isRecognitionAllowed() {
+        // if mRecognitionRequested is false, call and power state listeners are not registered so
+        // we read current state directly from services
+        if (!mRecognitionRequested) {
+            mCallActive = mTelephonyManager.getCallState() == TelephonyManager.CALL_STATE_OFFHOOK;
+            mIsPowerSaveMode =
+                mPowerManager.getPowerSaveState(ServiceType.SOUND).batterySaverEnabled;
+        }
         return !mCallActive && !mServiceDisabled && !mIsPowerSaveMode;
     }
 
@@ -1116,6 +1137,9 @@
             return STATUS_OK;
         }
 
+        if (mModule == null) {
+            return STATUS_ERROR;
+        }
         int status = mModule.startRecognition(handle, config);
         if (status != SoundTrigger.STATUS_OK) {
             Slog.w(TAG, "startRecognition failed with " + status);
@@ -1152,8 +1176,11 @@
     }
 
     private int stopRecognitionLocked(ModelData modelData, boolean notify) {
-        IRecognitionStatusCallback callback = modelData.getCallback();
+        if (mModule == null) {
+            return STATUS_ERROR;
+        }
 
+        IRecognitionStatusCallback callback = modelData.getCallback();
         // Stop recognition.
         int status = STATUS_OK;
 
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index e1ffb0f..46d7509 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -1281,9 +1281,12 @@
 
             RoleObserver(@NonNull @CallbackExecutor Executor executor) {
                 mRm.addOnRoleHoldersChangedListenerAsUser(executor, this, UserHandle.ALL);
-                UserHandle currentUser = UserHandle.of(LocalServices.getService(
-                        ActivityManagerInternal.class).getCurrentUserId());
-                onRoleHoldersChanged(RoleManager.ROLE_ASSISTANT, currentUser);
+                // Sync only if assistant role has been initialized.
+                if (mRm.isRoleAvailable(RoleManager.ROLE_ASSISTANT)) {
+                    UserHandle currentUser = UserHandle.of(LocalServices.getService(
+                            ActivityManagerInternal.class).getCurrentUserId());
+                    onRoleHoldersChanged(RoleManager.ROLE_ASSISTANT, currentUser);
+                }
             }
 
             private @NonNull String getDefaultRecognizer(@NonNull UserHandle user) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index f16dec6..0ff9273 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -194,7 +194,7 @@
             if (!mFullyBound) {
                 mFullyBound = mContext.bindServiceAsUser(mBindIntent, mFullConnection,
                         Context.BIND_AUTO_CREATE | Context.BIND_TREAT_LIKE_ACTIVITY
-                                | Context.BIND_FOREGROUND_SERVICE
+                                | Context.BIND_SCHEDULE_LIKE_TOP_APP
                                 | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS,
                         new UserHandle(mUser));
             }
diff --git a/telecomm/java/android/telecom/Logging/Session.java b/telecomm/java/android/telecom/Logging/Session.java
index 50c3cd9..95a47e1 100644
--- a/telecomm/java/android/telecom/Logging/Session.java
+++ b/telecomm/java/android/telecom/Logging/Session.java
@@ -33,6 +33,8 @@
  */
 public class Session {
 
+    public static final String LOG_TAG = "Session";
+
     public static final String START_SESSION = "START_SESSION";
     public static final String START_EXTERNAL_SESSION = "START_EXTERNAL_SESSION";
     public static final String CREATE_SUBSESSION = "CREATE_SUBSESSION";
@@ -45,6 +47,9 @@
     public static final String EXTERNAL_INDICATOR = "E-";
     public static final String TRUNCATE_STRING = "...";
 
+    // Prevent infinite recursion by setting a reasonable limit.
+    private static final int SESSION_RECURSION_LIMIT = 25;
+
     /**
      * Initial value of mExecutionEndTimeMs and the final value of {@link #getLocalExecutionTime()}
      * if the Session is canceled.
@@ -226,6 +231,15 @@
 
     // Builds full session id recursively
     private String getFullSessionId() {
+        return getFullSessionId(0);
+    }
+
+    // keep track of calls and bail if we hit the recursion limit
+    private String getFullSessionId(int parentCount) {
+        if (parentCount >= SESSION_RECURSION_LIMIT) {
+            Log.w(LOG_TAG, "getFullSessionId: Hit recursion limit!");
+            return TRUNCATE_STRING + mSessionId;
+        }
         // Cache mParentSession locally to prevent a concurrency problem where
         // Log.endParentSessions() is called while a logging statement is running (Log.i, for
         // example) and setting mParentSession to null in a different thread after the null check
@@ -235,42 +249,57 @@
             return mSessionId;
         } else {
             if (Log.VERBOSE) {
-                return parentSession.getFullSessionId() +
+                return parentSession.getFullSessionId(parentCount + 1)
                         // Append "_X" to subsession to show subsession designation.
-                        SESSION_SEPARATION_CHAR_CHILD + mSessionId;
+                        + SESSION_SEPARATION_CHAR_CHILD + mSessionId;
             } else {
                 // Only worry about the base ID at the top of the tree.
-                return parentSession.getFullSessionId();
+                return parentSession.getFullSessionId(parentCount + 1);
             }
 
         }
     }
 
-    // Print out the full Session tree from any subsession node
-    public String printFullSessionTree() {
-        // Get to the top of the tree
+    private Session getRootSession(String callingMethod) {
+        int currParentCount = 0;
         Session topNode = this;
         while (topNode.getParentSession() != null) {
+            if (currParentCount >= SESSION_RECURSION_LIMIT) {
+                Log.w(LOG_TAG, "getRootSession: Hit recursion limit from " + callingMethod);
+                break;
+            }
             topNode = topNode.getParentSession();
+            currParentCount++;
         }
-        return topNode.printSessionTree();
+        return topNode;
+    }
+
+    // Print out the full Session tree from any subsession node
+    public String printFullSessionTree() {
+        return getRootSession("printFullSessionTree").printSessionTree();
     }
 
     // Recursively move down session tree using DFS, but print out each node when it is reached.
-    public String printSessionTree() {
+    private String printSessionTree() {
         StringBuilder sb = new StringBuilder();
-        printSessionTree(0, sb);
+        printSessionTree(0, sb, 0);
         return sb.toString();
     }
 
-    private void printSessionTree(int tabI, StringBuilder sb) {
+    private void printSessionTree(int tabI, StringBuilder sb, int currChildCount) {
+        // Prevent infinite recursion.
+        if (currChildCount >= SESSION_RECURSION_LIMIT) {
+            Log.w(LOG_TAG, "printSessionTree: Hit recursion limit!");
+            sb.append(TRUNCATE_STRING);
+            return;
+        }
         sb.append(toString());
         for (Session child : mChildSessions) {
             sb.append("\n");
             for (int i = 0; i <= tabI; i++) {
                 sb.append("\t");
             }
-            child.printSessionTree(tabI + 1, sb);
+            child.printSessionTree(tabI + 1, sb, currChildCount + 1);
         }
     }
 
@@ -279,11 +308,17 @@
     // recent) will be truncated to "..."
     public String getFullMethodPath(boolean truncatePath) {
         StringBuilder sb = new StringBuilder();
-        getFullMethodPath(sb, truncatePath);
+        getFullMethodPath(sb, truncatePath, 0);
         return sb.toString();
     }
 
-    private synchronized void getFullMethodPath(StringBuilder sb, boolean truncatePath) {
+    private synchronized void getFullMethodPath(StringBuilder sb, boolean truncatePath,
+            int parentCount) {
+        if (parentCount >= SESSION_RECURSION_LIMIT) {
+            Log.w(LOG_TAG, "getFullMethodPath: Hit recursion limit!");
+            sb.append(TRUNCATE_STRING);
+            return;
+        }
         // Return cached value for method path. When returning the truncated path, recalculate the
         // full path without using the cached value.
         if (!TextUtils.isEmpty(mFullMethodPathCache) && !truncatePath) {
@@ -296,7 +331,7 @@
             // Check to see if the session has been renamed yet. If it has not, then the session
             // has not been continued.
             isSessionStarted = !mShortMethodName.equals(parentSession.mShortMethodName);
-            parentSession.getFullMethodPath(sb, truncatePath);
+            parentSession.getFullMethodPath(sb, truncatePath, parentCount + 1);
             sb.append(SUBSESSION_SEPARATION_CHAR);
         }
         // Encapsulate the external session's method name so it is obvious what part of the session
@@ -319,13 +354,10 @@
             mFullMethodPathCache = sb.toString();
         }
     }
+
     // Recursively move to the top of the tree to see if the parent session is external.
     private boolean isSessionExternal() {
-        if (getParentSession() == null) {
-            return isExternal();
-        } else {
-            return getParentSession().isSessionExternal();
-        }
+        return getRootSession("isSessionExternal").isExternal();
     }
 
     @Override
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 8e56fe7..3d28cf6 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -3917,6 +3917,12 @@
         public static final Uri CONTENT_URI = Uri.parse("content://cellbroadcasts");
 
         /**
+         * The id of the subscription which received this cell broadcast message.
+         * <P>Type: INTEGER</P>
+         */
+        public static final String SUB_ID = "sub_id";
+
+        /**
          * Message geographical scope.
          * <P>Type: INTEGER</P>
          */
@@ -4049,6 +4055,64 @@
         public static final String DEFAULT_SORT_ORDER = DELIVERY_TIME + " DESC";
 
         /**
+         * The timestamp in millisecond of when the device received the message.
+         * <P>Type: BIGINT</P>
+         */
+        public static final String RECEIVED_TIME = "received_time";
+
+        /**
+         * Indicates that whether the message has been broadcasted to the application.
+         * <P>Type: BOOLEAN</P>
+         */
+        public static final String MESSAGE_BROADCASTED = "message_broadcasted";
+
+        /**
+         * The Warning Area Coordinates Elements. This element is used for geo-fencing purpose.
+         *
+         * The geometry and its coordinates are separated vertical bar, the first item is the
+         * geometry type and the remaining items are the parameter of this geometry.
+         *
+         * Only circle and polygon are supported. The coordinates are represented in Horizontal
+         * coordinates format.
+         *
+         * Coordinate encoding:
+         * "latitude, longitude"
+         * where -90.00000 <= latitude <= 90.00000 and -180.00000 <= longitude <= 180.00000
+         *
+         * Polygon encoding:
+         * "polygon|lat1,lng1|lat2,lng2|...|latn,lngn"
+         * lat1,lng1 ... latn,lngn are the vertices coordinate of the polygon.
+         *
+         * Circle encoding:
+         * "circle|lat,lng|radius".
+         * lat,lng is the center of the circle. The unit of circle's radius is meter.
+         *
+         * Example:
+         * "circle|0,0|100" mean a circle which center located at (0,0) and its radius is 100 meter.
+         * "polygon|0,1.5|0,1|1,1|1,0" mean a polygon has vertices (0,1.5),(0,1),(1,1),(1,0).
+         *
+         * There could be more than one geometry store in this field, they are separated by a
+         * semicolon.
+         *
+         * Example:
+         * "circle|0,0|100;polygon|0,0|0,1.5|1,1|1,0;circle|100.123,100|200.123"
+         *
+         * <P>Type: TEXT</P>
+         */
+        public static final String GEOMETRIES = "geometries";
+
+        /**
+         * Geo-Fencing Maximum Wait Time in second. The range of the time is [0, 255]. A device
+         * shall allow to determine its position meeting operator policy. If the device is unable to
+         * determine its position meeting operator policy within the GeoFencing Maximum Wait Time,
+         * it shall present the alert to the user and discontinue further positioning determination
+         * for the alert.
+         *
+         * <P>Type: INTEGER</P>
+         */
+        public static final String MAXIMUM_WAIT_TIME = "maximum_wait_time";
+
+        /**
          * Query columns for instantiating {@link android.telephony.CellBroadcastMessage} objects.
          */
         public static final String[] QUERY_COLUMNS = {
@@ -4073,6 +4137,34 @@
                 CMAS_URGENCY,
                 CMAS_CERTAINTY
         };
+
+        /**
+         * Query columns for instantiating {@link android.telephony.SmsCbMessage} objects.
+         */
+        public static final String[] QUERY_COLUMNS_FWK = {
+                _ID,
+                GEOGRAPHICAL_SCOPE,
+                PLMN,
+                LAC,
+                CID,
+                SERIAL_NUMBER,
+                SERVICE_CATEGORY,
+                LANGUAGE_CODE,
+                MESSAGE_BODY,
+                MESSAGE_FORMAT,
+                MESSAGE_PRIORITY,
+                ETWS_WARNING_TYPE,
+                CMAS_MESSAGE_CLASS,
+                CMAS_CATEGORY,
+                CMAS_RESPONSE_TYPE,
+                CMAS_SEVERITY,
+                CMAS_URGENCY,
+                CMAS_CERTAINTY,
+                RECEIVED_TIME,
+                MESSAGE_BROADCASTED,
+                GEOMETRIES,
+                MAXIMUM_WAIT_TIME
+        };
     }
 
     /**
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index de83473..8b3b237 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1387,6 +1387,13 @@
             "read_only_apn_fields_string_array";
 
     /**
+     * Default value of APN types field if not specified by user when adding/modifying an APN.
+     * @hide
+     */
+    public static final String KEY_APN_SETTINGS_DEFAULT_APN_TYPES_STRING_ARRAY =
+            "apn_settings_default_apn_types_string_array";
+
+    /**
      * Boolean indicating if intent for emergency call state changes should be broadcast
      * @hide
      */
@@ -2628,25 +2635,34 @@
             "call_waiting_service_class_int";
 
     /**
-     * This configuration allow the system UI to display different 5G icon for different 5G status.
+     * This configuration allow the system UI to display different 5G icon for different 5G
+     * scenario.
      *
-     * There are four 5G status:
+     * There are five 5G scenarios:
      * 1. connected_mmwave: device currently connected to 5G cell as the secondary cell and using
      *    millimeter wave.
      * 2. connected: device currently connected to 5G cell as the secondary cell but not using
      *    millimeter wave.
-     * 3. not_restricted: device camped on a network that has 5G capability(not necessary to connect
-     *    a 5G cell as a secondary cell) and the use of 5G is not restricted.
-     * 4. restricted: device camped on a network that has 5G capability(not necessary to connect a
+     * 3. not_restricted_rrc_idle: device camped on a network that has 5G capability(not necessary
+     *    to connect a 5G cell as a secondary cell) and the use of 5G is not restricted and RRC
+     *    currently in IDLE state.
+     * 4. not_restricted_rrc_con: device camped on a network that has 5G capability(not necessary
+     *    to connect a 5G cell as a secondary cell) and the use of 5G is not restricted and RRC
+     *    currently in CONNECTED state.
+     * 5. restricted: device camped on a network that has 5G capability(not necessary to connect a
      *    5G cell as a secondary cell) but the use of 5G is restricted.
      *
      * The configured string contains multiple key-value pairs separated by comma. For each pair,
      * the key and value is separated by a colon. The key is corresponded to a 5G status above and
      * the value is the icon name. Use "None" as the icon name if no icon should be shown in a
-     * specific 5G status.
+     * specific 5G scenario. If the scenario is "None", config can skip this key and value.
      *
-     * Here is an example of the configuration:
-     * "connected_mmwave:5GPlus,connected:5G,not_restricted:None,restricted:None"
+     * Icon name options: "5G_Plus", "5G".
+     *
+     * Here is an example:
+     * UE want to display 5G_Plus icon for scenario#1, and 5G icon for scenario#2; otherwise no
+     * define.
+     * The configuration is: "connected_mmwave:5G_Plus,connected:5G"
      *
      * @hide
      */
@@ -2654,6 +2670,22 @@
             "5g_icon_configuration_string";
 
     /**
+     * Timeout in second for displaying 5G icon, default value is 0 which means the timer is
+     * disabled.
+     *
+     * System UI will show the 5G icon and start a timer with the timeout from this config when the
+     * device connects to a 5G cell. System UI stops displaying 5G icon when both the device
+     * disconnects from 5G cell and the timer is expired.
+     *
+     * If 5G is reacquired during this timer, the timer is canceled and restarted when 5G is next
+     * lost. Allows us to momentarily lose 5G without blinking the icon.
+     *
+     * @hide
+     */
+    public static final String KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT =
+            "5g_icon_display_grace_period_sec_int";
+
+    /**
      * Support ASCII 7-BIT encoding for long SMS. This carrier config is used to enable
      * this feature.
      * @hide
@@ -2705,12 +2737,28 @@
 
     /**
      * Controls hysteresis time in milli seconds for which OpportunisticNetworkService
-     * will wait before switching data to a network.
+     * will wait before switching data to an opportunistic network.
      */
     public static final String KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_HYSTERESIS_TIME_LONG =
             "opportunistic_network_data_switch_hysteresis_time_long";
 
     /**
+     * Controls hysteresis time in milli seconds for which OpportunisticNetworkService
+     * will wait before switching data from opportunistic network to primary network.
+     * @hide
+     */
+    public static final String KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG =
+            "opportunistic_network_data_switch_exit_hysteresis_time_long";
+
+    /**
+     * Controls whether to do ping test before switching data to opportunistic network.
+     * This carrier config is used to disable this feature.
+     * @hide
+     */
+    public static final String KEY_PING_TEST_BEFORE_DATA_SWITCH_BOOL =
+            "ping_test_before_data_switch_bool";
+
+    /**
      * Indicates zero or more emergency number prefix(es), because some carrier requires
      * if users dial an emergency number address with a specific prefix, the combination of the
      * prefix and the address is also a valid emergency number to dial. For example, an emergency
@@ -3063,6 +3111,13 @@
     public static final String KEY_SUPPORT_WPS_OVER_IMS_BOOL =
             "support_wps_over_ims_bool";
 
+    /**
+     * Holds the list of carrier certificate hashes. Note that each carrier has its own certificates
+     * @hide
+     */
+    public static final String KEY_CARRIER_CERTIFICATE_STRING_ARRAY =
+            "carrier_certificate_string_array";
+
     /** The default value for every variable. */
     private final static PersistableBundle sDefaults;
 
@@ -3179,6 +3234,7 @@
         sDefaults.putBoolean(KEY_ALLOW_ADDING_APNS_BOOL, true);
         sDefaults.putStringArray(KEY_READ_ONLY_APN_TYPES_STRING_ARRAY, new String[] {"dun"});
         sDefaults.putStringArray(KEY_READ_ONLY_APN_FIELDS_STRING_ARRAY, null);
+        sDefaults.putStringArray(KEY_APN_SETTINGS_DEFAULT_APN_TYPES_STRING_ARRAY, null);
         sDefaults.putBoolean(KEY_BROADCAST_EMERGENCY_CALL_STATE_CHANGES_BOOL, false);
         sDefaults.putBoolean(KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL, false);
         sDefaults.putBoolean(KEY_DISABLE_SEVERE_WHEN_EXTREME_DISABLED_BOOL, true);
@@ -3442,7 +3498,8 @@
         sDefaults.putBoolean(KEY_USE_CALLER_ID_USSD_BOOL, false);
         sDefaults.putInt(KEY_CALL_WAITING_SERVICE_CLASS_INT, 1 /* SERVICE_CLASS_VOICE */);
         sDefaults.putString(KEY_5G_ICON_CONFIGURATION_STRING,
-                "connected_mmwave:None,connected:5G,not_restricted:None,restricted:None");
+                "connected_mmwave:5G,connected:5G");
+        sDefaults.putInt(KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT, 0);
         sDefaults.putBoolean(KEY_ASCII_7_BIT_SUPPORT_FOR_LONG_MESSAGE_BOOL, false);
         /* Default value is minimum RSRP level needed for SIGNAL_STRENGTH_GOOD */
         sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSRP_INT, -108);
@@ -3458,6 +3515,9 @@
         sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_ENTRY_OR_EXIT_HYSTERESIS_TIME_LONG, 10000);
         /* Default value is 10 seconds. */
         sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_HYSTERESIS_TIME_LONG, 10000);
+        /* Default value is 3 seconds. */
+        sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG, 3000);
+        sDefaults.putBoolean(KEY_PING_TEST_BEFORE_DATA_SWITCH_BOOL, true);
         sDefaults.putAll(Gps.getDefaults());
         sDefaults.putAll(Wifi.getDefaults());
         sDefaults.putIntArray(KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY,
@@ -3467,7 +3527,7 @@
         sDefaults.putStringArray(KEY_EMERGENCY_NUMBER_PREFIX_STRING_ARRAY, new String[0]);
         sDefaults.putBoolean(KEY_USE_USIM_BOOL, false);
         sDefaults.putBoolean(KEY_SHOW_WFC_LOCATION_PRIVACY_POLICY_BOOL, false);
-        sDefaults.putBoolean(KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION, false);
+        sDefaults.putBoolean(KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION, true);
         sDefaults.putString(KEY_SMART_FORWARDING_CONFIG_COMPONENT_NAME_STRING, "");
         sDefaults.putBoolean(KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN,
                 false);
@@ -3481,6 +3541,7 @@
                         -89,  /* SIGNAL_STRENGTH_GREAT */
                 });
         sDefaults.putBoolean(KEY_SUPPORT_WPS_OVER_IMS_BOOL, true);
+        sDefaults.putStringArray(KEY_CARRIER_CERTIFICATE_STRING_ARRAY, null);
     }
 
     /**
diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java
index 258a873..432978d 100644
--- a/telephony/java/android/telephony/CellIdentity.java
+++ b/telephony/java/android/telephony/CellIdentity.java
@@ -17,6 +17,7 @@
 package android.telephony;
 
 import android.annotation.CallSuper;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -61,7 +62,7 @@
         mType = type;
 
         // Only allow INT_MAX if unknown string mcc/mnc
-        if (mcc == null || mcc.matches("^[0-9]{3}$")) {
+        if (mcc == null || isMcc(mcc)) {
             mMccStr = mcc;
         } else if (mcc.isEmpty() || mcc.equals(String.valueOf(Integer.MAX_VALUE))) {
             // If the mccStr is empty or unknown, set it as null.
@@ -73,7 +74,7 @@
             log("invalid MCC format: " + mcc);
         }
 
-        if (mnc == null || mnc.matches("^[0-9]{2,3}$")) {
+        if (mnc == null || isMnc(mnc)) {
             mMncStr = mnc;
         } else if (mnc.isEmpty() || mnc.equals(String.valueOf(Integer.MAX_VALUE))) {
             // If the mncStr is empty or unknown, set it as null.
@@ -262,4 +263,30 @@
         if ((value < rangeMin || value > rangeMax) && value != special) return CellInfo.UNAVAILABLE;
         return value;
     }
+
+    /** @hide */
+    private static boolean isMcc(@NonNull String mcc) {
+        // ensure no out of bounds indexing
+        if (mcc.length() != 3) return false;
+
+        // Character.isDigit allows all unicode digits, not just [0-9]
+        for (int i = 0; i < 3; i++) {
+            if (mcc.charAt(i) < '0' || mcc.charAt(i) > '9') return false;
+        }
+
+        return true;
+    }
+
+    /** @hide */
+    private static boolean isMnc(@NonNull String mnc) {
+        // ensure no out of bounds indexing
+        if (mnc.length() < 2 || mnc.length() > 3) return false;
+
+        // Character.isDigit allows all unicode digits, not just [0-9]
+        for (int i = 0; i < mnc.length(); i++) {
+            if (mnc.charAt(i) < '0' || mnc.charAt(i) > '9') return false;
+        }
+
+        return true;
+    }
 }
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 2651346..2ea9688 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -986,6 +986,9 @@
             case RIL_RADIO_TECHNOLOGY_LTE_CA:
                 rtString = "LTE_CA";
                 break;
+            case RIL_RADIO_TECHNOLOGY_NR:
+                rtString = "LTE_NR";
+                break;
             default:
                 rtString = "Unexpected";
                 Rlog.w(LOG_TAG, "Unexpected radioTechnology=" + rt);
@@ -1552,6 +1555,7 @@
                 return AccessNetworkType.CDMA2000;
             case RIL_RADIO_TECHNOLOGY_LTE:
             case RIL_RADIO_TECHNOLOGY_LTE_CA:
+            case RIL_RADIO_TECHNOLOGY_NR:
                 return AccessNetworkType.EUTRAN;
             case RIL_RADIO_TECHNOLOGY_IWLAN:
                 return AccessNetworkType.IWLAN;
@@ -1600,6 +1604,8 @@
                 return ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN;
             case TelephonyManager.NETWORK_TYPE_LTE_CA:
                 return ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA;
+            case TelephonyManager.NETWORK_TYPE_NR:
+                return ServiceState.RIL_RADIO_TECHNOLOGY_NR;
             default:
                 return ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
         }
@@ -1690,7 +1696,8 @@
                 || radioTechnology == RIL_RADIO_TECHNOLOGY_GSM
                 || radioTechnology == RIL_RADIO_TECHNOLOGY_TD_SCDMA
                 || radioTechnology == RIL_RADIO_TECHNOLOGY_IWLAN
-                || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA;
+                || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA
+                || radioTechnology == RIL_RADIO_TECHNOLOGY_NR;
 
     }
 
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index 1e6cd47..163be51 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -38,6 +38,7 @@
 import android.util.DisplayMetrics;
 import android.util.Log;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
@@ -147,7 +148,14 @@
      * The access rules for this subscription, if it is embedded and defines any.
      */
     @Nullable
-    private UiccAccessRule[] mAccessRules;
+    private UiccAccessRule[] mNativeAccessRules;
+
+    /**
+     * The carrier certificates for this subscription that are saved in carrier configs.
+     * The other carrier certificates are embedded on Uicc and stored as part of mNativeAccessRules.
+     */
+    @Nullable
+    private UiccAccessRule[] mCarrierConfigAccessRules;
 
     /**
      * The string ID of the SIM card. It is the ICCID of the active profile for a UICC card and the
@@ -206,12 +214,12 @@
     public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
             CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
             Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded,
-            @Nullable UiccAccessRule[] accessRules, String cardString) {
+            @Nullable UiccAccessRule[] nativeAccessRules, String cardString) {
         this(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number,
-                roaming, icon, mcc, mnc, countryIso, isEmbedded, accessRules, cardString, -1,
+                roaming, icon, mcc, mnc, countryIso, isEmbedded, nativeAccessRules, cardString, -1,
                 false, null, false, TelephonyManager.UNKNOWN_CARRIER_ID,
                 SubscriptionManager.PROFILE_CLASS_DEFAULT,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, null);
+                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, null, null);
     }
 
     /**
@@ -220,12 +228,12 @@
     public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
             CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
             Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded,
-            @Nullable UiccAccessRule[] accessRules, String cardString, boolean isOpportunistic,
-            @Nullable String groupUUID, int carrierId, int profileClass) {
+            @Nullable UiccAccessRule[] nativeAccessRules, String cardString,
+            boolean isOpportunistic, @Nullable String groupUUID, int carrierId, int profileClass) {
         this(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number,
-                roaming, icon, mcc, mnc, countryIso, isEmbedded, accessRules, cardString, -1,
+                roaming, icon, mcc, mnc, countryIso, isEmbedded, nativeAccessRules, cardString, -1,
                 isOpportunistic, groupUUID, false, carrierId, profileClass,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, null);
+                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, null, null);
     }
 
     /**
@@ -234,9 +242,10 @@
     public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
             CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
             Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded,
-            @Nullable UiccAccessRule[] accessRules, String cardString, int cardId,
+            @Nullable UiccAccessRule[] nativeAccessRules, String cardString, int cardId,
             boolean isOpportunistic, @Nullable String groupUUID, boolean isGroupDisabled,
-            int carrierId, int profileClass, int subType, @Nullable String groupOwner) {
+            int carrierId, int profileClass, int subType, @Nullable String groupOwner,
+            @Nullable UiccAccessRule[] carrierConfigAccessRules) {
         this.mId = id;
         this.mIccId = iccId;
         this.mSimSlotIndex = simSlotIndex;
@@ -251,7 +260,7 @@
         this.mMnc = mnc;
         this.mCountryIso = countryIso;
         this.mIsEmbedded = isEmbedded;
-        this.mAccessRules = accessRules;
+        this.mNativeAccessRules = nativeAccessRules;
         this.mCardString = cardString;
         this.mCardId = cardId;
         this.mIsOpportunistic = isOpportunistic;
@@ -261,6 +270,7 @@
         this.mProfileClass = profileClass;
         this.mSubscriptionType = subType;
         this.mGroupOwner = groupOwner;
+        this.mCarrierConfigAccessRules = carrierConfigAccessRules;
     }
 
     /**
@@ -541,7 +551,6 @@
      *
      * @param context Context of the application to check.
      * @return whether the app is authorized to manage this subscription per its metadata.
-     * @throws UnsupportedOperationException if this subscription is not embedded.
      * @hide
      * @deprecated - Do not use.
      */
@@ -557,26 +566,25 @@
      * @param context Any context.
      * @param packageName Package name of the app to check.
      * @return whether the app is authorized to manage this subscription per its metadata.
-     * @throws UnsupportedOperationException if this subscription is not embedded.
      * @hide
      * @deprecated - Do not use.
      */
     @Deprecated
     public boolean canManageSubscription(Context context, String packageName) {
-        if (!isEmbedded()) {
-            throw new UnsupportedOperationException("Not an embedded subscription");
-        }
-        if (mAccessRules == null) {
+        List<UiccAccessRule> allAccessRules = getAllAccessRules();
+        if (allAccessRules == null) {
             return false;
         }
         PackageManager packageManager = context.getPackageManager();
         PackageInfo packageInfo;
         try {
-            packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
+            packageInfo = packageManager.getPackageInfo(packageName,
+                PackageManager.GET_SIGNING_CERTIFICATES);
         } catch (PackageManager.NameNotFoundException e) {
-            throw new IllegalArgumentException("Unknown package: " + packageName, e);
+            Log.d("SubscriptionInfo", "canManageSubscription: Unknown package: " + packageName, e);
+            return false;
         }
-        for (UiccAccessRule rule : mAccessRules) {
+        for (UiccAccessRule rule : allAccessRules) {
             if (rule.getCarrierPrivilegeStatus(packageInfo)
                     == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
                 return true;
@@ -586,17 +594,33 @@
     }
 
     /**
-     * @return the {@link UiccAccessRule}s dictating who is authorized to manage this subscription.
+     * @return the {@link UiccAccessRule}s that are stored in Uicc, dictating who
+     * is authorized to manage this subscription.
+     * TODO and fix it properly in R / master: either deprecate this and have 3 APIs
+     *  native + carrier + all, or have this return all by default.
      * @throws UnsupportedOperationException if this subscription is not embedded.
      * @hide
      */
     @SystemApi
     public @Nullable List<UiccAccessRule> getAccessRules() {
-        if (!isEmbedded()) {
-            throw new UnsupportedOperationException("Not an embedded subscription");
+        if (mNativeAccessRules == null) return null;
+        return Arrays.asList(mNativeAccessRules);
+    }
+
+    /**
+     * @return the {@link UiccAccessRule}s that are both stored on Uicc and in carrierConfigs
+     * dictating who is authorized to manage this subscription.
+     * @hide
+     */
+    public @Nullable List<UiccAccessRule> getAllAccessRules() {
+        List<UiccAccessRule> merged = new ArrayList<>();
+        if (mNativeAccessRules != null) {
+            merged.addAll(getAccessRules());
         }
-        if (mAccessRules == null) return null;
-        return Arrays.asList(mAccessRules);
+        if (mCarrierConfigAccessRules != null) {
+            merged.addAll(Arrays.asList(mCarrierConfigAccessRules));
+        }
+        return merged.isEmpty() ? null : merged;
     }
 
     /**
@@ -651,7 +675,7 @@
             String countryIso = source.readString();
             Bitmap iconBitmap = source.readParcelable(Bitmap.class.getClassLoader());
             boolean isEmbedded = source.readBoolean();
-            UiccAccessRule[] accessRules = source.createTypedArray(UiccAccessRule.CREATOR);
+            UiccAccessRule[] nativeAccessRules = source.createTypedArray(UiccAccessRule.CREATOR);
             String cardString = source.readString();
             int cardId = source.readInt();
             boolean isOpportunistic = source.readBoolean();
@@ -663,11 +687,14 @@
             String[] ehplmns = source.readStringArray();
             String[] hplmns = source.readStringArray();
             String groupOwner = source.readString();
+            UiccAccessRule[] carrierConfigAccessRules = source.createTypedArray(
+                UiccAccessRule.CREATOR);
 
             SubscriptionInfo info = new SubscriptionInfo(id, iccId, simSlotIndex, displayName,
                     carrierName, nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc,
-                    countryIso, isEmbedded, accessRules, cardString, cardId, isOpportunistic,
-                    groupUUID, isGroupDisabled, carrierid, profileClass, subType, groupOwner);
+                    countryIso, isEmbedded, nativeAccessRules, cardString, cardId, isOpportunistic,
+                    groupUUID, isGroupDisabled, carrierid, profileClass, subType, groupOwner,
+                    carrierConfigAccessRules);
             info.setAssociatedPlmns(ehplmns, hplmns);
             return info;
         }
@@ -694,7 +721,7 @@
         dest.writeString(mCountryIso);
         dest.writeParcelable(mIconBitmap, flags);
         dest.writeBoolean(mIsEmbedded);
-        dest.writeTypedArray(mAccessRules, flags);
+        dest.writeTypedArray(mNativeAccessRules, flags);
         dest.writeString(mCardString);
         dest.writeInt(mCardId);
         dest.writeBoolean(mIsOpportunistic);
@@ -706,6 +733,7 @@
         dest.writeStringArray(mEhplmns);
         dest.writeStringArray(mHplmns);
         dest.writeString(mGroupOwner);
+        dest.writeTypedArray(mCarrierConfigAccessRules, flags);
     }
 
     @Override
@@ -738,7 +766,7 @@
                 + " iconTint=" + mIconTint + " mNumber=" + Rlog.pii(Build.IS_DEBUGGABLE, mNumber)
                 + " dataRoaming=" + mDataRoaming + " iconBitmap=" + mIconBitmap + " mcc " + mMcc
                 + " mnc " + mMnc + "mCountryIso=" + mCountryIso + " isEmbedded " + mIsEmbedded
-                + " accessRules " + Arrays.toString(mAccessRules)
+                + " nativeAccessRules " + Arrays.toString(mNativeAccessRules)
                 + " cardString=" + cardStringToPrint + " cardId=" + mCardId
                 + " isOpportunistic " + mIsOpportunistic + " mGroupUUID=" + mGroupUUID
                 + " mIsGroupDisabled=" + mIsGroupDisabled
@@ -746,14 +774,15 @@
                 + " ehplmns = " + Arrays.toString(mEhplmns)
                 + " hplmns = " + Arrays.toString(mHplmns)
                 + " subscriptionType=" + mSubscriptionType
-                + " mGroupOwner=" + mGroupOwner + "}";
+                + " mGroupOwner=" + mGroupOwner
+                + " carrierConfigAccessRules=" + mCarrierConfigAccessRules + "}";
     }
 
     @Override
     public int hashCode() {
         return Objects.hash(mId, mSimSlotIndex, mNameSource, mIconTint, mDataRoaming, mIsEmbedded,
                 mIsOpportunistic, mGroupUUID, mIccId, mNumber, mMcc, mMnc,
-                mCountryIso, mCardString, mCardId, mDisplayName, mCarrierName, mAccessRules,
+                mCountryIso, mCardString, mCardId, mDisplayName, mCarrierName, mNativeAccessRules,
                 mIsGroupDisabled, mCarrierId, mProfileClass, mGroupOwner);
     }
 
@@ -789,7 +818,7 @@
                 && Objects.equals(mGroupOwner, toCompare.mGroupOwner)
                 && TextUtils.equals(mDisplayName, toCompare.mDisplayName)
                 && TextUtils.equals(mCarrierName, toCompare.mCarrierName)
-                && Arrays.equals(mAccessRules, toCompare.mAccessRules)
+                && Arrays.equals(mNativeAccessRules, toCompare.mNativeAccessRules)
                 && mProfileClass == toCompare.mProfileClass
                 && Arrays.equals(mEhplmns, toCompare.mEhplmns)
                 && Arrays.equals(mHplmns, toCompare.mHplmns);
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 2822fcc..126644d 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -571,6 +571,16 @@
     public static final String ACCESS_RULES = "access_rules";
 
     /**
+     * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from
+     * {@link UiccAccessRule#encodeRules} but for the rules that come from CarrierConfigs.
+     * Only present if there are access rules in CarrierConfigs
+     * <p>TYPE: BLOB
+     * @hide
+     */
+    public static final String ACCESS_RULES_FROM_CARRIER_CONFIGS =
+            "access_rules_from_carrier_configs";
+
+    /**
      * TelephonyProvider column name identifying whether an embedded subscription is on a removable
      * card. Such subscriptions are marked inaccessible as soon as the current card is removed.
      * Otherwise, they will remain accessible unless explicitly deleted. Only present if
@@ -2578,7 +2588,6 @@
      *
      * @param info The subscription to check.
      * @return whether the app is authorized to manage this subscription per its metadata.
-     * @throws IllegalArgumentException if this subscription is not embedded.
      */
     public boolean canManageSubscription(SubscriptionInfo info) {
         return canManageSubscription(info, mContext.getPackageName());
@@ -2594,24 +2603,22 @@
      * @param info The subscription to check.
      * @param packageName Package name of the app to check.
      * @return whether the app is authorized to manage this subscription per its access rules.
-     * @throws IllegalArgumentException if this subscription is not embedded.
      * @hide
      */
     public boolean canManageSubscription(SubscriptionInfo info, String packageName) {
-        if (!info.isEmbedded()) {
-            throw new IllegalArgumentException("Not an embedded subscription");
-        }
-        if (info.getAccessRules() == null) {
+        if (info == null || info.getAllAccessRules() == null) {
             return false;
         }
         PackageManager packageManager = mContext.getPackageManager();
         PackageInfo packageInfo;
         try {
-            packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
+            packageInfo = packageManager.getPackageInfo(packageName,
+                PackageManager.GET_SIGNING_CERTIFICATES);
         } catch (PackageManager.NameNotFoundException e) {
-            throw new IllegalArgumentException("Unknown package: " + packageName, e);
+            logd("Unknown package: " + packageName);
+            return false;
         }
-        for (UiccAccessRule rule : info.getAccessRules()) {
+        for (UiccAccessRule rule : info.getAllAccessRules()) {
             if (rule.getCarrierPrivilegeStatus(packageInfo)
                     == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
                 return true;
@@ -3002,7 +3009,7 @@
         // to the caller.
         boolean hasCarrierPrivilegePermission = TelephonyManager.from(mContext)
                 .hasCarrierPrivileges(info.getSubscriptionId())
-                || (info.isEmbedded() && canManageSubscription(info));
+                || canManageSubscription(info);
         return hasCarrierPrivilegePermission;
     }
 
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 7477c3e..b37acf3 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -2716,6 +2716,8 @@
     /** Class of broadly defined "4G" networks. {@hide} */
     @UnsupportedAppUsage
     public static final int NETWORK_CLASS_4_G = 3;
+    /** Class of broadly defined "5G" networks. {@hide} */
+    public static final int NETWORK_CLASS_5_G = 4;
 
     /**
      * Return general class of network type, such as "3G" or "4G". In cases
@@ -2748,6 +2750,8 @@
             case NETWORK_TYPE_IWLAN:
             case NETWORK_TYPE_LTE_CA:
                 return NETWORK_CLASS_4_G;
+            case NETWORK_TYPE_NR:
+                return NETWORK_CLASS_5_G;
             default:
                 return NETWORK_CLASS_UNKNOWN;
         }
@@ -11001,6 +11005,8 @@
      * The {@link #EXTRA_NETWORK_COUNTRY} extra indicates the country code of the current
      * network returned by {@link #getNetworkCountryIso()}.
      *
+     * <p>There may be a delay of several minutes before reporting that no country is detected.
+     *
      * @see #EXTRA_NETWORK_COUNTRY
      * @see #getNetworkCountryIso()
      */
diff --git a/telephony/java/android/telephony/TelephonyScanManager.java b/telephony/java/android/telephony/TelephonyScanManager.java
index 28747da..9ff8515 100644
--- a/telephony/java/android/telephony/TelephonyScanManager.java
+++ b/telephony/java/android/telephony/TelephonyScanManager.java
@@ -104,7 +104,7 @@
 
     private final Looper mLooper;
     private final Messenger mMessenger;
-    private SparseArray<NetworkScanInfo> mScanInfo = new SparseArray<NetworkScanInfo>();
+    private final SparseArray<NetworkScanInfo> mScanInfo = new SparseArray<NetworkScanInfo>();
 
     public TelephonyScanManager() {
         HandlerThread thread = new HandlerThread(TAG);
@@ -204,14 +204,16 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                int scanId = telephony.requestNetworkScan(
-                        subId, request, mMessenger, new Binder(), callingPackage);
-                if (scanId == INVALID_SCAN_ID) {
-                    Rlog.e(TAG, "Failed to initiate network scan");
-                    return null;
+                synchronized (mScanInfo) {
+                    int scanId = telephony.requestNetworkScan(
+                            subId, request, mMessenger, new Binder(), callingPackage);
+                    if (scanId == INVALID_SCAN_ID) {
+                        Rlog.e(TAG, "Failed to initiate network scan");
+                        return null;
+                    }
+                    saveScanInfo(scanId, request, executor, callback);
+                    return new NetworkScan(scanId, subId);
                 }
-                saveScanInfo(scanId, request, executor, callback);
-                return new NetworkScan(scanId, subId);
             }
         } catch (RemoteException ex) {
             Rlog.e(TAG, "requestNetworkScan RemoteException", ex);
@@ -223,9 +225,7 @@
 
     private void saveScanInfo(
             int id, NetworkScanRequest request, Executor executor, NetworkScanCallback callback) {
-        synchronized (mScanInfo) {
-            mScanInfo.put(id, new NetworkScanInfo(request, executor, callback));
-        }
+        mScanInfo.put(id, new NetworkScanInfo(request, executor, callback));
     }
 
     private ITelephony getITelephony() {
diff --git a/telephony/java/android/telephony/UiccAccessRule.java b/telephony/java/android/telephony/UiccAccessRule.java
index 37a4491..cb3c384 100644
--- a/telephony/java/android/telephony/UiccAccessRule.java
+++ b/telephony/java/android/telephony/UiccAccessRule.java
@@ -19,6 +19,7 @@
 import android.annotation.SystemApi;
 import android.content.pm.PackageInfo;
 import android.content.pm.Signature;
+import android.content.pm.SigningInfo;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
@@ -168,17 +169,28 @@
      *
      * @param packageInfo package info fetched from
      *     {@link android.content.pm.PackageManager#getPackageInfo}.
-     *     {@link android.content.pm.PackageManager#GET_SIGNATURES} must have been passed in.
+     *     {@link android.content.pm.PackageManager#GET_SIGNING_CERTIFICATES} must have been
+     *         passed in.
      * @return either {@link TelephonyManager#CARRIER_PRIVILEGE_STATUS_HAS_ACCESS} or
      *     {@link TelephonyManager#CARRIER_PRIVILEGE_STATUS_NO_ACCESS}.
      */
     public int getCarrierPrivilegeStatus(PackageInfo packageInfo) {
-        if (packageInfo.signatures == null || packageInfo.signatures.length == 0) {
-            throw new IllegalArgumentException(
-                    "Must use GET_SIGNATURES when looking up package info");
+        Signature[] signatures = packageInfo.signatures;
+        SigningInfo sInfo = packageInfo.signingInfo;
+
+        if (sInfo != null) {
+            signatures = sInfo.getSigningCertificateHistory();
+            if (sInfo.hasMultipleSigners()) {
+                signatures = sInfo.getApkContentsSigners();
+            }
         }
 
-        for (Signature sig : packageInfo.signatures) {
+        if (signatures == null || signatures.length == 0) {
+            throw new IllegalArgumentException(
+                    "Must use GET_SIGNING_CERTIFICATES when looking up package info");
+        }
+
+        for (Signature sig : signatures) {
             int accessStatus = getCarrierPrivilegeStatus(sig, packageInfo.packageName);
             if (accessStatus != TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS) {
                 return accessStatus;
diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java
index 20aba4d..7241ac5 100644
--- a/telephony/java/android/telephony/ims/ImsReasonInfo.java
+++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java
@@ -884,6 +884,12 @@
      */
     public static final int CODE_WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION = 1623;
 
+    /**
+     * The dialed RTT call should be retried without RTT
+     * @hide
+     */
+    public static final int CODE_RETRY_ON_IMS_WITHOUT_RTT = 3001;
+
     /*
      * OEM specific error codes. To be used by OEMs when they don't want to reveal error code which
      * would be replaced by ERROR_UNSPECIFIED.
@@ -1064,6 +1070,7 @@
             CODE_REJECT_VT_AVPF_NOT_ALLOWED,
             CODE_REJECT_ONGOING_ENCRYPTED_CALL,
             CODE_REJECT_ONGOING_CS_CALL,
+            CODE_RETRY_ON_IMS_WITHOUT_RTT,
             CODE_OEM_CAUSE_1,
             CODE_OEM_CAUSE_2,
             CODE_OEM_CAUSE_3,
diff --git a/telephony/java/com/android/internal/telephony/CbGeoUtils.java b/telephony/java/com/android/internal/telephony/CbGeoUtils.java
new file mode 100644
index 0000000..0b73252
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/CbGeoUtils.java
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.annotation.NonNull;
+import android.telephony.Rlog;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+
+/**
+ * This utils class is specifically used for geo-targeting of CellBroadcast messages.
+ * The coordinates used by this utils class are latitude and longitude, but some algorithms in this
+ * class only use them as coordinates on plane, so the calculation will be inaccurate. So don't use
+ * this class for anything other then geo-targeting of cellbroadcast messages.
+ */
+public class CbGeoUtils {
+    /** Geometric interface. */
+    public interface Geometry {
+        /**
+         * Determines if the given point {@code p} is inside the geometry.
+         * @param p point in latitude, longitude format.
+         * @return {@code True} if the given point is inside the geometry.
+         */
+        boolean contains(LatLng p);
+    }
+
+    /**
+     * Tolerance for determining if the value is 0. If the absolute value of a value is less than
+     * this tolerance, it will be treated as 0.
+     */
+    public static final double EPS = 1e-7;
+
+    /** The radius of earth. */
+    public static final int EARTH_RADIUS_METER = 6371 * 1000;
+
+    private static final String TAG = "CbGeoUtils";
+
+    /** The TLV tags of WAC, defined in ATIS-0700041 5.2.3 WAC tag coding. */
+    public static final int GEO_FENCING_MAXIMUM_WAIT_TIME = 0x01;
+    public static final int GEOMETRY_TYPE_POLYGON = 0x02;
+    public static final int GEOMETRY_TYPE_CIRCLE = 0x03;
+
+    /** The identifier of geometry in the encoded string. */
+    private static final String CIRCLE_SYMBOL = "circle";
+    private static final String POLYGON_SYMBOL = "polygon";
+
+    /** Point represent by (latitude, longitude). */
+    public static class LatLng {
+        public final double lat;
+        public final double lng;
+
+        /**
+         * Constructor.
+         * @param lat latitude, range [-90, 90]
+         * @param lng longitude, range [-180, 180]
+         */
+        public LatLng(double lat, double lng) {
+            this.lat = lat;
+            this.lng = lng;
+        }
+
+        /**
+         * @param p the point use to calculate the subtraction result.
+         * @return the result of this point subtract the given point {@code p}.
+         */
+        public LatLng subtract(LatLng p) {
+            return new LatLng(lat - p.lat, lng - p.lng);
+        }
+
+        /**
+         * Calculate the distance in meter between this point and the given point {@code p}.
+         * @param p the point use to calculate the distance.
+         * @return the distance in meter.
+         */
+        public double distance(LatLng p) {
+            double dlat = Math.sin(0.5 * Math.toRadians(lat - p.lat));
+            double dlng = Math.sin(0.5 * Math.toRadians(lng - p.lng));
+            double x = dlat * dlat
+                    + dlng * dlng * Math.cos(Math.toRadians(lat)) * Math.cos(Math.toRadians(p.lat));
+            return 2 * Math.atan2(Math.sqrt(x), Math.sqrt(1 - x)) * EARTH_RADIUS_METER;
+        }
+
+        @Override
+        public String toString() {
+            return "(" + lat + "," + lng + ")";
+        }
+    }
+
+    /**
+     * The class represents a simple polygon with at least 3 points.
+     */
+    public static class Polygon implements Geometry {
+        /**
+         * In order to reduce the loss of precision in floating point calculations, all vertices
+         * of the polygon are scaled. Set the value of scale to 1000 can take into account the
+         * actual distance accuracy of 1 meter if the EPS is 1e-7 during the calculation.
+         */
+        private static final double SCALE = 1000.0;
+
+        private final List<LatLng> mVertices;
+        private final List<Point> mScaledVertices;
+        private final LatLng mOrigin;
+
+        /**
+         * Constructs a simple polygon from the given vertices. The adjacent two vertices are
+         * connected to form an edge of the polygon. The polygon has at least 3 vertices, and the
+         * last vertices and the first vertices must be adjacent.
+         *
+         * The longitude difference in the vertices should be less than 180 degree.
+         */
+        public Polygon(@NonNull List<LatLng> vertices) {
+            mVertices = vertices;
+
+            // Find the point with smallest longitude as the mOrigin point.
+            int idx = 0;
+            for (int i = 1; i < vertices.size(); i++) {
+                if (vertices.get(i).lng < vertices.get(idx).lng) {
+                    idx = i;
+                }
+            }
+            mOrigin = vertices.get(idx);
+
+            mScaledVertices = vertices.stream()
+                    .map(latLng -> convertAndScaleLatLng(latLng))
+                    .collect(Collectors.toList());
+        }
+
+        public List<LatLng> getVertices() {
+            return mVertices;
+        }
+
+        /**
+         * Check if the given point {@code p} is inside the polygon. This method counts the number
+         * of times the polygon winds around the point P, A.K.A "winding number". The point is
+         * outside only when this "winding number" is 0.
+         *
+         * If a point is on the edge of the polygon, it is also considered to be inside the polygon.
+         */
+        @Override
+        public boolean contains(LatLng latLng) {
+            Point p = convertAndScaleLatLng(latLng);
+
+            int n = mScaledVertices.size();
+            int windingNumber = 0;
+            for (int i = 0; i < n; i++) {
+                Point a = mScaledVertices.get(i);
+                Point b = mScaledVertices.get((i + 1) % n);
+
+                // CCW is counterclockwise
+                // CCW = ab x ap
+                // CCW > 0 -> ap is on the left side of ab
+                // CCW == 0 -> ap is on the same line of ab
+                // CCW < 0 -> ap is on the right side of ab
+                int ccw = sign(crossProduct(b.subtract(a), p.subtract(a)));
+
+                if (ccw == 0) {
+                    if (Math.min(a.x, b.x) <= p.x && p.x <= Math.max(a.x, b.x)
+                            && Math.min(a.y, b.y) <= p.y && p.y <= Math.max(a.y, b.y)) {
+                        return true;
+                    }
+                } else {
+                    if (sign(a.y - p.y) <= 0) {
+                        // upward crossing
+                        if (ccw > 0 && sign(b.y - p.y) > 0) {
+                            ++windingNumber;
+                        }
+                    } else {
+                        // downward crossing
+                        if (ccw < 0 && sign(b.y - p.y) <= 0) {
+                            --windingNumber;
+                        }
+                    }
+                }
+            }
+            return windingNumber != 0;
+        }
+
+        /**
+         * Move the given point {@code latLng} to the coordinate system with {@code mOrigin} as the
+         * origin and scale it. {@code mOrigin} is selected from the vertices of a polygon, it has
+         * the smallest longitude value among all of the polygon vertices.
+         *
+         * @param latLng the point need to be converted and scaled.
+         * @Return a {@link Point} object.
+         */
+        private Point convertAndScaleLatLng(LatLng latLng) {
+            double x = latLng.lat - mOrigin.lat;
+            double y = latLng.lng - mOrigin.lng;
+
+            // If the point is in different hemispheres(western/eastern) than the mOrigin, and the
+            // edge between them cross the 180th meridian, then its relative coordinates will be
+            // extended.
+            // For example, suppose the longitude of the mOrigin is -178, and the longitude of the
+            // point to be converted is 175, then the longitude after the conversion is -8.
+            // calculation: (-178 - 8) - (-178).
+            if (sign(mOrigin.lng) != 0 && sign(mOrigin.lng) != sign(latLng.lng)) {
+                double distCross0thMeridian = Math.abs(mOrigin.lng) + Math.abs(latLng.lng);
+                if (sign(distCross0thMeridian * 2 - 360) > 0) {
+                    y = sign(mOrigin.lng) * (360 - distCross0thMeridian);
+                }
+            }
+            return new Point(x * SCALE, y * SCALE);
+        }
+
+        private static double crossProduct(Point a, Point b) {
+            return a.x * b.y - a.y * b.x;
+        }
+
+        static final class Point {
+            public final double x;
+            public final double y;
+
+            Point(double x, double y) {
+                this.x = x;
+                this.y = y;
+            }
+
+            public Point subtract(Point p) {
+                return new Point(x - p.x, y - p.y);
+            }
+        }
+    }
+
+    /** The class represents a circle. */
+    public static class Circle implements Geometry {
+        private final LatLng mCenter;
+        private final double mRadiusMeter;
+
+        public Circle(LatLng center, double radiusMeter) {
+            this.mCenter = center;
+            this.mRadiusMeter = radiusMeter;
+        }
+
+        public LatLng getCenter() {
+            return mCenter;
+        }
+
+        public double getRadius() {
+            return mRadiusMeter;
+        }
+
+        @Override
+        public boolean contains(LatLng p) {
+            return mCenter.distance(p) <= mRadiusMeter;
+        }
+    }
+
+    /**
+     * Parse the geometries from the encoded string {@code str}. The string must follow the
+     * geometry encoding specified by {@link android.provider.Telephony.CellBroadcasts#GEOMETRIES}.
+     */
+    @NonNull
+    public static List<Geometry> parseGeometriesFromString(@NonNull String str) {
+        List<Geometry> geometries = new ArrayList<>();
+        for (String geometryStr : str.split("\\s*;\\s*")) {
+            String[] geoParameters = geometryStr.split("\\s*\\|\\s*");
+            switch (geoParameters[0]) {
+                case CIRCLE_SYMBOL:
+                    geometries.add(new Circle(parseLatLngFromString(geoParameters[1]),
+                            Double.parseDouble(geoParameters[2])));
+                    break;
+                case POLYGON_SYMBOL:
+                    List<LatLng> vertices = new ArrayList<>(geoParameters.length - 1);
+                    for (int i = 1; i < geoParameters.length; i++) {
+                        vertices.add(parseLatLngFromString(geoParameters[i]));
+                    }
+                    geometries.add(new Polygon(vertices));
+                    break;
+                default:
+                    Rlog.e(TAG, "Invalid geometry format " + geometryStr);
+            }
+        }
+        return geometries;
+    }
+
+    /**
+     * Encode a list of geometry objects to string. The encoding format is specified by
+     * {@link android.provider.Telephony.CellBroadcasts#GEOMETRIES}.
+     *
+     * @param geometries the list of geometry objects need to be encoded.
+     * @return the encoded string.
+     */
+    @NonNull
+    public static String encodeGeometriesToString(List<Geometry> geometries) {
+        if (geometries == null || geometries.isEmpty()) return "";
+        return geometries.stream()
+                .map(geometry -> encodeGeometryToString(geometry))
+                .filter(encodedStr -> !TextUtils.isEmpty(encodedStr))
+                .collect(Collectors.joining(";"));
+    }
+
+
+    /**
+     * Encode the geometry object to string. The encoding format is specified by
+     * {@link android.provider.Telephony.CellBroadcasts#GEOMETRIES}.
+     * @param geometry the geometry object need to be encoded.
+     * @return the encoded string.
+     */
+    @NonNull
+    private static String encodeGeometryToString(@NonNull Geometry geometry) {
+        StringBuilder sb = new StringBuilder();
+        if (geometry instanceof Polygon) {
+            sb.append(POLYGON_SYMBOL);
+            for (LatLng latLng : ((Polygon) geometry).getVertices()) {
+                sb.append("|");
+                sb.append(latLng.lat);
+                sb.append(",");
+                sb.append(latLng.lng);
+            }
+        } else if (geometry instanceof Circle) {
+            sb.append(CIRCLE_SYMBOL);
+            Circle circle = (Circle) geometry;
+
+            // Center
+            sb.append("|");
+            sb.append(circle.getCenter().lat);
+            sb.append(",");
+            sb.append(circle.getCenter().lng);
+
+            // Radius
+            sb.append("|");
+            sb.append(circle.getRadius());
+        } else {
+            Rlog.e(TAG, "Unsupported geometry object " + geometry);
+            return null;
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Parse {@link LatLng} from {@link String}. Latitude and longitude are separated by ",".
+     * Example: "13.56,-55.447".
+     *
+     * @param str encoded lat/lng string.
+     * @Return {@link LatLng} object.
+     */
+    @NonNull
+    public static LatLng parseLatLngFromString(@NonNull String str) {
+        String[] latLng = str.split("\\s*,\\s*");
+        return new LatLng(Double.parseDouble(latLng[0]), Double.parseDouble(latLng[1]));
+    }
+
+    /**
+     * @Return the sign of the given value {@code value} with the specified tolerance. Return 1
+     * means the sign is positive, -1 means negative, 0 means the value will be treated as 0.
+     */
+    public static int sign(double value) {
+        if (value > EPS) return 1;
+        if (value < -EPS) return -1;
+        return 0;
+    }
+}
diff --git a/telephony/java/com/android/internal/telephony/SmsCbMessage.java b/telephony/java/com/android/internal/telephony/SmsCbMessage.java
index 046bf8c..2157666 100644
--- a/telephony/java/com/android/internal/telephony/SmsCbMessage.java
+++ b/telephony/java/com/android/internal/telephony/SmsCbMessage.java
@@ -16,8 +16,17 @@
 
 package android.telephony;
 
+import android.annotation.Nullable;
+import android.content.ContentValues;
+import android.database.Cursor;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.provider.Telephony.CellBroadcasts;
+
+import com.android.internal.telephony.CbGeoUtils;
+import com.android.internal.telephony.CbGeoUtils.Geometry;
+
+import java.util.List;
 
 /**
  * Parcelable object containing a received cell broadcast message. There are four different types
@@ -95,6 +104,9 @@
     /** Emergency message priority. */
     public static final int MESSAGE_PRIORITY_EMERGENCY = 3;
 
+    /** ATIS-0700041 Section 5.2.8 WAC Geo-Fencing Maximum Wait Time Table 12. */
+    public static final int MAXIMUM_WAIT_TIME_NOT_SET = 255;
+
     /** Format of this message (for interpretation of service category values). */
     private final int mMessageFormat;
 
@@ -139,11 +151,38 @@
     private final SmsCbCmasInfo mCmasWarningInfo;
 
     /**
+     * Geo-Fencing Maximum Wait Time in second, a device shall allow to determine its position
+     * meeting operator policy. If the device is unable to determine its position meeting operator
+     * policy within the GeoFencing Maximum Wait Time, it shall present the alert to the user and
+     * discontinue further positioning determination for the alert.
+     */
+    private final int mMaximumWaitTimeSec;
+
+    /** UNIX timestamp of when the message was received. */
+    private final long mReceivedTimeMillis;
+
+    /** CMAS warning area coordinates. */
+    private final List<Geometry> mGeometries;
+
+    /**
      * Create a new SmsCbMessage with the specified data.
      */
     public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber,
             SmsCbLocation location, int serviceCategory, String language, String body,
             int priority, SmsCbEtwsInfo etwsWarningInfo, SmsCbCmasInfo cmasWarningInfo) {
+
+        this(messageFormat, geographicalScope, serialNumber, location, serviceCategory, language,
+                body, priority, etwsWarningInfo, cmasWarningInfo, 0 /* maximumWaitingTime */,
+                null /* geometries */, System.currentTimeMillis());
+    }
+
+    /**
+     * Create a new {@link SmsCbMessage} with the warning area coordinates information.
+     */
+    public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber,
+            SmsCbLocation location, int serviceCategory, String language, String body,
+            int priority, SmsCbEtwsInfo etwsWarningInfo, SmsCbCmasInfo cmasWarningInfo,
+            int maximumWaitTimeSec, List<Geometry> geometries, long receivedTimeMillis) {
         mMessageFormat = messageFormat;
         mGeographicalScope = geographicalScope;
         mSerialNumber = serialNumber;
@@ -154,6 +193,9 @@
         mPriority = priority;
         mEtwsWarningInfo = etwsWarningInfo;
         mCmasWarningInfo = cmasWarningInfo;
+        mReceivedTimeMillis = receivedTimeMillis;
+        mGeometries = geometries;
+        mMaximumWaitTimeSec = maximumWaitTimeSec;
     }
 
     /** Create a new SmsCbMessage object from a Parcel. */
@@ -184,6 +226,10 @@
                 mEtwsWarningInfo = null;
                 mCmasWarningInfo = null;
         }
+        mReceivedTimeMillis = in.readLong();
+        String geoStr = in.readString();
+        mGeometries = geoStr != null ? CbGeoUtils.parseGeometriesFromString(geoStr) : null;
+        mMaximumWaitTimeSec = in.readInt();
     }
 
     /**
@@ -214,6 +260,10 @@
             // no ETWS or CMAS warning information
             dest.writeInt('0');
         }
+        dest.writeLong(mReceivedTimeMillis);
+        dest.writeString(
+                mGeometries != null ? CbGeoUtils.encodeGeometriesToString(mGeometries) : null);
+        dest.writeInt(mMaximumWaitTimeSec);
     }
 
     public static final Parcelable.Creator<SmsCbMessage> CREATOR
@@ -293,6 +343,32 @@
     }
 
     /**
+     * Get the warning area coordinates information represent by polygons and circles.
+     * @return a list of geometries, {@link Nullable} means there is no coordinate information
+     * associated to this message.
+     */
+    @Nullable
+    public List<Geometry> getGeometries() {
+        return mGeometries;
+    }
+
+    /**
+     * Get the Geo-Fencing Maximum Wait Time.
+     * @return the time in second.
+     */
+    public int getMaximumWaitingTime() {
+        return mMaximumWaitTimeSec;
+    }
+
+    /**
+     * Get the time when this message was received.
+     * @return the time in millisecond
+     */
+    public long getReceivedTime() {
+        return mReceivedTimeMillis;
+    }
+
+    /**
      * Get the message format ({@link #MESSAGE_FORMAT_3GPP} or {@link #MESSAGE_FORMAT_3GPP2}).
      * @return an integer representing 3GPP or 3GPP2 message format
      */
@@ -368,7 +444,11 @@
                 + mServiceCategory + ", language=" + mLanguage + ", body=" + mBody
                 + ", priority=" + mPriority
                 + (mEtwsWarningInfo != null ? (", " + mEtwsWarningInfo.toString()) : "")
-                + (mCmasWarningInfo != null ? (", " + mCmasWarningInfo.toString()) : "") + '}';
+                + (mCmasWarningInfo != null ? (", " + mCmasWarningInfo.toString()) : "")
+                + ", maximumWaitingTime = " + mMaximumWaitTimeSec
+                + ", geo=" + (mGeometries != null
+                ? CbGeoUtils.encodeGeometriesToString(mGeometries) : "null")
+                + '}';
     }
 
     /**
@@ -379,4 +459,177 @@
     public int describeContents() {
         return 0;
     }
+
+    /**
+     * @return the {@link ContentValues} instance that includes the cell broadcast data.
+     */
+    public ContentValues getContentValues() {
+        ContentValues cv = new ContentValues(16);
+        cv.put(CellBroadcasts.GEOGRAPHICAL_SCOPE, mGeographicalScope);
+        if (mLocation.getPlmn() != null) {
+            cv.put(CellBroadcasts.PLMN, mLocation.getPlmn());
+        }
+        if (mLocation.getLac() != -1) {
+            cv.put(CellBroadcasts.LAC, mLocation.getLac());
+        }
+        if (mLocation.getCid() != -1) {
+            cv.put(CellBroadcasts.CID, mLocation.getCid());
+        }
+        cv.put(CellBroadcasts.SERIAL_NUMBER, getSerialNumber());
+        cv.put(CellBroadcasts.SERVICE_CATEGORY, getServiceCategory());
+        cv.put(CellBroadcasts.LANGUAGE_CODE, getLanguageCode());
+        cv.put(CellBroadcasts.MESSAGE_BODY, getMessageBody());
+        cv.put(CellBroadcasts.MESSAGE_FORMAT, getMessageFormat());
+        cv.put(CellBroadcasts.MESSAGE_PRIORITY, getMessagePriority());
+
+        SmsCbEtwsInfo etwsInfo = getEtwsWarningInfo();
+        if (etwsInfo != null) {
+            cv.put(CellBroadcasts.ETWS_WARNING_TYPE, etwsInfo.getWarningType());
+        }
+
+        SmsCbCmasInfo cmasInfo = getCmasWarningInfo();
+        if (cmasInfo != null) {
+            cv.put(CellBroadcasts.CMAS_MESSAGE_CLASS, cmasInfo.getMessageClass());
+            cv.put(CellBroadcasts.CMAS_CATEGORY, cmasInfo.getCategory());
+            cv.put(CellBroadcasts.CMAS_RESPONSE_TYPE, cmasInfo.getResponseType());
+            cv.put(CellBroadcasts.CMAS_SEVERITY, cmasInfo.getSeverity());
+            cv.put(CellBroadcasts.CMAS_URGENCY, cmasInfo.getUrgency());
+            cv.put(CellBroadcasts.CMAS_CERTAINTY, cmasInfo.getCertainty());
+        }
+
+        cv.put(CellBroadcasts.RECEIVED_TIME, mReceivedTimeMillis);
+
+        if (mGeometries != null) {
+            cv.put(CellBroadcasts.GEOMETRIES, CbGeoUtils.encodeGeometriesToString(mGeometries));
+        } else {
+            cv.put(CellBroadcasts.GEOMETRIES, (String) null);
+        }
+
+        cv.put(CellBroadcasts.MAXIMUM_WAIT_TIME, mMaximumWaitTimeSec);
+
+        return cv;
+    }
+
+    /**
+     * Create a {@link SmsCbMessage} instance from a row in the cell broadcast database.
+     * @param cursor an open SQLite cursor pointing to the row to read
+     * @return a {@link SmsCbMessage} instance.
+     * @throws IllegalArgumentException if one of the required columns is missing
+     */
+    public static SmsCbMessage createFromCursor(Cursor cursor) {
+        int geoScope = cursor.getInt(
+                cursor.getColumnIndexOrThrow(CellBroadcasts.GEOGRAPHICAL_SCOPE));
+        int serialNum = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.SERIAL_NUMBER));
+        int category = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.SERVICE_CATEGORY));
+        String language = cursor.getString(
+                cursor.getColumnIndexOrThrow(CellBroadcasts.LANGUAGE_CODE));
+        String body = cursor.getString(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_BODY));
+        int format = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_FORMAT));
+        int priority = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_PRIORITY));
+
+        String plmn;
+        int plmnColumn = cursor.getColumnIndex(CellBroadcasts.PLMN);
+        if (plmnColumn != -1 && !cursor.isNull(plmnColumn)) {
+            plmn = cursor.getString(plmnColumn);
+        } else {
+            plmn = null;
+        }
+
+        int lac;
+        int lacColumn = cursor.getColumnIndex(CellBroadcasts.LAC);
+        if (lacColumn != -1 && !cursor.isNull(lacColumn)) {
+            lac = cursor.getInt(lacColumn);
+        } else {
+            lac = -1;
+        }
+
+        int cid;
+        int cidColumn = cursor.getColumnIndex(CellBroadcasts.CID);
+        if (cidColumn != -1 && !cursor.isNull(cidColumn)) {
+            cid = cursor.getInt(cidColumn);
+        } else {
+            cid = -1;
+        }
+
+        SmsCbLocation location = new SmsCbLocation(plmn, lac, cid);
+
+        SmsCbEtwsInfo etwsInfo;
+        int etwsWarningTypeColumn = cursor.getColumnIndex(CellBroadcasts.ETWS_WARNING_TYPE);
+        if (etwsWarningTypeColumn != -1 && !cursor.isNull(etwsWarningTypeColumn)) {
+            int warningType = cursor.getInt(etwsWarningTypeColumn);
+            etwsInfo = new SmsCbEtwsInfo(warningType, false, false, false, null);
+        } else {
+            etwsInfo = null;
+        }
+
+        SmsCbCmasInfo cmasInfo = null;
+        int cmasMessageClassColumn = cursor.getColumnIndex(CellBroadcasts.CMAS_MESSAGE_CLASS);
+        if (cmasMessageClassColumn != -1 && !cursor.isNull(cmasMessageClassColumn)) {
+            int messageClass = cursor.getInt(cmasMessageClassColumn);
+
+            int cmasCategory;
+            int cmasCategoryColumn = cursor.getColumnIndex(CellBroadcasts.CMAS_CATEGORY);
+            if (cmasCategoryColumn != -1 && !cursor.isNull(cmasCategoryColumn)) {
+                cmasCategory = cursor.getInt(cmasCategoryColumn);
+            } else {
+                cmasCategory = SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN;
+            }
+
+            int responseType;
+            int cmasResponseTypeColumn = cursor.getColumnIndex(CellBroadcasts.CMAS_RESPONSE_TYPE);
+            if (cmasResponseTypeColumn != -1 && !cursor.isNull(cmasResponseTypeColumn)) {
+                responseType = cursor.getInt(cmasResponseTypeColumn);
+            } else {
+                responseType = SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN;
+            }
+
+            int severity;
+            int cmasSeverityColumn = cursor.getColumnIndex(CellBroadcasts.CMAS_SEVERITY);
+            if (cmasSeverityColumn != -1 && !cursor.isNull(cmasSeverityColumn)) {
+                severity = cursor.getInt(cmasSeverityColumn);
+            } else {
+                severity = SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN;
+            }
+
+            int urgency;
+            int cmasUrgencyColumn = cursor.getColumnIndex(CellBroadcasts.CMAS_URGENCY);
+            if (cmasUrgencyColumn != -1 && !cursor.isNull(cmasUrgencyColumn)) {
+                urgency = cursor.getInt(cmasUrgencyColumn);
+            } else {
+                urgency = SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN;
+            }
+
+            int certainty;
+            int cmasCertaintyColumn = cursor.getColumnIndex(CellBroadcasts.CMAS_CERTAINTY);
+            if (cmasCertaintyColumn != -1 && !cursor.isNull(cmasCertaintyColumn)) {
+                certainty = cursor.getInt(cmasCertaintyColumn);
+            } else {
+                certainty = SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN;
+            }
+
+            cmasInfo = new SmsCbCmasInfo(messageClass, cmasCategory, responseType, severity,
+                    urgency, certainty);
+        }
+
+        String geoStr = cursor.getString(cursor.getColumnIndex(CellBroadcasts.GEOMETRIES));
+        List<Geometry> geometries =
+                geoStr != null ? CbGeoUtils.parseGeometriesFromString(geoStr) : null;
+
+        long receivedTimeMillis = cursor.getLong(
+                cursor.getColumnIndexOrThrow(CellBroadcasts.RECEIVED_TIME));
+
+        int maximumWaitTimeSec = cursor.getInt(
+                cursor.getColumnIndexOrThrow(CellBroadcasts.MAXIMUM_WAIT_TIME));
+
+        return new SmsCbMessage(format, geoScope, serialNum, location, category,
+                language, body, priority, etwsInfo, cmasInfo, maximumWaitTimeSec, geometries,
+                receivedTimeMillis);
+    }
+
+    /**
+     * @return {@code True} if this message needs geo-fencing check.
+     */
+    public boolean needGeoFencingCheck() {
+        return mMaximumWaitTimeSec > 0 && mGeometries != null;
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
index 8015b07..6eea118 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
@@ -22,58 +22,36 @@
 import static android.telephony.SmsCbEtwsInfo.ETWS_WARNING_TYPE_TEST_MESSAGE;
 import static android.telephony.SmsCbEtwsInfo.ETWS_WARNING_TYPE_TSUNAMI;
 
+import android.annotation.NonNull;
 import android.content.Context;
 import android.content.res.Resources;
 import android.telephony.SmsCbLocation;
 import android.telephony.SmsCbMessage;
 import android.util.Pair;
+import android.util.Slog;
 
 import com.android.internal.R;
+import com.android.internal.telephony.CbGeoUtils;
+import com.android.internal.telephony.CbGeoUtils.Circle;
+import com.android.internal.telephony.CbGeoUtils.Geometry;
+import com.android.internal.telephony.CbGeoUtils.LatLng;
+import com.android.internal.telephony.CbGeoUtils.Polygon;
 import com.android.internal.telephony.GsmAlphabet;
 import com.android.internal.telephony.SmsConstants;
+import com.android.internal.telephony.gsm.GsmSmsCbMessage.GeoFencingTriggerMessage.CellBroadcastIdentity;
+import com.android.internal.telephony.gsm.SmsCbHeader.DataCodingScheme;
 
 import java.io.UnsupportedEncodingException;
-import java.util.Locale;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * Parses a GSM or UMTS format SMS-CB message into an {@link SmsCbMessage} object. The class is
  * public because {@link #createSmsCbMessage(SmsCbLocation, byte[][])} is used by some test cases.
  */
 public class GsmSmsCbMessage {
-
-    /**
-     * Languages in the 0000xxxx DCS group as defined in 3GPP TS 23.038, section 5.
-     */
-    private static final String[] LANGUAGE_CODES_GROUP_0 = {
-            Locale.GERMAN.getLanguage(),        // German
-            Locale.ENGLISH.getLanguage(),       // English
-            Locale.ITALIAN.getLanguage(),       // Italian
-            Locale.FRENCH.getLanguage(),        // French
-            new Locale("es").getLanguage(),     // Spanish
-            new Locale("nl").getLanguage(),     // Dutch
-            new Locale("sv").getLanguage(),     // Swedish
-            new Locale("da").getLanguage(),     // Danish
-            new Locale("pt").getLanguage(),     // Portuguese
-            new Locale("fi").getLanguage(),     // Finnish
-            new Locale("nb").getLanguage(),     // Norwegian
-            new Locale("el").getLanguage(),     // Greek
-            new Locale("tr").getLanguage(),     // Turkish
-            new Locale("hu").getLanguage(),     // Hungarian
-            new Locale("pl").getLanguage(),     // Polish
-            null
-    };
-
-    /**
-     * Languages in the 0010xxxx DCS group as defined in 3GPP TS 23.038, section 5.
-     */
-    private static final String[] LANGUAGE_CODES_GROUP_2 = {
-            new Locale("cs").getLanguage(),     // Czech
-            new Locale("he").getLanguage(),     // Hebrew
-            new Locale("ar").getLanguage(),     // Arabic
-            new Locale("ru").getLanguage(),     // Russian
-            new Locale("is").getLanguage(),     // Icelandic
-            null, null, null, null, null, null, null, null, null, null, null
-    };
+    private static final String TAG = GsmSmsCbMessage.class.getSimpleName();
 
     private static final char CARRIAGE_RETURN = 0x0d;
 
@@ -114,8 +92,9 @@
      * @param pdus PDU bytes
      */
     public static SmsCbMessage createSmsCbMessage(Context context, SmsCbHeader header,
-                                                  SmsCbLocation location, byte[][] pdus)
+            SmsCbLocation location, byte[][] pdus)
             throws IllegalArgumentException {
+        long receivedTimeMillis = System.currentTimeMillis();
         if (header.isEtwsPrimaryNotification()) {
             // ETSI TS 23.041 ETWS Primary Notification message
             // ETWS primary message only contains 4 fields including serial number,
@@ -125,12 +104,46 @@
                     header.getSerialNumber(), location, header.getServiceCategory(), null,
                     getEtwsPrimaryMessage(context, header.getEtwsInfo().getWarningType()),
                     SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, header.getEtwsInfo(),
-                    header.getCmasInfo());
+                    header.getCmasInfo(), 0, null /* geometries */, receivedTimeMillis);
+        } else if (header.isUmtsFormat()) {
+            // UMTS format has only 1 PDU
+            byte[] pdu = pdus[0];
+            Pair<String, String> cbData = parseUmtsBody(header, pdu);
+            String language = cbData.first;
+            String body = cbData.second;
+            int priority = header.isEmergencyMessage() ? SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY
+                    : SmsCbMessage.MESSAGE_PRIORITY_NORMAL;
+            int nrPages = pdu[SmsCbHeader.PDU_HEADER_LENGTH];
+            int wacDataOffset = SmsCbHeader.PDU_HEADER_LENGTH
+                    + 1 // number of pages
+                    + (PDU_BODY_PAGE_LENGTH + 1) * nrPages; // cb data
+
+            // Has Warning Area Coordinates information
+            List<Geometry> geometries = null;
+            int maximumWaitingTimeSec = 255;
+            if (pdu.length > wacDataOffset) {
+                try {
+                    Pair<Integer, List<Geometry>> wac = parseWarningAreaCoordinates(pdu,
+                            wacDataOffset);
+                    maximumWaitingTimeSec = wac.first;
+                    geometries = wac.second;
+                } catch (Exception ex) {
+                    // Catch the exception here, the message will be considered as having no WAC
+                    // information which means the message will be broadcasted directly.
+                    Slog.e(TAG, "Can't parse warning area coordinates, ex = " + ex.toString());
+                }
+            }
+
+            return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP,
+                    header.getGeographicalScope(), header.getSerialNumber(), location,
+                    header.getServiceCategory(), language, body, priority,
+                    header.getEtwsInfo(), header.getCmasInfo(), maximumWaitingTimeSec, geometries,
+                    receivedTimeMillis);
         } else {
             String language = null;
             StringBuilder sb = new StringBuilder();
             for (byte[] pdu : pdus) {
-                Pair<String, String> p = parseBody(header, pdu);
+                Pair<String, String> p = parseGsmBody(header, pdu);
                 language = p.first;
                 sb.append(p.second);
             }
@@ -140,154 +153,208 @@
             return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP,
                     header.getGeographicalScope(), header.getSerialNumber(), location,
                     header.getServiceCategory(), language, sb.toString(), priority,
-                    header.getEtwsInfo(), header.getCmasInfo());
+                    header.getEtwsInfo(), header.getCmasInfo(), 0, null /* geometries */,
+                    receivedTimeMillis);
         }
     }
 
     /**
-     * Parse and unpack the body text according to the encoding in the DCS.
-     * After completing successfully this method will have assigned the body
-     * text into mBody, and optionally the language code into mLanguage
+     * Parse WEA Handset Action Message(WHAM) a.k.a geo-fencing trigger message.
+     *
+     * WEA Handset Action Message(WHAM) is a cell broadcast service message broadcast by the network
+     * to direct devices to perform a geo-fencing check on selected alerts.
+     *
+     * WEA Handset Action Message(WHAM) requirements from ATIS-0700041 section 4
+     * 1. The Warning Message contents of a WHAM shall be in Cell Broadcast(CB) data format as
+     * defined in TS 23.041.
+     * 2. The Warning Message Contents of WHAM shall be limited to one CB page(max 20 referenced
+     * WEA messages).
+     * 3. The broadcast area for a WHAM shall be the union of the broadcast areas of the referenced
+     * WEA message.
+     * @param pdu cell broadcast pdu, including the header
+     * @return {@link GeoFencingTriggerMessage} instance
+     */
+    public static GeoFencingTriggerMessage createGeoFencingTriggerMessage(byte[] pdu) {
+        try {
+            // Header length + 1(number of page). ATIS-0700041 define the number of page of
+            // geo-fencing trigger message is 1.
+            int whamOffset = SmsCbHeader.PDU_HEADER_LENGTH + 1;
+
+            BitStreamReader bitReader = new BitStreamReader(pdu, whamOffset);
+            int type = bitReader.read(4);
+            int length = bitReader.read(7);
+            // Skip the remained 5 bits
+            bitReader.skip();
+
+            int messageIdentifierCount = (length - 2) * 8 / 32;
+            List<CellBroadcastIdentity> cbIdentifiers = new ArrayList<>();
+            for (int i = 0; i < messageIdentifierCount; i++) {
+                // Both messageIdentifier and serialNumber are 16 bits integers.
+                // ATIS-0700041 Section 5.1.6
+                int messageIdentifier = bitReader.read(16);
+                int serialNumber = bitReader.read(16);
+                cbIdentifiers.add(new CellBroadcastIdentity(messageIdentifier, serialNumber));
+            }
+            return new GeoFencingTriggerMessage(type, cbIdentifiers);
+        } catch (Exception ex) {
+            Slog.e(TAG, "create geo-fencing trigger failed, ex = " + ex.toString());
+            return null;
+        }
+    }
+
+    /**
+     * Parse the broadcast area and maximum wait time from the Warning Area Coordinates TLV.
+     *
+     * @param pdu Warning Area Coordinates TLV.
+     * @param wacOffset the offset of Warning Area Coordinates TLV.
+     * @return a pair with the first element is maximum wait time and the second is the broadcast
+     * area. The default value of the maximum wait time is 255 which means use the device default
+     * value.
+     */
+    private static Pair<Integer, List<Geometry>> parseWarningAreaCoordinates(
+            byte[] pdu, int wacOffset) {
+        // little-endian
+        int wacDataLength = (pdu[wacOffset + 1] << 8) | pdu[wacOffset];
+        int offset = wacOffset + 2;
+
+        if (offset + wacDataLength > pdu.length) {
+            throw new IllegalArgumentException("Invalid wac data, expected the length of pdu at"
+                    + "least " + offset + wacDataLength + ", actual is " + pdu.length);
+        }
+
+        BitStreamReader bitReader = new BitStreamReader(pdu, offset);
+
+        int maximumWaitTimeSec = SmsCbMessage.MAXIMUM_WAIT_TIME_NOT_SET;
+
+        List<Geometry> geo = new ArrayList<>();
+        int remainedBytes = wacDataLength;
+        while (remainedBytes > 0) {
+            int type = bitReader.read(4);
+            int length = bitReader.read(10);
+            remainedBytes -= length;
+            // Skip the 2 remained bits
+            bitReader.skip();
+
+            switch (type) {
+                case CbGeoUtils.GEO_FENCING_MAXIMUM_WAIT_TIME:
+                    maximumWaitTimeSec = bitReader.read(8);
+                    break;
+                case CbGeoUtils.GEOMETRY_TYPE_POLYGON:
+                    List<LatLng> latLngs = new ArrayList<>();
+                    // Each coordinate is represented by 44 bits integer.
+                    // ATIS-0700041 5.2.4 Coordinate coding
+                    int n = (length - 2) * 8 / 44;
+                    for (int i = 0; i < n; i++) {
+                        latLngs.add(getLatLng(bitReader));
+                    }
+                    // Skip the padding bits
+                    bitReader.skip();
+                    geo.add(new Polygon(latLngs));
+                    break;
+                case CbGeoUtils.GEOMETRY_TYPE_CIRCLE:
+                    LatLng center = getLatLng(bitReader);
+                    // radius = (wacRadius / 2^6). The unit of wacRadius is km, we use meter as the
+                    // distance unit during geo-fencing.
+                    // ATIS-0700041 5.2.5 radius coding
+                    double radius = (bitReader.read(20) * 1.0 / (1 << 6)) * 1000.0;
+                    geo.add(new Circle(center, radius));
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unsupported geoType = " + type);
+            }
+        }
+        return new Pair(maximumWaitTimeSec, geo);
+    }
+
+    /**
+     * The coordinate is (latitude, longitude), represented by a 44 bits integer.
+     * The coding is defined in ATIS-0700041 5.2.4
+     * @param bitReader
+     * @return coordinate (latitude, longitude)
+     */
+    private static LatLng getLatLng(BitStreamReader bitReader) {
+        // wacLatitude = floor(((latitude + 90) / 180) * 2^22)
+        // wacLongitude = floor(((longitude + 180) / 360) * 2^22)
+        int wacLat = bitReader.read(22);
+        int wacLng = bitReader.read(22);
+
+        // latitude = wacLatitude * 180 / 2^22 - 90
+        // longitude = wacLongitude * 360 / 2^22 -180
+        return new LatLng((wacLat * 180.0 / (1 << 22)) - 90, (wacLng * 360.0 / (1 << 22) - 180));
+    }
+
+    /**
+     * Parse and unpack the UMTS body text according to the encoding in the data coding scheme.
      *
      * @param header the message header to use
      * @param pdu the PDU to decode
-     * @return a Pair of Strings containing the language and body of the message
+     * @return a pair of string containing the language and body of the message in order
      */
-    private static Pair<String, String> parseBody(SmsCbHeader header, byte[] pdu) {
-        int encoding;
-        String language = null;
-        boolean hasLanguageIndicator = false;
-        int dataCodingScheme = header.getDataCodingScheme();
+    private static Pair<String, String> parseUmtsBody(SmsCbHeader header, byte[] pdu) {
+        // Payload may contain multiple pages
+        int nrPages = pdu[SmsCbHeader.PDU_HEADER_LENGTH];
+        String language = header.getDataCodingSchemeStructedData().language;
 
-        // Extract encoding and language from DCS, as defined in 3gpp TS 23.038,
-        // section 5.
-        switch ((dataCodingScheme & 0xf0) >> 4) {
-            case 0x00:
-                encoding = SmsConstants.ENCODING_7BIT;
-                language = LANGUAGE_CODES_GROUP_0[dataCodingScheme & 0x0f];
-                break;
-
-            case 0x01:
-                hasLanguageIndicator = true;
-                if ((dataCodingScheme & 0x0f) == 0x01) {
-                    encoding = SmsConstants.ENCODING_16BIT;
-                } else {
-                    encoding = SmsConstants.ENCODING_7BIT;
-                }
-                break;
-
-            case 0x02:
-                encoding = SmsConstants.ENCODING_7BIT;
-                language = LANGUAGE_CODES_GROUP_2[dataCodingScheme & 0x0f];
-                break;
-
-            case 0x03:
-                encoding = SmsConstants.ENCODING_7BIT;
-                break;
-
-            case 0x04:
-            case 0x05:
-                switch ((dataCodingScheme & 0x0c) >> 2) {
-                    case 0x01:
-                        encoding = SmsConstants.ENCODING_8BIT;
-                        break;
-
-                    case 0x02:
-                        encoding = SmsConstants.ENCODING_16BIT;
-                        break;
-
-                    case 0x00:
-                    default:
-                        encoding = SmsConstants.ENCODING_7BIT;
-                        break;
-                }
-                break;
-
-            case 0x06:
-            case 0x07:
-                // Compression not supported
-            case 0x09:
-                // UDH structure not supported
-            case 0x0e:
-                // Defined by the WAP forum not supported
-                throw new IllegalArgumentException("Unsupported GSM dataCodingScheme "
-                        + dataCodingScheme);
-
-            case 0x0f:
-                if (((dataCodingScheme & 0x04) >> 2) == 0x01) {
-                    encoding = SmsConstants.ENCODING_8BIT;
-                } else {
-                    encoding = SmsConstants.ENCODING_7BIT;
-                }
-                break;
-
-            default:
-                // Reserved values are to be treated as 7-bit
-                encoding = SmsConstants.ENCODING_7BIT;
-                break;
+        if (pdu.length < SmsCbHeader.PDU_HEADER_LENGTH + 1 + (PDU_BODY_PAGE_LENGTH + 1)
+                * nrPages) {
+            throw new IllegalArgumentException("Pdu length " + pdu.length + " does not match "
+                    + nrPages + " pages");
         }
 
-        if (header.isUmtsFormat()) {
-            // Payload may contain multiple pages
-            int nrPages = pdu[SmsCbHeader.PDU_HEADER_LENGTH];
+        StringBuilder sb = new StringBuilder();
 
-            if (pdu.length < SmsCbHeader.PDU_HEADER_LENGTH + 1 + (PDU_BODY_PAGE_LENGTH + 1)
-                    * nrPages) {
-                throw new IllegalArgumentException("Pdu length " + pdu.length + " does not match "
-                        + nrPages + " pages");
+        for (int i = 0; i < nrPages; i++) {
+            // Each page is 82 bytes followed by a length octet indicating
+            // the number of useful octets within those 82
+            int offset = SmsCbHeader.PDU_HEADER_LENGTH + 1 + (PDU_BODY_PAGE_LENGTH + 1) * i;
+            int length = pdu[offset + PDU_BODY_PAGE_LENGTH];
+
+            if (length > PDU_BODY_PAGE_LENGTH) {
+                throw new IllegalArgumentException("Page length " + length
+                        + " exceeds maximum value " + PDU_BODY_PAGE_LENGTH);
             }
 
-            StringBuilder sb = new StringBuilder();
-
-            for (int i = 0; i < nrPages; i++) {
-                // Each page is 82 bytes followed by a length octet indicating
-                // the number of useful octets within those 82
-                int offset = SmsCbHeader.PDU_HEADER_LENGTH + 1 + (PDU_BODY_PAGE_LENGTH + 1) * i;
-                int length = pdu[offset + PDU_BODY_PAGE_LENGTH];
-
-                if (length > PDU_BODY_PAGE_LENGTH) {
-                    throw new IllegalArgumentException("Page length " + length
-                            + " exceeds maximum value " + PDU_BODY_PAGE_LENGTH);
-                }
-
-                Pair<String, String> p = unpackBody(pdu, encoding, offset, length,
-                        hasLanguageIndicator, language);
-                language = p.first;
-                sb.append(p.second);
-            }
-            return new Pair<String, String>(language, sb.toString());
-        } else {
-            // Payload is one single page
-            int offset = SmsCbHeader.PDU_HEADER_LENGTH;
-            int length = pdu.length - offset;
-
-            return unpackBody(pdu, encoding, offset, length, hasLanguageIndicator, language);
+            Pair<String, String> p = unpackBody(pdu, offset, length,
+                    header.getDataCodingSchemeStructedData());
+            language = p.first;
+            sb.append(p.second);
         }
+        return new Pair(language, sb.toString());
+
     }
 
     /**
-     * Unpack body text from the pdu using the given encoding, position and
-     * length within the pdu
+     * Parse and unpack the GSM body text according to the encoding in the data coding scheme.
+     * @param header the message header to use
+     * @param pdu the PDU to decode
+     * @return a pair of string containing the language and body of the message in order
+     */
+    private static Pair<String, String> parseGsmBody(SmsCbHeader header, byte[] pdu) {
+        // Payload is one single page
+        int offset = SmsCbHeader.PDU_HEADER_LENGTH;
+        int length = pdu.length - offset;
+        return unpackBody(pdu, offset, length, header.getDataCodingSchemeStructedData());
+    }
+
+    /**
+     * Unpack body text from the pdu using the given encoding, position and length within the pdu.
      *
      * @param pdu The pdu
-     * @param encoding The encoding, as derived from the DCS
      * @param offset Position of the first byte to unpack
      * @param length Number of bytes to unpack
-     * @param hasLanguageIndicator true if the body text is preceded by a
-     *            language indicator. If so, this method will as a side-effect
-     *            assign the extracted language code into mLanguage
-     * @param language the language to return if hasLanguageIndicator is false
+     * @param dcs data coding scheme
      * @return a Pair of Strings containing the language and body of the message
      */
-    private static Pair<String, String> unpackBody(byte[] pdu, int encoding, int offset, int length,
-            boolean hasLanguageIndicator, String language) {
+    private static Pair<String, String> unpackBody(byte[] pdu, int offset, int length,
+            DataCodingScheme dcs) {
         String body = null;
 
-        switch (encoding) {
+        String language = dcs.language;
+        switch (dcs.encoding) {
             case SmsConstants.ENCODING_7BIT:
                 body = GsmAlphabet.gsm7BitPackedToString(pdu, offset, length * 8 / 7);
 
-                if (hasLanguageIndicator && body != null && body.length() > 2) {
+                if (dcs.hasLanguageIndicator && body != null && body.length() > 2) {
                     // Language is two GSM characters followed by a CR.
                     // The actual body text is offset by 3 characters.
                     language = body.substring(0, 2);
@@ -296,7 +363,7 @@
                 break;
 
             case SmsConstants.ENCODING_16BIT:
-                if (hasLanguageIndicator && pdu.length >= offset + 2) {
+                if (dcs.hasLanguageIndicator && pdu.length >= offset + 2) {
                     // Language is two GSM characters.
                     // The actual body text is offset by 2 bytes.
                     language = GsmAlphabet.gsm7BitPackedToString(pdu, offset, 2);
@@ -330,4 +397,105 @@
 
         return new Pair<String, String>(language, body);
     }
+
+    /** A class use to facilitate the processing of bits stream data. */
+    private static final class BitStreamReader {
+        /** The bits stream represent by a bytes array. */
+        private final byte[] mData;
+
+        /** The offset of the current byte. */
+        private int mCurrentOffset;
+
+        /**
+         * The remained bits of the current byte which have not been read. The most significant
+         * will be read first, so the remained bits are always the least significant bits.
+         */
+        private int mRemainedBit;
+
+        /**
+         * Constructor
+         * @param data bit stream data represent by byte array.
+         * @param offset the offset of the first byte.
+         */
+        BitStreamReader(byte[] data, int offset) {
+            mData = data;
+            mCurrentOffset = offset;
+            mRemainedBit = 8;
+        }
+
+        /**
+         * Read the first {@code count} bits.
+         * @param count the number of bits need to read
+         * @return {@code bits} represent by an 32-bits integer, therefore {@code count} must be no
+         * greater than 32.
+         */
+        public int read(int count) throws IndexOutOfBoundsException {
+            int val = 0;
+            while (count > 0) {
+                if (count >= mRemainedBit) {
+                    val <<= mRemainedBit;
+                    val |= mData[mCurrentOffset] & ((1 << mRemainedBit) - 1);
+                    count -= mRemainedBit;
+                    mRemainedBit = 8;
+                    ++mCurrentOffset;
+                } else {
+                    val <<= count;
+                    val |= (mData[mCurrentOffset] & ((1 << mRemainedBit) - 1))
+                            >> (mRemainedBit - count);
+                    mRemainedBit -= count;
+                    count = 0;
+                }
+            }
+            return val;
+        }
+
+        /**
+         * Skip the current bytes if the remained bits is less than 8. This is useful when
+         * processing the padding or reserved bits.
+         */
+        public void skip() {
+            if (mRemainedBit < 8) {
+                mRemainedBit = 8;
+                ++mCurrentOffset;
+            }
+        }
+    }
+
+    static final class GeoFencingTriggerMessage {
+        /**
+         * Indicate the list of active alerts share their warning area coordinates which means the
+         * broadcast area is the union of the broadcast areas of the active alerts in this list.
+         */
+        public static final int TYPE_ACTIVE_ALERT_SHARE_WAC = 2;
+
+        public final int type;
+        public final List<CellBroadcastIdentity> cbIdentifiers;
+
+        GeoFencingTriggerMessage(int type, @NonNull List<CellBroadcastIdentity> cbIdentifiers) {
+            this.type = type;
+            this.cbIdentifiers = cbIdentifiers;
+        }
+
+        boolean shouldShareBroadcastArea() {
+            return type == TYPE_ACTIVE_ALERT_SHARE_WAC;
+        }
+
+        static final class CellBroadcastIdentity {
+            public final int messageIdentifier;
+            public final int serialNumber;
+            CellBroadcastIdentity(int messageIdentifier, int serialNumber) {
+                this.messageIdentifier = messageIdentifier;
+                this.serialNumber = serialNumber;
+            }
+        }
+
+        @Override
+        public String toString() {
+            String identifiers = cbIdentifiers.stream()
+                    .map(cbIdentifier ->String.format("(msgId = %d, serial = %d)",
+                            cbIdentifier.messageIdentifier, cbIdentifier.serialNumber))
+                    .collect(Collectors.joining(","));
+            return "triggerType=" + type + " identifiers=" + identifiers;
+        }
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
index 541ca8d..5ad2b9d 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
@@ -215,9 +215,11 @@
     public static final int MESSAGE_ID_CMAS_ALERT_STATE_LOCAL_TEST_LANGUAGE
             = 0x112F; // 4399
 
-    /** End of CMAS Message Identifier range (including future extensions). */
-    public static final int MESSAGE_ID_CMAS_LAST_IDENTIFIER
-            = 0x112F; // 4399
+    /** CMAS Message Identifier for CMAS geo fencing trigger message. */
+    public static final int MESSAGE_ID_CMAS_GEO_FENCING_TRIGGER = 0x1130; // 4440
+
+    /** End of CMAS Message Identifier range. */
+    public static final int MESSAGE_ID_CMAS_LAST_IDENTIFIER = MESSAGE_ID_CMAS_GEO_FENCING_TRIGGER;
 
     /** End of PWS Message Identifier range (includes ETWS, CMAS, and future extensions). */
     public static final int MESSAGE_ID_PWS_LAST_IDENTIFIER
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java
index 0dbc186..acdc838 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java
@@ -19,7 +19,10 @@
 import android.telephony.SmsCbCmasInfo;
 import android.telephony.SmsCbEtwsInfo;
 
+import com.android.internal.telephony.SmsConstants;
+
 import java.util.Arrays;
+import java.util.Locale;
 
 /**
  * Parses a 3GPP TS 23.041 cell broadcast message header. This class is public for use by
@@ -32,6 +35,39 @@
  * The raw PDU is no longer sent to SMS CB applications.
  */
 public class SmsCbHeader {
+    /**
+     * Languages in the 0000xxxx DCS group as defined in 3GPP TS 23.038, section 5.
+     */
+    private static final String[] LANGUAGE_CODES_GROUP_0 = {
+            Locale.GERMAN.getLanguage(),        // German
+            Locale.ENGLISH.getLanguage(),       // English
+            Locale.ITALIAN.getLanguage(),       // Italian
+            Locale.FRENCH.getLanguage(),        // French
+            new Locale("es").getLanguage(),     // Spanish
+            new Locale("nl").getLanguage(),     // Dutch
+            new Locale("sv").getLanguage(),     // Swedish
+            new Locale("da").getLanguage(),     // Danish
+            new Locale("pt").getLanguage(),     // Portuguese
+            new Locale("fi").getLanguage(),     // Finnish
+            new Locale("nb").getLanguage(),     // Norwegian
+            new Locale("el").getLanguage(),     // Greek
+            new Locale("tr").getLanguage(),     // Turkish
+            new Locale("hu").getLanguage(),     // Hungarian
+            new Locale("pl").getLanguage(),     // Polish
+            null
+    };
+
+    /**
+     * Languages in the 0010xxxx DCS group as defined in 3GPP TS 23.038, section 5.
+     */
+    private static final String[] LANGUAGE_CODES_GROUP_2 = {
+            new Locale("cs").getLanguage(),     // Czech
+            new Locale("he").getLanguage(),     // Hebrew
+            new Locale("ar").getLanguage(),     // Arabic
+            new Locale("ru").getLanguage(),     // Russian
+            new Locale("is").getLanguage(),     // Icelandic
+            null, null, null, null, null, null, null, null, null, null, null
+    };
 
     /**
      * Length of SMS-CB header
@@ -84,6 +120,8 @@
 
     private final int mFormat;
 
+    private DataCodingScheme mDataCodingSchemeStructedData;
+
     /** ETWS warning notification info. */
     private final SmsCbEtwsInfo mEtwsInfo;
 
@@ -162,6 +200,10 @@
             mNrOfPages = 1;
         }
 
+        if (mDataCodingScheme != -1) {
+            mDataCodingSchemeStructedData = new DataCodingScheme(mDataCodingScheme);
+        }
+
         if (isEtwsMessage()) {
             boolean emergencyUserAlert = isEtwsEmergencyUserAlert();
             boolean activatePopup = isEtwsPopupAlert();
@@ -199,6 +241,10 @@
         return mDataCodingScheme;
     }
 
+    DataCodingScheme getDataCodingSchemeStructedData() {
+        return mDataCodingSchemeStructedData;
+    }
+
     int getPageIndex() {
         return mPageIndex;
     }
@@ -448,4 +494,93 @@
                 + ", DCS=0x" + Integer.toHexString(mDataCodingScheme)
                 + ", page " + mPageIndex + " of " + mNrOfPages + '}';
     }
+
+    /**
+     * CBS Data Coding Scheme.
+     * Reference: 3GPP TS 23.038 version 15.0.0 section #5, CBS Data Coding Scheme
+     */
+    public static final class DataCodingScheme {
+        public final int encoding;
+        public final String language;
+        public final boolean hasLanguageIndicator;
+
+        public DataCodingScheme(int dataCodingScheme) {
+            int encoding = 0;
+            String language = null;
+            boolean hasLanguageIndicator = false;
+
+            // Extract encoding and language from DCS, as defined in 3gpp TS 23.038,
+            // section 5.
+            switch ((dataCodingScheme & 0xf0) >> 4) {
+                case 0x00:
+                    encoding = SmsConstants.ENCODING_7BIT;
+                    language = LANGUAGE_CODES_GROUP_0[dataCodingScheme & 0x0f];
+                    break;
+
+                case 0x01:
+                    hasLanguageIndicator = true;
+                    if ((dataCodingScheme & 0x0f) == 0x01) {
+                        encoding = SmsConstants.ENCODING_16BIT;
+                    } else {
+                        encoding = SmsConstants.ENCODING_7BIT;
+                    }
+                    break;
+
+                case 0x02:
+                    encoding = SmsConstants.ENCODING_7BIT;
+                    language = LANGUAGE_CODES_GROUP_2[dataCodingScheme & 0x0f];
+                    break;
+
+                case 0x03:
+                    encoding = SmsConstants.ENCODING_7BIT;
+                    break;
+
+                case 0x04:
+                case 0x05:
+                    switch ((dataCodingScheme & 0x0c) >> 2) {
+                        case 0x01:
+                            encoding = SmsConstants.ENCODING_8BIT;
+                            break;
+
+                        case 0x02:
+                            encoding = SmsConstants.ENCODING_16BIT;
+                            break;
+
+                        case 0x00:
+                        default:
+                            encoding = SmsConstants.ENCODING_7BIT;
+                            break;
+                    }
+                    break;
+
+                case 0x06:
+                case 0x07:
+                    // Compression not supported
+                case 0x09:
+                    // UDH structure not supported
+                case 0x0e:
+                    // Defined by the WAP forum not supported
+                    throw new IllegalArgumentException("Unsupported GSM dataCodingScheme "
+                            + dataCodingScheme);
+
+                case 0x0f:
+                    if (((dataCodingScheme & 0x04) >> 2) == 0x01) {
+                        encoding = SmsConstants.ENCODING_8BIT;
+                    } else {
+                        encoding = SmsConstants.ENCODING_7BIT;
+                    }
+                    break;
+
+                default:
+                    // Reserved values are to be treated as 7-bit
+                    encoding = SmsConstants.ENCODING_7BIT;
+                    break;
+            }
+
+
+            this.encoding = encoding;
+            this.language = language;
+            this.hasLanguageIndicator = hasLanguageIndicator;
+        }
+    }
 }
\ No newline at end of file
diff --git a/tests/testables/src/android/testing/DexmakerShareClassLoaderRule.java b/tests/testables/src/android/testing/DexmakerShareClassLoaderRule.java
index 1b8e58c..7057a90 100644
--- a/tests/testables/src/android/testing/DexmakerShareClassLoaderRule.java
+++ b/tests/testables/src/android/testing/DexmakerShareClassLoaderRule.java
@@ -20,6 +20,8 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 
+import libcore.util.SneakyThrow;
+
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
@@ -55,7 +57,11 @@
      * WARNING: This is absolutely incompatible with running tests in parallel!
      */
     public static void runWithDexmakerShareClassLoader(Runnable r) {
-        apply(r::run).run();
+        try {
+            apply(r::run).run();
+        } catch (Throwable t) {
+            SneakyThrow.sneakyThrow(t);
+        }
     }
 
     /**
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index f540492..0f09ccb 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1752,12 +1752,13 @@
     }
 
     /**
-     * Remove the Passpoint configuration identified by its FQDN (Fully Qualified Domain Name).
+     * Remove the Passpoint configuration identified by its FQDN (Fully Qualified Domain Name) added
+     * by the caller.
      *
-     * @param fqdn The FQDN of the Passpoint configuration to be removed
+     * @param fqdn The FQDN of the Passpoint configuration added by the caller to be removed
      * @throws IllegalArgumentException if no configuration is associated with the given FQDN or
      *                                  Passpoint is not enabled on the device.
-     * @deprecated This is no longer supported.
+     * @deprecated This will be non-functional in a future release.
      */
     @Deprecated
     @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
@@ -1772,12 +1773,12 @@
     }
 
     /**
-     * Return the list of installed Passpoint configurations.
+     * Return the list of installed Passpoint configurations added by the caller.
      *
      * An empty list will be returned when no configurations are installed.
      *
-     * @return A list of {@link PasspointConfiguration}
-     * @deprecated This is no longer supported.
+     * @return A list of {@link PasspointConfiguration} added by the caller
+     * @deprecated This will be non-functional in a future release.
      */
     @Deprecated
     @RequiresPermission(anyOf = {