Merge "Treat R8 warnings as failures for system_server" am: 1f440e7a62 am: df2014cba1 am: 62fadfafd0

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2209838

Change-Id: I0b4efd58a380853842ec33fb2b7eb33c280155d8
Signed-off-by: Automerger Merge Worker <[email protected]>
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 07fbde5..4188a7ef 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import static android.Manifest.permission.CONTROL_KEYGUARD;
 import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
@@ -371,9 +372,8 @@
     private static final String KEY_LAUNCH_INTO_PIP_PARAMS =
             "android.activity.launchIntoPipParams";
 
-    /** See {@link #setDismissKeyguardIfInsecure()}. */
-    private static final String KEY_DISMISS_KEYGUARD_IF_INSECURE =
-            "android.activity.dismissKeyguardIfInsecure";
+    /** See {@link #setDismissKeyguard()}. */
+    private static final String KEY_DISMISS_KEYGUARD = "android.activity.dismissKeyguard";
 
     private static final String KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE =
             "android.activity.ignorePendingIntentCreatorForegroundState";
@@ -475,7 +475,7 @@
     private boolean mLaunchedFromBubble;
     private boolean mTransientLaunch;
     private PictureInPictureParams mLaunchIntoPipParams;
-    private boolean mDismissKeyguardIfInsecure;
+    private boolean mDismissKeyguard;
     private boolean mIgnorePendingIntentCreatorForegroundState;
 
     /**
@@ -1282,7 +1282,7 @@
         mLaunchIntoPipParams = opts.getParcelable(KEY_LAUNCH_INTO_PIP_PARAMS);
         mIsEligibleForLegacyPermissionPrompt =
                 opts.getBoolean(KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE);
-        mDismissKeyguardIfInsecure = opts.getBoolean(KEY_DISMISS_KEYGUARD_IF_INSECURE);
+        mDismissKeyguard = opts.getBoolean(KEY_DISMISS_KEYGUARD);
         mIgnorePendingIntentCreatorForegroundState = opts.getBoolean(
                 KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE);
     }
@@ -1903,24 +1903,24 @@
     }
 
     /**
-     * Sets whether the insecure keyguard should go away when this activity launches. In case the
-     * keyguard is secure, this option will be ignored.
+     * Sets whether the keyguard should go away when this activity launches.
      *
      * @see Activity#setShowWhenLocked(boolean)
      * @see android.R.attr#showWhenLocked
      * @hide
      */
-    public void setDismissKeyguardIfInsecure() {
-        mDismissKeyguardIfInsecure = true;
+    @RequiresPermission(CONTROL_KEYGUARD)
+    public void setDismissKeyguard() {
+        mDismissKeyguard = true;
     }
 
     /**
-     * @see #setDismissKeyguardIfInsecure()
+     * @see #setDismissKeyguard()
      * @return whether the insecure keyguard should go away when the activity launches.
      * @hide
      */
-    public boolean getDismissKeyguardIfInsecure() {
-        return mDismissKeyguardIfInsecure;
+    public boolean getDismissKeyguard() {
+        return mDismissKeyguard;
     }
 
     /**
@@ -2204,8 +2204,8 @@
             b.putBoolean(KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE,
                     mIsEligibleForLegacyPermissionPrompt);
         }
-        if (mDismissKeyguardIfInsecure) {
-            b.putBoolean(KEY_DISMISS_KEYGUARD_IF_INSECURE, mDismissKeyguardIfInsecure);
+        if (mDismissKeyguard) {
+            b.putBoolean(KEY_DISMISS_KEYGUARD, mDismissKeyguard);
         }
         if (mIgnorePendingIntentCreatorForegroundState) {
             b.putBoolean(KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE,
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java
index 691690c..5b1973a 100644
--- a/core/java/android/hardware/camera2/CameraCaptureSession.java
+++ b/core/java/android/hardware/camera2/CameraCaptureSession.java
@@ -1234,6 +1234,42 @@
         }
 
         /**
+         * This method is called when the camera device has started reading out the output
+         * image for the request, at the beginning of the sensor image readout.
+         *
+         * <p>For a capture request, this callback is invoked right after
+         * {@link #onCaptureStarted}. Unlike {@link #onCaptureStarted}, instead of passing
+         * a timestamp of start of exposure, this callback passes a timestamp of start of
+         * camera data readout. This is useful because for a camera running at fixed frame
+         * rate, the start of readout is at fixed interval, which is not necessarily true for
+         * the start of exposure, particularly when autoexposure is changing exposure duration
+         * between frames.</p>
+         *
+         * <p>This timestamp may not match {@link CaptureResult#SENSOR_TIMESTAMP the result
+         * timestamp field}. It will, however, match the timestamp of buffers sent to the
+         * output surfaces with {@link OutputConfiguration#TIMESTAMP_BASE_READOUT_SENSOR}
+         * timestamp base.</p>
+         *
+         * <p>This callback will be called only if {@link
+         * CameraCharacteristics#SENSOR_READOUT_TIMESTAMP} is
+         * {@link CameraMetadata#SENSOR_READOUT_TIMESTAMP_HARDWARE}, and it's called
+         * right after {@link #onCaptureStarted}.</p>
+         *
+         * @param session the session returned by {@link CameraDevice#createCaptureSession}
+         * @param request the request for the readout that just began
+         * @param timestamp the timestamp at start of readout for a regular request, or
+         *                  the timestamp at the input image's start of readout for a
+         *                  reprocess request, in nanoseconds.
+         * @param frameNumber the frame number for this capture
+         *
+         * @hide
+         */
+        public void onReadoutStarted(@NonNull CameraCaptureSession session,
+                @NonNull CaptureRequest request, long timestamp, long frameNumber) {
+            // default empty implementation
+        }
+
+        /**
          * This method is called when some results from an image capture are
          * available.
          *
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 98a8cbd..861a850 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -1326,6 +1326,10 @@
      * {@link android.hardware.camera2.CameraManager#turnOnTorchWithStrengthLevel }.
      * If this value is equal to 1, flashlight brightness control is not supported.
      * The value for this key will be null for devices with no flash unit.</p>
+     * <p>The maximum value is guaranteed to be safe to use for an indefinite duration in
+     * terms of device flashlight lifespan, but may be too bright for comfort for many
+     * use cases. Use the default torch brightness value to avoid problems with an
+     * over-bright flashlight.</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      */
     @PublicKey
@@ -4415,6 +4419,40 @@
             new Key<android.graphics.Rect[]>("android.sensor.opticalBlackRegions", android.graphics.Rect[].class);
 
     /**
+     * <p>Whether or not the camera device supports readout timestamp and
+     * onReadoutStarted callback.</p>
+     * <p>If this tag is HARDWARE, the camera device calls onReadoutStarted in addition to the
+     * onCaptureStarted callback for each capture. The timestamp passed into the callback
+     * is the start of camera image readout rather than the start of the exposure. In
+     * addition, the application can configure an
+     * {@link android.hardware.camera2.params.OutputConfiguration } with
+     * TIMESTAMP_BASE_READOUT_SENSOR timestamp base, in which case, the timestamp of the
+     * output surface matches the timestamp from the corresponding onReadoutStarted callback.</p>
+     * <p>The readout timestamp is beneficial for video recording, because the encoder favors
+     * uniform timestamps, and the readout timestamps better reflect the cadence camera sensors
+     * output data.</p>
+     * <p>If this tag is HARDWARE, the camera device produces the start-of-exposure and
+     * start-of-readout together. As a result, the onReadoutStarted is called right after
+     * onCaptureStarted. The difference in start-of-readout and start-of-exposure is the sensor
+     * exposure time, plus certain constant offset. The offset is usually due to camera sensor
+     * level crop, and it remains constant for a given camera sensor mode.</p>
+     * <p><b>Possible values:</b></p>
+     * <ul>
+     *   <li>{@link #SENSOR_READOUT_TIMESTAMP_NOT_SUPPORTED NOT_SUPPORTED}</li>
+     *   <li>{@link #SENSOR_READOUT_TIMESTAMP_HARDWARE HARDWARE}</li>
+     * </ul>
+     *
+     * <p>This key is available on all devices.</p>
+     * @see #SENSOR_READOUT_TIMESTAMP_NOT_SUPPORTED
+     * @see #SENSOR_READOUT_TIMESTAMP_HARDWARE
+     * @hide
+     */
+    @PublicKey
+    @NonNull
+    public static final Key<Integer> SENSOR_READOUT_TIMESTAMP =
+            new Key<Integer>("android.sensor.readoutTimestamp", int.class);
+
+    /**
      * <p>List of lens shading modes for {@link CaptureRequest#SHADING_MODE android.shading.mode} that are supported by this camera device.</p>
      * <p>This list contains lens shading modes that can be set for the camera device.
      * Camera devices that support the MANUAL_POST_PROCESSING capability will always
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index eb8c73a..c67a560 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -1658,6 +1658,28 @@
     public static final int SENSOR_REFERENCE_ILLUMINANT1_ISO_STUDIO_TUNGSTEN = 24;
 
     //
+    // Enumeration values for CameraCharacteristics#SENSOR_READOUT_TIMESTAMP
+    //
+
+    /**
+     * <p>This camera device doesn't support readout timestamp and onReadoutStarted
+     * callback.</p>
+     * @see CameraCharacteristics#SENSOR_READOUT_TIMESTAMP
+     * @hide
+     */
+    public static final int SENSOR_READOUT_TIMESTAMP_NOT_SUPPORTED = 0;
+
+    /**
+     * <p>This camera device supports the onReadoutStarted callback as well as outputting
+     * readout timestamp for streams with TIMESTAMP_BASE_READOUT_SENSOR timestamp base. The
+     * readout timestamp is generated by the camera hardware and it has the same accuracy
+     * and timing characteristics of the start-of-exposure time.</p>
+     * @see CameraCharacteristics#SENSOR_READOUT_TIMESTAMP
+     * @hide
+     */
+    public static final int SENSOR_READOUT_TIMESTAMP_HARDWARE = 1;
+
+    //
     // Enumeration values for CameraCharacteristics#LED_AVAILABLE_LEDS
     //
 
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
index 9a9163c..b9eba9c 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -657,6 +657,21 @@
             }
 
             @Override
+            public void onReadoutStarted(CameraDevice camera,
+                    CaptureRequest request, long timestamp, long frameNumber) {
+                if ((callback != null) && (executor != null)) {
+                    final long ident = Binder.clearCallingIdentity();
+                    try {
+                        executor.execute(() -> callback.onReadoutStarted(
+                                    CameraCaptureSessionImpl.this, request, timestamp,
+                                    frameNumber));
+                    } finally {
+                        Binder.restoreCallingIdentity(ident);
+                    }
+                }
+            }
+
+            @Override
             public void onCapturePartial(CameraDevice camera,
                     CaptureRequest request, android.hardware.camera2.CaptureResult result) {
                 if ((callback != null) && (executor != null)) {
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 3cb0c93..a6c79b3 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -2025,12 +2025,16 @@
                     resultExtras.getLastCompletedReprocessFrameNumber();
             final long lastCompletedZslFrameNumber =
                     resultExtras.getLastCompletedZslFrameNumber();
+            final boolean hasReadoutTimestamp = resultExtras.hasReadoutTimestamp();
+            final long readoutTimestamp = resultExtras.getReadoutTimestamp();
 
             if (DEBUG) {
                 Log.d(TAG, "Capture started for id " + requestId + " frame number " + frameNumber
                         + ": completedRegularFrameNumber " + lastCompletedRegularFrameNumber
                         + ", completedReprocessFrameNUmber " + lastCompletedReprocessFrameNumber
-                        + ", completedZslFrameNumber " + lastCompletedZslFrameNumber);
+                        + ", completedZslFrameNumber " + lastCompletedZslFrameNumber
+                        + ", hasReadoutTimestamp " + hasReadoutTimestamp
+                        + (hasReadoutTimestamp ? ", readoutTimestamp " + readoutTimestamp : "")) ;
             }
             final CaptureCallbackHolder holder;
 
@@ -2082,14 +2086,26 @@
                                                 CameraDeviceImpl.this,
                                                 holder.getRequest(i),
                                                 timestamp - (subsequenceId - i) *
-                                                NANO_PER_SECOND/fpsRange.getUpper(),
+                                                NANO_PER_SECOND / fpsRange.getUpper(),
                                                 frameNumber - (subsequenceId - i));
+                                            if (hasReadoutTimestamp) {
+                                                holder.getCallback().onReadoutStarted(
+                                                    CameraDeviceImpl.this,
+                                                    holder.getRequest(i),
+                                                    readoutTimestamp - (subsequenceId - i) *
+                                                    NANO_PER_SECOND / fpsRange.getUpper(),
+                                                    frameNumber - (subsequenceId - i));
+                                            }
                                         }
                                     } else {
                                         holder.getCallback().onCaptureStarted(
-                                            CameraDeviceImpl.this,
-                                            holder.getRequest(resultExtras.getSubsequenceId()),
+                                            CameraDeviceImpl.this, request,
                                             timestamp, frameNumber);
+                                        if (hasReadoutTimestamp) {
+                                            holder.getCallback().onReadoutStarted(
+                                                CameraDeviceImpl.this, request,
+                                                readoutTimestamp, frameNumber);
+                                        }
                                     }
                                 }
                             }
diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
index 4d0ba63..41822e7 100644
--- a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
@@ -1693,8 +1693,10 @@
                         ((i != idx) || notifyCurrentIndex)) {
                     TotalCaptureResult result = previewMap.valueAt(i).second;
                     Long timestamp = result.get(CaptureResult.SENSOR_TIMESTAMP);
-                    mCaptureResultHandler.onCaptureCompleted(timestamp,
-                            initializeFilteredResults(result));
+                    if (mCaptureResultHandler != null) {
+                        mCaptureResultHandler.onCaptureCompleted(timestamp,
+                                initializeFilteredResults(result));
+                    }
 
                     Log.w(TAG, "Preview frame drop with timestamp: " + previewMap.keyAt(i));
                     final long ident = Binder.clearCallingIdentity();
@@ -1739,6 +1741,20 @@
                     // abruptly.
                     Log.w(TAG, "Output surface likely abandoned, dropping buffer!");
                     img.close();
+                } catch (RuntimeException e) {
+                    // NOTE: This is intended to catch RuntimeException from ImageReader.detachImage
+                    // ImageReader.detachImage is not supposed to throw RuntimeExceptions but the
+                    // bug went unchecked for a few years and now its behavior cannot be changed
+                    // without breaking backwards compatibility.
+
+                    if (!e.getClass().equals(RuntimeException.class)) {
+                        // re-throw any exceptions that aren't base RuntimeException since they are
+                        // coming from elsewhere, and we shouldn't silently drop those.
+                        throw e;
+                    }
+
+                    Log.w(TAG, "Output surface likely abandoned, dropping buffer!");
+                    img.close();
                 }
             }
         }
@@ -1773,9 +1789,23 @@
                 }
                 try {
                     reader.detachImage(img);
-                } catch (Exception e) {
-                    Log.e(TAG,
-                            "Failed to detach image!");
+                } catch (IllegalStateException e) {
+                    Log.e(TAG, "Failed to detach image!");
+                    img.close();
+                    return;
+                } catch (RuntimeException e) {
+                    // NOTE: This is intended to catch RuntimeException from ImageReader.detachImage
+                    // ImageReader.detachImage is not supposed to throw RuntimeExceptions but the
+                    // bug went unchecked for a few years and now its behavior cannot be changed
+                    // without breaking backwards compatibility.
+
+                    if (!e.getClass().equals(RuntimeException.class)) {
+                        // re-throw any exceptions that aren't base RuntimeException since they are
+                        // coming from elsewhere, and we shouldn't silently drop those.
+                        throw e;
+                    }
+
+                    Log.e(TAG, "Failed to detach image!");
                     img.close();
                     return;
                 }
diff --git a/core/java/android/hardware/camera2/impl/CaptureCallback.java b/core/java/android/hardware/camera2/impl/CaptureCallback.java
index 6defe63..b064e6a 100644
--- a/core/java/android/hardware/camera2/impl/CaptureCallback.java
+++ b/core/java/android/hardware/camera2/impl/CaptureCallback.java
@@ -66,6 +66,13 @@
             CaptureRequest request, long timestamp, long frameNumber);
 
     /**
+     * This method is called when the camera device has started reading out the output
+     * image for the request, at the beginning of the sensor image readout.
+     */
+    public abstract void onReadoutStarted(CameraDevice camera,
+            CaptureRequest request, long timestamp, long frameNumber);
+
+    /**
      * This method is called when some results from an image capture are
      * available.
      *
diff --git a/core/java/android/hardware/camera2/impl/CaptureResultExtras.java b/core/java/android/hardware/camera2/impl/CaptureResultExtras.java
index 5d9da73..8bf9498 100644
--- a/core/java/android/hardware/camera2/impl/CaptureResultExtras.java
+++ b/core/java/android/hardware/camera2/impl/CaptureResultExtras.java
@@ -33,6 +33,8 @@
     private long lastCompletedRegularFrameNumber;
     private long lastCompletedReprocessFrameNumber;
     private long lastCompletedZslFrameNumber;
+    private boolean hasReadoutTimestamp;
+    private long readoutTimestamp;
 
     public static final @android.annotation.NonNull Parcelable.Creator<CaptureResultExtras> CREATOR =
             new Parcelable.Creator<CaptureResultExtras>() {
@@ -56,7 +58,8 @@
                                int partialResultCount, int errorStreamId,
                                String errorPhysicalCameraId, long lastCompletedRegularFrameNumber,
                                long lastCompletedReprocessFrameNumber,
-                               long lastCompletedZslFrameNumber) {
+                               long lastCompletedZslFrameNumber, boolean hasReadoutTimestamp,
+                               long readoutTimestamp) {
         this.requestId = requestId;
         this.subsequenceId = subsequenceId;
         this.afTriggerId = afTriggerId;
@@ -68,6 +71,8 @@
         this.lastCompletedRegularFrameNumber = lastCompletedRegularFrameNumber;
         this.lastCompletedReprocessFrameNumber = lastCompletedReprocessFrameNumber;
         this.lastCompletedZslFrameNumber = lastCompletedZslFrameNumber;
+        this.hasReadoutTimestamp = hasReadoutTimestamp;
+        this.readoutTimestamp = readoutTimestamp;
     }
 
     @Override
@@ -93,6 +98,10 @@
         dest.writeLong(lastCompletedRegularFrameNumber);
         dest.writeLong(lastCompletedReprocessFrameNumber);
         dest.writeLong(lastCompletedZslFrameNumber);
+        dest.writeBoolean(hasReadoutTimestamp);
+        if (hasReadoutTimestamp) {
+            dest.writeLong(readoutTimestamp);
+        }
     }
 
     public void readFromParcel(Parcel in) {
@@ -110,6 +119,10 @@
         lastCompletedRegularFrameNumber = in.readLong();
         lastCompletedReprocessFrameNumber = in.readLong();
         lastCompletedZslFrameNumber = in.readLong();
+        hasReadoutTimestamp = in.readBoolean();
+        if (hasReadoutTimestamp) {
+            readoutTimestamp = in.readLong();
+        }
     }
 
     public String getErrorPhysicalCameraId() {
@@ -155,4 +168,12 @@
     public long getLastCompletedZslFrameNumber() {
         return lastCompletedZslFrameNumber;
     }
+
+    public boolean hasReadoutTimestamp() {
+        return hasReadoutTimestamp;
+    }
+
+    public long getReadoutTimestamp() {
+        return readoutTimestamp;
+    }
 }
diff --git a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableArray.java b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableArray.java
index 6cf5d60..598170d 100644
--- a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableArray.java
+++ b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableArray.java
@@ -26,6 +26,10 @@
 
 import java.lang.reflect.Array;
 import java.nio.ByteBuffer;
+import java.nio.DoubleBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.LongBuffer;
 import java.util.ArrayList;
 
 /**
@@ -45,46 +49,49 @@
     private static final boolean DEBUG = false;
 
     private static interface PrimitiveArrayFiller {
-        public void fillPosition(Object arr, int index, ByteBuffer buffer);
+        public void fillArray(Object arr, int size, ByteBuffer buffer);
         static PrimitiveArrayFiller getPrimitiveArrayFiller(Class<?> componentType) {
             if (componentType == int.class) {
                 return new PrimitiveArrayFiller() {
                       @Override
-                      public void fillPosition(Object arr, int index, ByteBuffer buffer) {
-                          int i = buffer.getInt();
-                          Array.setInt(arr, index, i);
+                      public void fillArray(Object arr, int size, ByteBuffer buffer) {
+                          IntBuffer ib = buffer.asIntBuffer().get(int[].class.cast(arr), 0, size);
+                          // Update buffer position since the IntBuffer has independent position.
+                          buffer.position(buffer.position() + ib.position() * Integer.BYTES);
                       }
                 };
             } else if (componentType == float.class) {
                 return new PrimitiveArrayFiller() {
                       @Override
-                      public void fillPosition(Object arr, int index, ByteBuffer buffer) {
-                          float i = buffer.getFloat();
-                          Array.setFloat(arr, index, i);
+                      public void fillArray(Object arr, int size, ByteBuffer buffer) {
+                          FloatBuffer fb =
+                                  buffer.asFloatBuffer().get(float[].class.cast(arr), 0, size);
+                          buffer.position(buffer.position() + fb.position() * Float.BYTES);
                       }
                 };
             } else if (componentType == long.class) {
                 return new PrimitiveArrayFiller() {
                       @Override
-                      public void fillPosition(Object arr, int index, ByteBuffer buffer) {
-                          long i = buffer.getLong();
-                          Array.setLong(arr, index, i);
+                      public void fillArray(Object arr, int size, ByteBuffer buffer) {
+                          LongBuffer lb =
+                                  buffer.asLongBuffer().get(long[].class.cast(arr), 0, size);
+                          buffer.position(buffer.position() + lb.position() * Long.BYTES);
                       }
                 };
             } else if (componentType == double.class) {
                 return new PrimitiveArrayFiller() {
                       @Override
-                      public void fillPosition(Object arr, int index, ByteBuffer buffer) {
-                          double i = buffer.getDouble();
-                          Array.setDouble(arr, index, i);
+                      public void fillArray(Object arr, int size, ByteBuffer buffer) {
+                          DoubleBuffer db =
+                                  buffer.asDoubleBuffer().get(double[].class.cast(arr), 0, size);
+                          buffer.position(buffer.position() + db.position() * Double.BYTES);
                       }
                 };
             } else if (componentType == byte.class) {
                 return new PrimitiveArrayFiller() {
                       @Override
-                      public void fillPosition(Object arr, int index, ByteBuffer buffer) {
-                          byte i = buffer.get();
-                          Array.setByte(arr, index, i);
+                      public void fillArray(Object arr, int size, ByteBuffer buffer) {
+                          buffer.get(byte[].class.cast(arr), 0, size);
                       }
                 };
             }
@@ -93,13 +100,6 @@
         }
     };
 
-    static void unmarshalPrimitiveArray(Object arr, int size, ByteBuffer buffer,
-            PrimitiveArrayFiller filler) {
-        for (int i = 0; i < size; i++) {
-            filler.fillPosition(arr, i, buffer);
-        }
-    }
-
     private class MarshalerArray extends Marshaler<T> {
         private final Class<T> mClass;
         private final Marshaler<?> mComponentMarshaler;
@@ -150,8 +150,8 @@
                 array = Array.newInstance(mComponentClass, arraySize);
                 if (isUnwrappedPrimitiveClass(mComponentClass) &&
                         mComponentClass == getPrimitiveTypeClass(mNativeType)) {
-                    unmarshalPrimitiveArray(array, arraySize, buffer,
-                            PrimitiveArrayFiller.getPrimitiveArrayFiller(mComponentClass));
+                    PrimitiveArrayFiller.getPrimitiveArrayFiller(mComponentClass).fillArray(array,
+                            arraySize, buffer);
                 } else {
                     for (int i = 0; i < arraySize; ++i) {
                         Object elem = mComponentMarshaler.unmarshal(buffer);
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index 4a25177..9e87037 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -245,6 +245,26 @@
      */
     public static final int TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED = 4;
 
+    /**
+     * Timestamp is the start of readout in the same time domain as TIMESTAMP_BASE_SENSOR.
+     *
+     * <p>The start of the camera sensor readout after exposure. For a rolling shutter camera
+     * sensor, the timestamp is typically equal to the start of exposure time +
+     * exposure time + certain fixed offset. The fixed offset could be due to camera sensor
+     * level crop. The benefit of using readout time is that when camera runs in a fixed
+     * frame rate, the timestamp intervals between frames are constant.</p>
+     *
+     * <p>This timestamp is in the same time domain as in TIMESTAMP_BASE_SENSOR, with the exception
+     * that one is start of exposure, and the other is start of readout.</p>
+     *
+     * <p>This timestamp base is supported only if {@link
+     * CameraCharacteristics#SENSOR_READOUT_TIMESTAMP} is
+     * {@link CameraMetadata#SENSOR_READOUT_TIMESTAMP_HARDWARE}.</p>
+     *
+     * @hide
+     */
+    public static final int TIMESTAMP_BASE_READOUT_SENSOR = 5;
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = {"TIMESTAMP_BASE_"}, value =
@@ -252,7 +272,8 @@
          TIMESTAMP_BASE_SENSOR,
          TIMESTAMP_BASE_MONOTONIC,
          TIMESTAMP_BASE_REALTIME,
-         TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED})
+         TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED,
+         TIMESTAMP_BASE_READOUT_SENSOR})
     public @interface TimestampBase {};
 
     /** @hide */
@@ -974,7 +995,7 @@
     public void setTimestampBase(@TimestampBase int timestampBase) {
         // Verify that the value is in range
         if (timestampBase < TIMESTAMP_BASE_DEFAULT ||
-                timestampBase > TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED) {
+                timestampBase > TIMESTAMP_BASE_READOUT_SENSOR) {
             throw new IllegalArgumentException("Not a valid timestamp base value " +
                     timestampBase);
         }
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 31f3b6a..7092e43 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -1363,19 +1363,31 @@
 
             // Consolidate positional feedback to reduce noise during authentication.
             case FACE_ACQUIRED_NOT_DETECTED:
+                return context.getString(R.string.face_acquired_not_detected);
             case FACE_ACQUIRED_TOO_CLOSE:
+                return context.getString(R.string.face_acquired_too_close);
             case FACE_ACQUIRED_TOO_FAR:
+                return context.getString(R.string.face_acquired_too_far);
             case FACE_ACQUIRED_TOO_HIGH:
+                // TODO(b/181269243) Change back once error codes are fixed.
+                return context.getString(R.string.face_acquired_too_low);
             case FACE_ACQUIRED_TOO_LOW:
+                // TODO(b/181269243) Change back once error codes are fixed.
+                return context.getString(R.string.face_acquired_too_high);
             case FACE_ACQUIRED_TOO_RIGHT:
+                // TODO(b/181269243) Change back once error codes are fixed.
+                return context.getString(R.string.face_acquired_too_left);
             case FACE_ACQUIRED_TOO_LEFT:
+                // TODO(b/181269243) Change back once error codes are fixed.
+                return context.getString(R.string.face_acquired_too_right);
             case FACE_ACQUIRED_POOR_GAZE:
-            case FACE_ACQUIRED_PAN_TOO_EXTREME:
-            case FACE_ACQUIRED_TILT_TOO_EXTREME:
-            case FACE_ACQUIRED_ROLL_TOO_EXTREME:
                 return context.getString(R.string.face_acquired_poor_gaze);
-
-            // Provide more detailed feedback for other soft errors.
+            case FACE_ACQUIRED_PAN_TOO_EXTREME:
+                return context.getString(R.string.face_acquired_pan_too_extreme);
+            case FACE_ACQUIRED_TILT_TOO_EXTREME:
+                return context.getString(R.string.face_acquired_tilt_too_extreme);
+            case FACE_ACQUIRED_ROLL_TOO_EXTREME:
+                return context.getString(R.string.face_acquired_roll_too_extreme);
             case FACE_ACQUIRED_INSUFFICIENT:
                 return context.getString(R.string.face_acquired_insufficient);
             case FACE_ACQUIRED_TOO_BRIGHT:
@@ -1394,6 +1406,10 @@
                 return context.getString(R.string.face_acquired_obscured);
             case FACE_ACQUIRED_SENSOR_DIRTY:
                 return context.getString(R.string.face_acquired_sensor_dirty);
+            case FACE_ACQUIRED_DARK_GLASSES_DETECTED:
+                return context.getString(R.string.face_acquired_dark_glasses_detected);
+            case FACE_ACQUIRED_MOUTH_COVERING_DETECTED:
+                return context.getString(R.string.face_acquired_mouth_covering_detected);
 
             // Find and return the appropriate vendor-specific message.
             case FACE_ACQUIRED_VENDOR: {
@@ -1459,11 +1475,13 @@
             case FACE_ACQUIRED_ROLL_TOO_EXTREME:
                 return context.getString(R.string.face_acquired_roll_too_extreme);
             case FACE_ACQUIRED_FACE_OBSCURED:
-            case FACE_ACQUIRED_DARK_GLASSES_DETECTED:
-            case FACE_ACQUIRED_MOUTH_COVERING_DETECTED:
                 return context.getString(R.string.face_acquired_obscured);
             case FACE_ACQUIRED_SENSOR_DIRTY:
                 return context.getString(R.string.face_acquired_sensor_dirty);
+            case FACE_ACQUIRED_DARK_GLASSES_DETECTED:
+                return context.getString(R.string.face_acquired_dark_glasses_detected);
+            case FACE_ACQUIRED_MOUTH_COVERING_DETECTED:
+                return context.getString(R.string.face_acquired_mouth_covering_detected);
             case FACE_ACQUIRED_VENDOR: {
                 String[] msgArray = context.getResources().getStringArray(
                         R.array.face_acquired_vendor);
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 149db319..e373c50 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -116,6 +116,7 @@
     repeated KeyguardOccludedProto keyguard_occluded_states = 2 [deprecated=true];
     optional bool aod_showing = 3;
     repeated KeyguardPerDisplayProto keyguard_per_display = 4;
+    optional bool keyguard_going_away = 5;
 }
 
 message KeyguardOccludedProto {
@@ -132,6 +133,7 @@
     optional bool keyguard_showing = 2;
     optional bool aod_showing = 3;
     optional bool keyguard_occluded = 4;
+    optional bool keyguard_going_away = 5;
 }
 
 /* represents PhoneWindowManager */
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index d1af2cd..7457339 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -2274,11 +2274,9 @@
     <string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> ترجمه شد."</string>
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"پیام از <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> به <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> ترجمه شد."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"فعالیت در پس‌زمینه"</string>
-    <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
-    <skip />
+    <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"برنامه‌ای شارژ باتری را خالی می‌کند"</string>
     <string name="notification_title_long_running_fgs" msgid="8170284286477131587">"یکی از برنامه‌ها همچنان فعال است"</string>
-    <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
-    <skip />
+    <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"<xliff:g id="APP">%1$s</xliff:g> در پس‌زمینه درحال اجرا است. برای مدیریت مصرف باتری ضربه بزنید."</string>
     <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> ممکن است بر عمر باتری تأثیر بگذارد. برای مرور برنامه‌های فعال، ضربه بزنید."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"بررسی برنامه‌های فعال"</string>
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"نمی‌توان از <xliff:g id="DEVICE">%1$s</xliff:g> شما به دوربین تلفن دسترسی داشت"</string>
diff --git a/core/res/res/values/bools.xml b/core/res/res/values/bools.xml
index fe296c7..5fd9dc0 100644
--- a/core/res/res/values/bools.xml
+++ b/core/res/res/values/bools.xml
@@ -30,4 +30,5 @@
          lockscreen, setting this to true should come with customized drawables. -->
     <bool name="use_lock_pattern_drawable">false</bool>
     <bool name="resolver_landscape_phone">true</bool>
+    <bool name="system_server_plays_face_haptics">true</bool>
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 2215c26..4c0178a 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1786,45 +1786,57 @@
     <string name="fingerprint_recalibrate_notification_content">Visit a repair provider.</string>
 
     <!-- Message shown during face acquisition when the face cannot be recognized [CHAR LIMIT=50] -->
-    <string name="face_acquired_insufficient">Couldn\u2019t capture accurate face data. Try again.</string>
+    <string name="face_acquired_insufficient">Can\u2019t create your face model. Try again.</string>
     <!-- Message shown during face acquisition when the image is too bright [CHAR LIMIT=50] -->
     <string name="face_acquired_too_bright">Too bright. Try gentler lighting.</string>
     <!-- Message shown during face acquisition when the image is too dark [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_dark">Too dark. Try brighter lighting.</string>
+    <string name="face_acquired_too_dark">Try brighter lighting</string>
     <!-- Message shown during face acquisition when the user is too close to sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_close">Move phone farther away.</string>
+    <string name="face_acquired_too_close">Move phone farther away</string>
     <!-- Message shown during face acquisition when the user is too far from sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_far">Move phone closer.</string>
+    <string name="face_acquired_too_far">Move phone closer</string>
     <!-- Message shown during face acquisition when the user is too high relatively to sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_high">Move phone higher.</string>
+    <string name="face_acquired_too_high">Move phone higher</string>
     <!-- Message shown during face acquisition when the user is too low relatively to sensor [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_low">Move phone lower.</string>
+    <string name="face_acquired_too_low">Move phone lower</string>
     <!-- Message shown during face acquisition when only the right part of the user's face was detected [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_right">Move phone to the left.</string>
+    <string name="face_acquired_too_right">Move phone to your left</string>
     <!-- Message shown during face acquisition when only the left part of the user's face was detected [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_left">Move phone to the right.</string>
+    <string name="face_acquired_too_left">Move phone to your right</string>
     <!-- Message shown during face acquisition when the user is not front facing the sensor [CHAR LIMIT=50] -->
     <string name="face_acquired_poor_gaze">Please look more directly at your device.</string>
-    <!-- Message shown during face acquisition when the user is not detected [CHAR LIMIT=50] -->
-    <string name="face_acquired_not_detected">Position your face directly in front of the phone.</string>
+    <!-- Message shown during face acquisition when the user is not detected [CHAR LIMIT=75] -->
+    <string name="face_acquired_not_detected">Can\u2019t see your face. Hold your phone at eye level.</string>
     <!-- Message shown during face acquisition when the device is not steady [CHAR LIMIT=50] -->
     <string name="face_acquired_too_much_motion">Too much motion. Hold phone steady.</string>
     <!-- Message shown during face acquisition when the sensor needs to be recalibrated [CHAR LIMIT=50] -->
     <string name="face_acquired_recalibrate">Please re-enroll your face.</string>
     <!-- Message shown during face enrollment when a different person's face is detected [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_different">No longer able to recognize face. Try again.</string>
+    <string name="face_acquired_too_different">Can\u2019t recognize face. Try again.</string>
     <!-- Message shown during face enrollment when the face is too similar to a previous acquisition [CHAR LIMIT=50] -->
-    <string name="face_acquired_too_similar">Too similar, please change your pose.</string>
+    <string name="face_acquired_too_similar">Change the position of your head slightly</string>
     <!-- Message shown during acqusition when the user's face is turned too far left or right [CHAR LIMIT=50] -->
-    <string name="face_acquired_pan_too_extreme">Turn your head a little less.</string>
+    <string name="face_acquired_pan_too_extreme">Look more directly at your phone</string>
     <!-- Message shown during acqusition when the user's face is tilted too high or too low [CHAR LIMIT=50] -->
-    <string name="face_acquired_tilt_too_extreme">Tilt your head a little less.</string>
+    <string name="face_acquired_tilt_too_extreme">Look more directly at your phone</string>
     <!-- Message shown during acquisiton when the user's face is tilted too far left or right [CHAR LIMIT=50] -->
-    <string name="face_acquired_roll_too_extreme">Turn your head a little less.</string>
+    <string name="face_acquired_roll_too_extreme">Look more directly at your phone</string>
     <!-- Message shown during acquisition when the user's face is obscured [CHAR LIMIT=50] -->
     <string name="face_acquired_obscured">Remove anything hiding your face.</string>
     <!-- Message shown during acquisition when the sensor is dirty [CHAR LIMIT=100] -->
     <string name="face_acquired_sensor_dirty">Clean the top of your screen, including the black bar</string>
+    <!-- Message shown during acquisition when dark glasses were detected [CHAR LIMIT=75] -->
+    <string name="face_acquired_dark_glasses_detected">Your face must be fully visible</string>
+    <!-- Message shown during acquisition when a mouth covering was detected [CHAR LIMIT=75] -->
+    <string name="face_acquired_mouth_covering_detected">Your face must be fully visible</string>
+
+    <!-- Message shown during face acquisition when the sensor needs to be recalibrated [CHAR LIMIT=75] -->
+    <string name="face_acquired_recalibrate_alt">Can\u2019t create your face model. Try again.</string>
+    <!-- Message shown during acquisition when dark glasses were detected [CHAR LIMIT=100] -->
+    <string name="face_acquired_dark_glasses_detected_alt">Dark glasses detected. Your face must be fully visible.</string>
+    <!-- Message shown during acquisition when a mouth covering was detected [CHAR LIMIT=100] -->
+    <string name="face_acquired_mouth_covering_detected_alt">Face covering detected. Your face must be fully visible.</string>
+
     <!-- Array containing custom messages shown during face acquisition from vendor.  Vendor is expected to add and translate these strings -->
     <string-array name="face_acquired_vendor">
     </string-array>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3867723..69c7bf1 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2646,6 +2646,11 @@
   <java-symbol type="string" name="face_acquired_roll_too_extreme" />
   <java-symbol type="string" name="face_acquired_obscured" />
   <java-symbol type="string" name="face_acquired_sensor_dirty" />
+  <java-symbol type="string" name="face_acquired_dark_glasses_detected" />
+  <java-symbol type="string" name="face_acquired_mouth_covering_detected" />
+  <java-symbol type="string" name="face_acquired_recalibrate_alt" />
+  <java-symbol type="string" name="face_acquired_dark_glasses_detected_alt" />
+  <java-symbol type="string" name="face_acquired_mouth_covering_detected_alt" />
   <java-symbol type="array" name="face_acquired_vendor" />
   <java-symbol type="string" name="face_name_template" />
   <java-symbol type="string" name="face_app_setting_name" />
@@ -4787,4 +4792,6 @@
   <java-symbol type="id" name="language_picker_header" />
 
   <java-symbol type="dimen" name="status_bar_height_default" />
+
+  <java-symbol type="bool" name="system_server_plays_face_haptics" />
 </resources>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index c94455d..bae2357 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -211,24 +211,24 @@
 
     /** Applies new configuration, returns {@code false} if there's no effect to the layout. */
     public boolean updateConfiguration(Configuration configuration) {
-        // Always update configuration after orientation changed to make sure to render divider bar
-        // with proper resources that matching screen orientation.
-        final int orientation = configuration.orientation;
-        if (mOrientation != orientation) {
-            mContext = mContext.createConfigurationContext(configuration);
-            mSplitWindowManager.setConfiguration(configuration);
-            mOrientation = orientation;
-        }
-
         // Update the split bounds when necessary. Besides root bounds changed, split bounds need to
         // be updated when the rotation changed to cover the case that users rotated the screen 180
         // degrees.
+        // Make sure to render the divider bar with proper resources that matching the screen
+        // orientation.
         final int rotation = configuration.windowConfiguration.getRotation();
         final Rect rootBounds = configuration.windowConfiguration.getBounds();
-        if (mRotation == rotation && mRootBounds.equals(rootBounds)) {
+        final int orientation = configuration.orientation;
+
+        if (mOrientation == orientation
+                && mRotation == rotation
+                && mRootBounds.equals(rootBounds)) {
             return false;
         }
 
+        mContext = mContext.createConfigurationContext(configuration);
+        mSplitWindowManager.setConfiguration(configuration);
+        mOrientation = orientation;
         mTempRect.set(mRootBounds);
         mRootBounds.set(rootBounds);
         mRotation = rotation;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index dad261a..4b1e5f8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -542,24 +542,44 @@
             mMenuController.attachPipMenuView();
             // Calculate the snap fraction of the current stack along the old movement bounds
             final PipSnapAlgorithm pipSnapAlgorithm = mPipBoundsAlgorithm.getSnapAlgorithm();
-            final Rect postChangeStackBounds = new Rect(mPipBoundsState.getBounds());
-            final float snapFraction = pipSnapAlgorithm.getSnapFraction(postChangeStackBounds,
-                    mPipBoundsAlgorithm.getMovementBounds(postChangeStackBounds),
+            final Rect postChangeBounds = new Rect(mPipBoundsState.getBounds());
+            final float snapFraction = pipSnapAlgorithm.getSnapFraction(postChangeBounds,
+                    mPipBoundsAlgorithm.getMovementBounds(postChangeBounds),
                     mPipBoundsState.getStashedState());
 
+            // Scale PiP on density dpi change, so it appears to be the same size physically.
+            final boolean densityDpiChanged = mPipBoundsState.getDisplayLayout().densityDpi() != 0
+                    && (mPipBoundsState.getDisplayLayout().densityDpi() != layout.densityDpi());
+            if (densityDpiChanged) {
+                final float scale = (float) layout.densityDpi()
+                        / mPipBoundsState.getDisplayLayout().densityDpi();
+                postChangeBounds.set(0, 0,
+                        (int) (postChangeBounds.width() * scale),
+                        (int) (postChangeBounds.height() * scale));
+            }
+
             updateDisplayLayout.run();
 
-            // Calculate the stack bounds in the new orientation based on same fraction along the
+            // Calculate the PiP bounds in the new orientation based on same fraction along the
             // rotated movement bounds.
             final Rect postChangeMovementBounds = mPipBoundsAlgorithm.getMovementBounds(
-                    postChangeStackBounds, false /* adjustForIme */);
-            pipSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds,
+                    postChangeBounds, false /* adjustForIme */);
+            pipSnapAlgorithm.applySnapFraction(postChangeBounds, postChangeMovementBounds,
                     snapFraction, mPipBoundsState.getStashedState(),
                     mPipBoundsState.getStashOffset(),
                     mPipBoundsState.getDisplayBounds(),
                     mPipBoundsState.getDisplayLayout().stableInsets());
 
-            mTouchHandler.getMotionHelper().movePip(postChangeStackBounds);
+            if (densityDpiChanged) {
+                // Using PipMotionHelper#movePip directly here may cause race condition since
+                // the app content in PiP mode may or may not be updated for the new density dpi.
+                final int duration = mContext.getResources().getInteger(
+                        R.integer.config_pipEnterAnimationDuration);
+                mPipTaskOrganizer.scheduleAnimateResizePip(
+                        postChangeBounds, duration, null /* updateBoundsCallback */);
+            } else {
+                mTouchHandler.getMotionHelper().movePip(postChangeBounds);
+            }
         } else {
             updateDisplayLayout.run();
         }
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index 190e1cc..fba4249 100644
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -142,6 +142,14 @@
         public int textEncoding;
     }
 
+    /** Callbacks for Emergency call events. */
+    public interface EmergencyCallCallback {
+        /** Callback invoked when an emergency call starts */
+        void onEmergencyCallStart(int subId);
+        /** Callback invoked when an emergency call ends */
+        void onEmergencyCallEnd();
+    }
+
     private class EmergencyCallListener extends TelephonyCallback implements
             TelephonyCallback.OutgoingEmergencyCallListener,
             TelephonyCallback.CallStateListener {
@@ -152,6 +160,7 @@
                 int subscriptionId) {
             mIsInEmergencyCall = true;
             if (DEBUG) Log.d(TAG, "onOutgoingEmergencyCall(): inEmergency = " + getInEmergency());
+            mEmergencyCallCallback.onEmergencyCallStart(subscriptionId);
         }
 
         @Override
@@ -163,6 +172,7 @@
                 if (mIsInEmergencyCall) {
                     mCallEndElapsedRealtimeMillis = SystemClock.elapsedRealtime();
                     mIsInEmergencyCall = false;
+                    mEmergencyCallCallback.onEmergencyCallEnd();
                 }
             }
         }
@@ -180,8 +190,11 @@
      */
     private Notification.Builder mNiNotificationBuilder;
 
+    private final EmergencyCallCallback mEmergencyCallCallback;
+
     public GpsNetInitiatedHandler(Context context,
                                   INetInitiatedListener netInitiatedListener,
+                                  EmergencyCallCallback emergencyCallCallback,
                                   boolean isSuplEsEnabled) {
         mContext = context;
 
@@ -190,6 +203,7 @@
         } else {
             mNetInitiatedListener = netInitiatedListener;
         }
+        mEmergencyCallCallback = emergencyCallCallback;
 
         setSuplEsEnabled(isSuplEsEnabled);
         mLocationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index f9c6121..b4d28d7 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -95,7 +95,7 @@
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Desconectando…"</string>
     <string name="bluetooth_connecting" msgid="5871702668260192755">"Estableciendo conexión…"</string>
     <string name="bluetooth_connected" msgid="8065345572198502293">"Conectado<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_pairing" msgid="4269046942588193600">"Vinculando…"</string>
+    <string name="bluetooth_pairing" msgid="4269046942588193600">"Emparejando…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Conectado a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (sin audio de teléfono)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Conectado (sin audio multimedia) a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Conectado a <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (sin acceso a mensajes)"</string>
@@ -570,7 +570,7 @@
     <string name="user_add_profile_item_title" msgid="3111051717414643029">"Perfil restringido"</string>
     <string name="user_add_user_title" msgid="5457079143694924885">"¿Añadir nuevo usuario?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Puedes compartir este dispositivo si creas más usuarios. Cada uno tendrá su propio espacio y podrá personalizarlo con aplicaciones, un fondo de pantalla y mucho más. Los usuarios también pueden ajustar opciones del dispositivo, como la conexión Wi‑Fi, que afectan a todos los usuarios.\n\nCuando añadas un usuario, tendrá que configurar su espacio.\n\nCualquier usuario puede actualizar aplicaciones de todos los usuarios. Es posible que no se transfieran los servicios y opciones de accesibilidad al nuevo usuario."</string>
-    <string name="user_add_user_message_short" msgid="3295959985795716166">"Al añadir un usuario nuevo, este debe configurar su espacio.\n\nCualquier usuario puede actualizar las aplicaciones del resto de usuarios."</string>
+    <string name="user_add_user_message_short" msgid="3295959985795716166">"Al añadir un usuario nuevo, debe configurar su espacio.\n\nCualquier usuario puede actualizar las aplicaciones del resto de usuarios."</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"¿Configurar usuario ahora?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Asegúrate de que la persona está disponible en este momento para usar el dispositivo y configurar su espacio."</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"¿Quieres configurar un perfil ahora?"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 29376f3..37a6db2 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -589,7 +589,7 @@
     <string name="add_user_failed" msgid="4809887794313944872">"Uue kasutaja loomine ebaõnnestus"</string>
     <string name="add_guest_failed" msgid="8074548434469843443">"Uue külalise loomine ei õnnestunud"</string>
     <string name="user_nickname" msgid="262624187455825083">"Hüüdnimi"</string>
-    <string name="user_add_user" msgid="7876449291500212468">"Kasutaja lisamine"</string>
+    <string name="user_add_user" msgid="7876449291500212468">"Lisa kasutaja"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Lisa külaline"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Eemalda külaline"</string>
     <string name="guest_reset_guest" msgid="6110013010356013758">"Lähtesta külastajaseanss"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 02b78c1..325fdbb 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -570,7 +570,7 @@
     <string name="user_add_profile_item_title" msgid="3111051717414643029">"प्रतिबंधित प्रोफ़ाइल"</string>
     <string name="user_add_user_title" msgid="5457079143694924885">"नया उपयोगकर्ता जोड़ें?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"आप और ज़्यादा उपयोगकर्ता बनाकर इस डिवाइस को दूसरे लोगों के साथ शेयर कर सकते हैं. हर उपयोगकर्ता के पास अपनी जगह होती है, जिसमें वह मनपसंद तरीके से ऐप्लिकेशन, वॉलपेपर और दूसरी चीज़ों में बदलाव कर सकते हैं. उपयोगकर्ता वाई-फ़ाई जैसी डिवाइस सेटिंग में भी बदलाव कर सकते हैं, जिसका असर हर किसी पर पड़ेगा.\n\nजब आप कोई नया उपयोगकर्ता जोड़ते हैं तो उन्हें अपनी जगह सेट करनी होगी.\n\nकोई भी उपयोगकर्ता दूसरे सभी उपयोगकर्ताओं के लिए ऐप्लिकेशन अपडेट कर सकता है. ऐसा भी हो सकता है कि सुलभता सेटिंग और सेवाएं नए उपयोगकर्ता को ट्रांसफ़र न हो पाएं."</string>
-    <string name="user_add_user_message_short" msgid="3295959985795716166">"जब आप कोई नया उपयोगकर्ता जोड़ते हैं, तो उसे अपनी जगह सेट करनी होती है.\n\nकोई भी उपयोगकर्ता बाकी सभी उपयोगकर्ताओं के लिए ऐप्लिकेशन अपडेट कर सकता है."</string>
+    <string name="user_add_user_message_short" msgid="3295959985795716166">"कोई नया उपयोगकर्ता जोड़ने पर, उसे अपनी जगह सेट करनी होती है.\n\nकोई भी उपयोगकर्ता बाकी सभी उपयोगकर्ताओं के लिए ऐप्लिकेशन अपडेट कर सकता है."</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"उपयोगकर्ता को अभी सेट करें?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"पक्का करें कि व्यक्ति डिवाइस का इस्तेमाल करने और अपनी जगह सेट करने के लिए मौजूद है"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"प्रोफ़ाइल अभी सेट करें?"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 2196c75..c50b180 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -594,7 +594,7 @@
     <string name="guest_exit_guest" msgid="5908239569510734136">"הסרת אורח"</string>
     <string name="guest_reset_guest" msgid="6110013010356013758">"איפוס הגלישה כאורח"</string>
     <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"לאפס את הגלישה כאורח?"</string>
-    <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"להסיר את האורח/ת?"</string>
+    <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"להסיר את האורח?"</string>
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"איפוס"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"הסרה"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"מתבצע איפוס של הגלישה כאורח…"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 8af2627..73830c5 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -95,7 +95,7 @@
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Ажыратылууда…"</string>
     <string name="bluetooth_connecting" msgid="5871702668260192755">"Туташууда…"</string>
     <string name="bluetooth_connected" msgid="8065345572198502293">"Туташып турат<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_pairing" msgid="4269046942588193600">"Жупташтырылууда…"</string>
+    <string name="bluetooth_pairing" msgid="4269046942588193600">"Туташууда…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Туташып турат (телефониясыз)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Туташып турат (медиасыз)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Туташып турат (SMS/MMS жазышуусуз)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
@@ -150,7 +150,7 @@
     <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"ЖУПТАШТЫРУУ"</string>
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Жок"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Жупташканда байланыштарыңыз менен чалуу таржымалыңызды пайдалана аласыз."</string>
-    <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> менен жупташуу мүмкүн эмес."</string>
+    <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгүнө туташуу мүмкүн болгон жок."</string>
     <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"PIN-код же сырсөз туура эмес болгондуктан, \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\" түзмөгүнө туташуу мүмкүн болгон жок."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> менен байланышуу мүмкүн эмес."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Жупташтырууну <xliff:g id="DEVICE_NAME">%1$s</xliff:g> четке какты."</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 4006665..5c3578c 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -95,7 +95,7 @@
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"डिस्कनेक्ट करत आहे..."</string>
     <string name="bluetooth_connecting" msgid="5871702668260192755">"कनेक्ट करत आहे..."</string>
     <string name="bluetooth_connected" msgid="8065345572198502293">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>कनेक्ट केले"</string>
-    <string name="bluetooth_pairing" msgid="4269046942588193600">"जोडत आहे…"</string>
+    <string name="bluetooth_pairing" msgid="4269046942588193600">"पेअर करत आहे…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"कनेक्ट केले (फोन नाही)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"कनेक्ट केले (मीडिया नाही)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"कनेक्ट केले (मेसेज अ‍ॅक्सेस नाही)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
@@ -151,7 +151,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"रद्द करा"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"कनेक्‍ट केल्यावर पेअरिंग तुमचे संपर्क आणि कॉल इतिहास यामध्ये अ‍ॅक्सेस देते."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> शी जोडू शकलो नाही."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"अयोग्य पिन किंवा पासकीमुळे <xliff:g id="DEVICE_NAME">%1$s</xliff:g> सह जोडू शकलो नाही."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"अयोग्य पिन किंवा पासकीमुळे <xliff:g id="DEVICE_NAME">%1$s</xliff:g> सह पेअर करू शकलो नाही."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> शी संवाद प्रस्थापित करू शकत नाही."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> द्वारे पेअरिंग नाकारले."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"कॉंप्युटर"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 98bac84..c0aafc4 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -95,7 +95,7 @@
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"အဆက်အသွယ်ဖြတ်တောက်သည်"</string>
     <string name="bluetooth_connecting" msgid="5871702668260192755">"ချိတ်ဆက်နေသည်"</string>
     <string name="bluetooth_connected" msgid="8065345572198502293">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> ချိတ်ဆက်ပြီးပြီ"</string>
-    <string name="bluetooth_pairing" msgid="4269046942588193600">"တွဲချိတ်ပါ"</string>
+    <string name="bluetooth_pairing" msgid="4269046942588193600">"တွဲချိတ်နေသည်…"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> ချိတ်ဆက်ပြီးပြီ (ဖုန်းမရှိပါ)"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> ချိတ်ဆက်ပြီးပြီ (မီဒီယာ မရှိပါ)"</string>
     <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> ချိတ်ဆက်ပြီးပြီ (မက်ဆေ့ဂျ် သုံး၍မရပါ)"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 13bdd7e..4f64d10 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -95,7 +95,7 @@
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Kobler fra…"</string>
     <string name="bluetooth_connecting" msgid="5871702668260192755">"Kobler til…"</string>
     <string name="bluetooth_connected" msgid="8065345572198502293">"Koblet til <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_pairing" msgid="4269046942588193600">"Sammenkobles …"</string>
+    <string name="bluetooth_pairing" msgid="4269046942588193600">"Kobler til …"</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Koblet til (ingen telefon) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Koblet til (ingen medier) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Koblet til (ingen meldingstilgang) <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
@@ -570,7 +570,7 @@
     <string name="user_add_profile_item_title" msgid="3111051717414643029">"Begrenset profil"</string>
     <string name="user_add_user_title" msgid="5457079143694924885">"Vil du legge til en ny bruker?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Du kan dele denne enheten med andre folk ved å opprette flere brukere. Hver bruker har sin egen plass de kan tilpasse med apper, bakgrunner og annet. Brukere kan også justere enhetsinnstillinger, for eksempel Wi-Fi, som påvirker alle.\n\nNår du legger til en ny bruker, må vedkommende angi innstillinger for plassen sin.\n\nAlle brukere kan oppdatere apper for alle andre brukere. Innstillinger og tjenester for tilgjengelighet overføres kanskje ikke til den nye brukeren."</string>
-    <string name="user_add_user_message_short" msgid="3295959985795716166">"Når du legger til en ny bruker, må vedkommende konfigurere sitt eget område.\n\nAlle brukere kan oppdatere apper for alle andre brukere."</string>
+    <string name="user_add_user_message_short" msgid="3295959985795716166">"Når du legger til en ny bruker, må hen konfigurere sitt eget område.\n\nAlle brukere kan oppdatere apper for alle andre brukere."</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Konfigurere brukeren nå?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Sørg for at brukeren er tilgjengelig for å konfigurere området sitt på enheten"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Vil du konfigurere profilen nå?"</string>
@@ -590,7 +590,7 @@
     <string name="add_guest_failed" msgid="8074548434469843443">"Kunne ikke opprette en ny gjest"</string>
     <string name="user_nickname" msgid="262624187455825083">"Kallenavn"</string>
     <string name="user_add_user" msgid="7876449291500212468">"Legg til bruker"</string>
-    <string name="guest_new_guest" msgid="3482026122932643557">"Legg til en gjest"</string>
+    <string name="guest_new_guest" msgid="3482026122932643557">"Legg til gjest"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Fjern gjesten"</string>
     <string name="guest_reset_guest" msgid="6110013010356013758">"Tilbakestill gjest"</string>
     <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Vil du tilbakestille gjesten?"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 187e179..c25966c 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -95,7 +95,7 @@
     <string name="bluetooth_disconnecting" msgid="7638892134401574338">"డిస్‌కనెక్ట్ చేస్తోంది..."</string>
     <string name="bluetooth_connecting" msgid="5871702668260192755">"కనెక్ట్ చేస్తోంది..."</string>
     <string name="bluetooth_connected" msgid="8065345572198502293">"కనెక్ట్ చేయబడిన<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_pairing" msgid="4269046942588193600">"జత చేస్తోంది..."</string>
+    <string name="bluetooth_pairing" msgid="4269046942588193600">"పెయిరింగ్..."</string>
     <string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"కనెక్ట్ చేయబడింది (ఫోన్ కాదు)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"కనెక్ట్ చేయబడింది (మీడియా కాదు)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"కనెక్ట్ చేయబడింది (సందేశ యాక్సెస్ లేదు)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
@@ -594,7 +594,7 @@
     <string name="guest_exit_guest" msgid="5908239569510734136">"గెస్ట్‌ను తీసివేయండి"</string>
     <string name="guest_reset_guest" msgid="6110013010356013758">"గెస్ట్ సెషన్‌ను రీసెట్ చేయండి"</string>
     <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"గెస్ట్ సెషన్‌ను రీసెట్ చేయాలా?"</string>
-    <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"అతిథిని తీసివేయాలా?"</string>
+    <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"గెస్ట్‌ను తీసివేయాలా?"</string>
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"రీసెట్ చేయండి"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"తీసివేయండి"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"గెస్ట్ సెషన్‌ను రీసెట్ చేస్తోంది…"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java b/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java
index 8b34cf3..44a37f4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java
@@ -25,6 +25,7 @@
 import android.util.Log;
 import android.util.MathUtils;
 import android.view.Display;
+import android.view.DisplayInfo;
 import android.view.IWindowManager;
 import android.view.WindowManagerGlobal;
 
@@ -87,14 +88,14 @@
         }
 
         final Resources res = context.getResources();
-        final DisplayMetrics metrics = new DisplayMetrics();
-        context.getDisplayNoVerify().getRealMetrics(metrics);
+        DisplayInfo info = new DisplayInfo();
+        context.getDisplayNoVerify().getDisplayInfo(info);
 
-        final int currentDensity = metrics.densityDpi;
+        final int currentDensity = info.logicalDensityDpi;
         int currentDensityIndex = -1;
 
         // Compute number of "larger" and "smaller" scales for this display.
-        final int minDimensionPx = Math.min(metrics.widthPixels, metrics.heightPixels);
+        final int minDimensionPx = Math.min(info.logicalWidth, info.logicalHeight);
         final int maxDensity = DisplayMetrics.DENSITY_MEDIUM * minDimensionPx / MIN_DIMENSION_DP;
         final float maxScaleDimen = context.getResources().getFraction(
                 R.fraction.display_density_max_scale, 1, 1);
diff --git a/packages/SystemUI/TEST_MAPPING b/packages/SystemUI/TEST_MAPPING
index 3bd6d51..edb5ee3 100644
--- a/packages/SystemUI/TEST_MAPPING
+++ b/packages/SystemUI/TEST_MAPPING
@@ -91,7 +91,7 @@
   //
   // If you don't use @Staging or @Postsubmit, your new test will immediately
   // block presubmit, which is probably not what you want!
-  "platinum-postsubmit": [
+  "sysui-platinum-postsubmit": [
     {
       "name": "PlatformScenarioTests",
       "options": [
@@ -110,7 +110,7 @@
       ]
     }
   ],
-  "staged-platinum-postsubmit": [
+  "sysui-staged-platinum-postsubmit": [
     {
       "name": "PlatformScenarioTests",
       "options": [
diff --git a/packages/SystemUI/animation/res/values/ids.xml b/packages/SystemUI/animation/res/values/ids.xml
index 03ca462..f7150ab 100644
--- a/packages/SystemUI/animation/res/values/ids.xml
+++ b/packages/SystemUI/animation/res/values/ids.xml
@@ -21,6 +21,7 @@
 
     <!-- ViewBoundsAnimator -->
     <item type="id" name="tag_animator"/>
+    <item type="id" name="tag_alpha_animator"/>
     <item type="id" name="tag_layout_listener"/>
     <item type="id" name="tag_override_bottom"/>
     <item type="id" name="tag_override_left"/>
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
index bb6eb78..323db85 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
@@ -494,9 +494,10 @@
         }
 
         private fun applyStateToWindow(window: RemoteAnimationTarget, state: LaunchAnimator.State) {
-            if (transactionApplierView.viewRootImpl == null) {
-                // If the view root we synchronize with was detached, don't apply any transaction
-                // (as [SyncRtSurfaceTransactionApplier.scheduleApply] would otherwise throw).
+            if (transactionApplierView.viewRootImpl == null || !window.leash.isValid) {
+                // Don't apply any transaction if the view root we synchronize with was detached or
+                // if the SurfaceControl associated with [window] is not valid, as
+                // [SyncRtSurfaceTransactionApplier.scheduleApply] would otherwise throw.
                 return
             }
 
@@ -557,9 +558,10 @@
             state: LaunchAnimator.State,
             linearProgress: Float
         ) {
-            if (transactionApplierView.viewRootImpl == null) {
-                // If the view root we synchronize with was detached, don't apply any transaction
-                // (as [SyncRtSurfaceTransactionApplier.scheduleApply] would otherwise throw).
+            if (transactionApplierView.viewRootImpl == null || !navigationBar.leash.isValid) {
+                // Don't apply any transaction if the view root we synchronize with was detached or
+                // if the SurfaceControl associated with [navigationBar] is not valid, as
+                // [SyncRtSurfaceTransactionApplier.scheduleApply] would otherwise throw.
                 return
             }
 
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
index 093589f..4c3cd3c 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
@@ -39,6 +39,7 @@
         private val DEFAULT_INTERPOLATOR = Interpolators.STANDARD
         private val DEFAULT_ADDITION_INTERPOLATOR = Interpolators.STANDARD_DECELERATE
         private val DEFAULT_REMOVAL_INTERPOLATOR = Interpolators.STANDARD_ACCELERATE
+        private val DEFAULT_FADE_IN_INTERPOLATOR = Interpolators.ALPHA_IN
 
         /** The properties used to animate the view bounds. */
         private val PROPERTIES = mapOf(
@@ -162,6 +163,10 @@
          * animate an already visible view, see [animate] and [animateNextUpdate].
          *
          * Then animator unregisters itself once the first addition animation is complete.
+         *
+         * @param includeFadeIn true if the animator should also fade in the view and child views.
+         * @param fadeInInterpolator the interpolator to use when fading in the view. Unused if
+         *     [includeFadeIn] is false.
          */
         @JvmOverloads
         fun animateAddition(
@@ -169,7 +174,9 @@
             origin: Hotspot = Hotspot.CENTER,
             interpolator: Interpolator = DEFAULT_ADDITION_INTERPOLATOR,
             duration: Long = DEFAULT_DURATION,
-            includeMargins: Boolean = false
+            includeMargins: Boolean = false,
+            includeFadeIn: Boolean = false,
+            fadeInInterpolator: Interpolator = DEFAULT_FADE_IN_INTERPOLATOR
         ): Boolean {
             if (isVisible(
                     rootView.visibility,
@@ -186,6 +193,42 @@
                 origin, interpolator, duration, ignorePreviousValues = !includeMargins
             )
             addListener(rootView, listener, recursive = true)
+
+            if (!includeFadeIn) {
+                return true
+            }
+
+            if (rootView is ViewGroup) {
+                // First, fade in the container view
+                val containerDuration = duration / 6
+                createAndStartFadeInAnimator(
+                    rootView, containerDuration, startDelay = 0, interpolator = fadeInInterpolator
+                )
+
+                // Then, fade in the child views
+                val childDuration = duration / 3
+                for (i in 0 until rootView.childCount) {
+                    val view = rootView.getChildAt(i)
+                    createAndStartFadeInAnimator(
+                        view,
+                        childDuration,
+                        // Wait until the container fades in before fading in the children
+                        startDelay = containerDuration,
+                        interpolator = fadeInInterpolator
+                    )
+                }
+                // For now, we don't recursively fade in additional sub views (e.g. grandchild
+                // views) since it hasn't been necessary, but we could add that functionality.
+            } else {
+                // Fade in the view during the first half of the addition
+                createAndStartFadeInAnimator(
+                    rootView,
+                    duration / 2,
+                    startDelay = 0,
+                    interpolator = fadeInInterpolator
+                )
+            }
+
             return true
         }
 
@@ -834,6 +877,27 @@
             view.setTag(R.id.tag_animator, animator)
             animator.start()
         }
+
+        private fun createAndStartFadeInAnimator(
+            view: View,
+            duration: Long,
+            startDelay: Long,
+            interpolator: Interpolator
+        ) {
+            val animator = ObjectAnimator.ofFloat(view, "alpha", 1f)
+            animator.startDelay = startDelay
+            animator.duration = duration
+            animator.interpolator = interpolator
+            animator.addListener(object : AnimatorListenerAdapter() {
+                override fun onAnimationEnd(animation: Animator) {
+                    view.setTag(R.id.tag_alpha_animator, null /* tag */)
+                }
+            })
+
+            (view.getTag(R.id.tag_alpha_animator) as? ObjectAnimator)?.cancel()
+            view.setTag(R.id.tag_alpha_animator, animator)
+            animator.start()
+        }
     }
 
     /** An enum used to determine the origin of addition animations. */
diff --git a/packages/SystemUI/res-keyguard/values/config.xml b/packages/SystemUI/res-keyguard/values/config.xml
index a25ab51..b1d3375 100644
--- a/packages/SystemUI/res-keyguard/values/config.xml
+++ b/packages/SystemUI/res-keyguard/values/config.xml
@@ -28,6 +28,11 @@
     <!-- Will display the bouncer on one side of the display, and the current user icon and
          user switcher on the other side -->
     <bool name="config_enableBouncerUserSwitcher">false</bool>
+    <!-- Whether to show the face scanning animation on devices with face auth supported.
+         The face scanning animation renders in a SW layer in ScreenDecorations.
+         Enabling this will also render the camera protection in the SW layer
+         (instead of HW, if relevant)."=-->
+    <bool name="config_enableFaceScanningAnimation">true</bool>
     <!-- Time to be considered a consecutive fingerprint failure in ms -->
     <integer name="fp_consecutive_failure_time_ms">3500</integer>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index 64aa8ee..1be2d99 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -220,8 +220,8 @@
     <!-- Face hint message when finger was not recognized. [CHAR LIMIT=20] -->
     <string name="kg_face_not_recognized">Not recognized</string>
 
-     <!-- Error message indicating that the camera privacy sensor has been turned on [CHAR LIMIT=NONE] -->
-    <string name="kg_face_sensor_privacy_enabled">To use Face Unlock, turn on <b>Camera access</b> in Settings > Privacy</string>
+     <!-- Error message indicating that the camera privacy sensor has been turned on [CHAR LIMIT=53] -->
+    <string name="kg_face_sensor_privacy_enabled">To use Face Unlock, turn on camera access in Settings</string>
 
     <!-- Instructions telling the user remaining times when enter SIM PIN view.  -->
     <plurals name="kg_password_default_pin_message">
diff --git a/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml b/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
index 3a08a71..41123c8 100644
--- a/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
+++ b/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
@@ -16,19 +16,13 @@
 * limitations under the License.
 */
 -->
-<ripple
+<shape
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-    android:color="?android:attr/textColorPrimary">
-  <item>
-    <shape
-        android:shape="rectangle">
-      <solid android:color="?androidprv:attr/colorSurface"/>
-      <size
-          android:width="@dimen/keyguard_affordance_width"
-          android:height="@dimen/keyguard_affordance_height"/>
-      <corners android:radius="@dimen/keyguard_affordance_fixed_radius"/>
-    </shape>
-  </item>
-</ripple>
-
+    android:shape="rectangle">
+  <solid android:color="?androidprv:attr/colorSurface"/>
+  <size
+      android:width="@dimen/keyguard_affordance_width"
+      android:height="@dimen/keyguard_affordance_height"/>
+  <corners android:radius="@dimen/keyguard_affordance_fixed_radius"/>
+</shape>
diff --git a/packages/SystemUI/res/layout/auth_biometric_view.xml b/packages/SystemUI/res/layout/auth_biometric_view.xml
deleted file mode 100644
index ee4da25..0000000
--- a/packages/SystemUI/res/layout/auth_biometric_view.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-  ~ Copyright (C) 2022 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.biometrics.AuthBiometricView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/contents"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical">
-
-    <include layout="@layout/auth_biometric_contents"/>
-
-</com.android.systemui.biometrics.AuthBiometricView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/media_ttt_chip.xml b/packages/SystemUI/res/layout/media_ttt_chip.xml
index a502d33..4d24140 100644
--- a/packages/SystemUI/res/layout/media_ttt_chip.xml
+++ b/packages/SystemUI/res/layout/media_ttt_chip.xml
@@ -13,71 +13,85 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<LinearLayout
+<!-- Wrap in a frame layout so that we can update the margins on the inner layout. (Since this view
+     is the root view of a window, we cannot change the root view's margins.) -->
+<!-- Alphas start as 0 because the view will be animated in. -->
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:id="@+id/media_ttt_sender_chip"
-    android:orientation="horizontal"
     android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:padding="@dimen/media_ttt_chip_outer_padding"
-    android:background="@drawable/media_ttt_chip_background"
-    android:layout_marginTop="50dp"
-    android:clipToPadding="false"
-    android:gravity="center_vertical"
-    >
+    android:layout_height="wrap_content">
 
-    <com.android.internal.widget.CachingIconView
-        android:id="@+id/app_icon"
-        android:layout_width="@dimen/media_ttt_app_icon_size"
-        android:layout_height="@dimen/media_ttt_app_icon_size"
-        android:layout_marginEnd="12dp"
-        />
-
-    <TextView
-        android:id="@+id/text"
+    <LinearLayout
+        android:id="@+id/media_ttt_sender_chip_inner"
+        android:orientation="horizontal"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:textSize="@dimen/media_ttt_text_size"
-        android:textColor="?android:attr/textColorPrimary"
-        />
+        android:padding="@dimen/media_ttt_chip_outer_padding"
+        android:background="@drawable/media_ttt_chip_background"
+        android:layout_marginTop="20dp"
+        android:clipToPadding="false"
+        android:gravity="center_vertical"
+        android:alpha="0.0"
+        >
 
-    <!-- At most one of [loading, failure_icon, undo] will be visible at a time. -->
+        <com.android.internal.widget.CachingIconView
+            android:id="@+id/app_icon"
+            android:layout_width="@dimen/media_ttt_app_icon_size"
+            android:layout_height="@dimen/media_ttt_app_icon_size"
+            android:layout_marginEnd="12dp"
+            android:alpha="0.0"
+            />
 
-    <ProgressBar
-        android:id="@+id/loading"
-        android:indeterminate="true"
-        android:layout_width="@dimen/media_ttt_status_icon_size"
-        android:layout_height="@dimen/media_ttt_status_icon_size"
-        android:layout_marginStart="@dimen/media_ttt_last_item_start_margin"
-        android:indeterminateTint="?androidprv:attr/colorAccentPrimaryVariant"
-        style="?android:attr/progressBarStyleSmall"
-        />
+        <TextView
+            android:id="@+id/text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textSize="@dimen/media_ttt_text_size"
+            android:textColor="?android:attr/textColorPrimary"
+            android:alpha="0.0"
+            />
 
-    <ImageView
-        android:id="@+id/failure_icon"
-        android:layout_width="@dimen/media_ttt_status_icon_size"
-        android:layout_height="@dimen/media_ttt_status_icon_size"
-        android:layout_marginStart="@dimen/media_ttt_last_item_start_margin"
-        android:src="@drawable/ic_warning"
-        android:tint="@color/GM2_red_500"
-        />
+        <!-- At most one of [loading, failure_icon, undo] will be visible at a time. -->
+        <ProgressBar
+            android:id="@+id/loading"
+            android:indeterminate="true"
+            android:layout_width="@dimen/media_ttt_status_icon_size"
+            android:layout_height="@dimen/media_ttt_status_icon_size"
+            android:layout_marginStart="@dimen/media_ttt_last_item_start_margin"
+            android:indeterminateTint="?androidprv:attr/colorAccentPrimaryVariant"
+            style="?android:attr/progressBarStyleSmall"
+            android:alpha="0.0"
+            />
 
-    <TextView
-        android:id="@+id/undo"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="@string/media_transfer_undo"
-        android:textColor="?androidprv:attr/textColorOnAccent"
-        android:layout_marginStart="@dimen/media_ttt_last_item_start_margin"
-        android:textSize="@dimen/media_ttt_text_size"
-        android:paddingStart="@dimen/media_ttt_chip_outer_padding"
-        android:paddingEnd="@dimen/media_ttt_chip_outer_padding"
-        android:paddingTop="@dimen/media_ttt_undo_button_vertical_padding"
-        android:paddingBottom="@dimen/media_ttt_undo_button_vertical_padding"
-        android:layout_marginTop="@dimen/media_ttt_undo_button_vertical_negative_margin"
-        android:layout_marginBottom="@dimen/media_ttt_undo_button_vertical_negative_margin"
-        android:background="@drawable/media_ttt_undo_background"
-        />
+        <ImageView
+            android:id="@+id/failure_icon"
+            android:layout_width="@dimen/media_ttt_status_icon_size"
+            android:layout_height="@dimen/media_ttt_status_icon_size"
+            android:layout_marginStart="@dimen/media_ttt_last_item_start_margin"
+            android:src="@drawable/ic_warning"
+            android:tint="@color/GM2_red_500"
+            android:alpha="0.0"
+            />
 
-</LinearLayout>
+        <TextView
+            android:id="@+id/undo"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/media_transfer_undo"
+            android:textColor="?androidprv:attr/textColorOnAccent"
+            android:layout_marginStart="@dimen/media_ttt_last_item_start_margin"
+            android:textSize="@dimen/media_ttt_text_size"
+            android:paddingStart="@dimen/media_ttt_chip_outer_padding"
+            android:paddingEnd="@dimen/media_ttt_chip_outer_padding"
+            android:paddingTop="@dimen/media_ttt_undo_button_vertical_padding"
+            android:paddingBottom="@dimen/media_ttt_undo_button_vertical_padding"
+            android:layout_marginTop="@dimen/media_ttt_undo_button_vertical_negative_margin"
+            android:layout_marginBottom="@dimen/media_ttt_undo_button_vertical_negative_margin"
+            android:background="@drawable/media_ttt_undo_background"
+            android:alpha="0.0"
+            />
+
+    </LinearLayout>
+</FrameLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 0cb7735..f101b7c 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bevestig"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tik op Bevestig om te voltooi"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Ontsluit met gesig. Druk die ontsluitikoon om voort te gaan."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ontsluit met gesig. Druk om voort te gaan."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Gesig is herken. Druk om voort te gaan."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gesig is herken. Druk die ontsluitikoon om voort te gaan."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Gestaaf"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Gebruik PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Gebruik patroon"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Swiep op om oop te maak"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Druk die onsluitikoon om oop te maak"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ontsluit met gesig. Druk die ontsluitikoon om oop te maak."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ontsluit met gesig. Druk om oop te maak."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Gesig is herken. Druk om oop te maak."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Gesig is herken. Druk die ontsluitikoon om oop te maak."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Swiep op om weer te probeer"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ontsluit om NFC te gebruik"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Hierdie toestel behoort aan jou organisasie"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 4cd2a3d..5838dbf 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ተረጋግጧል"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ለማጠናቀቅ አረጋግጥን መታ ያድርጉ"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"በመልክ ተከፍቷል። ለመቀጠል የመክፈቻ አዶውን ይጫኑ።"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"በመልክ ተከፍቷል። ለመቀጠል ይጫኑ።"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"መልክ ተለይቶ ታውቋል። ለመቀጠል ይጫኑ።"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"መልክ ተለይቶ ታውቋል። ለመቀጠል የመክፈቻ አዶውን ይጫኑ።"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"የተረጋገጠ"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ፒን ይጠቀሙ"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ሥርዓተ ጥለትን ተጠቀም"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"ለመክፈት በጣት ወደ ላይ ጠረግ ያድርጉ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ለመክፈት የመክፈቻ አዶውን ይጫኑ"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"በመልክ ተከፍቷል። ለመክፈት የመክፈቻ አዶውን ይጫኑ።"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"በመልክ ተከፍቷል። ለመክፈት ይጫኑ።"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"መልክ ተለይቶ ታውቋል። ለመክፈት ይጫኑ።"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"መልክ ተለይቶ ታውቋል። ለመክፈት የመክፈቻ አዶውን ይጫኑ።"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"እንደገና ለመሞከር ወደ ላይ ይጥረጉ"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCን ለመጠቀም ይክፈቱ"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ይህ መሣሪያ የድርጅትዎ ነው"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 60bf247..d711d59 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"تمّ التأكيد."</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"يمكنك النقر على \"تأكيد\" لإكمال المهمة."</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"فُتح القفل عندما تمّ التعرّف على وجهك. للمتابعة، اضغط على رمز فتح القفل."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"تم فتح قفل جهازك عند تقريبه من وجهك. اضغط للمتابعة."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"تم التعرّف على الوجه. اضغط للمتابعة."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"تم التعرّف على الوجه. للمتابعة، اضغط على رمز فتح القفل."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"مصادقة"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"استخدام رقم تعريف شخصي"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"استخدام نقش"</string>
@@ -320,6 +323,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"يمكنك الفتح بالتمرير سريعًا لأعلى."</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"اضغط على رمز فتح القفل لفتح قفل الشاشة."</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"فُتح القفل عندما تمّ التعرّف على وجهك. اضغط على رمز فتح القفل لفتحه."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"تم فتح قفل جهازك عند تقريبه من وجهك. اضغط لفتح الجهاز."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"تم التعرّف على الوجه. اضغط لفتح الجهاز."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"تم التعرّف على الوجه. اضغط على رمز فتح القفل لفتح الجهاز."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"مرِّر سريعًا للأعلى لإعادة المحاولة."</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"‏افتح قفل الشاشة لاستخدام تقنية NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"هذا الجهاز يخص مؤسستك."</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index b9ba840..68728a7 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"নিশ্চিত কৰিলে"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"সম্পূৰ্ণ কৰিবলৈ নিশ্চিত কৰক-ত টিপক"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। অব্যাহত ৰাখিবলৈ আনলক কৰক চিহ্নটোত টিপক।"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। অব্যাহত ৰাখিবলৈ টিপক।"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"মুখাৱয়ব চিনাক্ত কৰা হৈছে। অব্যাহত ৰাখিবলৈ টিপক।"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"মুখাৱয়ব চিনাক্ত কৰা হৈছে। অব্যাহত ৰাখিবলৈ আনলক কৰক চিহ্নটোত টিপক।"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ’ল"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"পিন ব্যৱহাৰ কৰক"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"আৰ্হি ব্যৱহাৰ কৰক"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"খুলিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"খুলিবলৈ আনলক কৰক চিহ্নটোত টিপক"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। খুলিবলৈ আনলক কৰক চিহ্নটোত টিপক।"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। খুলিবলৈ টিপক।"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"মুখাৱয়ব চিনাক্ত কৰা হৈছে। খুলিবলৈ টিপক।"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"মুখাৱয়ব চিনাক্ত কৰা হৈছে। খুলিবলৈ আনলক কৰক চিহ্নটোত টিপক।"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"পুনৰ চেষ্টা কৰিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ব্যৱহাৰ কৰিবলৈ আনলক কৰক"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"এই ডিভাইচটো আপোনাৰ প্ৰতিষ্ঠানৰ"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index c0735cc..e4ab386 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Təsdiqləndi"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tamamlamaq üçün \"Təsdiq edin\" seçiminə toxunun"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Üzlə kilidi açılıb. \"Kilidi aç\" ikonasına basıb davam edin."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Üz ilə kiliddən çıxarılıb. Davam etmək üçün basın."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Üz tanınıb. Davam etmək üçün basın."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Üz tanınıb. \"Kiliddən çıxar\" ikonasına basıb davam edin."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Doğrulandı"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN istifadə edin"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Model istifadə edin"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Açmaq üçün yuxarı sürüşdürün"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"\"Kilidi aç\" ikonasına basıb açın"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Üzlə kilidi açılıb. \"Kilidi aç\" ikonasına basıb açın."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Üz ilə kiliddən çıxarılıb. Açmaq üçün basın."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Üz tanınıb. Açmaq üçün basın."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Üz tanınıb. \"Kiliddən çıxar\" ikonasına basıb açın."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Yenidən cəhd etmək üçün yuxarı sürüşdürün"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC istifadə etmək üçün kiliddən çıxarın"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Bu cihaz təşkilatınıza məxsusdur"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 585b879..ac7b219f 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrđeno"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Dodirnite Potvrdi da biste završili"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Otključano je licem. Pritisnite ikonu otključavanja za nastavak"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Otključano je licem. Pritisnite da biste nastavili."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Lice je prepoznato. Pritisnite da biste nastavili."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice prepoznato. Pritisnite ikonu otključavanja za nastavak."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Identitet je potvrđen"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Koristite PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Koristite šablon"</string>
@@ -314,6 +317,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Prevucite nagore da biste otvorili"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pritisnite ikonu otključavanja za otvaranje"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Otključano je licem. Pritisnite ikonu otključavanja za otvaranje"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Otključano je licem. Pritisnite da biste otvorili."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Lice je prepoznato. Pritisnite da biste otvorili."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Lice prepoznato. Pritisnite ikonu otključavanja za otvaranje."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Prevucite nagore da biste probali ponovo"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Otključajte da biste koristili NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada organizaciji"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 0837997..7f006f4 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Пацверджана"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Націсніце \"Пацвердзіць\", каб завяршыць"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Твар распазнаны. Для працягу націсніце значок разблакіроўкі."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Разблакіравана распазнаваннем твару. Націсніце для працягу."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Твар распазнаны. Націсніце для працягу."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Твар распазнаны. Для працягу націсніце значок разблакіроўкі."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Распазнана"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Увесці PIN-код"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Выкарыстаць узор разблакіроўкі"</string>
@@ -316,6 +319,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Каб адкрыць, прагарніце ўверх"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Каб адкрыць, націсніце значок разблакіроўкі"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Твар распазнаны. Для адкрыцця націсніце значок разблакіроўкі"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Разблакіравана распазнаваннем твару. Націсніце, каб адкрыць."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Твар распазнаны. Націсніце, каб адкрыць."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Твар распазнаны. Для адкрыцця націсніце значок разблакіроўкі."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Прагартайце ўверх, каб паўтарыць спробу"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Разблакіруйце, каб выкарыстоўваць NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Гэта прылада належыць вашай арганізацыі"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index c9d1e81..901572d 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Потвърдено"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Докоснете „Потвърждаване“ за завършване"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Отключено с лице. Натиснете иконата за отключване, за да продължите."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Отключено с лице. Натиснете, за да продължите."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лицето бе разпознато. Натиснете, за да продължите."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицето бе разпознато. Продължете чрез иконата за отключване."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Удостоверено"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Използване на ПИН"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Използване на фигура"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Прекарайте пръст нагоре, за да отключите"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Натиснете иконата за отключване, за да отворите"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Отключено с лице. Натиснете иконата за отключване, за да отворите."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Отключено с лице. Натиснете за отваряне."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лицето бе разпознато. Натиснете за отваряне."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Лицето бе разпознато. Отворете чрез иконата за отключване."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Плъзнете бързо нагоре, за да опитате отново"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Отключете, за да използвате NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Това устройство принадлежи на организацията ви"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index e5920fc..180d80b 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"কনফার্ম করা হয়েছে"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"সম্পূর্ণ করতে \'কনফার্ম করুন\' বোতামে ট্যাপ করুন"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ফেসের সাহায্যে আনলক করা হয়েছে। চালিয়ে যাওয়ার জন্য আনলক আইকনে প্রেস করুন।"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"প্রমাণীকৃত"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"পিন ব্যবহার করুন"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"প্যাটার্ন ব্যবহার করুন"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"খোলার জন্য উপরে সোয়াইপ করুন"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"খোলার জন্য আনলক আইকন প্রেস করুন"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ফেসের সাহায্যে আনলক করা হয়েছে। খোলার জন্য আনলক আইকন প্রেস করুন।"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"আবার চেষ্টা করতে উপরের দিকে সোয়াইপ করুন"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ব্যবহার করতে আনলক করুন"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"এই ডিভাইসটি আপনার প্রতিষ্ঠানের"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 3d84113..b1edfd9 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrđeno"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Dodirnite Potvrdi da završite"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Otključano licem. Pritisnite ikonu za otklj. da nastavite."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Otključano licem. Pritisnite da nastavite."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Lice prepoznato. Pritisnite da nastavite."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice prepoznato. Pritisnite ikonu za otklj. da nastavite."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentificirano"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Koristi PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Koristi uzorak"</string>
@@ -314,6 +317,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Prevucite da otvorite"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pritisnite ikonu za otključavanje da otvorite."</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Otključano licem. Pritisnite ikonu za otklj. da otvorite."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Otključano licem. Pritisnite da otvorite."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Lice prepoznato. Pritisnite da otvorite."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Lice prepoznato. Pritisnite ikonu za otklj. da otvorite."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Prevucite prema gore da pokušate ponovo"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Otključajte da koristite NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada vašoj organizaciji"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 8822875..20e5a5a 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmat"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toca Confirma per completar"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"S\'ha desbloquejat amb la cara. Prem la icona per continuar."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticat"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utilitza el PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Utilitza el patró"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Llisca cap amunt per obrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Prem la icona de desbloqueig per obrir"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"S\'ha desbloquejat amb la cara. Prem la icona per obrir."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"Llisca cap a dalt per tornar-ho a provar"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloqueja per utilitzar l\'NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Aquest dispositiu pertany a la teva organització"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 820749f..14749b5 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrzeno"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ověření dokončíte klepnutím na Potvrdit"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Odemknuto obličejem. Klepněte na ikonu odemknutí."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odemknuto obličejem. Pokračujte stisknutím."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Obličej rozpoznán. Pokračujte stisknutím."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Obličej rozpoznán. Klepněte na ikonu odemknutí."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Ověřeno"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Použít kód PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Použít gesto"</string>
@@ -316,6 +319,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Otevřete přejetím prstem nahoru"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Otevřete klepnutím na ikonu odemknutí"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odemknuto obličejem. Klepněte na ikonu odemknutí."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Odemknuto obličejem. Stisknutím otevřete."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Obličej rozpoznán. Stisknutím otevřete."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Obličej rozpoznán. Klepněte na ikonu odemknutí."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Přejetím nahoru to zkusíte znovu"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC vyžaduje odemknutou obrazovku"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Toto zařízení patří vaší organizaci"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 135b480a..8e5095b 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bekræftet"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tryk på Bekræft for at udføre"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Låst op vha. ansigt. Tryk på oplåsningsikonet for at fortsætte."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Låst op ved hjælp af ansigt. Tryk for at fortsætte."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ansigt genkendt. Tryk for at fortsætte."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansigt genkendt. Tryk på oplåsningsikonet for at fortsætte."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Godkendt"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Brug pinkode"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Brug mønster"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Stryg opad for at åbne"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Tryk på oplåsningsikonet for at åbne"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Låst op vha. ansigt. Tryk på oplåsningsikonet for at åbne."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Låst op ved hjælp af ansigt. Tryk for at åbne."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ansigt genkendt. Tryk for at åbne."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Ansigt genkendt. Tryk på oplåsningsikonet for at åbne."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Stryg opad for at prøve igen"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Lås op for at bruge NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Denne enhed tilhører din organisation"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 50061fb..e0a3eac 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bestätigt"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Zum Abschließen auf \"Bestätigen\" tippen"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Gerät mit dem Gesicht entsperrt. Tippe auf das Symbol „Entsperren“, um fortzufahren."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifiziert"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN verwenden"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Muster verwenden"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Zum Öffnen nach oben wischen"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Tippe zum Öffnen auf das Symbol „Entsperren“"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Gerät mit dem Gesicht entsperrt. Tippe zum Öffnen auf das Symbol „Entsperren“."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"Zum Wiederholen nach oben wischen"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Zur Verwendung von NFC entsperren"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Dieses Gerät gehört deiner Organisation"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index d82a28c..bb29f6f 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Επιβεβαιώθηκε"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Πατήστε Επιβεβαίωση για ολοκλήρωση"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Ξεκλ. με αναγν. προσώπου. Πατ. το εικον. ξεκλ. για συνέχεια."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ξεκλείδωμα με αναγνώριση προσώπου. Πατήστε για συνέχεια."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Το πρόσωπο αναγνωρίστηκε. Πατήστε για συνέχεια."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Το πρόσωπο αναγνωρ. Πατήστε το εικον. ξεκλειδ. για συνέχεια."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Ολοκληρώθηκε ο έλεγχος ταυτότητας"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Χρήση PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Χρήση μοτίβου"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Σύρετε προς τα επάνω για άνοιγμα"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Πατήστε το εικονίδιο ξεκλειδώματος για άνοιγμα"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ξεκλ. με αναγν. προσώπου. Πατ. το εικον. ξεκλ. για άνοιγμα."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ξεκλείδωμα με αναγνώριση προσώπου. Πατήστε για άνοιγμα."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Το πρόσωπο αναγνωρίστηκε. Πατήστε για άνοιγμα."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Το πρόσωπο αναγνωρ. Πατήστ. το εικον. ξεκλειδ. για άνοιγμα."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Σύρετε προς τα πάνω για να δοκιμάσετε ξανά"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ξεκλείδωμα για χρήση του NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Αυτή η συσκευή ανήκει στον οργανισμό σας."</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 2ca4d80..790bf3f 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmed"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Unlocked by face. Press the unlock icon to continue."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognised. Press to continue."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Press the unlock icon to open"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Unlocked by face. Press the unlock icon to open."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Unlocked by face. Press to open."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Face recognised. Press to open."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Face recognised. Press the unlock icon to open."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index d7a4dec..ce76459 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmed"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Unlocked by face. Press the unlock icon to continue."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognised. Press to continue."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Press the unlock icon to open"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Unlocked by face. Press the unlock icon to open."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Unlocked by face. Press to open."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Face recognised. Press to open."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Face recognised. Press the unlock icon to open."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 2ca4d80..790bf3f 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmed"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Unlocked by face. Press the unlock icon to continue."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognised. Press to continue."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Press the unlock icon to open"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Unlocked by face. Press the unlock icon to open."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Unlocked by face. Press to open."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Face recognised. Press to open."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Face recognised. Press the unlock icon to open."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 2ca4d80..790bf3f 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmed"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Unlocked by face. Press the unlock icon to continue."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognised. Press to continue."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Press the unlock icon to open"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Unlocked by face. Press the unlock icon to open."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Unlocked by face. Press to open."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Face recognised. Press to open."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Face recognised. Press the unlock icon to open."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index be94028..30240d4 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‏‎‏‎‏‎‎‎‎‎‏‏‏‎‎‎‏‏‏‎‎‎‎‏‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‏‎‏‎‎Confirmed‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‏‏‏‎‎Tap Confirm to complete‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‏‎‏‏‏‎‏‎‏‎‏‎‎‏‏‏‎Unlocked by face. Press the unlock icon to continue.‎‏‎‎‏‎"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‎‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‎‏‎Unlocked by face. Press to continue.‎‏‎‎‏‎"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‏‏‏‎‎‎‎‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‏‎‎‎Face recognized. Press to continue.‎‏‎‎‏‎"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‏‏‎‏‎‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎Face recognized. Press the unlock icon to continue.‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‎‎Authenticated‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‎‏‎‎‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‎‏‎Use PIN‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‏‎‏‏‏‎‏‎‎Use pattern‎‏‎‎‏‎"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‏‏‏‎‎‎‏‎‎‏‎‎‎‎‎‏‎Swipe up to open‎‏‎‎‏‎"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‏‏‎‎‎‏‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‎‏‏‎‎‎‎‏‎‏‏‎‎‏‎‎‏‎Press the unlock icon to open‎‏‎‎‏‎"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‏‎‏‎‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‏‏‎‎‏‏‎‏‎‎‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‎‎‎Unlocked by face. Press the unlock icon to open.‎‏‎‎‏‎"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‎‎‎‏‎‏‏‎‎‏‎‏‏‎‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‏‎‎‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‎‎Unlocked by face. Press to open.‎‏‎‎‏‎"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎‏‎‏‏‎‏‎‎‏‎‎‎‏‏‎‏‏‎‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎Face recognized. Press to open.‎‏‎‎‏‎"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‏‏‏‏‎‎‏‎‎‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‎‏‏‏‎‎‏‎‏‎‎Face recognized. Press the unlock icon to open.‎‏‎‎‏‎"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‎Swipe up to try again‎‏‎‎‏‎"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‎‏‎‏‎‎‏‏‏‏‎Unlock to use NFC‎‏‎‎‏‎"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‏‎‎‏‎‏‏‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‎‏‎‏‏‏‏‎‏‏‏‏‏‎This device belongs to your organization‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index ec3c79a..f2c7236 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmado"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Presiona Confirmar para completar"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Desbloqueo con rostro. Presiona ícono desbl. para continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueo con rostro. Presiona para continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rostro reconocido. Presiona para continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rostro reconocido. Presiona el desbloqueo para continuar."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar patrón"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Desliza el dedo hacia arriba para abrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Presiona el ícono de desbloquear para abrir"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueo con rostro. Presiona ícono desbloq. para abrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueo con rostro. Presiona para abrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Rostro reconocido. Presiona para abrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Rostro reconocido. Presiona el desbloqueo para abrir."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Desliza el dedo hacia arriba para volver a intentarlo"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquea el dispositivo para usar NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertenece a tu organización"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 9839405..f394e00 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmada"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toca Confirmar para completar la acción"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Desbloqueado con datos faciales. Pulsa el icono desbloquear para continuar."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Se ha autenticado"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar patrón"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Desliza el dedo hacia arriba para abrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pulsa el icono desbloquear para abrir"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueado con datos faciales. Pulsa el icono desbloquear para abrir."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"Desliza el dedo hacia arriba para volverlo a intentar"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquea para usar el NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertenece a tu organización"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 42842fc..8a47781 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Kinnitatud"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Lõpuleviimiseks puudutage nuppu Kinnita"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Avati näoga. Jätkamiseks vajutage avamise ikooni."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenditud"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Kasuta PIN-koodi"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Kasuta mustrit"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Pühkige avamiseks üles"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Avamiseks vajutage avamise ikooni"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Avati näoga. Avamiseks vajutage avamise ikooni."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"Uuesti proovimiseks pühkige üles"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC kasutamiseks avage."</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"See seade kuulub teie organisatsioonile"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 53c3698..d832aac 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Berretsita"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Amaitzeko, sakatu \"Berretsi\""</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Aurpegiaren bidez desblokeatu da. Aurrera egiteko, sakatu desblokeatzeko ikonoa."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikatuta"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Erabili PINa"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Erabili eredua"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Pasatu hatza gora irekitzeko"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Irekitzeko, sakatu desblokeatzeko ikonoa"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Aurpegiaren bidez desblokeatu da. Irekitzeko, sakatu desblokeatzeko ikonoa."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"Berriro saiatzeko, pasatu hatza gora"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desblokea ezazu NFC erabiltzeko"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Gailu hau zure erakundearena da"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 38b1f9f..93b0b66 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"تأیید شد"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"برای تکمیل، روی تأیید ضربه بزنید"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"قفلْ با چهره باز شد. برای ادامه، نماد قفل‌گشایی را فشار دهید."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"قفلْ با چهره باز شد. برای ادامه، فشار دهید."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"چهره شناسایی شد. برای ادامه، فشار دهید."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"چهره شناسایی شد. برای ادامه، نماد قفل‌گشایی را فشار دهید."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"راستی‌آزمایی‌شده"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"استفاده از پین"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"استفاده از الگو"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"برای باز کردن، انگشتتان را تند به‌بالا بکشید"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"برای باز کردن، نماد قفل‌گشایی را فشار دهید"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"قفلْ با چهره باز شد. برای باز کردن، نماد قفل‌گشایی را فشار دهید."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"قفلْ با چهره باز شد. برای باز کردن، فشار دهید."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"چهره شناسایی شد. برای باز کردن، فشار دهید."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"چهره شناسایی شد. برای باز کردن، نماد قفل‌گشایی را فشار دهید."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"برای امتحان مجدد، انگشتتان را تند به‌بالا بکشید"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"‏برای استفاده از NFC، قفل را باز کنید"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"این دستگاه به سازمان شما تعلق دارد"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index c10bfcb..b9b0071 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Vahvistettu"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Valitse lopuksi Vahvista"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Avattu kasvojen avulla. Jatka lukituksen avauskuvakkeella."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Avattu kasvojen avulla. Jatka painamalla."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Kasvot tunnistettu. Jatka painamalla."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Kasvot tunnistettu. Jatka lukituksen avauskuvakkeella."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Todennettu"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Käytä PIN-koodia"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Käytä kuviota"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Avaa pyyhkäisemällä ylös"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Jatka painamalla lukituksen avauskuvaketta."</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Avattu kasvojen avulla. Jatka lukituksen avauskuvakkeella."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Avattu kasvojen avulla. Avaa painamalla."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Kasvot tunnistettu. Avaa painamalla."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Kasvot tunnistettu. Jatka lukituksen avauskuvakkeella."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Yritä uudelleen pyyhkäisemällä ylös"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Avaa lukitus, jotta voit käyttää NFC:tä"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Organisaatiosi omistaa tämän laitteen"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 75e4869..071b445 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmé"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Touchez Confirmer pour terminer"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Déverrouillé avec le visage. Appuyez Déverrouiller pour cont."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifié"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utiliser un NIP"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Utiliser un schéma"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Balayez l\'écran vers le haut pour ouvrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Appuyez sur l\'icône Déverrouiller pour ouvrir"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Déverrouillé avec le visage. Appuyez Déverrouiller pour ouvrir"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"Balayez l\'écran vers le haut pour réessayer"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Déverrouillez l\'écran pour utiliser la CCP"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Cet appareil appartient à votre organisation"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 8854de2..c042f4a 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmé"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Appuyez sur \"Confirmer\" pour terminer"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Déverrouillé par visage. Appuyez sur icône déverrouillage pour continuer."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Déverrouillé par visage. Appuyez pour continuer."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Visage reconnu. Appuyez pour continuer."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Visage reconnu. Appuyez sur l\'icône de déverrouillage pour continuer."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifié"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utiliser un code PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Utiliser un schéma"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Balayer vers le haut pour ouvrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Appuyez sur l\'icône de déverrouillage pour ouvrir"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Déverrouillé par visage. Appuyez sur icône déverrouillage pour ouvrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Déverrouillé par visage. Appuyez pour ouvrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Visage reconnu. Appuyez pour ouvrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Visage reconnu. Appuyez sur l\'icône de déverrouillage pour ouvrir."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Balayez l\'écran vers le haut pour réessayer"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Déverrouillez l\'écran pour pouvoir utiliser NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Cet appareil appartient à votre organisation"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index d56e2ba..5b47e52 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmada"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toca Confirmar para completar o proceso"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Usouse o desbloqueo facial. Preme a icona de desbloquear."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Usouse o desbloqueo facial. Preme para continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Recoñeceuse a cara. Preme para continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Recoñeceuse a cara. Preme a icona de desbloquear."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar padrón"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Pasa o dedo cara arriba para abrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Preme a icona de desbloquear para abrir a porta"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Usouse o desbloqueo facial. Preme a icona de desbloquear."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Usouse o desbloqueo facial. Preme para abrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Recoñeceuse a cara. Preme para abrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Recoñeceuse a cara. Preme a icona de desbloquear para abrir."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Pasa o dedo cara arriba para tentalo de novo"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquea o dispositivo para utilizar a NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence á túa organización."</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 9981769..aee9c0d 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"પુષ્ટિ કરી"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"પરીક્ષણ પૂર્ણ કરવા કન્ફર્મ કરોને ટૅપ કરો"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ચહેરા દ્વારા અનલૉક કર્યું. આગળ વધવા \'અનલૉક કરો\' આઇકન દબાવો."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"પ્રમાણિત"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"પિનનો ઉપયોગ કરો"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"પૅટર્નનો ઉપયોગ કરો"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"ખોલવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ખોલવા માટે \'અનલૉક કરો\' આઇકન દબાવો"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ચહેરા દ્વારા અનલૉક કર્યું. ખોલવા \'અનલૉક કરો\' આઇકન દબાવો."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"ફરી પ્રયાસ કરવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCનો ઉપયોગ કરવા માટે અનલૉક કરો"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"આ ડિવાઇસ તમારી સંસ્થાની માલિકીનું છે"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 416e0c4..8f90f62 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"पुष्टि हो गई"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"\'पुष्टि करें\' पर टैप करके पूरा करें"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"चेहरे से अनलॉक किया. जारी रखने के लिए, अनलॉक आइकॉन को दबाएं."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"पुष्टि हो गई"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"पिन इस्तेमाल करें"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"पैटर्न इस्तेमाल करें"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"खोलने के लिए ऊपर स्वाइप करें"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"डिवाइस अनलॉक करने के लिए, अनलॉक आइकॉन को दबाएं"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"चेहरे से अनलॉक किया. डिवाइस अनलॉक करने के लिए, अनलॉक आइकॉन को दबाएं."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"फिर से कोशिश करने के लिए ऊपर की ओर स्वाइप करें"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"एनएफ़सी इस्तेमाल करने के लिए स्क्रीन को अनलॉक करें"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"इस डिवाइस का मालिकाना हक आपके संगठन के पास है"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 66613d4..e0cd639 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrđeno"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Dodirnite Potvrdi za dovršetak"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Otključano pomoću lica. Pritisnite ikonu otključavanja da biste nastavili."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Otključano pomoću lica. Pritisnite da biste nastavili."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Lice je prepoznato. Pritisnite da biste nastavili."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice je prepoznato. Pritisnite ikonu otključavanja da biste nastavili."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentičnost provjerena"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Koristite PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Koristite uzorak"</string>
@@ -314,6 +317,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Prijeđite prstom prema gore da biste otvorili"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pritisnite ikonu otključavanja da biste otvorili"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Otključano pomoću lica. Pritisnite ikonu otključavanja da biste otvorili."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Otključano pomoću lica. Pritisnite da biste otvorili."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Lice je prepoznato. Pritisnite da biste otvorili."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Lice je prepoznato. Pritisnite ikonu otključavanja da biste otvorili."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Prijeđite prstom prema gore za ponovni pokušaj"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Otključajte da biste upotrijebili NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada vašoj organizaciji"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 89693de..bc8f8ef 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Megerősítve"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Koppintson a Megerősítés lehetőségre"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Zárolás arccal feloldva. Folytatás: Feloldásra koppintás."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Zárolás arccal feloldva. Koppintson a folytatáshoz."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Arc felismerve. Koppintson a folytatáshoz."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Arc felismerve. A folytatáshoz koppintson a Feloldásra."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Hitelesítve"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN-kód használata"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Minta használata"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Csúsztasson felfelé a megnyitáshoz"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Az eszköz használatához nyomja meg a feloldás ikonját"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Zárolás arccal feloldva. Eszköz használata: Feloldás ikon."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Zárolás arccal feloldva. Koppintson az eszköz használatához."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Arc felismerve. Koppintson az eszköz használatához."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Arc felismerve. Eszköz használata: Feloldás ikon."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Az újrapróbálkozáshoz csúsztassa felfelé az ujját"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Az NFC használatához oldja fel a képernyőzárat"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Ez az eszköz az Ön szervezetének tulajdonában van"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index e21f8e0..8a6949a 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Հաստատվեց"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ավարտելու համար հպեք «Հաստատել»"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Ապակողպվել է դեմքով։ Սեղմեք ապակողպման պատկերակը։"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ապակողպվել է դեմքով։ Սեղմեք շարունակելու համար։"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Դեմքը ճանաչվեց։ Սեղմեք շարունակելու համար։"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Դեմքը ճանաչվեց։ Սեղմեք ապակողպման պատկերակը։"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Նույնականացված է"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Օգտագործել PIN կոդ"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Օգտագործել նախշ"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Բացելու համար սահեցրեք վերև"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Բացեք՝ սեղմելով ապակողպման պատկերակը"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ապակողպվել է դեմքով։ Բացեք՝ սեղմելով ապակողպման պատկերակը։"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ապակողպվել է դեմքով։ Սեղմեք բացելու համար։"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Դեմքը ճանաչվեց։ Սեղմեք բացելու համար։"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Դեմքը ճանաչվեց։ Բացելու համար սեղմեք ապակողպման պատկերակը։"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Սահեցրեք վերև՝ նորից փորձելու համար"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ապակողպեք՝ NFC-ն օգտագործելու համար"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Այս սարքը պատկանում է ձեր կազմակերպությանը"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 3a15692..59a3ede 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Dikonfirmasi"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ketuk Konfirmasi untuk menyelesaikan"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Kunci dibuka dengan wajah. Tekan ikon buka kunci untuk melanjutkan."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Kunci dibuka dengan wajah. Tekan untuk melanjutkan."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Wajah dikenali. Tekan untuk melanjutkan."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Wajah dikenali. Tekan ikon buka kunci untuk melanjutkan."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Diautentikasi"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Gunakan PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Gunakan pola"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Geser ke atas untuk membuka"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Tekan ikon buka kunci untuk membuka"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Kunci dibuka dengan wajah. Tekan ikon buka kunci untuk membuka."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Kunci dibuka dengan wajah. Tekan untuk membuka."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Wajah dikenali. Tekan untuk membuka."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Wajah dikenali. Tekan ikon buka kunci untuk membuka."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Geser ke atas untuk mencoba lagi"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Buka kunci untuk menggunakan NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Perangkat ini milik organisasi Anda"</string>
@@ -333,7 +339,7 @@
     <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Mengisi daya dengan lambat • Penuh dalam waktu <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
     <string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Mengisi Daya dengan Dok • Penuh dalam waktu <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Beralih pengguna"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua aplikasi dan data di sesi ini akan dihapus."</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua aplikasi dan data dalam sesi ini akan dihapus."</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Selamat datang kembali, tamu!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Lanjutkan sesi Anda?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Mulai ulang"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 5ddb0a3..779de2d 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Staðfest"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ýttu á „Staðfesta“ til að ljúka"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Opnað með andliti. Ýttu á táknið taka úr lás til að halda áfram."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Opnað með andliti. Ýttu til að halda áfram."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Andlitið var greint. Ýttu til að halda áfram."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Andlitið var greint. Ýttu á opnunartáknið til að halda áfr."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Auðkennt"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Nota PIN-númer"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Nota mynstur"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Strjúktu upp til að opna"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Ýttu á táknið til að taka úr lás til að opna"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Opnað með andliti. Ýttu á táknið taka úr lás til að opna."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Opnað með andliti. Ýttu til að opna."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Andlitið var greint. Ýttu til að opna."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Andlitið var greint. Ýttu á opnunartáknið til að opna."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Strjúktu upp til að reyna aftur"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Taktu úr lás til að nota NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Þetta tæki tilheyrir fyrirtækinu þínu"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 55c854b..c24dd863 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confermato"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tocca Conferma per completare"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Sbloccato con il volto. Premi l\'icona Sblocca e continua."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Sbloccato con il volto. Premi per continuare."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Volto riconosciuto. Premi per continuare."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Volto riconosciuto. Premi l\'icona Sblocca e continua."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticazione eseguita"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utilizza PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usa sequenza"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Scorri verso l\'alto per aprire"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Premi l\'icona Sblocca per aprire"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Sbloccato con il volto. Premi l\'icona Sblocca per aprire."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Sbloccato con il volto. Premi per aprire."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Volto riconosciuto. Premi per aprire."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Volto riconosciuto. Premi l\'icona Sblocca per aprire."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Scorri verso l\'alto per riprovare"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Sblocca per usare NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Questo dispositivo appartiene alla tua organizzazione"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 6cbc0a5..76e6491 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"יש אישור"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"יש להקיש על \'אישור\' לסיום התהליך"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"הנעילה בוטלה בזיהוי פנים. להמשך, לוחצים על סמל ביטול הנעילה."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"מאומת"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"שימוש בקוד אימות"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"שימוש בקו ביטול נעילה"</string>
@@ -316,6 +322,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"צריך להחליק כדי לפתוח"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"לפתיחה, לוחצים על סמל ביטול הנעילה"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"הנעילה בוטלה בזיהוי פנים. פותחים בלחיצה על סמל ביטול הנעילה."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"יש להחליק למעלה כדי לנסות שוב"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"‏יש לבטל את הנעילה כדי להשתמש ב-NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"המכשיר הזה שייך לארגון שלך"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 4b7e130..cb459e9 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"確認しました"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"完了するには [確認] をタップしてください"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"顔でロック解除しました。ロック解除アイコンを押して続行します。"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"認証済み"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN を使用"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"パターンを使用"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"開くには上にスワイプします"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ロック解除アイコンを押して開きます"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"顔でロック解除しました。ロック解除アイコンを押して開きます。"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"上にスワイプしてもう一度お試しください"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC を使用するには、ロックを解除してください"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"これは組織が所有するデバイスです"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 160927f..70a3ad6 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"დადასტურებული"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"დასასრულებლად შეეხეთ „დადასტურებას“"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"განიბლოკა სახით. გასაგრძელებლად დააჭირეთ განბლოკვის ხატულას."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"განიბლოკა სახით. დააჭირეთ გასაგრძელებლად."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ამოცნობილია სახით. დააჭირეთ გასაგრძელებლად."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ამოცნობილია სახით. გასაგრძელებლად დააჭირეთ განბლოკვის ხატულას."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ავტორიზებულია"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN-კოდის გამოყენება"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ნიმუშის გამოყენება"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"გასახსნელად გადაფურცლეთ ზემოთ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"გასახსნელად დააჭირეთ განბლოკვის ხატულას"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"განიბლოკა სახით. გასახსნელად დააჭირეთ განბლოკვის ხატულას."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"განიბლოკა სახით. დააჭირეთ გასახსნელად."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ამოცნობილია სახით. დააჭირეთ გასახსნელად."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"ამოცნობილია სახით. გასახსნელად დააჭირეთ განბლოკვის ხატულას."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"ხელახლა საცდელად გადაფურცლეთ ზემოთ"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"განბლოკეთ NFC-ის გამოსაყენებლად"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 6b233c8..9dbea98 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Расталды"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Аяқтау үшін \"Растау\" түймесін түртіңіз."</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Бет үлгісі арқылы ашылды. Жалғастыру үшін құлыпты ашу белгішесін басыңыз."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аутентификацияланған"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN кодын пайдалану"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Өрнекті пайдалану"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Ашу үшін жоғары қарай сырғытыңыз."</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Ашу үшін құлыпты ашу белгішесін басыңыз."</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Бет үлгісі арқылы ашылды. Ашу үшін құлыпты ашу белгішесін басыңыз."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"Әрекетті қайталау үшін жоғары сырғытыңыз."</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC пайдалану үшін құлыпты ашыңыз."</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Бұл құрылғы ұйымыңызға тиесілі."</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 7dcf066..3d8504e 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"បានបញ្ជាក់"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ចុច \"បញ្ជាក់\" ដើម្បីបញ្ចប់"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"បានដោះសោ​ដោយប្រើមុខ។ សូមចុចរូបដោះសោ ដើម្បីបន្ត។"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"បាន​ផ្ទៀងផ្ទាត់"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ប្រើកូដ PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ប្រើ​លំនាំ"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"អូសឡើងលើ​ដើម្បីបើក"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ចុចរូបដោះសោ ដើម្បីបើក"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"បានដោះសោ​ដោយប្រើមុខ។ សូមចុចរូបដោះសោ ដើម្បីបើក។"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"អូសឡើងលើ ដើម្បី​ព្យាយាម​ម្ដងទៀត"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"ដោះសោ ដើម្បីប្រើ NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ឧបករណ៍​នេះគឺជា​កម្មសិទ្ធិរបស់​ស្ថាប័ន​អ្នក"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index f6a38b8..0ce8ff8 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ಪೂರ್ಣಗೊಳಿಸಲು ದೃಢೀಕರಿಸಿ ಅನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ಪಿನ್ ಬಳಸಿ"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ಪ್ಯಾಟರ್ನ್ ಬಳಸಿ"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"ತೆರೆಯಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ತೆರೆಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ತೆರೆಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ಬಳಸಲು ಅನ್‌ಲಾಕ್ ಮಾಡಿ"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ಈ ಸಾಧನವು ನಿಮ್ಮ ಸಂಸ್ಥೆಗೆ ಸೇರಿದೆ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 1f4f913..c0d8279 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"확인함"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"완료하려면 확인을 탭하세요."</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"얼굴 인식으로 잠금 해제되었습니다. 계속하려면 잠금 해제 아이콘을 누르세요."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"인증됨"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN 사용"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"패턴 사용"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"위로 스와이프하여 열기"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"기기를 열려면 잠금 해제 아이콘을 누르세요."</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"얼굴 인식으로 잠금 해제되었습니다. 기기를 열려면 잠금 해제 아이콘을 누르세요."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"위로 스와이프하여 다시 시도해 주세요"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"잠금 해제하여 NFC 사용"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"내 조직에 속한 기기입니다."</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 9314c9d..2bef2b3 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Ырасталды"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Бүтүрүү үчүн \"Ырастоо\" баскычын басыңыз"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Кулпусун жүзүңүз менен ачтыңыз. Улантуу үчүн кулпусун ачуу сүрөтчөсүн басыңыз."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Кулпусун жүзүңүз менен ачтыңыз. Улантуу үчүн басыңыз."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Жүз таанылды. Улантуу үчүн басыңыз."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Жүз таанылды. Улантуу үчүн кулпусун ачуу сүрөтчөсүн басыңыз."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аныктыгы текшерилди"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN кодду колдонуу"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Графикалык ачкычты колдонуу"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Ачуу үчүн өйдө сүрүңүз"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Ачуу үчүн кулпусун ачуу сүрөтчөсүн басыңыз"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Кулпусун жүзүңүз менен ачтыңыз. Ачуу үчүн кулпусун ачуу сүрөтчөсүн басыңыз."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Кулпусун жүзүңүз менен ачтыңыз. Ачуу үчүн басыңыз."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Жүз таанылды. Ачуу үчүн басыңыз."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Жүз таанылды. Ачуу үчүн кулпусун ачуу сүрөтчөсүн басыңыз."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Кайталоо үчүн экранды өйдө сүрүңүз"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC колдонуу үчүн түзмөктүн кулпусун ачыңыз"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Бул түзмөк уюмуңузга таандык"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 2a52ab6..6858395 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ຢືນຢັນແລ້ວ"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ແຕະຢືນຢັນເພື່ອສຳເລັດ"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ປົດລັອກດ້ວຍໜ້າແລ້ວ. ກົດໄອຄອນປົດລັອກເພື່ອສືບຕໍ່."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ປົດລັອກດ້ວຍໜ້າແລ້ວ. ກົດເພື່ອສືບຕໍ່."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ຈຳແນກໜ້າໄດ້ແລ້ວ. ກົດເພື່ອສືບຕໍ່."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ຈຳແນກໜ້າໄດ້ແລ້ວ. ກົດໄອຄອນປົດລັອກເພື່ອສືບຕໍ່."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ຮັບຮອງຄວາມຖືກຕ້ອງແລ້ວ"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ໃຊ້ PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ໃຊ້ຮູບແບບ"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"ປັດຂຶ້ນເພື່ອເປີດ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ກົດໄອຄອນປົດລັອກເພື່ອເປີດ"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ປົດລັອກດ້ວຍໜ້າແລ້ວ. ກົດໄອຄອນປົດລັອກເພື່ອເປີດ."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ປົດລັອກດ້ວຍໜ້າແລ້ວ. ກົດເພື່ອເປີດ."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ຈຳແນກໜ້າໄດ້ແລ້ວ. ກົດເພື່ອເປີດ."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"ຈຳແນກໜ້າໄດ້ແລ້ວ. ກົດໄອຄອນປົດລັອກເພື່ອເປີດ."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"ປັດຂຶ້ນເພື່ອລອງໃໝ່"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"ປົດລັອກເພື່ອໃຊ້ NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ອຸປະກອນນີ້ເປັນຂອງອົງການທ່ານ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 6a7898a..f596720 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Patvirtinta"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Paliesk. „Patvirtinti“, kad užbaigtumėte"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Atrakinta pagal veidą. Pasp. atrak. pikt., kad tęstumėte."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikuota"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Naudoti PIN kodą"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Naudoti atrakinimo piešinį"</string>
@@ -316,6 +322,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Perbraukite aukštyn, kad atidarytumėte"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Paspauskite atrakinimo piktogramą, kad atidarytumėte"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Atrakinta pagal veidą. Pasp. atr. pikt., kad atidarytumėte."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"Jei norite bandyti dar kartą, perbraukite aukštyn"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Norėdami naudoti NFC, atrakinkite"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Šis įrenginys priklauso jūsų organizacijai"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index b53e763..7f98fed 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Apstiprināts"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Lai pabeigtu, pieskarieties Apstiprināt"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Atbloķēta ar seju. Turpināt: nospiediet atbloķēšanas ikonu."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikācija veikta"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Izmantot PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Izmantot kombināciju"</string>
@@ -314,6 +320,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Velciet augšup, lai atvērtu"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Lai atvērtu, nospiediet atbloķēšanas ikonu"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Atbloķēta ar seju. Atvērt: nospiediet atbloķēšanas ikonu."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"Velciet augšup, lai mēģinātu vēlreiz"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Atbloķējiet ierīci, lai izmantotu NFC."</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Šī ierīce pieder jūsu organizācijai."</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 2dee0e0..060e964 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Потврдено"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Допрете „Потврди“ за да се заврши"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Отклучено со лице. Притиснете ја иконата за отклучување за да продолжите."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Проверена"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Користи PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Користи шема"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Повлечете за да отворите"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Притиснете ја иконата за отклучување за да отворите"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Отклучено со лице. Притиснете ја иконата за отклучување за да отворите."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"Повлечете нагоре за да се обидете повторно"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Отклучете за да користите NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Уредов е во сопственост на организацијата"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index e32e305..38a4317 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"സ്ഥിരീകരിച്ചു"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"പൂർത്തിയാക്കാൻ സ്ഥിരീകരിക്കുക ടാപ്പ് ചെയ്യൂ"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്‌തു. തുടരാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്‌തു. തുടരാൻ അമർത്തുക."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"മുഖം തിരിച്ചറിഞ്ഞു. തുടരാൻ അമർത്തുക."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"മുഖം തിരിച്ചറിഞ്ഞു. തുടരാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"പരിശോധിച്ചുറപ്പിച്ചു"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"പിൻ ഉപയോഗിക്കുക"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"പാറ്റേൺ ഉപയോഗിക്കുക"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"തുറക്കാൻ മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"തുറക്കാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്‌തു. തുറക്കാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്‌തു. തുറക്കാൻ അമർത്തുക."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"മുഖം തിരിച്ചറിഞ്ഞു. തുറക്കാൻ അമർത്തുക."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"മുഖം തിരിച്ചറിഞ്ഞു. തുറക്കാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"വീണ്ടും ശ്രമിക്കാൻ മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ഉപയോഗിക്കാൻ അൺലോക്ക് ചെയ്യുക"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ഈ ഉപകരണം നിങ്ങളുടെ സ്ഥാപനത്തിന്റേതാണ്"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index b953a28..13aedc7 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Баталгаажсан"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Дуусгахын тулд баталгаажуулахыг товших"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Царайгаар түгжээг тайлсан. Үргэлжлүүлэхийн тулд түгжээг тайлах дүрс тэмдэг дээр дараарай."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Царайгаар түгжээг тайлсан. Үргэлжлүүлэхийн тулд дарна уу."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Царайг таньсан. Үргэлжлүүлэхийн тулд дарна уу."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Царайг таньсан. Үргэлжлүүлэх бол түгжээг тайлах дүрсийг дар."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Баталгаажуулагдсан"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ПИН ашиглах"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Хээ ашиглах"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Нээхийн тулд дээш шударна уу"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Нээхийн тулд түгжээг тайлах дүрс тэмдэг дээр дараарай"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Царайгаар түгжээг тайлсан. Нээхийн тулд түгжээг тайлах дүрс тэмдэг дээр дараарай."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Царайгаар түгжээг тайлсан. Нээхийн тулд дарна уу."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Царайг таньсан. Нээхийн тулд дарна уу."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Царайг таньсан. Нээх бол түгжээг тайлах дүрсийг дарна уу."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Дахин оролдохын тулд дээш шударна уу"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC-г ашиглахын тулд түгжээг тайлна уу"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Энэ төхөөрөмж танай байгууллагад харьяалагддаг"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 4add96d..1424efc 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"निश्चित केले"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"पूर्ण करण्यासाठी खात्री करा वर टॅप करा"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"चेहऱ्याने अनलॉक केले. सुरू ठेवण्यासाठी अनलॉक करा आयकन दाबा."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ऑथेंटिकेशन केलेले"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"पिन वापरा"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"पॅटर्न वापरा"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"उघडण्यासाठी वर स्वाइप करा"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"उघडण्यासाठी अनलॉक करा आयकन दाबा"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"चेहऱ्याने अनलॉक केले. उघडण्यासाठी अनलॉक करा आयकन दाबा."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"पुन्हा प्रयत्न करण्यासाठी वर स्‍वाइप करा"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC वापरण्यासाठी स्क्रीन अनलॉक करा"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"हे डिव्हाइस तुमच्या संस्थेचे आहे"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 4b31112..4c90c88 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Disahkan"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ketik Sahkan untuk menyelesaikan"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Dibuka kunci dengan wajah. Tekan ikon buka kunci untuk teruskan."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Dibuka kunci dengan wajah. Tekan untuk meneruskan."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Wajah dicam. Tekan untuk meneruskan."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Wajah dicam. Tekan ikon buka kunci untuk meneruskan."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Disahkan"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Gunakan PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Gunakan corak"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Leret ke atas untuk buka"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Tekan ikon buka kunci untuk buka"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Dibuka kunci dengan wajah. Tekan ikon buka kunci untuk buka."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Dibuka kunci dengan wajah. Tekan untuk membuka."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Wajah dicam. Tekan untuk membuka."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Wajah dicam. Tekan ikon buka kunci untuk membuka."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Leret ke atas untuk mencuba lagi"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Buka kunci untuk menggunakan NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Peranti ini milik organisasi anda"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 6f9250c..7260936 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"အတည်ပြုပြီးပြီ"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"အပြီးသတ်ရန်အတွက် \'အတည်ပြုရန်\' ကို တို့ပါ"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"မျက်နှာဖြင့် ဖွင့်ထားသည်။ ရှေ့ဆက်ရန် လော့ခ်ဖွင့်သင်္ကေတကို နှိပ်ပါ။"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"မျက်နှာဖြင့် ဖွင့်ထားသည်။ ရှေ့ဆက်ရန် နှိပ်ပါ။"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"မျက်နှာ မှတ်မိသည်။ ရှေ့ဆက်ရန် နှိပ်ပါ။"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"မျက်နှာ မှတ်မိသည်။ ရှေ့ဆက်ရန် လော့ခ်ဖွင့်သင်္ကေတကို နှိပ်ပါ။"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"အထောက်အထားစိစစ်ပြီးပြီ"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ပင်နံပါတ်သုံးရန်"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ပုံစံကို သုံးရန်"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"ဖွင့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ဖွင့်ရန် လော့ခ်ဖွင့်သင်္ကေတကို နှိပ်ပါ"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"မျက်နှာဖြင့် ဖွင့်ထားသည်။ ဖွင့်ရန် လော့ခ်ဖွင့်သင်္ကေတကို နှိပ်ပါ။"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"မျက်နှာဖြင့် ဖွင့်ထားသည်။ ဖွင့်ရန် နှိပ်ပါ။"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"မျက်နှာ မှတ်မိသည်။ ဖွင့်ရန် နှိပ်ပါ။"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"မျက်နှာ မှတ်မိသည်။ ဖွင့်ရန် လော့ခ်ဖွင့်သင်္ကေတကို နှိပ်ပါ။"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"ထပ်စမ်းကြည့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ကို အသုံးပြုရန် လော့ခ်ဖွင့်ပါ"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ဤစက်ကို သင့်အဖွဲ့အစည်းက ပိုင်ဆိုင်သည်"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index c946ca5..8c9a262 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bekreftet"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Trykk på Bekreft for å fullføre"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Låst opp med ansiktet. Trykk på lås opp-ikon for å fortsette"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Låst opp med ansiktet. Trykk for å fortsette."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ansiktet er gjenkjent. Trykk for å fortsette."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansiktet er gjenkjent. Trykk på lås opp-ikon for å fortsette"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentisert"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Bruk PIN-kode"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Bruk mønster"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Sveip opp for å åpne"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Trykk på lås opp-ikonet for å åpne"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Låst opp med ansiktet. Trykk på lås opp-ikon for å fortsette"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Låst opp med ansiktet. Trykk for å åpne."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ansiktet er gjenkjent. Trykk for å åpne."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Ansiktet er gjenkjent. Trykk på lås opp-ikon for å fortsette"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Sveip opp for å prøve igjen"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Lås opp for å bruke NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Denne enheten tilhører organisasjonen din"</string>
@@ -333,7 +339,7 @@
     <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Lader sakte • Fulladet om <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
     <string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ladedokk • Fulladet om <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Bytt bruker"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle appene og all informasjon i denne økten slettes."</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apper og data i denne økten blir slettet."</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Velkommen tilbake, gjest!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vil du fortsette økten?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start på nytt"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index d285c76..9fa75a8 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"पुष्टि भयो"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"पूरा गर्नका लागि पुष्टि गर्नुहोस् नामक विकल्पमा ट्याप गर्नुहोस्"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"अनुहार प्रयोग गरी अनलक गरियो। जारी राख्न अनलक आइकनमा थिच्नुहोस्।"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"प्रमाणीकरण गरियो"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN प्रयोग गर्नुहोस्"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ढाँचा प्रयोग गर्नुहोस्"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"खोल्न माथितिर स्वाइप गर्नुहोस्"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"खोल्न अनलक आइकनमा थिच्नुहोस्"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"अनुहार प्रयोग गरी अनलक गरियो। खोल्न अनलक आइकनमा थिच्नुहोस्।"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"फेरि प्रयास गर्न माथितिर स्वाइप गर्नुहोस्"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC प्रयोग गर्न स्क्रिन अनलक गर्नुहोस्"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"यो डिभाइस तपाईंको सङ्गठनको स्वामित्वमा छ"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index af703fd..6235dd5 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bevestigd"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tik op Bevestigen om te voltooien"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Ontgrendeld via gezicht. Druk op het ontgrendelicoon."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ontgrendeld via gezicht. Druk om door te gaan."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Gezicht herkend. Druk om door te gaan."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gezicht herkend. Druk op het ontgrendelicoon."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Geverifieerd"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Pincode gebruiken"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Patroon gebruiken"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Swipe omhoog om te openen"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Druk op het ontgrendelicoon om te openen"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ontgrendeld via gezicht. Druk op het ontgrendelicoon."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ontgrendeld via gezicht. Druk om te openen."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Gezicht herkend. Druk om te openen."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Gezicht herkend. Druk op het ontgrendelicoon."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Swipe omhoog om het opnieuw te proberen"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ontgrendel het apparaat om NFC te gebruiken"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Dit apparaat is eigendom van je organisatie"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 61be843..a8299a5 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ସୁନିଶ୍ଚିତ କରାଯାଇଛି"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ସମ୍ପୂର୍ଣ୍ଣ କରିବାକୁ ସୁନିଶ୍ଚିତ କରନ୍ତୁରେ ଟାପ୍ କରନ୍ତୁ"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ।"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ପ୍ରାମାଣିକତା ହୋଇଛି"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ପାଟର୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"ଖୋଲିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ଖୋଲିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଖୋଲିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ।"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"ପୁଣି ଚେଷ୍ଟା କରିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ବ୍ୟବହାର କରିବାକୁ ଅନଲକ୍ କରନ୍ତୁ"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ଏହି ଡିଭାଇସଟି ଆପଣଙ୍କ ସଂସ୍ଥାର ଅଟେ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index e03dbf3..ff40b55 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ਪੁਸ਼ਟੀ ਕੀਤੀ ਗਈ"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ਪੂਰਾ ਕਰਨ ਲਈ ਪੁਸ਼ਟੀ ਕਰੋ \'ਤੇ ਟੈਪ ਕਰੋ"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਜਾਰੀ ਰੱਖਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ।"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ਪ੍ਰਮਾਣਿਤ ਹੋਇਆ"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ਪਿੰਨ ਵਰਤੋ"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ਪੈਟਰਨ ਵਰਤੋ"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"ਖੋਲ੍ਹਣ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"ਖੋਲ੍ਹਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਖੋਲ੍ਹਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ।"</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਲਈ ਉੱਤੇ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ਵਰਤਣ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ਇਹ ਡੀਵਾਈਸ ਤੁਹਾਡੀ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 0ebbb49..d439def 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potwierdzono"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Aby zakończyć, kliknij Potwierdź"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Odblokowano skanem twarzy. Aby kontynuować, kliknij ikonę odblokowywania."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Uwierzytelniono"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Użyj kodu PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Użyj wzoru"</string>
@@ -316,6 +322,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Przesuń w górę, by otworzyć"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Aby otworzyć, kliknij ikonę odblokowywania"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odblokowano skanem twarzy. Aby otworzyć, kliknij ikonę odblokowywania."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"Przesuń w górę, by spróbować ponownie"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Odblokuj, by użyć komunikacji NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"To urządzenie należy do Twojej organizacji"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 8ae76bc..36ac0d2 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmada"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toque em \"Confirmar\" para concluir"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Desbloqueado pelo rosto. Pressione o ícone de desbloqueio para continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado pelo rosto. Pressione para continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rosto reconhecido. Pressione para continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Pressione o ícone para continuar."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar padrão"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Deslize para cima para abrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pressione o ícone de desbloqueio para abrir"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueado pelo rosto. Pressione o ícone de desbloqueio para abrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueado pelo rosto. Pressione para abrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Rosto reconhecido. Pressione para abrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Rosto reconhecido. Pressione o ícone de desbloq. para abrir."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Deslize para cima para tentar novamente"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloqueie para usar a NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence à sua organização"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index f9c4bee..fc40c5d 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmado"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toque em Confirmar para concluir."</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Desbloqueado c/ rosto. Prima o ícone de desb. p/ continuar."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utilizar PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Utilizar padrão"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Deslize rapidamente para cima para abrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Prima o ícone de desbloqueio para abrir"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueado com o rosto. Prima o ícone de desbl. p/ abrir."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"Deslize rapidamente para cima para tentar novamente."</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquear para utilizar o NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence à sua entidade."</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 8ae76bc..36ac0d2 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmada"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toque em \"Confirmar\" para concluir"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Desbloqueado pelo rosto. Pressione o ícone de desbloqueio para continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado pelo rosto. Pressione para continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rosto reconhecido. Pressione para continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Pressione o ícone para continuar."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar padrão"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Deslize para cima para abrir"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pressione o ícone de desbloqueio para abrir"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueado pelo rosto. Pressione o ícone de desbloqueio para abrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueado pelo rosto. Pressione para abrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Rosto reconhecido. Pressione para abrir."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Rosto reconhecido. Pressione o ícone de desbloq. para abrir."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Deslize para cima para tentar novamente"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloqueie para usar a NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence à sua organização"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index d37b52b..683b395 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmat"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Atingeți Confirmați pentru a finaliza"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"S-a deblocat cu ajutorul feței. Apăsați pictograma de deblocare pentru a continua"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"S-a deblocat cu ajutorul feței. Apăsați pentru a continua."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Chipul a fost recunoscut. Apăsați pentru a continua."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Chip recunoscut. Apăsați pictograma de deblocare să continuați."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentificat"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Folosiți PIN-ul"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Folosiți modelul"</string>
@@ -314,6 +317,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Glisați în sus pentru a deschide"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Apăsați pictograma de deblocare pentru a deschide"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"S-a deblocat cu ajutorul feței. Apăsați pictograma de deblocare pentru a deschide"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"S-a deblocat cu ajutorul feței. Apăsați pentru a deschide."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Chipul a fost recunoscut. Apăsați pentru a deschide."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Chip recunoscut. Apăsați pictograma de deblocare pentru a deschide"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Glisați pentru a încerca din nou"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Deblocați pentru a folosi NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Dispozitivul aparține organizației dvs."</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index e1b48cd..5733352 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Подтверждено"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Нажмите \"Подтвердить\""</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Сканирование выполнено. Нажмите на значок разблокировки."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Разблокировано сканированием лица. Нажмите, чтобы продолжить."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лицо распознано. Нажмите, чтобы продолжить."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицо распознано. Нажмите на значок разблокировки."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аутентификация выполнена"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN-код"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Использовать графический ключ"</string>
@@ -316,6 +319,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Проведите вверх, чтобы открыть"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Нажмите на значок разблокировки."</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Сканирование выполнено. Нажмите на значок разблокировки."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Разблокировано сканированием лица. Нажмите, чтобы открыть."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лицо распознано. Нажмите, чтобы открыть."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Лицо распознано. Нажмите на значок разблокировки."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Чтобы повторить попытку, проведите вверх"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Чтобы использовать NFC, разблокируйте устройство."</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Это устройство принадлежит вашей организации"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index a3a8534..65a07ef 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"තහවුරු කළා"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"සම්පූර්ණ කිරීමට තහවුරු කරන්න තට්ටු කර."</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"මුහුණ මගින් අගුලු හරින ලදි. දිගටම කරගෙන යාමට අගුලු හැරීමේ නිරූපකය ඔබන්න."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"මුහුණ මගින් අගුලු හරින ලදි. ඉදිරියට යාමට ඔබන්න."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"මුහුණ හඳුනා ගන්නා ලදි. ඉදිරියට යාමට ඔබන්න."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"මුහුණ හඳුනා ගන්නා ලදි. ඉදිරියට යාමට අගුලු හැරීමේ නිරූපකය ඔබන්න."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"සත්‍යාපනය විය"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN භාවිත කරන්න"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"රටාව භාවිත කරන්න"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"විවෘත කිරීමට ස්වයිප් කරන්න"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"විවෘත කිරීමට අගුලු හැරීමේ නිරූපකය ඔබන්න"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"මුහුණ මගින් අගුලු හරින ලදි. විවෘත කිරීමට අගුලු හැරීමේ නිරූපකය ඔබන්න."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"මුහුණ මගින් අගුලු හරින ලදි. විවෘත කිරීමට ඔබන්න."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"මුහුණ හඳුනා ගන්නා ලදි. විවෘත කිරීමට ඔබන්න."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"මුහුණ හඳුනා ගන්නා ලදි. විවෘත කිරීමට අගුලු හැරීමේ නිරූපකය ඔබන්න."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"නැවත උත්සාහ කිරීමට ඉහළට ස්වයිප් කරන්න"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC භාවිත කිරීමට අගුලු හරින්න"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"මෙම උපාංගය ඔබේ සංවිධානයට අයිතිය"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 2d46829..0b46c88 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrdené"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Overenie dokončíte klepnutím na Potvrdiť"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Odomknuté tvárou. Pokračujte klepnutím na ikonu odomknutia"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odomknuté tvárou. Pokračujte stlačením."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Tvár bola rozpoznaná. Pokračujte stlačením."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Tvár bola rozpoznaná. Pokračujte stlačením ikony odomknutia"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Overené"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Použiť PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Použiť vzor"</string>
@@ -316,6 +319,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Otvorte potiahnutím prstom nahor"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Otvorte klepnutím na ikonu odomknutia"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odomknuté tvárou. Otvorte klepnutím na ikonu odomknutia."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Odomknuté tvárou. Otvorte stlačením."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Tvár bola rozpoznaná. Otvorte stlačením."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Tvár bola rozpoznaná. Otvorte stlačením ikony odomknutia."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Potiahnutím nahor to skúste znova"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ak chcete použiť NFC, odomknite"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Toto zariadenie patrí vašej organizácii"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index aab95f1..8f15cfd 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potrjeno"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Za dokončanje se dotaknite »Potrdite«"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Odklenjeno z obrazom. Za nadaljevanje pritisnite ikono za odklepanje."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odklenjeno z obrazom. Pritisnite za nadaljevanje."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Obraz je prepoznan. Pritisnite za nadaljevanje."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Obraz je prepoznan. Za nadaljevanje pritisnite ikono za odklepanje."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Preverjena pristnost"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Uporabi kodo PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Uporabi vzorec"</string>
@@ -316,6 +319,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Povlecite navzgor, da odprete"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Za odpiranje pritisnite ikono za odklepanje."</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odklenjeno z obrazom. Za odpiranje pritisnite ikono za odklepanje."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Odklenjeno z obrazom. Pritisnite za odpiranje."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Obraz je prepoznan. Pritisnite za odpiranje."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Obraz je prepoznan. Za odpiranje pritisnite ikono za odklepanje."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Povlecite navzgor za vnovičen poskus"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Odklenite napravo, če želite uporabljati NFC."</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Ta naprava pripada vaši organizaciji"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 42aae9f..0205062 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Konfirmuar"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Trokit \"Konfirmo\" për ta përfunduar"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"U shkyç me fytyrë. Shtyp ikonën e shkyçjes për të vazhduar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"U shkyç me fytyrë. Shtyp për të vazhduar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Fytyra u njoh. Shtyp për të vazhduar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Fytyra u njoh. Shtyp ikonën e shkyçjes për të vazhduar."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"U vërtetua"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Përdor kodin PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Përdor motivin"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Rrëshqit lart për ta hapur"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Shtyp ikonën e shkyçjes për ta hapur"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"U shkyç me fytyrë. Shtyp ikonën e shkyçjes për ta hapur."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"U shkyç me fytyrë. Shtyp për ta hapur."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Fytyra u njoh. Shtyp për ta hapur."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Fytyra u njoh. Shtyp ikonën e shkyçjes për ta hapur."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Rrëshqit lart për të provuar përsëri"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Shkyçe për të përdorur NFC-në"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Kjo pajisje i përket organizatës sate"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 8b9b088..7d85e4c 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Потврђено"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Додирните Потврди да бисте завршили"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Откључано је лицем. Притисните икону откључавања за наставак"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Откључано је лицем. Притисните да бисте наставили."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лице је препознато. Притисните да бисте наставили."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лице препознато. Притисните икону откључавања за наставак."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Идентитет је потврђен"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Користите PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Користите шаблон"</string>
@@ -314,6 +317,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Превуците нагоре да бисте отворили"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Притисните икону откључавања за отварање"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Откључано је лицем. Притисните икону откључавања за отварање"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Откључано је лицем. Притисните да бисте отворили."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лице је препознато. Притисните да бисте отворили."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Лице препознато. Притисните икону откључавања за отварање."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Превуците нагоре да бисте пробали поново"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Откључајте да бисте користили NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Овај уређај припада организацији"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 9206685..4ed90a6 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bekräftat"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Slutför genom att trycka på Bekräfta"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Upplåst med ansiktslås. Tryck på ikonen lås upp för att fortsätta."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Upplåst med ansiktslås. Tryck för att fortsätta."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ansiktet har identifierats. Tryck för att fortsätta."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansiktet har identifierats. Tryck på ikonen lås upp."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentiserad"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Använd pinkod"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Använd mönster"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Öppna genom att svepa uppåt"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Tryck på ikonen lås upp för att öppna"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Upplåst med ansiktslås. Tryck på ikonen lås upp för att öppna."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Upplåst med ansiktslås. Tryck för att öppna."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ansiktet har identifierats. Tryck för att öppna."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Ansiktet har identifierats. Tryck på ikonen lås upp."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Svep uppåt om du vill försöka igen"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Lås upp om du vill använda NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Den här enheten tillhör organisationen"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index ad5d132..23acb09 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Imethibitishwa"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Gusa Thibitisha ili ukamilishe"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Imefunguliwa kwa kutumia uso wako. Bonyeza aikoni ya kufungua ili uendelee."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Imefunguliwa kwa kutumia uso wako. Bonyeza ili uendelee."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Uso umetambuliwa. Bonyeza ili uendelee."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Uso umetambuliwa. Bonyeza aikoni ya kufungua ili uendelee."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Umethibitishwa"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Tumia PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Tumia mchoro"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Telezesha kidole juu ili ufungue"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Bonyeza aikoni ya kufungua ili ufungue"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Imefunguliwa kwa kutumia uso wako. Bonyeza aikoni ya kufungua ili ufungue."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Imefunguliwa kwa kutumia uso wako. Bonyeza ili ufungue."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Uso umetambuliwa. Bonyeza ili ufungue."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Uso umetambuliwa. Bonyeza aikoni ya kufungua ili ufungue."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Telezesha kidole juu ili ujaribu tena"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Fungua ili utumie NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Kifaa hiki kinamilikiwa na shirika lako"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index d66bc41..a9dec1f 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"உறுதிப்படுத்தப்பட்டது"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"முடிக்க \'உறுதிப்படுத்துக\' என்பதை தட்டவும்"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. தொடர, அன்லாக் ஐகானை அழுத்துக."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"அங்கீகரிக்கப்பட்டது"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"பின்னைப் பயன்படுத்து"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"பேட்டர்னைப் பயன்படுத்து"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"திறப்பதற்கு மேல் நோக்கி ஸ்வைப் செய்யவும்"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"திறக்க, அன்லாக் ஐகானை அழுத்தவும்"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. திறக்க, அன்லாக் ஐகானை அழுத்துக."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"மீண்டும் முயல மேல்நோக்கி ஸ்வைப் செய்யவும்"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCயைப் பயன்படுத்த அன்லாக் செய்யவும்"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"இந்த சாதனம் உங்கள் நிறுவனத்துக்கு சொந்தமானது"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 8712825..3cc3d26 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"నిర్ధారించబడింది"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"పూర్తి చేయడానికి \"నిర్ధారించు\" నొక్కండి"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ముఖం ద్వారా అన్‌లాక్ చేయబడింది. కొనసాగించడానికి అన్‌లాక్ చిహ్నాన్ని నొక్కండి."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ప్రామాణీకరించబడింది"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"పిన్‌ను ఉపయోగించు"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ఆకృతిని ఉపయోగించు"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"తెరవడానికి, పైకి స్వైప్ చేయండి"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"తెరవడానికి అన్‌లాక్ చిహ్నాన్ని నొక్కండి"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ముఖం ద్వారా అన్‌లాక్ చేయబడింది. తెరవడానికి అన్‌లాక్ చిహ్నాన్ని నొక్కండి."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"మళ్ళీ ప్రయత్నించడానికి పైకి స్వైప్ చేయండి"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCని ఉపయోగించడానికి అన్‌లాక్ చేయండి"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ఈ పరికరం మీ సంస్థకు చెందినది"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 434c4f0..97806ce 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ยืนยันแล้ว"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"แตะยืนยันเพื่อดำเนินการให้เสร็จสมบูรณ์"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ปลดล็อกด้วยใบหน้าแล้ว กดไอคอนปลดล็อกเพื่อดำเนินการต่อ"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ปลดล็อกด้วยใบหน้าแล้ว กดเพื่อดำเนินการต่อ"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"จดจำใบหน้าได้ กดเพื่อดำเนินการต่อ"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"จดจำใบหน้าได้ กดไอคอนปลดล็อกเพื่อดำเนินการต่อ"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ตรวจสอบสิทธิ์แล้ว"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ใช้ PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ใช้รูปแบบ"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"เลื่อนขึ้นเพื่อเปิด"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"กดไอคอนปลดล็อกเพื่อเปิด"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ปลดล็อกด้วยใบหน้าแล้ว กดไอคอนปลดล็อกเพื่อเปิด"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ปลดล็อกด้วยใบหน้าแล้ว กดเพื่อเปิด"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"จดจำใบหน้าได้ กดเพื่อเปิด"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"จดจำใบหน้าได้ กดไอคอนปลดล็อกเพื่อเปิด"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"เลื่อนขึ้นเพื่อลองอีกครั้ง"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"ปลดล็อกเพื่อใช้ NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"องค์กรของคุณเป็นเจ้าของอุปกรณ์นี้"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 65c09eb..294fa00 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Nakumpirma"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"I-tap ang Kumpirmahin para kumpletuhin"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Na-unlock gamit ang mukha. Pindutin ang icon ng unlock para magpatuloy."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Na-unlock gamit ang mukha. Pindutin para magpatuloy."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Nakilala ang mukha. Pindutin para magpatuloy."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Nakilala ang mukha. Pindutin ang unlock para magpatuloy."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Na-authenticate"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Gumamit ng PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Gumamit ng pattern"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Mag-swipe pataas para buksan"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Pindutin ang icon ng unlock para buksan"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Na-unlock gamit ang mukha. Pindutin ang icon ng unlock para buksan."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Na-unlock gamit ang mukha. Pindutin para buksan."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Nakilala ang mukha. Pindutin para buksan."</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Nakilala ang mukha. Pindutin ang icon ng unlock para buksan."</string>
     <string name="keyguard_retry" msgid="886802522584053523">"Mag-swipe pataas para subukan ulit"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"I-unlock para magamit ang NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Pagmamay-ari ng iyong organisasyon ang device na ito"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index b7415fd..efa4043 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Onaylandı"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tamamlamak için Onayla\'ya dokunun"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Kilit, yüzünüzle açıldı. Kilit açma simgesine basın."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Kimliği Doğrulandı"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN kullan"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Deseni kullan"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Açmak için yukarı kaydırın"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Açmak için Kilit açma simgesine basın"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Kilit, yüzünüzle açıldı. Kilit açma simgesine basın."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"Tekrar denemek için yukarı kaydırın"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC\'yi kullanmak için kilidi açın"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Bu cihaz, kuruluşunuza ait"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 7a24191..66de3bb 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Підтверджено"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Щоб завершити, натисніть \"Підтвердити\""</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Розблоковано (фейсконтроль). Натисніть значок розблокування."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Автентифіковано"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Ввести PIN-код"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Намалювати ключ"</string>
@@ -316,6 +322,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Проведіть пальцем угору, щоб відкрити"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Щоб відкрити, натисніть значок розблокування."</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Розблоковано (фейсконтроль). Натисніть значок розблокування."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"Проведіть пальцем угору, щоб повторити спробу"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Розблокуйте екран, щоб скористатись NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Цей пристрій належить вашій організації"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 6ba3c4f..61a20c3 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"تصدیق شدہ"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"مکمل کرنے کیلئے \'تصدیق کریں\' تھپتھپائیں"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"چہرے سے انلاک کیا گیا۔ جاری رکھنے کیلئے انلاک آئیکن دبائیں۔"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"چہرے سے انلاک کیا گیا۔ جاری رکھنے کے لیے دبائیں۔"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"چہرے کی شناخت ہو گئی۔ جاری رکھنے کے لیے دبائیں۔"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"چہرے کی شناخت ہو گئی۔ جاری رکھنے کیلئے انلاک آئیکن دبائیں۔"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"تصدیق کردہ"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"‏PIN استعمال کریں"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"پیٹرن کا استعمال کریں"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"کھولنے کے لیے اوپر سوائپ کريں"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"کھولنے کیلئے انلاک آئیکن دبائیں"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"چہرے سے انلاک کیا گیا۔ کھولنے کیلئے انلاک آئیکن دبائیں۔"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"چہرے سے انلاک کیا گیا۔ کھولنے کے لیے دبائیں۔"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"چہرے کی شناخت ہو گئی۔ کھولنے کے لیے دبائیں۔"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"چہرے کی شناخت ہو گئی۔ کھولنے کیلئے انلاک آئیکن دبائیں۔"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"دوبارہ کوشش کرنے کے لیے اوپر سوائپ کريں"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"‏NFC استعمال کرنے کیلئے غیر مقفل کریں"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"یہ آلہ آپ کی تنظیم کا ہے"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index a2831e0..fe583f5 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Tasdiqlangan"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tasdiqlash uchun tegining"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Yuz orqali ochilgan. Davom etish uchun ochish belgisini bosing."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Tasdiqlandi"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN kod kiritish"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Grafik kalitdan foydalanish"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Ochish uchun tepaga suring"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Ochish uchun ochish belgisini bosing"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Yuz orqali ochilgan. Ochish uchun ochish belgisini bosing."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"Qayta urinish uchun tepaga suring"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ishlatish uchun qurilma qulfini oching"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Bu qurilma tashkilotingizga tegishli"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index ef782a2..9fd4f31 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Ðã xác nhận"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Nhấn vào Xác nhận để hoàn tất"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Đã mở khoá bằng khuôn mặt. Nhấn biểu tượng mở khoá để tiếp tục."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Đã xác thực"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Dùng mã PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Dùng hình mở khóa"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Vuốt lên để mở"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Nhấn biểu tượng mở khoá để mở"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Đã mở khoá bằng khuôn mặt. Nhấn biểu tượng mở khoá để mở."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"Vuốt lên để thử lại"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Mở khóa để sử dụng NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Thiết bị này thuộc về tổ chức của bạn"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index ac1b790..3fa6c60 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"已确认"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"点按“确认”即可完成"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"已通过面孔识别解锁。按下解锁图标即可继续。"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"已通过面孔识别解锁。点按即可继续。"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"识别出面孔。点按即可继续。"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"识别出面孔。按下解锁图标即可继续。"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"已经过身份验证"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"使用 PIN 码"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"使用图案"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"向上滑动即可打开"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"按下解锁图标即可打开"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"已通过面孔识别解锁。按下解锁图标即可打开。"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"已通过面孔识别解锁。点按即可打开。"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"识别出面孔。点按即可打开。"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"识别出面孔。按下解锁图标即可打开。"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"向上滑动即可重试"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"需要解锁才能使用 NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"此设备归贵单位所有"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 436e293..6950c20 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"已確認"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"輕按 [確定] 以完成"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"已使用面孔解鎖。按解鎖圖示即可繼續。"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"已使用面孔解鎖。按下即可繼續操作。"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"已識別面孔。按下即可繼續操作。"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"已識別面孔。按解鎖圖示即可繼續。"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"驗證咗"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"使用 PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"使用圖案"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"按解鎖圖示即可開啟"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"已使用面孔解鎖。按解鎖圖示即可開啟。"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"已使用面孔解鎖。按下即可開啟。"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"已識別面孔。按下即可開啟。"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"已識別面孔。按解鎖圖示即可開啟。"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"請向上滑動以再試一次"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"解鎖方可使用 NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"此裝置屬於您的機構"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 297715d..4222030 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -136,6 +136,9 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"確認完畢"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"輕觸 [確認] 完成驗證設定"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"裝置已透過人臉解鎖,按下「解鎖」圖示即可繼續操作。"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"裝置已透過你的臉解鎖,按下即可繼續操作。"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"臉孔辨識完成,按下即可繼續操作。"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"臉孔辨識完成,按下「解鎖」圖示即可繼續操作。"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"已通過驗證"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"使用 PIN 碼"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"使用解鎖圖案"</string>
@@ -312,6 +315,9 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"按下「解鎖」圖示即可開啟"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"裝置已透過人臉解鎖,按下「解鎖」圖示即可開啟。"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"裝置已透過你的臉解鎖,按下即可開啟。"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"臉孔辨識完成,按下即可開啟。"</string>
+    <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"臉孔辨識完成,按下「解鎖」圖示即可開啟。"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"向上滑動即可重試"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"如要使用 NFC,請先解鎖"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"這部裝置的擁有者為貴機構"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index d932406..bf013c9 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -136,6 +136,12 @@
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Kuqinisekisiwe"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Thepha okuthi Qinisekisa ukuze uqedele"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Ivulwe ngobuso. Cindezela isithonjana sokuvula ukuze uqhubeke."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_1 (439152621640507113) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_2 (8586608186457385108) -->
+    <skip />
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face_alt_3 (2192670471930606539) -->
+    <skip />
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Kugunyaziwe"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Sebenzisa iphinikhodi"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Sebenzisa iphethini"</string>
@@ -312,6 +318,12 @@
     <string name="keyguard_unlock" msgid="8031975796351361601">"Swayiphela phezulu ukuze uvule"</string>
     <string name="keyguard_unlock_press" msgid="9140109453735019209">"Cindezela isithonjana sokuvula ukuze uvule"</string>
     <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ivulwe ngobuso. Cindezela isithonjana sokuvula ukuze uvule."</string>
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_1 (5715461103913071474) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_2 (8310787946357120406) -->
+    <skip />
+    <!-- no translation found for keyguard_face_successful_unlock_press_alt_3 (7219030481255573962) -->
+    <skip />
     <string name="keyguard_retry" msgid="886802522584053523">"Swayiphela phezulu ukuze uzame futhi"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Vula ukuze usebenzise i-NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Le divayisi eyenhlangano yakho"</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 7ed9156..597e880 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -580,6 +580,9 @@
         280
     </integer>
 
+    <!-- The time (in ms) needed to trigger the lock icon view's long-press affordance -->
+    <integer name="config_lockIconLongPress" translatable="false">200</integer>
+
     <!-- package name of a built-in camera app to use to restrict implicit intent resolution
          when the double-press power gesture is used. Ignored if empty. -->
     <string translatable="false" name="config_cameraGesturePackage"></string>
@@ -611,6 +614,13 @@
          2 - Override the setting to never bypass keyguard -->
     <integer name="config_face_unlock_bypass_override">0</integer>
 
+    <!-- Which face help messages to surface when fingerprint is also enrolled.
+         Message ids correspond with the acquired ids in BiometricFaceConstants -->
+    <integer-array name="config_face_help_msgs_when_fingerprint_enrolled">
+        <item>25</item>
+        <item>26</item>
+    </integer-array>
+
     <!-- Whether the communal service should be enabled -->
     <bool name="config_communalServiceEnabled">false</bool>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 6648841..160dcd0 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -857,7 +857,7 @@
     <!-- The maximum offset for the under-display fingerprint sensor (UDFPS) icon in either
          direction that elements are moved to prevent burn-in on AOD-->
     <dimen name="udfps_burn_in_offset_x">7px</dimen>
-    <dimen name="udfps_burn_in_offset_y">28px</dimen>
+    <dimen name="udfps_burn_in_offset_y">20px</dimen>
 
     <!-- The absolute side margins of quick settings -->
     <dimen name="quick_settings_bottom_margin_media">8dp</dimen>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 5eacc3e..dca5ea8 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -176,5 +176,8 @@
     <item type="id" name="rounded_corner_top_right"/>
     <item type="id" name="rounded_corner_bottom_left"/>
     <item type="id" name="rounded_corner_bottom_right"/>
+
+    <!-- face scanning view id -->
+    <item type="id" name="face_scanning_anim"/>
 </resources>
 
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index af8d7ed..e144b43 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -341,6 +341,12 @@
     <string name="biometric_dialog_tap_confirm">Tap Confirm to complete</string>
     <!-- Message shown when a biometric has authenticated with a user's face and is waiting for the user to confirm authentication [CHAR LIMIT=60]-->
     <string name="biometric_dialog_tap_confirm_with_face">Unlocked by face. Press the unlock icon to continue.</string>
+    <!-- Message shown when a biometric has authenticated with a user's face and is waiting for the user to confirm authentication [CHAR LIMIT=60]-->
+    <string name="biometric_dialog_tap_confirm_with_face_alt_1">Unlocked by face. Press to continue.</string>
+    <!-- Message shown when a biometric has authenticated with a user's face and is waiting for the user to confirm authentication [CHAR LIMIT=60]-->
+    <string name="biometric_dialog_tap_confirm_with_face_alt_2">Face recognized. Press to continue.</string>
+    <!-- Message shown when a biometric has authenticated with a user's face and is waiting for the user to confirm authentication [CHAR LIMIT=60]-->
+    <string name="biometric_dialog_tap_confirm_with_face_alt_3">Face recognized. Press the unlock icon to continue.</string>
     <!-- Talkback string when a biometric is authenticated [CHAR LIMIT=NONE] -->
     <string name="biometric_dialog_authenticated">Authenticated</string>
 
@@ -803,6 +809,13 @@
 
     <!-- Message shown when non-bypass face authentication succeeds and UDFPS is supported. Provides extra instructions for how the user can enter their device [CHAR LIMIT=60] -->
     <string name="keyguard_face_successful_unlock_press">Unlocked by face. Press the unlock icon to open.</string>
+    <!-- Message shown when non-bypass face authentication succeeds and UDFPS is supported. Provides extra instructions for how the user can enter their device [CHAR LIMIT=60] -->
+    <string name="keyguard_face_successful_unlock_press_alt_1">Unlocked by face. Press to open.</string>
+    <!-- Message shown when non-bypass face authentication succeeds and UDFPS is supported. Provides extra instructions for how the user can enter their device [CHAR LIMIT=60] -->
+    <string name="keyguard_face_successful_unlock_press_alt_2">Face recognized. Press to open.</string>
+    <!-- Message shown when non-bypass face authentication succeeds and UDFPS is supported. Provides extra instructions for how the user can enter their device [CHAR LIMIT=60] -->
+    <string name="keyguard_face_successful_unlock_press_alt_3">Face recognized. Press the unlock icon to open.</string>
+
 
     <!-- Messages shown when users press outside of udfps region during -->
     <string-array name="udfps_accessibility_touch_hints">
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 13690f3..e87feff 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -275,7 +275,6 @@
     HashMap<Integer, SimData> mSimDatas = new HashMap<>();
     HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
 
-    private int mRingMode;
     private int mPhoneState;
     private boolean mKeyguardIsVisible;
     private boolean mCredentialAttempted;
@@ -752,6 +751,11 @@
 
     private void handleFingerprintAuthFailed() {
         Assert.isMainThread();
+        if (mHandler.hasCallbacks(mFpCancelNotReceived)) {
+            Log.d(TAG, "handleFingerprintAuthFailed()"
+                    + " triggered while waiting for cancellation, removing watchdog");
+            mHandler.removeCallbacks(mFpCancelNotReceived);
+        }
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
@@ -782,6 +786,11 @@
 
     private void handleFingerprintAuthenticated(int authUserId, boolean isStrongBiometric) {
         Trace.beginSection("KeyGuardUpdateMonitor#handlerFingerPrintAuthenticated");
+        if (mHandler.hasCallbacks(mFpCancelNotReceived)) {
+            Log.d(TAG, "handleFingerprintAuthenticated()"
+                    + " triggered while waiting for cancellation, removing watchdog");
+            mHandler.removeCallbacks(mFpCancelNotReceived);
+        }
         try {
             final int userId;
             try {
@@ -1041,7 +1050,7 @@
 
     private void handleFaceError(int msgId, String errString) {
         Assert.isMainThread();
-        if (DEBUG_FACE) Log.d(TAG, "Face error received: " + errString);
+        if (DEBUG_FACE) Log.d(TAG, "Face error received: " + errString + " msgId=" + msgId);
         if (mHandler.hasCallbacks(mFaceCancelNotReceived)) {
             mHandler.removeCallbacks(mFaceCancelNotReceived);
         }
@@ -1511,6 +1520,20 @@
                 handleFingerprintAuthenticated(userId, isStrongBiometric);
             };
 
+    /**
+     * Propagates a pointer down event to keyguard.
+     */
+    public void onUdfpsPointerDown(int sensorId) {
+        mFingerprintAuthenticationCallback.onUdfpsPointerDown(sensorId);
+    }
+
+    /**
+     * Propagates a pointer up event to keyguard.
+     */
+    public void onUdfpsPointerUp(int sensorId) {
+        mFingerprintAuthenticationCallback.onUdfpsPointerUp(sensorId);
+    }
+
     @VisibleForTesting
     final FingerprintManager.AuthenticationCallback mFingerprintAuthenticationCallback
             = new AuthenticationCallback() {
@@ -1551,15 +1574,18 @@
                     Trace.endSection();
                 }
 
+                /**
+                 * Note, this is currently called from UdfpsController.
+                 */
                 @Override
                 public void onUdfpsPointerDown(int sensorId) {
                     Log.d(TAG, "onUdfpsPointerDown, sensorId: " + sensorId);
                     requestFaceAuth(true);
-                    if (isFaceDetectionRunning()) {
-                        mKeyguardBypassController.setUserHasDeviceEntryIntent(true);
-                    }
                 }
 
+                /**
+                 * Note, this is currently called from UdfpsController.
+                 */
                 @Override
                 public void onUdfpsPointerUp(int sensorId) {
                     Log.d(TAG, "onUdfpsPointerUp, sensorId: " + sensorId);
@@ -1587,9 +1613,6 @@
                                 "faceFailure-" + reason);
 
                     handleFaceAuthFailed();
-                    if (mKeyguardBypassController != null) {
-                        mKeyguardBypassController.setUserHasDeviceEntryIntent(false);
-                    }
                 }
 
                 @Override
@@ -1597,10 +1620,6 @@
                     Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
                     handleFaceAuthenticated(result.getUserId(), result.isStrongBiometric());
                     Trace.endSection();
-
-                    if (mKeyguardBypassController != null) {
-                        mKeyguardBypassController.setUserHasDeviceEntryIntent(false);
-                    }
                 }
 
                 @Override
@@ -1611,9 +1630,6 @@
                 @Override
                 public void onAuthenticationError(int errMsgId, CharSequence errString) {
                     handleFaceError(errMsgId, errString.toString());
-                    if (mKeyguardBypassController != null) {
-                        mKeyguardBypassController.setUserHasDeviceEntryIntent(false);
-                    }
 
                     if (mActiveUnlockConfig.shouldRequestActiveUnlockOnFaceError(errMsgId)) {
                         requestActiveUnlock(
@@ -2177,6 +2193,10 @@
                         && mBiometricEnabledForUser.get(userId));
     }
 
+    public boolean isFaceSupported() {
+        return mFaceManager != null && mFaceManager.isHardwareDetected();
+    }
+
     /**
      * @return true if there's at least one udfps enrolled for the current user.
      */
@@ -2296,10 +2316,6 @@
         updateFaceListeningState(BIOMETRIC_ACTION_START);
     }
 
-    public boolean isFaceAuthUserRequested() {
-        return mIsFaceAuthUserRequested;
-    }
-
     /**
      * In case face auth is running, cancel it.
      */
@@ -2307,6 +2323,10 @@
         stopListeningForFace();
     }
 
+    public boolean isFaceScanning() {
+        return mFaceRunningState == BIOMETRIC_STATE_RUNNING;
+    }
+
     private void updateFaceListeningState(int action) {
         // If this message exists, we should not authenticate again until this message is
         // consumed by the handler
@@ -3160,11 +3180,6 @@
             mSecureCameraLaunched = false;
         }
 
-        if (mKeyguardBypassController != null) {
-            // LS visibility has changed, so reset deviceEntryIntent
-            mKeyguardBypassController.setUserHasDeviceEntryIntent(false);
-        }
-
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
@@ -3809,6 +3824,7 @@
             pw.println("    enabledByUser=" + mBiometricEnabledForUser.get(userId));
             pw.println("    mSecureCameraLaunched=" + mSecureCameraLaunched);
             pw.println("    mBouncerFullyShown=" + mBouncerFullyShown);
+            pw.println("    mNeedsSlowUnlockTransition=" + mNeedsSlowUnlockTransition);
         }
         mListenModels.print(pw);
 
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index 680b8bd..0097196 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -83,8 +83,8 @@
     private static final int sLockIconRadiusPx = (int) (sDefaultDensity * 36);
     private static final VibrationAttributes TOUCH_VIBRATION_ATTRIBUTES =
             VibrationAttributes.createForUsage(VibrationAttributes.USAGE_TOUCH);
-    private static final long LONG_PRESS_TIMEOUT = 200L; // milliseconds
 
+    private final long mLongPressTimeout;
     @NonNull private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     @NonNull private final KeyguardViewController mKeyguardViewController;
     @NonNull private final StatusBarStateController mStatusBarStateController;
@@ -176,6 +176,7 @@
         mView.setImageDrawable(mIcon);
         mUnlockedLabel = resources.getString(R.string.accessibility_unlock_button);
         mLockedLabel = resources.getString(R.string.accessibility_lock_icon);
+        mLongPressTimeout = resources.getInteger(R.integer.config_lockIconLongPress);
         dumpManager.registerDumpable(TAG, this);
     }
 
@@ -545,7 +546,7 @@
     /**
      * Handles the touch if it is within the lock icon view and {@link #isActionable()} is true.
      * Subsequently, will trigger {@link #onLongPress()} if a touch is continuously in the lock icon
-     * area for {@link #LONG_PRESS_TIMEOUT} ms.
+     * area for {@link #mLongPressTimeout} ms.
      *
      * Touch speed debouncing mimics logic from the velocity tracker in {@link UdfpsController}.
      */
@@ -585,7 +586,7 @@
 
                 mDownDetected = true;
                 mLongPressCancelRunnable = mExecutor.executeDelayed(
-                        this::onLongPress, LONG_PRESS_TIMEOUT);
+                        this::onLongPress, mLongPressTimeout);
                 break;
             case MotionEvent.ACTION_MOVE:
             case MotionEvent.ACTION_HOVER_MOVE:
@@ -600,7 +601,7 @@
                             + "high pointer velocity=" + velocity);
                     mLongPressCancelRunnable.run();
                     mLongPressCancelRunnable = mExecutor.executeDelayed(
-                            this::onLongPress, LONG_PRESS_TIMEOUT);
+                            this::onLongPress, mLongPressTimeout);
                 }
                 break;
             case MotionEvent.ACTION_UP:
@@ -651,7 +652,7 @@
                 Process.myUid(),
                 getContext().getOpPackageName(),
                 UdfpsController.EFFECT_CLICK,
-                "lock-icon-device-entry",
+                "lock-screen-lock-icon-longpress",
                 TOUCH_VIBRATION_ATTRIBUTES);
 
         mKeyguardViewController.showBouncer(/* scrim */ true);
@@ -676,6 +677,12 @@
     }
 
     private boolean isActionable() {
+        if (mIsBouncerShowing) {
+            Log.v(TAG, "lock icon long-press ignored, bouncer already showing.");
+            // a long press gestures from AOD may have already triggered the bouncer to show,
+            // so this touch is no longer actionable
+            return false;
+        }
         return mUdfpsSupported || mShowUnlockIcon;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt b/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt
index 34164f3..d2c229b 100644
--- a/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt
+++ b/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt
@@ -279,7 +279,7 @@
     }
 
     companion object {
-        private const val HIDDEN_CAMERA_PROTECTION_SCALE = 0.5f
+        const val HIDDEN_CAMERA_PROTECTION_SCALE = 0.5f
 
         @JvmStatic protected fun transformPhysicalToLogicalCoordinates(
             @Surface.Rotation rotation: Int,
diff --git a/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt b/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
new file mode 100644
index 0000000..c595586
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2022 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.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.AnimatorSet
+import android.animation.ValueAnimator
+import android.content.Context
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.Matrix
+import android.graphics.Paint
+import android.graphics.Path
+import android.graphics.RectF
+import android.hardware.biometrics.BiometricSourceType
+import android.view.View
+import androidx.core.graphics.ColorUtils
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.settingslib.Utils
+import com.android.systemui.animation.Interpolators
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import java.util.concurrent.Executor
+
+/**
+ * When the face is enrolled, we use this view to show the face scanning animation and the camera
+ * protection on the keyguard.
+ */
+class FaceScanningOverlay(
+    context: Context,
+    pos: Int,
+    val statusBarStateController: StatusBarStateController,
+    val keyguardUpdateMonitor: KeyguardUpdateMonitor,
+    val mainExecutor: Executor
+) : ScreenDecorations.DisplayCutoutView(context, pos) {
+    private var showScanningAnim = false
+    private val rimPaint = Paint()
+    private var rimProgress: Float = HIDDEN_CAMERA_PROTECTION_SCALE
+    private var rimAnimator: AnimatorSet? = null
+    private val rimRect = RectF()
+    private var cameraProtectionColor = Color.BLACK
+    var faceScanningAnimColor = Utils.getColorAttrDefaultColor(context,
+            com.android.systemui.R.attr.wallpaperTextColorAccent)
+    private var cameraProtectionAnimator: ValueAnimator? = null
+    var hideOverlayRunnable: Runnable? = null
+    var faceAuthSucceeded = false
+
+    init {
+        visibility = View.INVISIBLE // only show this view when face scanning is happening
+    }
+
+    override fun onAttachedToWindow() {
+        super.onAttachedToWindow()
+        mainExecutor.execute {
+            keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
+        }
+    }
+
+    override fun onDetachedFromWindow() {
+        super.onDetachedFromWindow()
+        mainExecutor.execute {
+            keyguardUpdateMonitor.removeCallback(keyguardUpdateMonitorCallback)
+        }
+    }
+
+    override fun setColor(color: Int) {
+        cameraProtectionColor = color
+        invalidate()
+    }
+
+    override fun drawCutoutProtection(canvas: Canvas) {
+        if (rimProgress > HIDDEN_RIM_SCALE && !protectionRect.isEmpty) {
+            val rimPath = Path(protectionPath)
+            val scaleMatrix = Matrix().apply {
+                val rimBounds = RectF()
+                rimPath.computeBounds(rimBounds, true)
+                setScale(rimProgress, rimProgress, rimBounds.centerX(), rimBounds.centerY())
+            }
+            rimPath.transform(scaleMatrix)
+            rimPaint.style = Paint.Style.FILL
+            val rimPaintAlpha = rimPaint.alpha
+            rimPaint.color = ColorUtils.blendARGB(
+                    faceScanningAnimColor,
+                    Color.WHITE,
+                    statusBarStateController.dozeAmount)
+            rimPaint.alpha = rimPaintAlpha
+            canvas.drawPath(rimPath, rimPaint)
+        }
+
+        if (cameraProtectionProgress > HIDDEN_CAMERA_PROTECTION_SCALE &&
+                !protectionRect.isEmpty) {
+            val scaledProtectionPath = Path(protectionPath)
+            val scaleMatrix = Matrix().apply {
+                val protectionPathRect = RectF()
+                scaledProtectionPath.computeBounds(protectionPathRect, true)
+                setScale(cameraProtectionProgress, cameraProtectionProgress,
+                        protectionPathRect.centerX(), protectionPathRect.centerY())
+            }
+            scaledProtectionPath.transform(scaleMatrix)
+            paint.style = Paint.Style.FILL
+            paint.color = cameraProtectionColor
+            canvas.drawPath(scaledProtectionPath, paint)
+        }
+    }
+
+    override fun updateVisOnUpdateCutout(): Boolean {
+        return false // instead, we always update the visibility whenever face scanning starts/ends
+    }
+
+    override fun enableShowProtection(show: Boolean) {
+        val showScanningAnimNow = keyguardUpdateMonitor.isFaceScanning && show
+        if (showScanningAnimNow == showScanningAnim) {
+            return
+        }
+        showScanningAnim = showScanningAnimNow
+        updateProtectionBoundingPath()
+        // Delay the relayout until the end of the animation when hiding,
+        // otherwise we'd clip it.
+        if (showScanningAnim) {
+            visibility = View.VISIBLE
+            requestLayout()
+        }
+
+        cameraProtectionAnimator?.cancel()
+        cameraProtectionAnimator = ValueAnimator.ofFloat(cameraProtectionProgress,
+                if (showScanningAnimNow) SHOW_CAMERA_PROTECTION_SCALE
+                else HIDDEN_CAMERA_PROTECTION_SCALE).apply {
+            startDelay =
+                    if (showScanningAnim) 0
+                    else if (faceAuthSucceeded) PULSE_SUCCESS_DISAPPEAR_DURATION
+                    else PULSE_ERROR_DISAPPEAR_DURATION
+            duration =
+                    if (showScanningAnim) CAMERA_PROTECTION_APPEAR_DURATION
+                    else if (faceAuthSucceeded) CAMERA_PROTECTION_SUCCESS_DISAPPEAR_DURATION
+                    else CAMERA_PROTECTION_ERROR_DISAPPEAR_DURATION
+            interpolator =
+                    if (showScanningAnim) Interpolators.STANDARD_ACCELERATE
+                    else if (faceAuthSucceeded) Interpolators.STANDARD
+                    else Interpolators.STANDARD_DECELERATE
+            addUpdateListener(ValueAnimator.AnimatorUpdateListener {
+                animation: ValueAnimator ->
+                cameraProtectionProgress = animation.animatedValue as Float
+                invalidate()
+            })
+            addListener(object : AnimatorListenerAdapter() {
+                override fun onAnimationEnd(animation: Animator) {
+                    cameraProtectionAnimator = null
+                    if (!showScanningAnim) {
+                        visibility = View.INVISIBLE
+                        hideOverlayRunnable?.run()
+                        hideOverlayRunnable = null
+                        requestLayout()
+                    }
+                }
+            })
+        }
+
+        rimAnimator?.cancel()
+        rimAnimator = AnimatorSet().apply {
+            if (showScanningAnim) {
+                val rimAppearAnimator = ValueAnimator.ofFloat(SHOW_CAMERA_PROTECTION_SCALE,
+                        PULSE_RADIUS_OUT).apply {
+                    duration = PULSE_APPEAR_DURATION
+                    interpolator = Interpolators.STANDARD_DECELERATE
+                    addUpdateListener(ValueAnimator.AnimatorUpdateListener {
+                        animation: ValueAnimator ->
+                        rimProgress = animation.animatedValue as Float
+                        invalidate()
+                    })
+                }
+
+                // animate in camera protection, rim, and then pulse in/out
+                playSequentially(cameraProtectionAnimator, rimAppearAnimator,
+                        createPulseAnimator(), createPulseAnimator(),
+                        createPulseAnimator(), createPulseAnimator(),
+                        createPulseAnimator(), createPulseAnimator())
+            } else {
+                val rimDisappearAnimator = ValueAnimator.ofFloat(
+                        rimProgress,
+                        if (faceAuthSucceeded) PULSE_RADIUS_SUCCESS
+                        else SHOW_CAMERA_PROTECTION_SCALE
+                ).apply {
+                    duration =
+                            if (faceAuthSucceeded) PULSE_SUCCESS_DISAPPEAR_DURATION
+                            else PULSE_ERROR_DISAPPEAR_DURATION
+                    interpolator =
+                            if (faceAuthSucceeded) Interpolators.STANDARD_DECELERATE
+                            else Interpolators.STANDARD
+                    addUpdateListener(ValueAnimator.AnimatorUpdateListener {
+                        animation: ValueAnimator ->
+                        rimProgress = animation.animatedValue as Float
+                        invalidate()
+                    })
+                    addListener(object : AnimatorListenerAdapter() {
+                        override fun onAnimationEnd(animation: Animator) {
+                            rimProgress = HIDDEN_RIM_SCALE
+                            invalidate()
+                        }
+                    })
+                }
+                if (faceAuthSucceeded) {
+                    val successOpacityAnimator = ValueAnimator.ofInt(255, 0).apply {
+                        duration = PULSE_SUCCESS_DISAPPEAR_DURATION
+                        interpolator = Interpolators.LINEAR
+                        addUpdateListener(ValueAnimator.AnimatorUpdateListener {
+                            animation: ValueAnimator ->
+                            rimPaint.alpha = animation.animatedValue as Int
+                            invalidate()
+                        })
+                        addListener(object : AnimatorListenerAdapter() {
+                            override fun onAnimationEnd(animation: Animator) {
+                                rimPaint.alpha = 255
+                                invalidate()
+                            }
+                        })
+                    }
+                    val rimSuccessAnimator = AnimatorSet()
+                    rimSuccessAnimator.playTogether(rimDisappearAnimator, successOpacityAnimator)
+                    playTogether(rimSuccessAnimator, cameraProtectionAnimator)
+                } else {
+                    playTogether(rimDisappearAnimator, cameraProtectionAnimator)
+                }
+            }
+
+            addListener(object : AnimatorListenerAdapter() {
+                override fun onAnimationEnd(animation: Animator) {
+                    rimAnimator = null
+                    if (!showScanningAnim) {
+                        requestLayout()
+                    }
+                }
+            })
+            start()
+        }
+    }
+
+    fun createPulseAnimator(): AnimatorSet {
+        return AnimatorSet().apply {
+            val pulseInwards = ValueAnimator.ofFloat(
+                    PULSE_RADIUS_OUT, PULSE_RADIUS_IN).apply {
+                duration = PULSE_DURATION_INWARDS
+                interpolator = Interpolators.STANDARD
+                addUpdateListener(ValueAnimator.AnimatorUpdateListener {
+                    animation: ValueAnimator ->
+                    rimProgress = animation.animatedValue as Float
+                    invalidate()
+                })
+            }
+            val pulseOutwards = ValueAnimator.ofFloat(
+                    PULSE_RADIUS_IN, PULSE_RADIUS_OUT).apply {
+                duration = PULSE_DURATION_OUTWARDS
+                interpolator = Interpolators.STANDARD
+                addUpdateListener(ValueAnimator.AnimatorUpdateListener {
+                    animation: ValueAnimator ->
+                    rimProgress = animation.animatedValue as Float
+                    invalidate()
+                })
+            }
+            playSequentially(pulseInwards, pulseOutwards)
+        }
+    }
+
+    override fun updateProtectionBoundingPath() {
+        super.updateProtectionBoundingPath()
+        rimRect.set(protectionRect)
+        rimRect.scale(rimProgress)
+    }
+
+    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+        if (mBounds.isEmpty()) {
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec)
+            return
+        }
+        if (showScanningAnim) {
+            // Make sure that our measured height encompasses the extra space for the animation
+            mTotalBounds.union(mBoundingRect)
+            mTotalBounds.union(
+                    rimRect.left.toInt(),
+                    rimRect.top.toInt(),
+                    rimRect.right.toInt(),
+                    rimRect.bottom.toInt())
+            setMeasuredDimension(
+                    resolveSizeAndState(mTotalBounds.width(), widthMeasureSpec, 0),
+                    resolveSizeAndState(mTotalBounds.height(), heightMeasureSpec, 0))
+        } else {
+            setMeasuredDimension(
+                    resolveSizeAndState(mBoundingRect.width(), widthMeasureSpec, 0),
+                    resolveSizeAndState(mBoundingRect.height(), heightMeasureSpec, 0))
+        }
+    }
+
+    private val keyguardUpdateMonitorCallback = object : KeyguardUpdateMonitorCallback() {
+        override fun onBiometricAuthenticated(
+            userId: Int,
+            biometricSourceType: BiometricSourceType?,
+            isStrongBiometric: Boolean
+        ) {
+            if (biometricSourceType == BiometricSourceType.FACE) {
+                post {
+                    faceAuthSucceeded = true
+                    enableShowProtection(true)
+                }
+            }
+        }
+
+        override fun onBiometricAcquired(
+            biometricSourceType: BiometricSourceType?,
+            acquireInfo: Int
+        ) {
+            if (biometricSourceType == BiometricSourceType.FACE) {
+                post {
+                    faceAuthSucceeded = false // reset
+                }
+            }
+        }
+
+        override fun onBiometricAuthFailed(biometricSourceType: BiometricSourceType?) {
+            if (biometricSourceType == BiometricSourceType.FACE) {
+                post {
+                    faceAuthSucceeded = false
+                    enableShowProtection(false)
+                }
+            }
+        }
+
+        override fun onBiometricError(
+            msgId: Int,
+            errString: String?,
+            biometricSourceType: BiometricSourceType?
+        ) {
+            if (biometricSourceType == BiometricSourceType.FACE) {
+                post {
+                    faceAuthSucceeded = false
+                    enableShowProtection(false)
+                }
+            }
+        }
+    }
+
+    companion object {
+        private const val HIDDEN_RIM_SCALE = HIDDEN_CAMERA_PROTECTION_SCALE
+        private const val SHOW_CAMERA_PROTECTION_SCALE = 1f
+
+        private const val PULSE_RADIUS_IN = 1.1f
+        private const val PULSE_RADIUS_OUT = 1.125f
+        private const val PULSE_RADIUS_SUCCESS = 1.25f
+
+        private const val CAMERA_PROTECTION_APPEAR_DURATION = 250L
+        private const val PULSE_APPEAR_DURATION = 250L // without start delay
+
+        private const val PULSE_DURATION_INWARDS = 500L
+        private const val PULSE_DURATION_OUTWARDS = 500L
+
+        private const val PULSE_SUCCESS_DISAPPEAR_DURATION = 400L
+        private const val CAMERA_PROTECTION_SUCCESS_DISAPPEAR_DURATION = 500L // without start delay
+
+        private const val PULSE_ERROR_DISAPPEAR_DURATION = 200L
+        private const val CAMERA_PROTECTION_ERROR_DISAPPEAR_DURATION = 300L // without start delay
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt b/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
index 0df2730..a74f2f8 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
@@ -44,7 +44,7 @@
 import kotlin.math.floor
 
 /**
- * When the HWC of the device supports Composition.DISPLAY_DECORATON, we use this layer to draw
+ * When the HWC of the device supports Composition.DISPLAY_DECORATION, we use this layer to draw
  * screen decorations.
  */
 class ScreenDecorHwcLayer(context: Context, displayDecorationSupport: DisplayDecorationSupport)
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index c04463a..edcaf49 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -69,12 +69,14 @@
 import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.util.Preconditions;
+import com.android.settingslib.Utils;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.decor.DecorProvider;
 import com.android.systemui.decor.DecorProviderFactory;
 import com.android.systemui.decor.DecorProviderKt;
+import com.android.systemui.decor.FaceScanningProviderFactory;
 import com.android.systemui.decor.OverlayWindow;
 import com.android.systemui.decor.PrivacyDotDecorProviderFactory;
 import com.android.systemui.decor.RoundedCornerDecorProviderFactory;
@@ -90,8 +92,10 @@
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.Executor;
 
 import javax.inject.Inject;
@@ -131,6 +135,8 @@
     private final PrivacyDotViewController mDotViewController;
     private final ThreadFactory mThreadFactory;
     private final DecorProviderFactory mDotFactory;
+    private final FaceScanningProviderFactory mFaceScanningFactory;
+    public final int mFaceScanningViewId;
 
     @VisibleForTesting
     protected RoundedCornerResDelegate mRoundedCornerResDelegate;
@@ -161,46 +167,84 @@
     @VisibleForTesting
     protected DisplayInfo mDisplayInfo = new DisplayInfo();
 
+    @VisibleForTesting
+    protected void showCameraProtection(@NonNull Path protectionPath, @NonNull Rect bounds) {
+        if (mFaceScanningFactory.shouldShowFaceScanningAnim()) {
+            DisplayCutoutView overlay = (DisplayCutoutView) getOverlayView(
+                    mFaceScanningViewId);
+            if (overlay != null) {
+                overlay.setProtection(protectionPath, bounds);
+                overlay.enableShowProtection(true);
+                updateOverlayWindowVisibilityIfViewExists(
+                        overlay.findViewById(mFaceScanningViewId));
+                // immediately return, bc FaceScanningOverlay also renders the camera
+                // protection, so we don't need to show the camera protection in
+                // mScreenDecorHwcLayer or mCutoutViews
+                return;
+            }
+        }
+
+        if (mScreenDecorHwcLayer != null) {
+            mScreenDecorHwcLayer.setProtection(protectionPath, bounds);
+            mScreenDecorHwcLayer.enableShowProtection(true);
+            return;
+        }
+
+        if (mCutoutViews == null) {
+            Log.w(TAG, "DisplayCutoutView not initialized onApplyCameraProtection");
+            return;
+        }
+
+        // Show the extra protection around the front facing camera if necessary
+        for (DisplayCutoutView dcv : mCutoutViews) {
+            // Check Null since not all mCutoutViews[pos] be inflated at the meanwhile
+            if (dcv != null) {
+                dcv.setProtection(protectionPath, bounds);
+                dcv.enableShowProtection(true);
+            }
+        }
+    }
+
+    @VisibleForTesting
+    protected void hideCameraProtection() {
+        FaceScanningOverlay faceScanningOverlay =
+                (FaceScanningOverlay) getOverlayView(mFaceScanningViewId);
+        if (faceScanningOverlay != null) {
+            faceScanningOverlay.setHideOverlayRunnable(() -> {
+                updateOverlayWindowVisibilityIfViewExists(
+                        faceScanningOverlay.findViewById(mFaceScanningViewId));
+            });
+            faceScanningOverlay.enableShowProtection(false);
+        }
+
+        if (mScreenDecorHwcLayer != null) {
+            mScreenDecorHwcLayer.enableShowProtection(false);
+            return;
+        }
+
+        if (mCutoutViews == null) {
+            Log.w(TAG, "DisplayCutoutView not initialized onHideCameraProtection");
+            return;
+        }
+        // Go back to the regular anti-aliasing
+        for (DisplayCutoutView dcv : mCutoutViews) {
+            // Check Null since not all mCutoutViews[pos] be inflated at the meanwhile
+            if (dcv != null) {
+                dcv.enableShowProtection(false);
+            }
+        }
+    }
+
     private CameraAvailabilityListener.CameraTransitionCallback mCameraTransitionCallback =
             new CameraAvailabilityListener.CameraTransitionCallback() {
         @Override
         public void onApplyCameraProtection(@NonNull Path protectionPath, @NonNull Rect bounds) {
-            if (mScreenDecorHwcLayer != null) {
-                mScreenDecorHwcLayer.setProtection(protectionPath, bounds);
-                mScreenDecorHwcLayer.enableShowProtection(true);
-                return;
-            }
-            if (mCutoutViews == null) {
-                Log.w(TAG, "DisplayCutoutView do not initialized");
-                return;
-            }
-            // Show the extra protection around the front facing camera if necessary
-            for (DisplayCutoutView dcv : mCutoutViews) {
-                // Check Null since not all mCutoutViews[pos] be inflated at the meanwhile
-                if (dcv != null) {
-                    dcv.setProtection(protectionPath, bounds);
-                    dcv.enableShowProtection(true);
-                }
-            }
+            showCameraProtection(protectionPath, bounds);
         }
 
         @Override
         public void onHideCameraProtection() {
-            if (mScreenDecorHwcLayer != null) {
-                mScreenDecorHwcLayer.enableShowProtection(false);
-                return;
-            }
-            if (mCutoutViews == null) {
-                Log.w(TAG, "DisplayCutoutView do not initialized");
-                return;
-            }
-            // Go back to the regular anti-aliasing
-            for (DisplayCutoutView dcv : mCutoutViews) {
-                // Check Null since not all mCutoutViews[pos] be inflated at the meanwhile
-                if (dcv != null) {
-                    dcv.enableShowProtection(false);
-                }
-            }
+            hideCameraProtection();
         }
     };
 
@@ -209,25 +253,24 @@
             new PrivacyDotViewController.ShowingListener() {
         @Override
         public void onPrivacyDotShown(@Nullable View v) {
-            setOverlayWindowVisibilityIfViewExist(v, View.VISIBLE);
+            updateOverlayWindowVisibilityIfViewExists(v);
         }
 
         @Override
         public void onPrivacyDotHidden(@Nullable View v) {
-            setOverlayWindowVisibilityIfViewExist(v, View.INVISIBLE);
+            updateOverlayWindowVisibilityIfViewExists(v);
         }
     };
 
     @VisibleForTesting
-    protected void setOverlayWindowVisibilityIfViewExist(@Nullable View view,
-            @View.Visibility int visibility) {
+    protected void updateOverlayWindowVisibilityIfViewExists(@Nullable View view) {
         if (view == null) {
             return;
         }
         mExecutor.execute(() -> {
             // We don't need to control the window visibility if rounded corners or cutout is drawn
             // on sw layer since the overlay windows are always visible in this case.
-            if (mOverlays == null || !isOnlyPrivacyDotInSwLayer()) {
+            if (mOverlays == null || !shouldOptimizeVisibility()) {
                 return;
             }
 
@@ -236,7 +279,7 @@
                     continue;
                 }
                 if (overlay.getView(view.getId()) != null) {
-                    overlay.getRootView().setVisibility(visibility);
+                    overlay.getRootView().setVisibility(getWindowVisibility(overlay, true));
                     return;
                 }
             }
@@ -258,7 +301,8 @@
             UserTracker userTracker,
             PrivacyDotViewController dotViewController,
             ThreadFactory threadFactory,
-            PrivacyDotDecorProviderFactory dotFactory) {
+            PrivacyDotDecorProviderFactory dotFactory,
+            FaceScanningProviderFactory faceScanningFactory) {
         super(context);
         mMainExecutor = mainExecutor;
         mSecureSettings = secureSettings;
@@ -268,6 +312,8 @@
         mDotViewController = dotViewController;
         mThreadFactory = threadFactory;
         mDotFactory = dotFactory;
+        mFaceScanningFactory = faceScanningFactory;
+        mFaceScanningViewId = com.android.systemui.R.id.face_scanning_anim;
     }
 
     @Override
@@ -289,6 +335,7 @@
     @NonNull
     private List<DecorProvider> getProviders(boolean hasHwLayer) {
         List<DecorProvider> decorProviders = new ArrayList<>(mDotFactory.getProviders());
+        decorProviders.addAll(mFaceScanningFactory.getProviders());
         if (!hasHwLayer) {
             decorProviders.addAll(mRoundedCornerFactory.getProviders());
         }
@@ -446,6 +493,13 @@
                         cutoutView.onDisplayChanged(displayId);
                     }
                 }
+
+                DisplayCutoutView overlay = (DisplayCutoutView) getOverlayView(mFaceScanningViewId);
+                if (overlay != null) {
+                    // handle display resolution changes
+                    overlay.onDisplayChanged(displayId);
+                }
+
                 if (mScreenDecorHwcLayer != null) {
                     mScreenDecorHwcLayer.onDisplayChanged(displayId);
                 }
@@ -466,7 +520,6 @@
             if (overlay == null) {
                 continue;
             }
-
             final View view = overlay.getView(id);
             if (view != null) {
                 return view;
@@ -503,7 +556,9 @@
     }
 
     private void setupDecorations() {
-        if (hasRoundedCorners() || shouldDrawCutout() || isPrivacyDotEnabled()) {
+        if (hasRoundedCorners() || shouldDrawCutout() || isPrivacyDotEnabled()
+                || mFaceScanningFactory.getHasProviders()) {
+
             List<DecorProvider> decorProviders = getProviders(mHwcScreenDecorationSupport != null);
             removeRedundantOverlayViews(decorProviders);
 
@@ -512,21 +567,24 @@
             } else {
                 removeHwcOverlay();
             }
+
             final DisplayCutout cutout = getCutout();
-            final boolean isOnlyPrivacyDotInSwLayer = isOnlyPrivacyDotInSwLayer();
+            final boolean shouldOptimizeVisibility = shouldOptimizeVisibility();
             for (int i = 0; i < BOUNDS_POSITION_LENGTH; i++) {
-                if (shouldShowSwLayerCutout(i, cutout) || shouldShowSwLayerRoundedCorner(i, cutout)
+                if (shouldShowSwLayerCutout(i, cutout)
+                        || shouldShowSwLayerFaceScan(i, cutout)
+                        || shouldShowSwLayerRoundedCorner(i, cutout)
                         || shouldShowSwLayerPrivacyDot(i, cutout)) {
                     Pair<List<DecorProvider>, List<DecorProvider>> pair =
                             DecorProviderKt.partitionAlignedBound(decorProviders, i);
                     decorProviders = pair.getSecond();
-                    createOverlay(i, pair.getFirst(), isOnlyPrivacyDotInSwLayer);
+                    createOverlay(i, pair.getFirst(), shouldOptimizeVisibility);
                 } else {
                     removeOverlay(i);
                 }
             }
 
-            if (isOnlyPrivacyDotInSwLayer) {
+            if (shouldOptimizeVisibility) {
                 mDotViewController.setShowingListener(mPrivacyDotShowingListener);
             } else {
                 mDotViewController.setShowingListener(null);
@@ -565,6 +623,7 @@
             }
             mColorInversionSetting.setListening(true);
             mColorInversionSetting.onChange(false);
+            updateColorInversion(mColorInversionSetting.getValue());
 
             IntentFilter filter = new IntentFilter();
             filter.addAction(Intent.ACTION_USER_SWITCHED);
@@ -626,59 +685,61 @@
 
     @View.Visibility
     private int getWindowVisibility(@NonNull OverlayWindow overlay,
-            boolean isOnlyPrivacyDotInSwLayer) {
-        if (!isOnlyPrivacyDotInSwLayer) {
-            // Multiple views inside overlay, no need to optimize
+            boolean shouldOptimizeVisibility) {
+        if (!shouldOptimizeVisibility) {
+            // All overlays have visible views so there's no need to optimize visibility.
+            // For example, the rounded corners could exist in each overlay and since the rounded
+            // corners are always visible, there's no need to optimize visibility.
             return View.VISIBLE;
         }
 
+        // Optimize if it's just the privacy dot & face scanning animation, since the privacy
+        // dot and face scanning overlay aren't always visible.
         int[] ids = {
                 R.id.privacy_dot_top_left_container,
                 R.id.privacy_dot_top_right_container,
                 R.id.privacy_dot_bottom_left_container,
-                R.id.privacy_dot_bottom_right_container
+                R.id.privacy_dot_bottom_right_container,
+                mFaceScanningViewId
         };
         for (int id: ids) {
-            final View view = overlay.getView(id);
-            if (view != null && view.getVisibility() == View.VISIBLE) {
-                // Only privacy dot in sw layers, overlay shall be VISIBLE if one of privacy dot
-                // views inside this overlay is VISIBLE
+            final View notAlwaysVisibleViews = overlay.getView(id);
+            if (notAlwaysVisibleViews != null
+                    && notAlwaysVisibleViews.getVisibility() == View.VISIBLE) {
+                // Overlay is VISIBLE if one the views inside this overlay is VISIBLE
                 return View.VISIBLE;
             }
         }
-        // Only privacy dot in sw layers, overlay shall be INVISIBLE like default if no privacy dot
-        // view inside this overlay is VISIBLE.
+
+        // Only non-visible views in this overlay, so set overlay to INVISIBLE
         return View.INVISIBLE;
     }
 
     private void createOverlay(
             @BoundsPosition int pos,
             @NonNull List<DecorProvider> decorProviders,
-            boolean isOnlyPrivacyDotInSwLayer) {
+            boolean shouldOptimizeVisibility) {
         if (mOverlays == null) {
             mOverlays = new OverlayWindow[BOUNDS_POSITION_LENGTH];
         }
 
         if (mOverlays[pos] != null) {
-            initOverlay(mOverlays[pos], decorProviders, isOnlyPrivacyDotInSwLayer);
+            initOverlay(mOverlays[pos], decorProviders, shouldOptimizeVisibility);
             return;
         }
-
         mOverlays[pos] = new OverlayWindow(mContext);
-        initOverlay(mOverlays[pos], decorProviders, isOnlyPrivacyDotInSwLayer);
+        initOverlay(mOverlays[pos], decorProviders, shouldOptimizeVisibility);
         final ViewGroup overlayView = mOverlays[pos].getRootView();
         overlayView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
         overlayView.setAlpha(0);
         overlayView.setForceDarkAllowed(false);
 
-        // Only show cutout and rounded corners in mOverlays when hwc don't support screen
-        // decoration.
+        // Only show cutout in mOverlays when hwc doesn't support screen decoration
         if (mHwcScreenDecorationSupport == null) {
             if (mCutoutViews == null) {
                 mCutoutViews = new DisplayCutoutView[BOUNDS_POSITION_LENGTH];
             }
             mCutoutViews[pos] = new DisplayCutoutView(mContext, pos);
-            mCutoutViews[pos].setColor(mTintColor);
             overlayView.addView(mCutoutViews[pos]);
             mCutoutViews[pos].updateRotation(mRotation);
         }
@@ -736,7 +797,7 @@
     private void initOverlay(
             @NonNull OverlayWindow overlay,
             @NonNull List<DecorProvider> decorProviders,
-            boolean isOnlyPrivacyDotInSwLayer) {
+            boolean shouldOptimizeVisibility) {
         if (!overlay.hasSameProviders(decorProviders)) {
             decorProviders.forEach(provider -> {
                 if (overlay.getView(provider.getViewId()) != null) {
@@ -746,9 +807,10 @@
                 overlay.addDecorProvider(provider, mRotation);
             });
         }
-        // Use visibility of privacy dot views if only privacy dot in sw layer
-        overlay.getRootView().setVisibility(
-                getWindowVisibility(overlay, isOnlyPrivacyDotInSwLayer));
+        // Use visibility of privacy dot views & face scanning view to determine the overlay's
+        // visibility if the screen decoration SW layer overlay isn't persistently showing
+        // (ie: rounded corners always showing in SW layer)
+        overlay.getRootView().setVisibility(getWindowVisibility(overlay, shouldOptimizeVisibility));
     }
 
     @VisibleForTesting
@@ -780,7 +842,8 @@
                         | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                         | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
                         | WindowManager.LayoutParams.FLAG_SLIPPERY
-                        | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
+                        | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
                 PixelFormat.TRANSLUCENT);
         lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS
                 | WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
@@ -888,23 +951,28 @@
             mTintColor = Color.RED;
         }
 
-        // When the hwc supports screen decorations, the layer will use the A8 color mode which
-        // won't be affected by the color inversion. If the composition goes the client composition
-        // route, the color inversion will be handled by the RenderEngine.
-        if (mOverlays == null || mHwcScreenDecorationSupport != null) {
+        if (mOverlays == null) {
             return;
         }
 
-        ColorStateList tintList = ColorStateList.valueOf(mTintColor);
-        mRoundedCornerResDelegate.setColorTintList(tintList);
-
-        Integer[] roundedCornerIds = {
-                R.id.rounded_corner_top_left,
-                R.id.rounded_corner_top_right,
-                R.id.rounded_corner_bottom_left,
-                R.id.rounded_corner_bottom_right
-        };
-
+        // When the hwc supports screen decorations, the layer will use the A8 color mode which
+        // won't be affected by the color inversion. If the composition goes the client composition
+        // route, the color inversion will be handled by the RenderEngine.
+        final Set<Integer> viewsMayNeedColorUpdate = new HashSet<>();
+        if (mHwcScreenDecorationSupport == null) {
+            ColorStateList tintList = ColorStateList.valueOf(mTintColor);
+            mRoundedCornerResDelegate.setColorTintList(tintList);
+            viewsMayNeedColorUpdate.add(R.id.rounded_corner_top_left);
+            viewsMayNeedColorUpdate.add(R.id.rounded_corner_top_right);
+            viewsMayNeedColorUpdate.add(R.id.rounded_corner_bottom_left);
+            viewsMayNeedColorUpdate.add(R.id.rounded_corner_bottom_right);
+            viewsMayNeedColorUpdate.add(R.id.display_cutout);
+        }
+        if (getOverlayView(mFaceScanningViewId) != null) {
+            viewsMayNeedColorUpdate.add(mFaceScanningViewId);
+        }
+        final Integer[] views = new Integer[viewsMayNeedColorUpdate.size()];
+        viewsMayNeedColorUpdate.toArray(views);
         for (int i = 0; i < BOUNDS_POSITION_LENGTH; i++) {
             if (mOverlays[i] == null) {
                 continue;
@@ -914,12 +982,13 @@
             View child;
             for (int j = 0; j < size; j++) {
                 child = overlayView.getChildAt(j);
-                if (child instanceof DisplayCutoutView) {
+                if (viewsMayNeedColorUpdate.contains(child.getId())
+                        && child instanceof DisplayCutoutView) {
                     ((DisplayCutoutView) child).setColor(mTintColor);
                 }
             }
-            mOverlays[i].onReloadResAndMeasure(roundedCornerIds, mProviderRefreshToken, mRotation,
-                    mDisplayUniqueId);
+            mOverlays[i].onReloadResAndMeasure(views, mProviderRefreshToken,
+                    mRotation, mDisplayUniqueId);
         }
     }
 
@@ -971,8 +1040,20 @@
     public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
         pw.println("ScreenDecorations state:");
         pw.println("  DEBUG_DISABLE_SCREEN_DECORATIONS:" + DEBUG_DISABLE_SCREEN_DECORATIONS);
+        if (DEBUG_DISABLE_SCREEN_DECORATIONS) {
+            return;
+        }
+
         pw.println("  mIsPrivacyDotEnabled:" + isPrivacyDotEnabled());
-        pw.println("  isOnlyPrivacyDotInSwLayer:" + isOnlyPrivacyDotInSwLayer());
+        pw.println("  shouldOptimizeOverlayVisibility:" + shouldOptimizeVisibility());
+        final boolean supportsShowingFaceScanningAnim = mFaceScanningFactory.getHasProviders();
+        pw.println("    supportsShowingFaceScanningAnim:" + supportsShowingFaceScanningAnim);
+        if (supportsShowingFaceScanningAnim) {
+            pw.println("      canShowFaceScanningAnim:"
+                    + mFaceScanningFactory.canShowFaceScanningAnim());
+            pw.println("      shouldShowFaceScanningAnim (at time dump was taken):"
+                    + mFaceScanningFactory.shouldShowFaceScanningAnim());
+        }
         pw.println("  mPendingConfigChange:" + mPendingConfigChange);
         if (mHwcScreenDecorationSupport != null) {
             pw.println("  mHwcScreenDecorationSupport:");
@@ -1041,6 +1122,14 @@
             // update all provider views inside overlay
             updateOverlayProviderViews();
         }
+
+        FaceScanningOverlay faceScanningOverlay =
+                (FaceScanningOverlay) getOverlayView(mFaceScanningViewId);
+        if (faceScanningOverlay != null) {
+            faceScanningOverlay.setFaceScanningAnimColor(
+                    Utils.getColorAttrDefaultColor(faceScanningOverlay.getContext(),
+                            com.android.systemui.R.attr.wallpaperTextColorAccent));
+        }
     }
 
     private boolean hasRoundedCorners() {
@@ -1074,6 +1163,11 @@
         return isPrivacyDotEnabled() && isDefaultShownOverlayPos(pos, cutout);
     }
 
+    private boolean shouldShowSwLayerFaceScan(@BoundsPosition int pos,
+            @Nullable DisplayCutout cutout) {
+        return mFaceScanningFactory.getHasProviders() && isDefaultShownOverlayPos(pos, cutout);
+    }
+
     private boolean shouldShowSwLayerCutout(@BoundsPosition int pos,
             @Nullable DisplayCutout cutout) {
         final Rect[] bounds = cutout == null ? null : cutout.getBoundingRectsAll();
@@ -1082,8 +1176,8 @@
                 && mHwcScreenDecorationSupport == null);
     }
 
-    private boolean isOnlyPrivacyDotInSwLayer() {
-        return isPrivacyDotEnabled()
+    private boolean shouldOptimizeVisibility() {
+        return (isPrivacyDotEnabled() || mFaceScanningFactory.getHasProviders())
                 && (mHwcScreenDecorationSupport != null
                     || (!hasRoundedCorners() && !shouldDrawCutout())
                 );
@@ -1197,9 +1291,9 @@
     }
 
     public static class DisplayCutoutView extends DisplayCutoutBaseView {
-        private final List<Rect> mBounds = new ArrayList();
-        private final Rect mBoundingRect = new Rect();
-        private Rect mTotalBounds = new Rect();
+        final List<Rect> mBounds = new ArrayList();
+        final Rect mBoundingRect = new Rect();
+        Rect mTotalBounds = new Rect();
 
         private int mColor = Color.BLACK;
         private int mRotation;
@@ -1209,6 +1303,7 @@
         public DisplayCutoutView(Context context, @BoundsPosition int pos) {
             super(context);
             mInitialPosition = pos;
+
             paint.setColor(mColor);
             paint.setStyle(Paint.Style.FILL);
             setId(R.id.display_cutout);
@@ -1253,11 +1348,15 @@
             } else {
                 newVisible = GONE;
             }
-            if (newVisible != getVisibility()) {
+            if (updateVisOnUpdateCutout() && newVisible != getVisibility()) {
                 setVisibility(newVisible);
             }
         }
 
+        protected boolean updateVisOnUpdateCutout() {
+            return true;
+        }
+
         private void updateBoundingPath() {
             final Path path = displayInfo.displayCutout.getCutoutPath();
             if (path != null) {
@@ -1305,7 +1404,7 @@
             }
 
             if (showProtection) {
-                // Make sure that our measured height encompases the protection
+                // Make sure that our measured height encompasses the protection
                 mTotalBounds.union(mBoundingRect);
                 mTotalBounds.union((int) protectionRect.left, (int) protectionRect.top,
                         (int) protectionRect.right, (int) protectionRect.bottom);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
index cd16379..606a73a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
@@ -36,12 +36,20 @@
     iconView: ImageView
 ) : AuthIconController(context, iconView) {
 
+    var iconLayoutParamsSize = 0
+        set(value) {
+            if (field == value) {
+                return
+            }
+            iconView.layoutParams.width = value
+            iconView.layoutParams.height = value
+            field = value
+        }
+
     init {
-        val size = context.resources.getDimensionPixelSize(
+        iconLayoutParamsSize = context.resources.getDimensionPixelSize(
             R.dimen.biometric_dialog_fingerprint_icon_size
         )
-        iconView.layoutParams.width = size
-        iconView.layoutParams.height = size
     }
 
     override fun updateIcon(@BiometricState lastState: Int, @BiometricState newState: Int) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.kt
index 368bc3a..24046f0 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.kt
@@ -22,6 +22,7 @@
 import android.widget.FrameLayout
 import android.widget.TextView
 import com.android.systemui.R
+import com.android.systemui.biometrics.AuthController.ScaleFactorProvider
 
 private const val TAG = "AuthBiometricFingerprintView"
 
@@ -35,6 +36,7 @@
         private set
 
     private var udfpsAdapter: UdfpsDialogMeasureAdapter? = null
+    private var scaleFactorProvider: ScaleFactorProvider? = null
 
     /** Set the [sensorProps] of this sensor so the view can be customized prior to layout. */
     fun setSensorProperties(sensorProps: FingerprintSensorPropertiesInternal) {
@@ -42,9 +44,15 @@
         udfpsAdapter = if (isUdfps) UdfpsDialogMeasureAdapter(this, sensorProps) else null
     }
 
+    fun setScaleFactorProvider(scaleProvider: ScaleFactorProvider?) {
+        scaleFactorProvider = scaleProvider
+    }
+
     override fun onMeasureInternal(width: Int, height: Int): AuthDialog.LayoutParams {
         val layoutParams = super.onMeasureInternal(width, height)
-        return udfpsAdapter?.onMeasureInternal(width, height, layoutParams) ?: layoutParams
+        val scale = scaleFactorProvider?.provide() ?: 1.0f
+        return udfpsAdapter?.onMeasureInternal(width, height, layoutParams,
+            scale) ?: layoutParams
     }
 
     override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
@@ -80,6 +88,13 @@
     override fun createIconController(): AuthIconController =
         AuthBiometricFingerprintIconController(mContext, mIconView)
 
+    fun updateOverrideIconLayoutParamsSize() {
+        udfpsAdapter?.let {
+            (mIconController as? AuthBiometricFingerprintIconController)?.iconLayoutParamsSize =
+                    it.getSensorDiameter(scaleFactorProvider?.provide() ?: 1.0f)
+        }
+    }
+
     override fun onAttachedToWindow() {
         super.onAttachedToWindow()
         showTouchSensorString()
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
index 1413f4a..d7ae9ef 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
@@ -59,7 +59,7 @@
 /**
  * Contains the Biometric views (title, subtitle, icon, buttons, etc.) and its controllers.
  */
-public class AuthBiometricView extends LinearLayout {
+public abstract class AuthBiometricView extends LinearLayout {
 
     private static final String TAG = "AuthBiometricView";
 
@@ -116,7 +116,7 @@
         void onAction(int action);
     }
 
-    protected final Handler mHandler;
+    private final Handler mHandler;
     private final AccessibilityManager mAccessibilityManager;
     private final LockPatternUtils mLockPatternUtils;
     protected final int mTextColorError;
@@ -155,8 +155,8 @@
     // Measurements when biometric view is showing text, buttons, etc.
     @Nullable @VisibleForTesting AuthDialog.LayoutParams mLayoutParams;
 
-    protected Callback mCallback;
-    protected @BiometricState int mState;
+    private Callback mCallback;
+    @BiometricState private int mState;
 
     private float mIconOriginalY;
 
@@ -166,6 +166,8 @@
     private final Runnable mResetErrorRunnable;
     private final Runnable mResetHelpRunnable;
 
+    private Animator.AnimatorListener mJankListener;
+
     private final OnClickListener mBackgroundClickListener = (view) -> {
         if (mState == STATE_AUTHENTICATED) {
             Log.w(TAG, "Ignoring background click after authenticated");
@@ -250,18 +252,9 @@
         return false;
     }
 
-    /**
-     * Create the controller for managing the icons transitions during the prompt.
-     *
-     * Subclass should override.
-     */
+    /** Create the controller for managing the icons transitions during the prompt.*/
     @NonNull
-    protected AuthIconController createIconController() {
-        return new AuthIconController(mContext, mIconView) {
-            @Override
-            public void updateIcon(int lastState, int newState) {}
-        };
-    }
+    protected abstract AuthIconController createIconController();
 
     void setPanelController(AuthPanelController panelController) {
         mPanelController = panelController;
@@ -291,6 +284,10 @@
         mRequireConfirmation = requireConfirmation && supportsRequireConfirmation();
     }
 
+    void setJankListener(Animator.AnimatorListener jankListener) {
+        mJankListener = jankListener;
+    }
+
     @VisibleForTesting
     final void updateSize(@AuthDialog.DialogSize int newSize) {
         Log.v(TAG, "Current size: " + mSize + " New size: " + newSize);
@@ -381,6 +378,9 @@
                 }
             });
 
+            if (mJankListener != null) {
+                as.addListener(mJankListener);
+            }
             as.play(iconAnimator).with(opacityAnimator);
             as.start();
             // Animate the panel
@@ -436,6 +436,9 @@
             animators.add(translationAnimator);
             animators.add(opacityAnimator);
 
+            if (mJankListener != null) {
+                as.addListener(mJankListener);
+            }
             as.playTogether(animators);
             as.setDuration(mAnimationDurationLong * 2 / 3);
             as.start();
@@ -881,4 +884,14 @@
     @AuthDialog.DialogSize int getSize() {
         return mSize;
     }
+
+    /** If authentication has successfully occurred and the view is done. */
+    boolean isAuthenticated() {
+        return mState == STATE_AUTHENTICATED;
+    }
+
+    /** If authentication is currently in progress. */
+    boolean isAuthenticating() {
+        return mState == STATE_AUTHENTICATING;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 6da2f50..bc1c5f4 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -19,6 +19,9 @@
 import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_DEFAULT;
 import static android.hardware.biometrics.BiometricManager.BiometricMultiSensorMode;
 
+import static com.android.internal.jank.InteractionJankMonitor.CUJ_BIOMETRIC_PROMPT_TRANSITION;
+
+import android.animation.Animator;
 import android.annotation.DurationMillisLong;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -53,13 +56,16 @@
 import android.widget.ScrollView;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.systemui.R;
 import com.android.systemui.animation.Interpolators;
+import com.android.systemui.biometrics.AuthController.ScaleFactorProvider;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.util.concurrency.DelayableExecutor;
 
+import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.HashSet;
@@ -84,6 +90,13 @@
     private static final int STATE_ANIMATING_OUT = 4;
     private static final int STATE_GONE = 5;
 
+    /** Shows biometric prompt dialog animation. */
+    private static final String SHOW = "show";
+    /** Dismiss biometric prompt dialog animation.  */
+    private static final String DISMISS = "dismiss";
+    /** Transit biometric prompt dialog to pin, password, pattern credential panel. */
+    private static final String TRANSIT = "transit";
+
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({STATE_UNKNOWN, STATE_ANIMATING_IN, STATE_PENDING_DISMISS, STATE_SHOWING,
             STATE_ANIMATING_OUT, STATE_GONE})
@@ -98,6 +111,7 @@
     private final CredentialCallback mCredentialCallback;
     private final LockPatternUtils mLockPatternUtils;
     private final WakefulnessLifecycle mWakefulnessLifecycle;
+    private final InteractionJankMonitor mInteractionJankMonitor;
 
     @VisibleForTesting final BiometricCallback mBiometricCallback;
 
@@ -133,6 +147,7 @@
         long mRequestId = -1;
         boolean mSkipAnimation = false;
         @BiometricMultiSensorMode int mMultiSensorConfig = BIOMETRIC_MULTI_SENSOR_DEFAULT;
+        ScaleFactorProvider mScaleProvider;
     }
 
     public static class Builder {
@@ -196,15 +211,22 @@
             return this;
         }
 
+        public Builder setScaleFactorProvider(ScaleFactorProvider scaleProvider) {
+            mConfig.mScaleProvider = scaleProvider;
+            return this;
+        }
+
         public AuthContainerView build(@Background DelayableExecutor bgExecutor, int[] sensorIds,
                 @Nullable List<FingerprintSensorPropertiesInternal> fpProps,
                 @Nullable List<FaceSensorPropertiesInternal> faceProps,
                 @NonNull WakefulnessLifecycle wakefulnessLifecycle,
                 @NonNull UserManager userManager,
-                @NonNull LockPatternUtils lockPatternUtils) {
+                @NonNull LockPatternUtils lockPatternUtils,
+                @NonNull InteractionJankMonitor jankMonitor) {
             mConfig.mSensorIds = sensorIds;
             return new AuthContainerView(mConfig, fpProps, faceProps, wakefulnessLifecycle,
-                    userManager, lockPatternUtils, new Handler(Looper.getMainLooper()), bgExecutor);
+                    userManager, lockPatternUtils, jankMonitor, new Handler(Looper.getMainLooper()),
+                    bgExecutor);
         }
     }
 
@@ -257,6 +279,7 @@
             @NonNull WakefulnessLifecycle wakefulnessLifecycle,
             @NonNull UserManager userManager,
             @NonNull LockPatternUtils lockPatternUtils,
+            @NonNull InteractionJankMonitor jankMonitor,
             @NonNull Handler mainHandler,
             @NonNull @Background DelayableExecutor bgExecutor) {
         super(config.mContext);
@@ -283,6 +306,7 @@
         mPanelView = mFrameLayout.findViewById(R.id.panel);
         mPanelController = new AuthPanelController(mContext, mPanelView);
         mBackgroundExecutor = bgExecutor;
+        mInteractionJankMonitor = jankMonitor;
 
         // Inflate biometric view only if necessary.
         if (Utils.isBiometricAllowed(mConfig.mPromptInfo)) {
@@ -296,12 +320,16 @@
                         (AuthBiometricFingerprintAndFaceView) layoutInflater.inflate(
                                 R.layout.auth_biometric_fingerprint_and_face_view, null, false);
                 fingerprintAndFaceView.setSensorProperties(fpProperties);
+                fingerprintAndFaceView.setScaleFactorProvider(config.mScaleProvider);
+                fingerprintAndFaceView.updateOverrideIconLayoutParamsSize();
                 mBiometricView = fingerprintAndFaceView;
             } else if (fpProperties != null) {
                 final AuthBiometricFingerprintView fpView =
                         (AuthBiometricFingerprintView) layoutInflater.inflate(
                                 R.layout.auth_biometric_fingerprint_view, null, false);
                 fpView.setSensorProperties(fpProperties);
+                fpView.setScaleFactorProvider(config.mScaleProvider);
+                fpView.updateOverrideIconLayoutParamsSize();
                 mBiometricView = fpView;
             } else if (faceProperties != null) {
                 mBiometricView = (AuthBiometricFaceView) layoutInflater.inflate(
@@ -320,6 +348,8 @@
             mBiometricView.setBackgroundView(mBackgroundView);
             mBiometricView.setUserId(mConfig.mUserId);
             mBiometricView.setEffectiveUserId(mEffectiveUserId);
+            mBiometricView.setJankListener(getJankListener(mBiometricView, TRANSIT,
+                    AuthDialog.ANIMATE_MEDIUM_TO_LARGE_DURATION_MS));
         }
 
         // TODO: De-dupe the logic with AuthCredentialPasswordView
@@ -447,6 +477,7 @@
                         .translationY(0)
                         .setDuration(animateDuration)
                         .setInterpolator(mLinearOutSlowIn)
+                        .setListener(getJankListener(mPanelView, SHOW, animateDuration))
                         .withLayer()
                         .withEndAction(this::onDialogAnimatedIn)
                         .start();
@@ -454,6 +485,7 @@
                         .translationY(0)
                         .setDuration(animateDuration)
                         .setInterpolator(mLinearOutSlowIn)
+                        .setListener(getJankListener(mBiometricScrollView, SHOW, animateDuration))
                         .withLayer()
                         .start();
                 if (mCredentialView != null && mCredentialView.isAttachedToWindow()) {
@@ -462,6 +494,7 @@
                             .translationY(0)
                             .setDuration(animateDuration)
                             .setInterpolator(mLinearOutSlowIn)
+                            .setListener(getJankListener(mCredentialView, SHOW, animateDuration))
                             .withLayer()
                             .start();
                 }
@@ -470,11 +503,49 @@
                         .setDuration(animateDuration)
                         .setInterpolator(mLinearOutSlowIn)
                         .withLayer()
+                        .setListener(getJankListener(this, SHOW, animateDuration))
                         .start();
             });
         }
     }
 
+    private Animator.AnimatorListener getJankListener(View v, String type, long timeout) {
+        return new Animator.AnimatorListener() {
+            @Override
+            public void onAnimationStart(@androidx.annotation.NonNull Animator animation) {
+                if (!v.isAttachedToWindow()) {
+                    Log.w(TAG, "Un-attached view should not begin Jank trace.");
+                    return;
+                }
+                mInteractionJankMonitor.begin(InteractionJankMonitor.Configuration.Builder.withView(
+                        CUJ_BIOMETRIC_PROMPT_TRANSITION, v).setTag(type).setTimeout(timeout));
+            }
+
+            @Override
+            public void onAnimationEnd(@androidx.annotation.NonNull Animator animation) {
+                if (!v.isAttachedToWindow()) {
+                    Log.w(TAG, "Un-attached view should not end Jank trace.");
+                    return;
+                }
+                mInteractionJankMonitor.end(CUJ_BIOMETRIC_PROMPT_TRANSITION);
+            }
+
+            @Override
+            public void onAnimationCancel(@androidx.annotation.NonNull Animator animation) {
+                if (!v.isAttachedToWindow()) {
+                    Log.w(TAG, "Un-attached view should not cancel Jank trace.");
+                    return;
+                }
+                mInteractionJankMonitor.cancel(CUJ_BIOMETRIC_PROMPT_TRANSITION);
+            }
+
+            @Override
+            public void onAnimationRepeat(@androidx.annotation.NonNull Animator animation) {
+                // no-op
+            }
+        };
+    }
+
     private static boolean shouldUpdatePositionForUdfps(@NonNull View view) {
         if (view instanceof AuthBiometricFingerprintView) {
             return ((AuthBiometricFingerprintView) view).isUdfps();
@@ -658,6 +729,7 @@
                     .translationY(mTranslationY)
                     .setDuration(animateDuration)
                     .setInterpolator(mLinearOutSlowIn)
+                    .setListener(getJankListener(mPanelView, DISMISS, animateDuration))
                     .withLayer()
                     .withEndAction(endActionRunnable)
                     .start();
@@ -665,6 +737,7 @@
                     .translationY(mTranslationY)
                     .setDuration(animateDuration)
                     .setInterpolator(mLinearOutSlowIn)
+                    .setListener(getJankListener(mBiometricScrollView, DISMISS, animateDuration))
                     .withLayer()
                     .start();
             if (mCredentialView != null && mCredentialView.isAttachedToWindow()) {
@@ -672,6 +745,7 @@
                         .translationY(mTranslationY)
                         .setDuration(animateDuration)
                         .setInterpolator(mLinearOutSlowIn)
+                        .setListener(getJankListener(mCredentialView, DISMISS, animateDuration))
                         .withLayer()
                         .start();
             }
@@ -679,6 +753,7 @@
                     .alpha(0f)
                     .setDuration(animateDuration)
                     .setInterpolator(mLinearOutSlowIn)
+                    .setListener(getJankListener(this, DISMISS, animateDuration))
                     .withLayer()
                     .start();
         });
@@ -739,4 +814,36 @@
         lp.token = windowToken;
         return lp;
     }
+
+    @Override
+    public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
+        pw.println("    isAttachedToWindow=" + isAttachedToWindow());
+        pw.println("    containerState=" + mContainerState);
+        pw.println("    pendingCallbackReason=" + mPendingCallbackReason);
+        pw.println("    config exist=" + (mConfig != null));
+        if (mConfig != null) {
+            pw.println("    config.sensorIds exist=" + (mConfig.mSensorIds != null));
+        }
+        final AuthBiometricView biometricView = mBiometricView;
+        pw.println("    scrollView=" + findViewById(R.id.biometric_scrollview));
+        pw.println("      biometricView=" + biometricView);
+        if (biometricView != null) {
+            int[] ids = {
+                    R.id.title,
+                    R.id.subtitle,
+                    R.id.description,
+                    R.id.biometric_icon_frame,
+                    R.id.biometric_icon,
+                    R.id.indicator,
+                    R.id.button_bar,
+                    R.id.button_negative,
+                    R.id.button_use_credential,
+                    R.id.button_confirm,
+                    R.id.button_try_again
+            };
+            for (final int id: ids) {
+                pw.println("        " + biometricView.findViewById(id));
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 1739646..a097c5e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -62,6 +62,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.systemui.CoreStartable;
@@ -75,6 +76,7 @@
 import com.android.systemui.util.concurrency.DelayableExecutor;
 import com.android.systemui.util.concurrency.Execution;
 
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -143,6 +145,7 @@
     private boolean mAllFingerprintAuthenticatorsRegistered;
     @NonNull private final UserManager mUserManager;
     @NonNull private final LockPatternUtils mLockPatternUtils;
+    @NonNull private final InteractionJankMonitor mInteractionJankMonitor;
     private final @Background DelayableExecutor mBackgroundExecutor;
 
     @VisibleForTesting
@@ -489,6 +492,9 @@
         final float scaleFactor = android.util.DisplayUtils.getPhysicalPixelDisplaySizeRatio(
                 mStableDisplaySize.x, mStableDisplaySize.y, displayInfo.getNaturalWidth(),
                 displayInfo.getNaturalHeight());
+        if (scaleFactor == Float.POSITIVE_INFINITY) {
+            return new PointF(mFaceAuthSensorLocation.x, mFaceAuthSensorLocation.y);
+        }
         return new PointF(mFaceAuthSensorLocation.x * scaleFactor,
                 mFaceAuthSensorLocation.y * scaleFactor);
     }
@@ -549,6 +555,7 @@
             @NonNull UserManager userManager,
             @NonNull LockPatternUtils lockPatternUtils,
             @NonNull StatusBarStateController statusBarStateController,
+            @NonNull InteractionJankMonitor jankMonitor,
             @Main Handler handler,
             @Background DelayableExecutor bgExecutor) {
         super(context);
@@ -566,6 +573,7 @@
         mSidefpsControllerFactory = sidefpsControllerFactory;
         mDisplayManager = displayManager;
         mWindowManager = windowManager;
+        mInteractionJankMonitor = jankMonitor;
         mUdfpsEnrolledForUser = new SparseBooleanArray();
 
         mOrientationListener = new BiometricDisplayListener(
@@ -1037,8 +1045,36 @@
                 .setOperationId(operationId)
                 .setRequestId(requestId)
                 .setMultiSensorConfig(multiSensorConfig)
+                .setScaleFactorProvider(() -> {
+                    return getScaleFactor();
+                })
                 .build(bgExecutor, sensorIds, mFpProps, mFaceProps, wakefulnessLifecycle,
-                        userManager, lockPatternUtils);
+                        userManager, lockPatternUtils, mInteractionJankMonitor);
+    }
+
+    @Override
+    public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
+        final AuthDialog dialog = mCurrentDialog;
+        pw.println("  stableDisplaySize=" + mStableDisplaySize);
+        pw.println("  faceAuthSensorLocation=" + mFaceAuthSensorLocation);
+        pw.println("  fingerprintLocation=" + mFingerprintLocation);
+        pw.println("  udfpsBounds=" + mUdfpsBounds);
+        pw.println("  allFingerprintAuthenticatorsRegistered="
+                + mAllFingerprintAuthenticatorsRegistered);
+        pw.println("  currentDialog=" + dialog);
+        if (dialog != null) {
+            dialog.dump(pw, args);
+        }
+    }
+
+    /**
+     * Provides a float that represents the resolution scale(if the controller is for UDFPS).
+     */
+    public interface ScaleFactorProvider {
+        /**
+         * Returns a float representing the scaled resolution(if the controller if for UDFPS).
+         */
+        float provide();
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
index 4ff19f6..51f39b3 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
@@ -23,13 +23,15 @@
 import android.os.Bundle;
 import android.view.WindowManager;
 
+import com.android.systemui.Dumpable;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
 /**
  * Interface for the biometric dialog UI.
  */
-public interface AuthDialog {
+public interface AuthDialog extends Dumpable {
 
     String KEY_CONTAINER_GOING_AWAY = "container_going_away";
     String KEY_BIOMETRIC_SHOWING = "biometric_showing";
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
index 86e5016..38fab8f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
@@ -23,7 +23,6 @@
 import android.graphics.PointF
 import android.hardware.biometrics.BiometricFingerprintConstants
 import android.hardware.biometrics.BiometricSourceType
-import android.util.DisplayMetrics
 import android.util.Log
 import androidx.annotation.VisibleForTesting
 import com.android.keyguard.KeyguardUpdateMonitor
@@ -46,7 +45,6 @@
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.ViewController
-import com.android.systemui.util.leak.RotationUtils
 import java.io.PrintWriter
 import javax.inject.Inject
 import javax.inject.Provider
@@ -127,17 +125,37 @@
         }
 
         updateSensorLocation()
-        if (biometricSourceType == BiometricSourceType.FINGERPRINT &&
-            fingerprintSensorLocation != null) {
-            mView.setFingerprintSensorLocation(fingerprintSensorLocation!!, udfpsRadius)
-            showUnlockedRipple()
-        } else if (biometricSourceType == BiometricSourceType.FACE &&
-            faceSensorLocation != null) {
-            if (!bypassController.canBypass()) {
+        if (biometricSourceType == BiometricSourceType.FINGERPRINT) {
+            fingerprintSensorLocation?.let {
+                mView.setFingerprintSensorLocation(it, udfpsRadius)
+                circleReveal = CircleReveal(
+                        it.x,
+                        it.y,
+                        0f,
+                        Math.max(
+                                Math.max(it.x, centralSurfaces.displayWidth - it.x),
+                                Math.max(it.y, centralSurfaces.displayHeight - it.y)
+                        )
+                )
+                showUnlockedRipple()
+            }
+        } else if (biometricSourceType == BiometricSourceType.FACE) {
+            if (!bypassController.canBypass() && !authController.isUdfpsFingerDown) {
                 return
             }
-            mView.setSensorLocation(faceSensorLocation!!)
-            showUnlockedRipple()
+            faceSensorLocation?.let {
+                mView.setSensorLocation(it)
+                circleReveal = CircleReveal(
+                        it.x,
+                        it.y,
+                        0f,
+                        Math.max(
+                                Math.max(it.x, centralSurfaces.displayWidth - it.x),
+                                Math.max(it.y, centralSurfaces.displayHeight - it.y)
+                        )
+                )
+                showUnlockedRipple()
+            }
         }
     }
 
@@ -209,48 +227,8 @@
     }
 
     fun updateSensorLocation() {
-        updateFingerprintLocation()
+        fingerprintSensorLocation = authController.fingerprintSensorLocation
         faceSensorLocation = authController.faceAuthSensorLocation
-        fingerprintSensorLocation?.let {
-            circleReveal = CircleReveal(
-                it.x,
-                it.y,
-                0f,
-                Math.max(
-                    Math.max(it.x, centralSurfaces.displayWidth - it.x),
-                    Math.max(it.y, centralSurfaces.displayHeight - it.y)
-                )
-            )
-        }
-    }
-
-    private fun updateFingerprintLocation() {
-        val displayMetrics = DisplayMetrics()
-        sysuiContext.display?.getRealMetrics(displayMetrics)
-        val width = displayMetrics.widthPixels
-        val height = displayMetrics.heightPixels
-
-        authController.fingerprintSensorLocation?.let {
-            fingerprintSensorLocation = when (RotationUtils.getRotation(sysuiContext)) {
-                RotationUtils.ROTATION_LANDSCAPE -> {
-                    val normalizedYPos: Float = it.y / width
-                    val normalizedXPos: Float = it.x / height
-                    PointF(width * normalizedYPos, height * (1 - normalizedXPos))
-                }
-                RotationUtils.ROTATION_UPSIDE_DOWN -> {
-                    PointF(width - it.x, height - it.y)
-                }
-                RotationUtils.ROTATION_SEASCAPE -> {
-                    val normalizedYPos: Float = it.y / width
-                    val normalizedXPos: Float = it.x / height
-                    PointF(width * (1 - normalizedYPos), height * normalizedXPos)
-                }
-                else -> {
-                    // ROTATION_NONE
-                    PointF(it.x, it.y)
-                }
-            }
-        }
     }
 
     private fun updateRippleColor() {
@@ -372,6 +350,7 @@
                         showUnlockRipple(BiometricSourceType.FINGERPRINT)
                     }
                     "face" -> {
+                        // note: only shows when about to proceed to the home screen
                         updateSensorLocation()
                         pw.println("face ripple sensorLocation=$faceSensorLocation")
                         showUnlockRipple(BiometricSourceType.FACE)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 6e2dcae..fb502e5 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -20,6 +20,7 @@
 import static android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD;
 
 import static com.android.internal.util.Preconditions.checkNotNull;
+import static com.android.systemui.classifier.Classifier.LOCK_ICON;
 import static com.android.systemui.classifier.Classifier.UDFPS_AUTHENTICATION;
 
 import android.annotation.NonNull;
@@ -167,11 +168,16 @@
     private final Set<Callback> mCallbacks = new HashSet<>();
 
     @VisibleForTesting
-    public static final VibrationAttributes VIBRATION_ATTRIBUTES =
+    public static final VibrationAttributes UDFPS_VIBRATION_ATTRIBUTES =
             new VibrationAttributes.Builder()
                     // vibration will bypass battery saver mode:
                     .setUsage(VibrationAttributes.USAGE_COMMUNICATION_REQUEST)
                     .build();
+    @VisibleForTesting
+    public static final VibrationAttributes LOCK_ICON_VIBRATION_ATTRIBUTES =
+            new VibrationAttributes.Builder()
+                    .setUsage(VibrationAttributes.USAGE_TOUCH)
+                    .build();
 
     // haptic to use for successful device entry
     public static final VibrationEffect EFFECT_CLICK =
@@ -671,7 +677,7 @@
                     mContext.getOpPackageName(),
                     EFFECT_CLICK,
                     "udfps-onStart-click",
-                    VIBRATION_ATTRIBUTES);
+                    UDFPS_VIBRATION_ATTRIBUTES);
         }
     }
 
@@ -748,7 +754,19 @@
         }
 
         if (!mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
+            if (mFalsingManager.isFalseTouch(LOCK_ICON)) {
+                Log.v(TAG, "aod lock icon long-press rejected by the falsing manager.");
+                return;
+            }
             mKeyguardViewManager.showBouncer(true);
+
+            // play the same haptic as the LockIconViewController longpress
+            mVibrator.vibrate(
+                    Process.myUid(),
+                    mContext.getOpPackageName(),
+                    UdfpsController.EFFECT_CLICK,
+                    "aod-lock-icon-longpress",
+                    LOCK_ICON_VIBRATION_ATTRIBUTES);
             return;
         }
 
@@ -841,6 +859,11 @@
             mBiometricExecutor.execute(() -> {
                 mAlternateTouchProvider.onPointerDown(requestId, x, y, minor, major);
             });
+            mFgExecutor.execute(() -> {
+                if (mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
+                    mKeyguardUpdateMonitor.onUdfpsPointerDown((int) requestId);
+                }
+            });
         } else {
             mFingerprintManager.onPointerDown(requestId, mSensorId, x, y, minor, major);
         }
@@ -856,7 +879,6 @@
                 } else {
                     mFingerprintManager.onUiReady(requestId, mSensorId);
                     mLatencyTracker.onActionEnd(LatencyTracker.ACTION_UDFPS_ILLUMINATE);
-
                 }
             });
         }
@@ -875,6 +897,11 @@
                 mBiometricExecutor.execute(() -> {
                     mAlternateTouchProvider.onPointerUp(requestId);
                 });
+                mFgExecutor.execute(() -> {
+                    if (mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
+                        mKeyguardUpdateMonitor.onUdfpsPointerUp((int) requestId);
+                    }
+                });
             } else {
                 mFingerprintManager.onPointerUp(requestId, mSensorId);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java
index 8de7213..43745bf 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java
@@ -64,15 +64,16 @@
 
     @NonNull
     AuthDialog.LayoutParams onMeasureInternal(
-            int width, int height, @NonNull AuthDialog.LayoutParams layoutParams) {
+            int width, int height, @NonNull AuthDialog.LayoutParams layoutParams,
+            float scaleFactor) {
 
         final int displayRotation = mView.getDisplay().getRotation();
         switch (displayRotation) {
             case Surface.ROTATION_0:
-                return onMeasureInternalPortrait(width, height);
+                return onMeasureInternalPortrait(width, height, scaleFactor);
             case Surface.ROTATION_90:
             case Surface.ROTATION_270:
-                return onMeasureInternalLandscape(width, height);
+                return onMeasureInternalLandscape(width, height, scaleFactor);
             default:
                 Log.e(TAG, "Unsupported display rotation: " + displayRotation);
                 return layoutParams;
@@ -89,8 +90,16 @@
         return mBottomSpacerHeight;
     }
 
+    /**
+     * @return sensor diameter size as scaleFactor
+     */
+    public int getSensorDiameter(float scaleFactor) {
+        return (int) (scaleFactor * mSensorProps.getLocation().sensorRadius * 2);
+    }
+
     @NonNull
-    private AuthDialog.LayoutParams onMeasureInternalPortrait(int width, int height) {
+    private AuthDialog.LayoutParams onMeasureInternalPortrait(int width, int height,
+            float scaleFactor) {
         final WindowMetrics windowMetrics = mWindowManager.getMaximumWindowMetrics();
 
         // Figure out where the bottom of the sensor anim should be.
@@ -101,12 +110,12 @@
         final Insets navbarInsets = getNavbarInsets(windowMetrics);
         mBottomSpacerHeight = calculateBottomSpacerHeightForPortrait(
                 mSensorProps, displayHeight, textIndicatorHeight, buttonBarHeight,
-                dialogMargin, navbarInsets.bottom);
+                dialogMargin, navbarInsets.bottom, scaleFactor);
 
         // Go through each of the children and do the custom measurement.
         int totalHeight = 0;
         final int numChildren = mView.getChildCount();
-        final int sensorDiameter = mSensorProps.getLocation().sensorRadius * 2;
+        final int sensorDiameter = getSensorDiameter(scaleFactor);
         for (int i = 0; i < numChildren; i++) {
             final View child = mView.getChildAt(i);
             if (child.getId() == R.id.biometric_icon_frame) {
@@ -176,7 +185,8 @@
     }
 
     @NonNull
-    private AuthDialog.LayoutParams onMeasureInternalLandscape(int width, int height) {
+    private AuthDialog.LayoutParams onMeasureInternalLandscape(int width, int height,
+            float scaleFactor) {
         final WindowMetrics windowMetrics = mWindowManager.getMaximumWindowMetrics();
 
         // Find the spacer height needed to vertically align the icon with the sensor.
@@ -197,9 +207,9 @@
         final int dialogMargin = getDialogMarginPx();
         final int horizontalInset = navbarInsets.left + navbarInsets.right;
         final int horizontalSpacerWidth = calculateHorizontalSpacerWidthForLandscape(
-                mSensorProps, displayWidth, dialogMargin, horizontalInset);
+                mSensorProps, displayWidth, dialogMargin, horizontalInset, scaleFactor);
 
-        final int sensorDiameter = mSensorProps.getLocation().sensorRadius * 2;
+        final int sensorDiameter = getSensorDiameter(scaleFactor);
         final int remeasuredWidth = sensorDiameter + 2 * horizontalSpacerWidth;
 
         int remeasuredHeight = 0;
@@ -281,11 +291,11 @@
     static int calculateBottomSpacerHeightForPortrait(
             @NonNull FingerprintSensorPropertiesInternal sensorProperties, int displayHeightPx,
             int textIndicatorHeightPx, int buttonBarHeightPx, int dialogMarginPx,
-            int navbarBottomInsetPx) {
+            int navbarBottomInsetPx, float scaleFactor) {
         final SensorLocationInternal location = sensorProperties.getLocation();
         final int sensorDistanceFromBottom = displayHeightPx
-                - location.sensorLocationY
-                - location.sensorRadius;
+                - (int) (scaleFactor * location.sensorLocationY)
+                - (int) (scaleFactor * location.sensorRadius);
 
         final int spacerHeight = sensorDistanceFromBottom
                 - textIndicatorHeightPx
@@ -298,7 +308,8 @@
                     + ", Distance from bottom: " + sensorDistanceFromBottom
                     + ", Bottom margin: " + dialogMarginPx
                     + ", Navbar bottom inset: " + navbarBottomInsetPx
-                    + ", Bottom spacer height (portrait): " + spacerHeight);
+                    + ", Bottom spacer height (portrait): " + spacerHeight
+                    + ", Scale Factor: " + scaleFactor);
         }
 
         return spacerHeight;
@@ -346,11 +357,11 @@
     @VisibleForTesting
     static int calculateHorizontalSpacerWidthForLandscape(
             @NonNull FingerprintSensorPropertiesInternal sensorProperties, int displayWidthPx,
-            int dialogMarginPx, int navbarHorizontalInsetPx) {
+            int dialogMarginPx, int navbarHorizontalInsetPx, float scaleFactor) {
         final SensorLocationInternal location = sensorProperties.getLocation();
         final int sensorDistanceFromEdge = displayWidthPx
-                - location.sensorLocationY
-                - location.sensorRadius;
+                - (int) (scaleFactor * location.sensorLocationY)
+                - (int) (scaleFactor * location.sensorRadius);
 
         final int horizontalPadding = sensorDistanceFromEdge
                 - dialogMarginPx
@@ -361,7 +372,8 @@
                     + ", Distance from edge: " + sensorDistanceFromEdge
                     + ", Dialog margin: " + dialogMarginPx
                     + ", Navbar horizontal inset: " + navbarHorizontalInsetPx
-                    + ", Horizontal spacer width (landscape): " + horizontalPadding);
+                    + ", Horizontal spacer width (landscape): " + horizontalPadding
+                    + ", Scale Factor: " + scaleFactor);
         }
 
         return horizontalPadding;
diff --git a/packages/SystemUI/src/com/android/systemui/decor/DecorProvider.kt b/packages/SystemUI/src/com/android/systemui/decor/DecorProvider.kt
index 03ee8b1..169b50e 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/DecorProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/DecorProvider.kt
@@ -79,4 +79,16 @@
     override val alignedBounds: List<Int> by lazy {
         listOf(alignedBound1, alignedBound2)
     }
-}
\ No newline at end of file
+}
+
+/**
+ * A provider for view shown on bound.
+ */
+abstract class BoundDecorProvider : DecorProvider() {
+    /** The bound which a view is aligned based on rotation 0 */
+    @DisplayCutout.BoundsPosition protected abstract val alignedBound: Int
+
+    override val alignedBounds: List<Int> by lazy {
+        listOf(alignedBound)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt b/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt
new file mode 100644
index 0000000..81d3d6c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2022 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.decor
+
+import android.content.Context
+import android.util.Log
+import android.view.DisplayCutout
+import android.view.DisplayCutout.BOUNDS_POSITION_BOTTOM
+import android.view.DisplayCutout.BOUNDS_POSITION_LEFT
+import android.view.DisplayCutout.BOUNDS_POSITION_RIGHT
+import android.view.DisplayCutout.BOUNDS_POSITION_TOP
+import android.view.DisplayInfo
+import android.view.Gravity
+import android.view.Surface
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.systemui.FaceScanningOverlay
+import com.android.systemui.biometrics.AuthController
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import java.util.concurrent.Executor
+import javax.inject.Inject
+
+@SysUISingleton
+class FaceScanningProviderFactory @Inject constructor(
+    private val authController: AuthController,
+    private val context: Context,
+    private val statusBarStateController: StatusBarStateController,
+    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
+    @Main private val mainExecutor: Executor,
+    private val featureFlags: FeatureFlags
+) : DecorProviderFactory() {
+    private val display = context.display
+    private val displayInfo = DisplayInfo()
+
+    override val hasProviders: Boolean
+        get() {
+            if (!featureFlags.isEnabled(Flags.FACE_SCANNING_ANIM) ||
+                    authController.faceAuthSensorLocation == null) {
+                return false
+            }
+
+            // update display info
+            display?.getDisplayInfo(displayInfo) ?: run {
+                Log.w(TAG, "display is null, can't update displayInfo")
+            }
+            return DisplayCutout.getFillBuiltInDisplayCutout(
+                    context.resources, displayInfo.uniqueId)
+        }
+
+    override val providers: List<DecorProvider>
+        get() {
+            if (!hasProviders) {
+                return emptyList()
+            }
+
+            return ArrayList<DecorProvider>().also { list ->
+                // displayInfo must be updated before using it; however it will already have
+                // been updated when accessing the hasProviders field above
+                displayInfo.displayCutout?.getBoundBaseOnCurrentRotation()?.let { bounds ->
+                    // Add a face scanning view for each screen orientation.
+                    // Cutout drawing is updated in ScreenDecorations#updateCutout
+                    for (bound in bounds) {
+                        list.add(
+                                FaceScanningOverlayProviderImpl(
+                                        bound.baseOnRotation0(displayInfo.rotation),
+                                        authController,
+                                        statusBarStateController,
+                                        keyguardUpdateMonitor,
+                                        mainExecutor
+                                )
+                        )
+                    }
+                }
+            }
+        }
+
+    fun canShowFaceScanningAnim(): Boolean {
+        return hasProviders && keyguardUpdateMonitor.isFaceEnrolled
+    }
+
+    fun shouldShowFaceScanningAnim(): Boolean {
+        return canShowFaceScanningAnim() && keyguardUpdateMonitor.isFaceScanning
+    }
+}
+
+class FaceScanningOverlayProviderImpl(
+    override val alignedBound: Int,
+    private val authController: AuthController,
+    private val statusBarStateController: StatusBarStateController,
+    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
+    private val mainExecutor: Executor
+) : BoundDecorProvider() {
+    override val viewId: Int = com.android.systemui.R.id.face_scanning_anim
+
+    override fun onReloadResAndMeasure(
+        view: View,
+        reloadToken: Int,
+        rotation: Int,
+        displayUniqueId: String?
+    ) {
+        (view.layoutParams as FrameLayout.LayoutParams).let {
+            updateLayoutParams(it, rotation)
+            view.layoutParams = it
+        }
+    }
+
+    override fun inflateView(
+        context: Context,
+        parent: ViewGroup,
+        @Surface.Rotation rotation: Int
+    ): View {
+        val view = FaceScanningOverlay(
+                context,
+                alignedBound,
+                statusBarStateController,
+                keyguardUpdateMonitor,
+                mainExecutor
+        )
+        view.id = viewId
+        FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT).let {
+            updateLayoutParams(it, rotation)
+            parent.addView(view, it)
+        }
+        return view
+    }
+
+    private fun updateLayoutParams(
+        layoutParams: FrameLayout.LayoutParams,
+        @Surface.Rotation rotation: Int
+    ) {
+        layoutParams.let { lp ->
+            lp.width = ViewGroup.LayoutParams.MATCH_PARENT
+            lp.height = ViewGroup.LayoutParams.MATCH_PARENT
+            authController.faceAuthSensorLocation?.y?.let { faceAuthSensorHeight ->
+                val faceScanningHeight = (faceAuthSensorHeight * 2).toInt()
+                when (rotation) {
+                    Surface.ROTATION_0, Surface.ROTATION_180 ->
+                        lp.height = faceScanningHeight
+                    Surface.ROTATION_90, Surface.ROTATION_270 ->
+                        lp.width = faceScanningHeight
+                }
+            }
+
+            lp.gravity = when (rotation) {
+                Surface.ROTATION_0 -> Gravity.TOP or Gravity.START
+                Surface.ROTATION_90 -> Gravity.LEFT or Gravity.START
+                Surface.ROTATION_180 -> Gravity.BOTTOM or Gravity.END
+                Surface.ROTATION_270 -> Gravity.RIGHT or Gravity.END
+                else -> -1 /* invalid rotation */
+            }
+        }
+    }
+}
+
+fun DisplayCutout.getBoundBaseOnCurrentRotation(): List<Int> {
+    return ArrayList<Int>().also {
+        if (!boundingRectLeft.isEmpty) {
+            it.add(BOUNDS_POSITION_LEFT)
+        }
+        if (!boundingRectTop.isEmpty) {
+            it.add(BOUNDS_POSITION_TOP)
+        }
+        if (!boundingRectRight.isEmpty) {
+            it.add(BOUNDS_POSITION_RIGHT)
+        }
+        if (!boundingRectBottom.isEmpty) {
+            it.add(BOUNDS_POSITION_BOTTOM)
+        }
+    }
+}
+
+fun Int.baseOnRotation0(@DisplayCutout.BoundsPosition currentRotation: Int): Int {
+    return when (currentRotation) {
+        Surface.ROTATION_0 -> this
+        Surface.ROTATION_90 -> when (this) {
+            BOUNDS_POSITION_LEFT -> BOUNDS_POSITION_TOP
+            BOUNDS_POSITION_TOP -> BOUNDS_POSITION_RIGHT
+            BOUNDS_POSITION_RIGHT -> BOUNDS_POSITION_BOTTOM
+            else /* BOUNDS_POSITION_BOTTOM */ -> BOUNDS_POSITION_LEFT
+        }
+        Surface.ROTATION_270 -> when (this) {
+            BOUNDS_POSITION_LEFT -> BOUNDS_POSITION_BOTTOM
+            BOUNDS_POSITION_TOP -> BOUNDS_POSITION_LEFT
+            BOUNDS_POSITION_RIGHT -> BOUNDS_POSITION_TOP
+            else /* BOUNDS_POSITION_BOTTOM */ -> BOUNDS_POSITION_RIGHT
+        }
+        else /* Surface.ROTATION_180 */ -> when (this) {
+            BOUNDS_POSITION_LEFT -> BOUNDS_POSITION_RIGHT
+            BOUNDS_POSITION_TOP -> BOUNDS_POSITION_BOTTOM
+            BOUNDS_POSITION_RIGHT -> BOUNDS_POSITION_LEFT
+            else /* BOUNDS_POSITION_BOTTOM */ -> BOUNDS_POSITION_TOP
+        }
+    }
+}
+
+private const val TAG = "FaceScanningProvider"
diff --git a/packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt b/packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt
index 136f135..9f624b3 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt
@@ -28,6 +28,10 @@
 import com.android.systemui.dagger.qualifiers.Main
 import javax.inject.Inject
 
+/**
+ * Provides privacy dot views for each orientation. The PrivacyDot orientation and visibility
+ * of the privacy dot views are controlled by the PrivacyDotViewController.
+ */
 @SysUISingleton
 class PrivacyDotDecorProviderFactory @Inject constructor(
     @Main private val res: Resources
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index c8720e4..da6c163 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -183,7 +183,8 @@
                         mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION),
                         null /* setting */,
                         dozeParameters.getPulseOnSigMotion(),
-                        DozeLog.PULSE_REASON_SENSOR_SIGMOTION, false /* touchCoords */,
+                        DozeLog.PULSE_REASON_SENSOR_SIGMOTION,
+                        false /* touchCoords */,
                         false /* touchscreen */),
                 new TriggerSensor(
                         mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE),
@@ -193,7 +194,8 @@
                         DozeLog.REASON_SENSOR_PICKUP, false /* touchCoords */,
                         false /* touchscreen */,
                         false /* ignoresSetting */,
-                        false /* requires prox */),
+                        false /* requires prox */,
+                        true /* immediatelyReRegister */),
                 new TriggerSensor(
                         findSensor(config.doubleTapSensorType()),
                         Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
@@ -211,6 +213,7 @@
                         true /* touchscreen */,
                         false /* ignoresSetting */,
                         dozeParameters.singleTapUsesProx(mDevicePosture) /* requiresProx */,
+                        true /* immediatelyReRegister */,
                         mDevicePosture),
                 new TriggerSensor(
                         findSensor(config.longPressSensorType()),
@@ -221,7 +224,8 @@
                         true /* reports touch coordinates */,
                         true /* touchscreen */,
                         false /* ignoresSetting */,
-                        dozeParameters.longPressUsesProx() /* requiresProx */),
+                        dozeParameters.longPressUsesProx() /* requiresProx */,
+                        true /* immediatelyReRegister */),
                 new TriggerSensor(
                         findSensor(config.udfpsLongPressSensorType()),
                         "doze_pulse_on_auth",
@@ -231,7 +235,8 @@
                         true /* reports touch coordinates */,
                         true /* touchscreen */,
                         false /* ignoresSetting */,
-                        dozeParameters.longPressUsesProx()),
+                        dozeParameters.longPressUsesProx(),
+                        false /* immediatelyReRegister */),
                 new PluginSensor(
                         new SensorManagerPlugin.Sensor(TYPE_WAKE_DISPLAY),
                         Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE,
@@ -257,7 +262,8 @@
                         false /* requiresTouchCoordinates */,
                         false /* requiresTouchscreen */,
                         false /* ignoresSetting */,
-                        false /* requiresProx */),
+                        false /* requiresProx */,
+                        true /* immediatelyReRegister */),
         };
         setProxListening(false);  // Don't immediately start listening when we register.
         mProximitySensor.register(
@@ -493,6 +499,10 @@
         private final boolean mRequiresTouchscreen;
         private final boolean mRequiresProx;
 
+        // Whether to immediately re-register this sensor after the sensor is triggered.
+        // If false, the sensor registration will be updated on the next AOD state transition.
+        private final boolean mImmediatelyReRegister;
+
         protected boolean mRequested;
         protected boolean mRegistered;
         protected boolean mDisabled;
@@ -516,7 +526,8 @@
                     reportsTouchCoordinates,
                     requiresTouchscreen,
                     false /* ignoresSetting */,
-                    false /* requiresProx */
+                    false /* requiresProx */,
+                    true /* immediatelyReRegister */
             );
         }
 
@@ -529,7 +540,8 @@
                 boolean reportsTouchCoordinates,
                 boolean requiresTouchscreen,
                 boolean ignoresSetting,
-                boolean requiresProx
+                boolean requiresProx,
+                boolean immediatelyReRegister
         ) {
             this(
                     new Sensor[]{ sensor },
@@ -541,6 +553,7 @@
                     requiresTouchscreen,
                     ignoresSetting,
                     requiresProx,
+                    immediatelyReRegister,
                     DevicePostureController.DEVICE_POSTURE_UNKNOWN
             );
         }
@@ -555,6 +568,7 @@
                 boolean requiresTouchscreen,
                 boolean ignoresSetting,
                 boolean requiresProx,
+                boolean immediatelyReRegister,
                 @DevicePostureController.DevicePostureInt int posture
         ) {
             mSensors = sensors;
@@ -567,6 +581,7 @@
             mIgnoresSetting = ignoresSetting;
             mRequiresProx = requiresProx;
             mPosture = posture;
+            mImmediatelyReRegister = immediatelyReRegister;
         }
 
         /**
@@ -702,8 +717,8 @@
                     screenY = event.values[1];
                 }
                 mSensorCallback.onSensorPulse(mPulseReason, screenX, screenY, event.values);
-                if (!mRegistered) {
-                    updateListening();  // reregister, this sensor only fires once
+                if (!mRegistered && mImmediatelyReRegister) {
+                    updateListening();
                 }
             }));
         }
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
index c43dd90..2c79830 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
@@ -80,6 +80,9 @@
     public static final ResourceBooleanFlag BOUNCER_USER_SWITCHER =
             new ResourceBooleanFlag(204, R.bool.config_enableBouncerUserSwitcher);
 
+    public static final ResourceBooleanFlag FACE_SCANNING_ANIM =
+            new ResourceBooleanFlag(205, R.bool.config_enableFaceScanningAnimation);
+
     /***************************************/
     // 300 - power menu
     public static final BooleanFlag POWER_MENU_LITE =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index c686b48..5ffc3f1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -169,7 +169,8 @@
             playingCannedAnimation: Boolean,
             fromWakeAndUnlock: Boolean,
             unlockAnimationStartDelay: Long,
-            unlockAnimationDuration: Long) {}
+            unlockAnimationDuration: Long
+        ) {}
 
         /**
          * Called when the remote unlock animation ends, in all cases, canned or swipe-to-unlock.
@@ -308,8 +309,12 @@
                     // call onKeyguardExitRemoteAnimationFinished since that will hide the keyguard
                     // and unlock the device as well as hiding the surface.
                     if (surfaceBehindAlpha == 0f) {
+                        Log.d(TAG, "surfaceBehindAlphaAnimator#onAnimationEnd")
                         keyguardViewMediator.get().finishSurfaceBehindRemoteAnimation(
                             false /* cancelled */)
+                    } else {
+                        Log.d(TAG, "skip finishSurfaceBehindRemoteAnimation" +
+                                " surfaceBehindAlpha=$surfaceBehindAlpha")
                     }
                 }
             })
@@ -325,6 +330,7 @@
             }
             addListener(object : AnimatorListenerAdapter() {
                 override fun onAnimationEnd(animation: Animator) {
+                    Log.d(TAG, "surfaceBehindEntryAnimator#onAnimationEnd")
                     playingCannedUnlockAnimation = false
                     keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(
                         false /* cancelled */
@@ -361,7 +367,6 @@
                 // the animations since they won't be visible.
                 !notificationShadeWindowController.isLaunchingActivity &&
                 launcherUnlockController != null &&
-                !keyguardStateController.isDismissingFromSwipe &&
                 // Temporarily disable for foldables since foldable launcher has two first pages,
                 // which breaks the in-window animation.
                 !isFoldable(context)
@@ -372,8 +377,8 @@
      * changed.
      */
     override fun onKeyguardGoingAwayChanged() {
-        if (keyguardStateController.isKeyguardGoingAway
-            && !statusBarStateController.leaveOpenOnKeyguardHide()) {
+        if (keyguardStateController.isKeyguardGoingAway &&
+                !statusBarStateController.leaveOpenOnKeyguardHide()) {
             prepareForInWindowLauncherAnimations()
         }
     }
@@ -427,7 +432,7 @@
             launcherUnlockController?.prepareForUnlock(
                 willUnlockWithSmartspaceTransition, /* willAnimateSmartspace */
                 lockscreenSmartspaceBounds, /* lockscreenSmartspaceBounds */
-                selectedPage, /* selectedPage */
+                selectedPage /* selectedPage */
             )
         } catch (e: RemoteException) {
             Log.e(TAG, "Remote exception in prepareForInWindowUnlockAnimations.", e)
@@ -466,16 +471,34 @@
 
         // If we specifically requested that the surface behind be made visible (vs. it being made
         // visible because we're unlocking), then we're in the middle of a swipe-to-unlock touch
-        // gesture and the surface behind the keyguard should be made visible.
+        // gesture and the surface behind the keyguard should be made visible so that we can animate
+        // it in.
         if (requestedShowSurfaceBehindKeyguard) {
-            // Fade in the surface, as long as we're not now flinging. The touch gesture ending in
-            // a fling during the time it takes the keyguard exit animation to start is an edge
-            // case race condition, and we'll handle it by playing a canned animation on the
-            // now-visible surface to finish unlocking.
-            if (!keyguardStateController.isFlingingToDismissKeyguard) {
-                fadeInSurfaceBehind()
-            } else {
+
+            // If we're flinging to dismiss here, it means the touch gesture ended in a fling during
+            // the time it takes the keyguard exit animation to start. This is an edge case race
+            // condition, which we handle by just playing a canned animation on the now-visible
+            // surface behind the keyguard to finish unlocking.
+            if (keyguardStateController.isFlingingToDismissKeyguard) {
                 playCannedUnlockAnimation()
+            } else if (keyguardStateController.isDismissingFromSwipe
+                    && willUnlockWithInWindowLauncherAnimations) {
+                // If we're swiping to unlock to the Launcher, and can play in-window animations,
+                // make the launcher surface fully visible and play the in-window unlock animation
+                // on the launcher icons. System UI will remain locked, using the swipe-to-unlock
+                // translation logic on the launcher window, until the swipe gesture ends (either in
+                // a successful unlock, or an aborted unlock).
+                surfaceBehindAlpha = 1f
+                setSurfaceBehindAppearAmount(1f)
+
+                launcherUnlockController?.playUnlockAnimation(
+                        true,
+                        UNLOCK_ANIMATION_DURATION_MS + CANNED_UNLOCK_START_DELAY,
+                        0 /* startDelay */)
+            } else {
+                // Otherwise, we're swiping in an app and should just fade it in. The swipe gesture
+                // will translate it until the end of the swipe gesture.
+                fadeInSurfaceBehind()
             }
         } else {
             // The surface was made visible since we're unlocking not from a swipe (fingerprint,
@@ -502,19 +525,23 @@
      * by the dismiss amount via [onKeyguardDismissAmountChanged].
      */
     private fun playCannedUnlockAnimation() {
+        Log.d(TAG, "playCannedUnlockAnimation")
         playingCannedUnlockAnimation = true
 
-
         when {
             // If we're set up for in-window launcher animations, ask Launcher to play its in-window
             // canned animation.
-            willUnlockWithInWindowLauncherAnimations -> unlockToLauncherWithInWindowAnimations()
+            willUnlockWithInWindowLauncherAnimations -> {
+                Log.d(TAG, "playCannedUnlockAnimation, unlockToLauncherWithInWindowAnimations")
+                unlockToLauncherWithInWindowAnimations()
+            }
 
             // If we're waking and unlocking to a non-Launcher app surface (or Launcher in-window
             // animations are not available), show it immediately and end the remote animation. The
             // circular light reveal will show the app surface, and it looks weird if it's moving
             // around behind that.
             biometricUnlockControllerLazy.get().isWakeAndUnlock -> {
+                Log.d(TAG, "playCannedUnlockAnimation, isWakeAndUnlock")
                 setSurfaceBehindAppearAmount(1f)
                 keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(
                     false /* cancelled */)
@@ -522,7 +549,10 @@
 
             // Otherwise, we're doing a normal full-window unlock. Start this animator, which will
             // scale/translate the window underneath the lockscreen.
-            else -> surfaceBehindEntryAnimator.start()
+            else -> {
+                Log.d(TAG, "playCannedUnlockAnimation, surfaceBehindEntryAnimator#start")
+                surfaceBehindEntryAnimator.start()
+            }
         }
     }
 
@@ -687,10 +717,18 @@
 
         // Otherwise, animate in the surface's scale/transltion.
         val surfaceHeight: Int = surfaceBehindRemoteAnimationTarget!!.screenSpaceBounds.height()
-        val scaleFactor = (SURFACE_BEHIND_START_SCALE_FACTOR +
+
+        var scaleFactor = (SURFACE_BEHIND_START_SCALE_FACTOR +
                 (1f - SURFACE_BEHIND_START_SCALE_FACTOR) *
                 MathUtils.clamp(amount, 0f, 1f))
 
+        // If we're dismissing via swipe to the Launcher, we'll play in-window scale animations, so
+        // don't also scale the window.
+        if (keyguardStateController.isDismissingFromSwipe
+                && willUnlockWithInWindowLauncherAnimations) {
+            scaleFactor = 1f
+        }
+
         // Scale up from a point at the center-bottom of the surface.
         surfaceBehindMatrix.setScale(
             scaleFactor,
@@ -774,16 +812,17 @@
     }
 
     private fun fadeInSurfaceBehind() {
+        Log.d(TAG, "fadeInSurfaceBehind")
         surfaceBehindAlphaAnimator.cancel()
         surfaceBehindAlphaAnimator.start()
     }
 
     private fun fadeOutSurfaceBehind() {
+        Log.d(TAG, "fadeOutSurfaceBehind")
         surfaceBehindAlphaAnimator.cancel()
         surfaceBehindAlphaAnimator.reverse()
     }
 
-
     private fun shouldPerformSmartspaceTransition(): Boolean {
         // Feature is disabled, so we don't want to.
         if (!featureFlags.isEnabled(Flags.SMARTSPACE_SHARED_ELEMENT_TRANSITION_ENABLED)) {
@@ -837,6 +876,12 @@
             return false
         }
 
+        // If we're swiping to dismiss, the smartspace will be swiped off the top of the screen
+        // so we can't shared element animate it.
+        if (keyguardStateController.isDismissingFromSwipe) {
+            return false
+        }
+
         // We don't do the shared element on tablets because they're large and the smartspace has to
         // fly across large distances, which is distracting.
         if (Utilities.isTablet(context)) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 0783eeec..f9b8ce28 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -635,13 +635,13 @@
                 case TelephonyManager.SIM_STATE_PUK_REQUIRED:
                     synchronized (KeyguardViewMediator.this) {
                         mSimWasLocked.append(slotId, true);
+                        mPendingPinLock = true;
                         if (!mShowing) {
                             if (DEBUG_SIM_STATES) Log.d(TAG,
                                     "INTENT_VALUE_ICC_LOCKED and keygaurd isn't "
                                     + "showing; need to show keyguard so user can enter sim pin");
                             doKeyguardLocked(null);
                         } else {
-                            mPendingPinLock = true;
                             resetStateLocked();
                         }
                     }
@@ -2424,7 +2424,7 @@
             RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers,
             RemoteAnimationTarget[] nonApps, IRemoteAnimationFinishedCallback finishedCallback) {
         Trace.beginSection("KeyguardViewMediator#handleStartKeyguardExitAnimation");
-        if (DEBUG) Log.d(TAG, "handleStartKeyguardExitAnimation startTime=" + startTime
+        Log.d(TAG, "handleStartKeyguardExitAnimation startTime=" + startTime
                 + " fadeoutDuration=" + fadeoutDuration);
         synchronized (KeyguardViewMediator.this) {
 
@@ -2620,7 +2620,11 @@
      * @param cancelled {@code true} if the animation was cancelled before it finishes.
      */
     public void onKeyguardExitRemoteAnimationFinished(boolean cancelled) {
+        Log.d(TAG, "onKeyguardExitRemoteAnimationFinished");
         if (!mSurfaceBehindRemoteAnimationRunning && !mSurfaceBehindRemoteAnimationRequested) {
+            Log.d(TAG, "skip onKeyguardExitRemoteAnimationFinished cancelled=" + cancelled
+                    + " surfaceAnimationRunning=" + mSurfaceBehindRemoteAnimationRunning
+                    + " surfaceAnimationRequested=" + mSurfaceBehindRemoteAnimationRequested);
             return;
         }
 
@@ -2634,7 +2638,13 @@
             onKeyguardExitFinished();
 
             if (mKeyguardStateController.isDismissingFromSwipe() || wasShowing) {
+                Log.d(TAG, "onKeyguardExitRemoteAnimationFinished"
+                        + "#hideKeyguardViewAfterRemoteAnimation");
                 mKeyguardUnlockAnimationControllerLazy.get().hideKeyguardViewAfterRemoteAnimation();
+            } else {
+                Log.d(TAG, "skip hideKeyguardViewAfterRemoteAnimation"
+                        + " dismissFromSwipe=" + mKeyguardStateController.isDismissingFromSwipe()
+                        + " wasShowing=" + wasShowing);
             }
 
             finishSurfaceBehindRemoteAnimation(cancelled);
@@ -2682,7 +2692,7 @@
     /** Hides the surface behind the keyguard by re-showing the keyguard/activity lock screen. */
     public void hideSurfaceBehindKeyguard() {
         mSurfaceBehindRemoteAnimationRequested = false;
-
+        mKeyguardStateController.notifyKeyguardGoingAway(false);
         if (mShowing) {
             setShowingLocked(true, true);
         }
@@ -2974,6 +2984,7 @@
         pw.print("  mPendingReset: "); pw.println(mPendingReset);
         pw.print("  mPendingLock: "); pw.println(mPendingLock);
         pw.print("  wakeAndUnlocking: "); pw.println(mWakeAndUnlocking);
+        pw.print("  mPendingPinLock: "); pw.println(mPendingPinLock);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt
index 54b0c13..7cc52e4 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt
@@ -106,6 +106,7 @@
                 PowerManager.WAKE_REASON_APPLICATION,
                 "com.android.systemui:media_tap_to_transfer_activated"
             )
+            animateChipIn(currentChipView)
         }
 
         // Cancel and re-set the chip timeout each time we get a new state.
@@ -138,6 +139,12 @@
     abstract fun updateChipView(chipInfo: T, currentChipView: ViewGroup)
 
     /**
+     * A method that can be implemented by subclcasses to do custom animations for when the chip
+     * appears.
+     */
+    open fun animateChipIn(chipView: ViewGroup) {}
+
+    /**
      * Returns the size that the icon should be, or null if no size override is needed.
      */
     open fun getIconSize(isAppIcon: Boolean): Int? = null
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
index 9f5ec7e..54b4380 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
@@ -27,6 +27,8 @@
 import android.widget.TextView
 import com.android.internal.statusbar.IUndoMediaTransferCallback
 import com.android.systemui.R
+import com.android.systemui.animation.Interpolators
+import com.android.systemui.animation.ViewHierarchyAnimator
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.media.taptotransfer.common.ChipInfoCommon
@@ -124,7 +126,6 @@
         currentChipView.requireViewById<View>(R.id.loading).visibility =
             chipState.isMidTransfer.visibleIfTrue()
 
-
         // Undo
         val undoView = currentChipView.requireViewById<View>(R.id.undo)
         val undoClickListener = chipState.undoClickListener(
@@ -138,6 +139,17 @@
             chipState.isTransferFailure.visibleIfTrue()
     }
 
+    override fun animateChipIn(chipView: ViewGroup) {
+        ViewHierarchyAnimator.animateAddition(
+            chipView.requireViewById<ViewGroup>(R.id.media_ttt_sender_chip_inner),
+            ViewHierarchyAnimator.Hotspot.TOP,
+            Interpolators.EMPHASIZED_DECELERATE,
+            duration = 500L,
+            includeMargins = true,
+            includeFadeIn = true,
+        )
+    }
+
     override fun removeChip(removalReason: String) {
         // Don't remove the chip if we're mid-transfer since the user should still be able to
         // see the status of the transfer. (But do remove it if it's finally timed out.)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index fcd9e10..bf83ad6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -110,6 +110,11 @@
     private Context mUserContext;
     private UserTracker mUserTracker;
     private SecureSettings mSecureSettings;
+    // Keep track of whether mTilesList contains the same information as the Settings value.
+    // This is a performance optimization to reduce the number of blocking calls to Settings from
+    // main thread.
+    // This is enforced by only cleaning the flag at the end of a successful run of #onTuningChanged
+    private boolean mTilesListDirty = true;
 
     private final TileServiceRequestController mTileServiceRequestController;
     private TileLifecycleManager.Factory mTileLifeCycleManagerFactory;
@@ -374,6 +379,7 @@
                 // the ones that are in the setting, update the Setting.
                 saveTilesToSettings(mTileSpecs);
             }
+            mTilesListDirty = false;
             for (int i = 0; i < mCallbacks.size(); i++) {
                 mCallbacks.get(i).onTilesChanged();
             }
@@ -437,6 +443,7 @@
     }
 
 
+    // When calling this, you may want to modify mTilesListDirty accordingly.
     @MainThread
     private void saveTilesToSettings(List<String> tileSpecs) {
         mSecureSettings.putStringForUser(TILES_SETTING, TextUtils.join(",", tileSpecs),
@@ -446,9 +453,15 @@
 
     @MainThread
     private void changeTileSpecs(Predicate<List<String>> changeFunction) {
-        final String setting = mSecureSettings.getStringForUser(TILES_SETTING, mCurrentUser);
-        final List<String> tileSpecs = loadTileSpecs(mContext, setting);
+        final List<String> tileSpecs;
+        if (!mTilesListDirty) {
+            tileSpecs = new ArrayList<>(mTileSpecs);
+        } else {
+            tileSpecs = loadTileSpecs(mContext,
+                    mSecureSettings.getStringForUser(TILES_SETTING, mCurrentUser));
+        }
         if (changeFunction.test(tileSpecs)) {
+            mTilesListDirty = true;
             saveTilesToSettings(tileSpecs);
         }
     }
@@ -508,6 +521,7 @@
             }
         }
         if (DEBUG) Log.d(TAG, "saveCurrentTiles " + newTiles);
+        mTilesListDirty = true;
         saveTilesToSettings(newTiles);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 1fb771e..9e02909 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -50,6 +50,7 @@
 import android.hardware.face.FaceManager;
 import android.hardware.fingerprint.FingerprintManager;
 import android.os.BatteryManager;
+import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -61,6 +62,7 @@
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityManager;
 
 import androidx.annotation.Nullable;
 
@@ -93,6 +95,8 @@
 
 import java.io.PrintWriter;
 import java.text.NumberFormat;
+import java.util.HashSet;
+import java.util.Set;
 
 import javax.inject.Inject;
 
@@ -113,12 +117,12 @@
 
     private static final String TAG = "KeyguardIndication";
     private static final boolean DEBUG_CHARGING_SPEED = false;
+    private static final boolean DEBUG = Build.IS_DEBUGGABLE;
 
     private static final int MSG_HIDE_TRANSIENT = 1;
     private static final int MSG_SHOW_ACTION_TO_UNLOCK = 2;
     private static final int MSG_HIDE_BIOMETRIC_MESSAGE = 3;
     private static final long TRANSIENT_BIOMETRIC_ERROR_TIMEOUT = 1300;
-    private static final float BOUNCE_ANIMATION_FINAL_Y = 0f;
 
     private final Context mContext;
     private final BroadcastDispatcher mBroadcastDispatcher;
@@ -139,6 +143,7 @@
     private final IActivityManager mIActivityManager;
     private final FalsingManager mFalsingManager;
     private final KeyguardBypassController mKeyguardBypassController;
+    private final AccessibilityManager mAccessibilityManager;
     private final Handler mHandler;
 
     protected KeyguardIndicationRotateTextViewController mRotateTextViewController;
@@ -167,6 +172,7 @@
     private boolean mBatteryPresent = true;
     private long mChargingTimeRemaining;
     private String mMessageToShowOnScreenOn;
+    private final Set<Integer> mCoExFaceHelpMsgIdsToShow;
     private boolean mInited;
 
     private KeyguardUpdateMonitorCallback mUpdateMonitorCallback;
@@ -214,7 +220,8 @@
             LockPatternUtils lockPatternUtils,
             ScreenLifecycle screenLifecycle,
             IActivityManager iActivityManager,
-            KeyguardBypassController keyguardBypassController) {
+            KeyguardBypassController keyguardBypassController,
+            AccessibilityManager accessibilityManager) {
         mContext = context;
         mBroadcastDispatcher = broadcastDispatcher;
         mDevicePolicyManager = devicePolicyManager;
@@ -232,9 +239,17 @@
         mIActivityManager = iActivityManager;
         mFalsingManager = falsingManager;
         mKeyguardBypassController = keyguardBypassController;
+        mAccessibilityManager = accessibilityManager;
         mScreenLifecycle = screenLifecycle;
         mScreenLifecycle.addObserver(mScreenObserver);
 
+        mCoExFaceHelpMsgIdsToShow = new HashSet<>();
+        int[] msgIds = context.getResources().getIntArray(
+                com.android.systemui.R.array.config_face_help_msgs_when_fingerprint_enrolled);
+        for (int msgId : msgIds) {
+            mCoExFaceHelpMsgIdsToShow.add(msgId);
+        }
+
         mHandler = new Handler(mainLooper) {
             @Override
             public void handleMessage(Message msg) {
@@ -885,7 +900,9 @@
                 mStatusBarKeyguardViewManager.showBouncerMessage(message, mInitialTextColorState);
             }
         } else {
-            if (mKeyguardUpdateMonitor.isUdfpsSupported()
+            if (!mAccessibilityManager.isEnabled()
+                    && !mAccessibilityManager.isTouchExplorationEnabled()
+                    && mKeyguardUpdateMonitor.isUdfpsSupported()
                     && mKeyguardUpdateMonitor.getUserCanSkipBouncer(
                     KeyguardUpdateMonitor.getCurrentUser())) {
                 final int stringId = mKeyguardUpdateMonitor.getIsFaceAuthenticated()
@@ -898,15 +915,6 @@
         }
     }
 
-    private void showFaceFailedTryFingerprintMsg(int msgId, String a11yString) {
-        showBiometricMessage(R.string.keyguard_face_failed_use_fp);
-
-        // Although we suppress face auth errors visually, we still announce them for a11y
-        if (!TextUtils.isEmpty(a11yString)) {
-            mLockScreenIndicationView.announceForAccessibility(a11yString);
-        }
-    }
-
     public void dump(PrintWriter pw, String[] args) {
         pw.println("KeyguardIndicationController:");
         pw.println("  mInitialTextColorState: " + mInitialTextColorState);
@@ -925,6 +933,7 @@
                 mTopIndicationView == null ? null : mTopIndicationView.getText()));
         pw.println("  computePowerIndication(): " + computePowerIndication());
         pw.println("  trustGrantedIndication: " + getTrustGrantedIndication());
+        pw.println("    mCoExFaceHelpMsgIdsToShow=" + mCoExFaceHelpMsgIdsToShow);
         mRotateTextViewController.dump(pw, args);
     }
 
@@ -983,9 +992,20 @@
                     .isUnlockingWithBiometricAllowed(true /* isStrongBiometric */)) {
                 return;
             }
+
             boolean showActionToUnlock =
                     msgId == KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
-            if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
+            if (biometricSourceType == BiometricSourceType.FACE
+                    && !showActionToUnlock
+                    && mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
+                            KeyguardUpdateMonitor.getCurrentUser())
+                    && !mCoExFaceHelpMsgIdsToShow.contains(msgId)) {
+                if (DEBUG) {
+                    Log.d(TAG, "skip showing msgId=" + msgId + " helpString=" + helpString
+                            + ", due to co-ex logic");
+                }
+                return;
+            } else if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
                 mStatusBarKeyguardViewManager.showBouncerMessage(helpString,
                         mInitialTextColorState);
             } else if (mScreenLifecycle.getScreenState() == SCREEN_ON) {
@@ -1002,14 +1022,28 @@
             if (shouldSuppressBiometricError(msgId, biometricSourceType, mKeyguardUpdateMonitor)) {
                 return;
             }
-            if (msgId == FaceManager.FACE_ERROR_TIMEOUT) {
+
+            if (biometricSourceType == BiometricSourceType.FACE
+                    && msgId == FaceManager.FACE_ERROR_UNABLE_TO_PROCESS) {
+                // suppress all face UNABLE_TO_PROCESS errors
+                if (DEBUG) {
+                    Log.d(TAG, "skip showing FACE_ERROR_UNABLE_TO_PROCESS errString="
+                            + errString);
+                }
+            } else if (biometricSourceType == BiometricSourceType.FACE
+                    && msgId == FaceManager.FACE_ERROR_TIMEOUT) {
+                if (mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
+                        KeyguardUpdateMonitor.getCurrentUser())) {
+                    // no message if fingerprint is also enrolled
+                    if (DEBUG) {
+                        Log.d(TAG, "skip showing FACE_ERROR_TIMEOUT due to co-ex logic");
+                    }
+                    return;
+                }
+
                 // The face timeout message is not very actionable, let's ask the user to
                 // manually retry.
-                if (!mStatusBarKeyguardViewManager.isBouncerShowing()
-                        && mKeyguardUpdateMonitor.isUdfpsEnrolled()
-                        && mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
-                    showFaceFailedTryFingerprintMsg(msgId, errString);
-                } else if (mStatusBarKeyguardViewManager.isShowingAlternateAuth()) {
+                if (mStatusBarKeyguardViewManager.isShowingAlternateAuth()) {
                     mStatusBarKeyguardViewManager.showBouncerMessage(
                             mContext.getResources().getString(R.string.keyguard_try_fingerprint),
                             mInitialTextColorState
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index 76f9db4..1ce05ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -736,12 +736,10 @@
                 }
                 boolean cannotAnimateDoze = mStatusBarStateController.isDozing()
                         && !ScrimState.AOD.getAnimateChange();
-                boolean needsBypassFading = mKeyguardStateController.isBypassFadingAnimation();
                 if (((mBiometricUnlockController != null && mBiometricUnlockController.getMode()
                         == BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
-                                || cannotAnimateDoze) && !needsBypassFading)
+                                || cannotAnimateDoze))
                         || hideBecauseOccluded) {
-
                     // We are unlocking directly - no animation!
                     mBackdrop.setVisibility(View.GONE);
                     mBackdropBack.setImageDrawable(null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
index 4f27fb4..d88f07c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
@@ -195,7 +195,6 @@
 
     @UiThread
     private fun showDotView(dot: View, animate: Boolean) {
-        showingListener?.onPrivacyDotShown(dot)
         dot.clearAnimation()
         if (animate) {
             dot.visibility = View.VISIBLE
@@ -209,6 +208,7 @@
             dot.visibility = View.VISIBLE
             dot.alpha = 1f
         }
+        showingListener?.onPrivacyDotShown(dot)
     }
 
     // Update the gravity and margins of the privacy views
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 577d536..755e3e1 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
@@ -151,6 +151,10 @@
                 R.color.notification_ripple_tinted_color);
         mNormalRippleColor = mContext.getColor(
                 R.color.notification_ripple_untinted_color);
+        // Reset background color tint and override tint, as they are from an old theme
+        mBgTint = NO_COLOR;
+        mOverrideTint = NO_COLOR;
+        mOverrideAmount = 0.0f;
     }
 
     /**
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 eb496ab..26614ff 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
@@ -141,7 +141,9 @@
     public static final float DEFAULT_HEADER_VISIBLE_AMOUNT = 1.0f;
     private static final long RECENTLY_ALERTED_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(30);
 
-    private boolean mUpdateBackgroundOnUpdate;
+    // We don't correctly track dark mode until the content views are inflated, so always update
+    // the background on first content update just in case it happens to be during a theme change.
+    private boolean mUpdateBackgroundOnUpdate = true;
     private boolean mNotificationTranslationFinished = false;
     private boolean mIsSnoozed;
     private boolean mIsFaded;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index a552f99..a76f0827 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -1312,6 +1312,7 @@
             }
             float bottomRoundness = last ? currentBottomRoundness : 0.0f;
             child.setBottomRoundness(bottomRoundness, isShown() /* animate */);
+            child.setTopRoundness(0.0f, false /* animate */);
             last = false;
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index e946bf1..39620ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -27,8 +27,11 @@
 import android.metrics.LogMaker;
 import android.os.Handler;
 import android.os.PowerManager;
+import android.os.Process;
 import android.os.SystemClock;
 import android.os.Trace;
+import android.os.VibrationAttributes;
+import android.os.VibrationEffect;
 import android.util.Log;
 
 import androidx.annotation.Nullable;
@@ -61,6 +64,7 @@
 import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import java.io.PrintWriter;
@@ -83,6 +87,12 @@
     private static final String BIOMETRIC_WAKE_LOCK_NAME = "wake-and-unlock:wakelock";
     private static final UiEventLogger UI_EVENT_LOGGER = new UiEventLoggerImpl();
     private static final int FP_ATTEMPTS_BEFORE_SHOW_BOUNCER = 2;
+    private static final VibrationEffect SUCCESS_VIBRATION_EFFECT =
+            VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
+    private static final VibrationEffect ERROR_VIBRATION_EFFECT =
+            VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
+    private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES =
+            VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK);
 
     @IntDef(prefix = { "MODE_" }, value = {
             MODE_NONE,
@@ -91,7 +101,6 @@
             MODE_SHOW_BOUNCER,
             MODE_ONLY_WAKE,
             MODE_UNLOCK_COLLAPSING,
-            MODE_UNLOCK_FADING,
             MODE_DISMISS_BOUNCER,
             MODE_WAKE_AND_UNLOCK_FROM_DREAM
     })
@@ -138,15 +147,9 @@
     public static final int MODE_WAKE_AND_UNLOCK_FROM_DREAM = 6;
 
     /**
-     * Faster mode of dismissing the lock screen when we cross fade to an app
-     * (used for keyguard bypass.)
-     */
-    public static final int MODE_UNLOCK_FADING = 7;
-
-    /**
      * When bouncer is visible and will be dismissed.
      */
-    public static final int MODE_DISMISS_BOUNCER = 8;
+    public static final int MODE_DISMISS_BOUNCER = 7;
 
     /**
      * How much faster we collapse the lockscreen when authenticating with biometric.
@@ -165,6 +168,7 @@
     private final NotificationShadeWindowController mNotificationShadeWindowController;
     private final SessionTracker mSessionTracker;
     private final int mConsecutiveFpFailureThreshold;
+    private final boolean mShouldVibrate;
     private int mMode;
     private BiometricSourceType mBiometricType;
     private KeyguardViewController mKeyguardViewController;
@@ -181,6 +185,7 @@
     private final AuthController mAuthController;
     private final StatusBarStateController mStatusBarStateController;
     private final LatencyTracker mLatencyTracker;
+    private final VibratorHelper mVibratorHelper;
 
     private long mLastFpFailureUptimeMillis;
     private int mNumConsecutiveFpFailures;
@@ -285,7 +290,8 @@
             KeyguardUnlockAnimationController keyguardUnlockAnimationController,
             SessionTracker sessionTracker,
             LatencyTracker latencyTracker,
-            ScreenOffAnimationController screenOffAnimationController) {
+            ScreenOffAnimationController screenOffAnimationController,
+            VibratorHelper vibrator) {
         mPowerManager = powerManager;
         mShadeController = shadeController;
         mUpdateMonitor = keyguardUpdateMonitor;
@@ -304,6 +310,8 @@
         mHandler = handler;
         mConsecutiveFpFailureThreshold = resources.getInteger(
                 R.integer.fp_consecutive_failure_time_ms);
+        mShouldVibrate = !(resources.getBoolean(
+                com.android.internal.R.bool.system_server_plays_face_haptics));
         mKeyguardBypassController = keyguardBypassController;
         mKeyguardBypassController.setUnlockController(this);
         mMetricsLogger = metricsLogger;
@@ -312,6 +320,8 @@
         mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
         mSessionTracker = sessionTracker;
         mScreenOffAnimationController = screenOffAnimationController;
+        mVibratorHelper = vibrator;
+
         dumpManager.registerDumpable(getClass().getName(), this);
     }
 
@@ -414,8 +424,14 @@
     }
 
     public void startWakeAndUnlock(BiometricSourceType biometricSourceType,
-            boolean isStrongBiometric) {
-        startWakeAndUnlock(calculateMode(biometricSourceType, isStrongBiometric));
+                                   boolean isStrongBiometric) {
+        int mode = calculateMode(biometricSourceType, isStrongBiometric);
+        if (BiometricSourceType.FACE == biometricSourceType && (mode == MODE_WAKE_AND_UNLOCK
+                || mode == MODE_WAKE_AND_UNLOCK_PULSING || mode == MODE_UNLOCK_COLLAPSING
+                || mode == MODE_WAKE_AND_UNLOCK_FROM_DREAM || mode == MODE_DISMISS_BOUNCER)) {
+            vibrateSuccess();
+        }
+        startWakeAndUnlock(mode);
     }
 
     public void startWakeAndUnlock(@WakeAndUnlockMode int mode) {
@@ -451,8 +467,7 @@
         }
         switch (mMode) {
             case MODE_DISMISS_BOUNCER:
-            case MODE_UNLOCK_FADING:
-                Trace.beginSection("MODE_DISMISS_BOUNCER or MODE_UNLOCK_FADING");
+                Trace.beginSection("MODE_DISMISS_BOUNCER");
                 mKeyguardViewController.notifyKeyguardAuthenticated(
                         false /* strongAuth */);
                 Trace.endSection();
@@ -590,7 +605,7 @@
                 mUpdateMonitor.isUnlockingWithBiometricAllowed(isStrongBiometric);
         boolean deviceDreaming = mUpdateMonitor.isDreaming();
         boolean bypass = mKeyguardBypassController.getBypassEnabled()
-                || mKeyguardBypassController.getUserHasDeviceEntryIntent();
+                || mAuthController.isUdfpsFingerDown();
         if (!mUpdateMonitor.isDeviceInteractive()) {
             if (!mKeyguardViewController.isShowing()) {
                 return bypass ? MODE_WAKE_AND_UNLOCK : MODE_ONLY_WAKE;
@@ -619,14 +634,9 @@
         if (mKeyguardViewController.isShowing()) {
             if ((mKeyguardViewController.bouncerIsOrWillBeShowing()
                     || mKeyguardBypassController.getAltBouncerShowing()) && unlockingAllowed) {
-                if (bypass && mKeyguardBypassController.canPlaySubtleWindowAnimations()) {
-                    return MODE_UNLOCK_FADING;
-                } else {
-                    return MODE_DISMISS_BOUNCER;
-                }
-            } else if (unlockingAllowed) {
-                return bypass || mAuthController.isUdfpsFingerDown()
-                        ? MODE_UNLOCK_FADING : MODE_NONE;
+                return MODE_DISMISS_BOUNCER;
+            } else if (unlockingAllowed && (bypass || mAuthController.isUdfpsFingerDown())) {
+                return MODE_UNLOCK_COLLAPSING;
             } else {
                 return bypass ? MODE_SHOW_BOUNCER : MODE_NONE;
             }
@@ -665,6 +675,14 @@
                 mNumConsecutiveFpFailures = 0;
             }
         }
+
+        // Suppress all face auth errors if fingerprint can be used to authenticate
+        if (biometricSourceType == BiometricSourceType.FACE
+                && !mUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
+                KeyguardUpdateMonitor.getCurrentUser())) {
+            vibrateError();
+        }
+
         cleanup();
     }
 
@@ -687,9 +705,30 @@
             startWakeAndUnlock(MODE_SHOW_BOUNCER);
             UI_EVENT_LOGGER.log(BiometricUiEvent.BIOMETRIC_BOUNCER_SHOWN, getSessionId());
         }
+
         cleanup();
     }
 
+    private void vibrateSuccess() {
+        if (mShouldVibrate) {
+            mVibratorHelper.vibrate(Process.myUid(),
+                    "com.android.systemui",
+                    SUCCESS_VIBRATION_EFFECT,
+                    getClass().getSimpleName() + "::success",
+                    HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES);
+        }
+    }
+
+    private void vibrateError() {
+        if (mShouldVibrate) {
+            mVibratorHelper.vibrate(Process.myUid(),
+                    "com.android.systemui",
+                    ERROR_VIBRATION_EFFECT,
+                    getClass().getSimpleName() + "::error",
+                    HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES);
+        }
+    }
+
     private void cleanup() {
         releaseBiometricWakeLock();
     }
@@ -802,7 +841,7 @@
      * on or off.
      */
     public boolean isBiometricUnlock() {
-        return isWakeAndUnlock() || mMode == MODE_UNLOCK_COLLAPSING || mMode == MODE_UNLOCK_FADING;
+        return isWakeAndUnlock() || mMode == MODE_UNLOCK_COLLAPSING;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index 9c6ba3a..37079e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -396,8 +396,7 @@
 
     void keyguardGoingAway();
 
-    void setKeyguardFadingAway(long startTime, long delay, long fadeoutDuration,
-            boolean isBypassFading);
+    void setKeyguardFadingAway(long startTime, long delay, long fadeoutDuration);
 
     void finishKeyguardFadingAway();
 
@@ -565,8 +564,6 @@
 
     void setLaunchEmergencyActionOnFinishedWaking(boolean launch);
 
-    void setTopHidesStatusBar(boolean hides);
-
     QSPanelController getQSPanelController();
 
     boolean areNotificationAlertsDisabled();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 0e35cbc..450d0d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -207,7 +207,6 @@
 import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
 import com.android.systemui.statusbar.notification.init.NotificationsController;
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
@@ -238,7 +237,6 @@
 import com.android.systemui.util.concurrency.DelayableExecutor;
 import com.android.systemui.util.concurrency.MessageRouter;
 import com.android.systemui.volume.VolumeComponent;
-import com.android.systemui.wmshell.BubblesManager;
 import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.startingsurface.SplashscreenContentDrawer;
 import com.android.wm.shell.startingsurface.StartingSurface;
@@ -405,11 +403,6 @@
     }
 
     @Override
-    public void setTopHidesStatusBar(boolean hides) {
-        mTopHidesStatusBar = hides;
-    }
-
-    @Override
     public QSPanelController getQSPanelController() {
         return mQSPanelController;
     }
@@ -451,7 +444,6 @@
     private BiometricUnlockController mBiometricUnlockController;
     private final LightBarController mLightBarController;
     private final Lazy<LockscreenWallpaper> mLockscreenWallpaperLazy;
-    private final LockscreenGestureLogger mLockscreenGestureLogger;
     @Nullable
     protected LockscreenWallpaper mLockscreenWallpaper;
     private final AutoHideController mAutoHideController;
@@ -518,9 +510,6 @@
 
     private boolean mExpandedVisible;
 
-    private final int[] mAbsPos = new int[2];
-
-    private final NotifShadeEventSource mNotifShadeEventSource;
     protected final NotificationEntryManager mEntryManager;
     private final NotificationGutsManager mGutsManager;
     private final NotificationLogger mNotificationLogger;
@@ -602,7 +591,6 @@
         }
     }
 
-    private Handler mMainHandler;
     private final DelayableExecutor mMainExecutor;
 
     private int mInteractingWindows;
@@ -636,12 +624,9 @@
 
     // Fingerprint (as computed by getLoggingFingerprint() of the last logged state.
     private int mLastLoggedStateFingerprint;
-    private boolean mTopHidesStatusBar;
-    private boolean mStatusBarWindowHidden;
     private boolean mIsLaunchingActivityOverLockscreen;
 
     private final UserSwitcherController mUserSwitcherController;
-    private final NetworkController mNetworkController;
     private final LifecycleRegistry mLifecycle = new LifecycleRegistry(this);
     protected final BatteryController mBatteryController;
     protected boolean mPanelExpanded;
@@ -661,7 +646,6 @@
     protected NotificationPresenter mPresenter;
     private NotificationActivityStarter mNotificationActivityStarter;
     private final Lazy<NotificationShadeDepthController> mNotificationShadeDepthControllerLazy;
-    private final Optional<BubblesManager> mBubblesManagerOptional;
     private final Optional<Bubbles> mBubblesOptional;
     private final Bubbles.BubbleExpandListener mBubbleExpandListener;
     private final Optional<StartingSurface> mStartingSurfaceOptional;
@@ -703,7 +687,6 @@
             FalsingManager falsingManager,
             FalsingCollector falsingCollector,
             BroadcastDispatcher broadcastDispatcher,
-            NotifShadeEventSource notifShadeEventSource,
             NotificationEntryManager notificationEntryManager,
             NotificationGutsManager notificationGutsManager,
             NotificationLogger notificationLogger,
@@ -718,13 +701,11 @@
             NotificationLockscreenUserManager lockScreenUserManager,
             NotificationRemoteInputManager remoteInputManager,
             UserSwitcherController userSwitcherController,
-            NetworkController networkController,
             BatteryController batteryController,
             SysuiColorExtractor colorExtractor,
             ScreenLifecycle screenLifecycle,
             WakefulnessLifecycle wakefulnessLifecycle,
             SysuiStatusBarStateController statusBarStateController,
-            Optional<BubblesManager> bubblesManagerOptional,
             Optional<Bubbles> bubblesOptional,
             VisualStabilityManager visualStabilityManager,
             DeviceProvisionedController deviceProvisionedController,
@@ -736,7 +717,6 @@
             DozeParameters dozeParameters,
             ScrimController scrimController,
             Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
-            LockscreenGestureLogger lockscreenGestureLogger,
             Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
             DozeServiceHost dozeServiceHost,
             PowerManager powerManager,
@@ -769,7 +749,6 @@
             LockscreenShadeTransitionController lockscreenShadeTransitionController,
             FeatureFlags featureFlags,
             KeyguardUnlockAnimationController keyguardUnlockAnimationController,
-            @Main Handler mainHandler,
             @Main DelayableExecutor delayableExecutor,
             @Main MessageRouter messageRouter,
             WallpaperManager wallpaperManager,
@@ -799,7 +778,6 @@
         mFalsingCollector = falsingCollector;
         mFalsingManager = falsingManager;
         mBroadcastDispatcher = broadcastDispatcher;
-        mNotifShadeEventSource = notifShadeEventSource;
         mEntryManager = notificationEntryManager;
         mGutsManager = notificationGutsManager;
         mNotificationLogger = notificationLogger;
@@ -814,13 +792,11 @@
         mLockscreenUserManager = lockScreenUserManager;
         mRemoteInputManager = remoteInputManager;
         mUserSwitcherController = userSwitcherController;
-        mNetworkController = networkController;
         mBatteryController = batteryController;
         mColorExtractor = colorExtractor;
         mScreenLifecycle = screenLifecycle;
         mWakefulnessLifecycle = wakefulnessLifecycle;
         mStatusBarStateController = statusBarStateController;
-        mBubblesManagerOptional = bubblesManagerOptional;
         mBubblesOptional = bubblesOptional;
         mVisualStabilityManager = visualStabilityManager;
         mDeviceProvisionedController = deviceProvisionedController;
@@ -834,7 +810,6 @@
         mDozeParameters = dozeParameters;
         mScrimController = scrimController;
         mLockscreenWallpaperLazy = lockscreenWallpaperLazy;
-        mLockscreenGestureLogger = lockscreenGestureLogger;
         mScreenPinningRequest = screenPinningRequest;
         mDozeScrimController = dozeScrimController;
         mBiometricUnlockControllerLazy = biometricUnlockControllerLazy;
@@ -861,7 +836,6 @@
         mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager;
         mFeatureFlags = featureFlags;
         mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
-        mMainHandler = mainHandler;
         mMainExecutor = delayableExecutor;
         mMessageRouter = messageRouter;
         mWallpaperManager = wallpaperManager;
@@ -1485,12 +1459,16 @@
             mPowerManager.wakeUp(
                     time, PowerManager.WAKE_REASON_GESTURE, "com.android.systemui:" + why);
             mWakeUpComingFromTouch = true;
-            where.getLocationInWindow(mTmpInt2);
 
             // NOTE, the incoming view can sometimes be the entire container... unsure if
             // this location is valuable enough
-            mWakeUpTouchLocation = new PointF(mTmpInt2[0] + where.getWidth() / 2,
-                    mTmpInt2[1] + where.getHeight() / 2);
+            if (where != null) {
+                where.getLocationInWindow(mTmpInt2);
+                mWakeUpTouchLocation = new PointF(mTmpInt2[0] + where.getWidth() / 2,
+                        mTmpInt2[1] + where.getHeight() / 2);
+            } else {
+                mWakeUpTouchLocation = new PointF(-1, -1);
+            }
             mFalsingCollector.onScreenOnFromTouch();
         }
     }
@@ -2274,8 +2252,7 @@
     public void updateBubblesVisibility() {
         mBubblesOptional.ifPresent(bubbles -> bubbles.onStatusBarVisibilityChanged(
                 mStatusBarMode != MODE_LIGHTS_OUT
-                        && mStatusBarMode != MODE_LIGHTS_OUT_TRANSPARENT
-                        && !mStatusBarWindowHidden));
+                        && mStatusBarMode != MODE_LIGHTS_OUT_TRANSPARENT));
     }
 
     void checkBarMode(@TransitionMode int mode, @WindowVisibleState int windowState,
@@ -2517,6 +2494,12 @@
                     animate, intent.getPackage(), (adapter) -> {
                         ActivityOptions options = new ActivityOptions(
                                 CentralSurfaces.getActivityOptions(mDisplayId, adapter));
+
+                        // We know that the intent of the caller is to dismiss the keyguard and
+                        // this runnable is called right after the keyguard is solved, so we tell
+                        // WM that we should dismiss it to avoid flickers when opening an activity
+                        // that can also be shown over the keyguard.
+                        options.setDismissKeyguard();
                         options.setDisallowEnterPictureInPictureWhileLaunching(
                                 disallowEnterPictureInPictureWhileLaunching);
                         if (CameraIntents.isInsecureCameraIntent(intent)) {
@@ -3194,14 +3177,12 @@
 
     /**
      * Notifies the status bar the Keyguard is fading away with the specified timings.
-     *  @param startTime the start time of the animations in uptime millis
+     * @param startTime the start time of the animations in uptime millis
      * @param delay the precalculated animation delay in milliseconds
      * @param fadeoutDuration the duration of the exit animation, in milliseconds
-     * @param isBypassFading is this a fading away animation while bypassing
      */
     @Override
-    public void setKeyguardFadingAway(long startTime, long delay, long fadeoutDuration,
-            boolean isBypassFading) {
+    public void setKeyguardFadingAway(long startTime, long delay, long fadeoutDuration) {
         mCommandQueue.appTransitionStarting(mDisplayId, startTime + fadeoutDuration
                         - LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION,
                 LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
@@ -3209,7 +3190,7 @@
         mCommandQueue.appTransitionStarting(mDisplayId,
                     startTime - LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION,
                     LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
-        mKeyguardStateController.notifyKeyguardFadingAway(delay, fadeoutDuration, isBypassFading);
+        mKeyguardStateController.notifyKeyguardFadingAway(delay, fadeoutDuration);
     }
 
     /**
@@ -3560,6 +3541,9 @@
         setBouncerShowingForStatusBarComponents(bouncerShowing);
         mStatusBarHideIconsForBouncerManager.setBouncerShowingAndTriggerUpdate(bouncerShowing);
         mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
+        if (mBouncerShowing) {
+            wakeUpIfDozing(SystemClock.uptimeMillis(), null, "BOUNCER_VISIBLE");
+        }
         updateScrimController();
         if (!mBouncerShowing) {
             updatePanelExpansionForKeyguard();
@@ -3926,7 +3910,8 @@
             mScrimController.transitionTo(ScrimState.AOD);
         } else if (mKeyguardStateController.isShowing() && !isOccluded() && !unlocking) {
             mScrimController.transitionTo(ScrimState.KEYGUARD);
-        } else if (mKeyguardStateController.isShowing() && mKeyguardUpdateMonitor.isDreaming()) {
+        } else if (mKeyguardStateController.isShowing() && mKeyguardUpdateMonitor.isDreaming()
+                && !unlocking) {
             mScrimController.transitionTo(ScrimState.DREAMING);
         } else {
             mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
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 8792118..9b88e26 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -216,9 +216,12 @@
 
             // Split up the work over multiple frames.
             DejankUtils.removeCallbacks(mResetRunnable);
-            if (mKeyguardStateController.isFaceAuthEnabled() && !needsFullscreenBouncer()
-                && !mKeyguardUpdateMonitor.userNeedsStrongAuth()
-                && !mKeyguardBypassController.getBypassEnabled()) {
+            if (mKeyguardStateController.isFaceAuthEnabled()
+                    && !mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
+                            KeyguardUpdateMonitor.getCurrentUser())
+                    && !needsFullscreenBouncer()
+                    && !mKeyguardUpdateMonitor.userNeedsStrongAuth()
+                    && !mKeyguardBypassController.getBypassEnabled()) {
                 mHandler.postDelayed(mShowRunnable, BOUNCER_FACE_DELAY);
             } else {
                 DejankUtils.postAfterTraversal(mShowRunnable);
@@ -394,10 +397,6 @@
         return mShowingSoon || mExpansion != EXPANSION_HIDDEN && mExpansion != EXPANSION_VISIBLE;
     }
 
-    public boolean getShowingSoon() {
-        return mShowingSoon;
-    }
-
     /**
      * @return {@code true} when bouncer's pre-hide animation already started but isn't completely
      *         hidden yet, {@code false} otherwise.
@@ -641,6 +640,10 @@
     public interface BouncerExpansionCallback {
         /**
          * Invoked when the bouncer expansion reaches {@link KeyguardBouncer#EXPANSION_VISIBLE}.
+         * This is NOT called each time the bouncer is shown, but rather only when the fully
+         * shown amount has changed based on the panel expansion. The bouncer is visibility
+         * can still change when the expansion amount hasn't changed.
+         * See {@link KeyguardBouncer#isShowing()} for the checks for the bouncer showing state.
          */
         default void onFullyShown() {
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
index 034fc58..b987f68 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
@@ -43,7 +43,6 @@
     private var hasFaceFeature: Boolean
     private var pendingUnlock: PendingUnlock? = null
     private val listeners = mutableListOf<OnBypassStateChangedListener>()
-    var userHasDeviceEntryIntent: Boolean = false // ie: attempted udfps auth
 
     private val faceAuthEnabledChangedCallback = object : KeyguardStateController.Callback {
         override fun onFaceAuthEnabledChanged() = notifyListeners()
@@ -197,20 +196,6 @@
         return false
     }
 
-    /**
-     * If shorter animations should be played when unlocking.
-     */
-    fun canPlaySubtleWindowAnimations(): Boolean {
-        if (bypassEnabled) {
-            return when {
-                statusBarStateController.state != StatusBarState.KEYGUARD -> false
-                qSExpanded -> false
-                else -> true
-            }
-        }
-        return false
-    }
-
     fun onStartedGoingToSleep() {
         pendingUnlock = null
     }
@@ -231,7 +216,6 @@
         pw.println("  launchingAffordance: $launchingAffordance")
         pw.println("  qSExpanded: $qSExpanded")
         pw.println("  hasFaceFeature: $hasFaceFeature")
-        pw.println("  userHasDeviceEntryIntent: $userHasDeviceEntryIntent")
     }
 
     /** Registers a listener for bypass state changes. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index 5d417e0..3e10166 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -165,6 +165,7 @@
     private float mInitialTouchY;
     private float mInitialTouchX;
     private boolean mTouchDisabled;
+    private boolean mInitialTouchFromKeyguard;
 
     /**
      * Whether or not the PanelView can be expanded or collapsed with a drag.
@@ -394,6 +395,7 @@
         mInitialOffsetOnTouch = expandedHeight;
         mInitialTouchY = newY;
         mInitialTouchX = newX;
+        mInitialTouchFromKeyguard = mKeyguardStateController.isShowing();
         if (startTracking) {
             mTouchSlopExceeded = true;
             setExpandedHeight(mInitialOffsetOnTouch);
@@ -412,24 +414,16 @@
             float vectorVel = (float) Math.hypot(
                     mVelocityTracker.getXVelocity(), mVelocityTracker.getYVelocity());
 
-            final boolean onKeyguard =
-                    mStatusBarStateController.getState() == StatusBarState.KEYGUARD;
-
+            final boolean onKeyguard = mKeyguardStateController.isShowing();
             final boolean expand;
-            if (event.getActionMasked() == MotionEvent.ACTION_CANCEL || forceCancel) {
-                // If the keyguard is fading away, don't expand it again. This can happen if you're
-                // swiping to unlock, the app below the keyguard is in landscape, and the screen
-                // rotates while your finger is still down after the swipe to unlock.
-                if (mKeyguardStateController.isKeyguardFadingAway()) {
-                    expand = false;
-                } else if (onKeyguard) {
+            if (mKeyguardStateController.isKeyguardFadingAway()
+                    || (mInitialTouchFromKeyguard && !onKeyguard)) {
+                // Don't expand for any touches that started from the keyguard and ended after the
+                // keyguard is gone.
+                expand = false;
+            } else if (event.getActionMasked() == MotionEvent.ACTION_CANCEL || forceCancel) {
+                if (onKeyguard) {
                     expand = true;
-                } else if (mKeyguardStateController.isKeyguardFadingAway()) {
-                    // If we're in the middle of dismissing the keyguard, don't expand due to the
-                    // cancelled gesture. Gesture cancellation during an unlock is expected in some
-                    // situations, such keeping your finger down while swiping to unlock to an app
-                    // that is locked in landscape (the rotation will cancel the touch event).
-                    expand = false;
                 } else {
                     // If we get a cancel, put the shade back to the state it was in when the
                     // gesture started
@@ -438,7 +432,6 @@
             } else {
                 expand = flingExpands(vel, vectorVel, x, y);
             }
-
             mDozeLog.traceFling(expand, mTouchAboveFalsingThreshold,
                     mCentralSurfaces.isFalsingThresholdNeeded(),
                     mCentralSurfaces.isWakeUpComingFromTouch());
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 4a5f712..b447f0d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -252,7 +252,7 @@
             mBehindTint = Color.BLACK;
             mBlankScreen = false;
 
-            if (previousState == ScrimState.AOD) {
+            if (mDisplayRequiresBlanking && previousState == ScrimState.AOD) {
                 // Set all scrims black, before they fade transparent.
                 updateScrimColor(mScrimInFront, 1f /* alpha */, Color.BLACK /* tint */);
                 updateScrimColor(mScrimBehind, 1f /* alpha */, Color.BLACK /* tint */);
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 61e123a..68d95e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -19,8 +19,8 @@
 import static android.view.WindowInsets.Type.navigationBars;
 
 import static com.android.systemui.plugins.ActivityStarter.OnDismissAction;
+import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_DISMISS_BOUNCER;
 import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_UNLOCK_COLLAPSING;
-import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_UNLOCK_FADING;
 import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
 import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
 
@@ -130,8 +130,6 @@
         public void onFullyShown() {
             mBouncerAnimating = false;
             updateStates();
-            mCentralSurfaces.wakeUpIfDozing(SystemClock.uptimeMillis(),
-                    mCentralSurfaces.getBouncerContainer(), "BOUNCER_VISIBLE");
         }
 
         @Override
@@ -384,6 +382,7 @@
             mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
         } else if (mShowing && !hideBouncerOverDream) {
             if (!isWakeAndUnlocking()
+                    && !(mBiometricUnlockController.getMode() == MODE_DISMISS_BOUNCER)
                     && !mCentralSurfaces.isInLaunchTransition()
                     && !isUnlockCollapsing()) {
                 mBouncer.setExpansion(fraction);
@@ -395,9 +394,8 @@
             }
         } else if (!mShowing && mBouncer.inTransit()) {
             // Keyguard is not visible anymore, but expansion animation was still running.
-            // We need to keep propagating the expansion state to the bouncer, otherwise it will be
-            // stuck in transit.
-            mBouncer.setExpansion(fraction);
+            // We need to hide the bouncer, otherwise it will be stuck in transit.
+            mBouncer.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN);
         } else if (mPulsing && fraction == KeyguardBouncer.EXPANSION_VISIBLE) {
             // Panel expanded while pulsing but didn't translate the bouncer (because we are
             // unlocked.) Let's simply wake-up to dismiss the lock screen.
@@ -736,8 +734,10 @@
         }
         mNotificationShadeWindowController.setKeyguardOccluded(mOccluded);
 
-        // setDozing(false) will call reset once we stop dozing.
-        if (!mDozing) {
+        // setDozing(false) will call reset once we stop dozing. Also, if we're going away, there's
+        // no need to reset the keyguard views as we'll be gone shortly. Resetting now could cause
+        // unexpected visible behavior if the keyguard is still visible as we're animating unlocked.
+        if (!mDozing && !mKeyguardStateController.isKeyguardGoingAway()) {
             // If Keyguard is reshown, don't hide the bouncer as it might just have been requested
             // by a FLAG_DISMISS_KEYGUARD_ACTIVITY.
             reset(isOccluding /* hideBouncerWhenShowing*/);
@@ -832,46 +832,17 @@
             executeAfterKeyguardGoneAction();
             boolean wakeUnlockPulsing =
                     mBiometricUnlockController.getMode() == MODE_WAKE_AND_UNLOCK_PULSING;
-            boolean needsFading = needsBypassFading();
-            if (needsFading) {
-                delay = 0;
-                fadeoutDuration = KeyguardBypassController.BYPASS_FADE_DURATION;
-            } else if (wakeUnlockPulsing) {
-                delay = 0;
-                fadeoutDuration = 240;
-            }
-            mCentralSurfaces.setKeyguardFadingAway(startTime, delay, fadeoutDuration, needsFading);
+            mCentralSurfaces.setKeyguardFadingAway(startTime, delay, fadeoutDuration);
             mBiometricUnlockController.startKeyguardFadingAway();
             hideBouncer(true /* destroyView */);
             if (wakeUnlockPulsing) {
-                if (needsFading) {
-                    ViewGroupFadeHelper.fadeOutAllChildrenExcept(
-                            mNotificationPanelViewController.getView(),
-                            mNotificationContainer,
-                            fadeoutDuration,
-                                    () -> {
-                        mCentralSurfaces.hideKeyguard();
-                        onKeyguardFadedAway();
-                    });
-                } else {
-                    mCentralSurfaces.fadeKeyguardWhilePulsing();
-                }
+                mCentralSurfaces.fadeKeyguardWhilePulsing();
                 wakeAndUnlockDejank();
             } else {
                 boolean staying = mStatusBarStateController.leaveOpenOnKeyguardHide();
                 if (!staying) {
                     mNotificationShadeWindowController.setKeyguardFadingAway(true);
-                    if (needsFading) {
-                        ViewGroupFadeHelper.fadeOutAllChildrenExcept(
-                                mNotificationPanelViewController.getView(),
-                                mNotificationContainer,
-                                fadeoutDuration,
-                                () -> {
-                                    mCentralSurfaces.hideKeyguard();
-                                });
-                    } else {
-                        mCentralSurfaces.hideKeyguard();
-                    }
+                    mCentralSurfaces.hideKeyguard();
                     // hide() will happen asynchronously and might arrive after the scrims
                     // were already hidden, this means that the transition callback won't
                     // be triggered anymore and StatusBarWindowController will be forever in
@@ -884,6 +855,7 @@
                     mBiometricUnlockController.finishKeyguardFadingAway();
                 }
             }
+
             updateStates();
             mNotificationShadeWindowController.setKeyguardShowing(false);
             mViewMediatorCallback.keyguardGone();
@@ -893,13 +865,6 @@
         Trace.endSection();
     }
 
-    private boolean needsBypassFading() {
-        return (mBiometricUnlockController.getMode() == MODE_UNLOCK_FADING
-                || mBiometricUnlockController.getMode() == MODE_WAKE_AND_UNLOCK_PULSING
-                || mBiometricUnlockController.getMode() == MODE_WAKE_AND_UNLOCK)
-                && mBypassController.getBypassEnabled();
-    }
-
     @Override
     public void onNavigationModeChanged(int mode) {
         boolean gesturalNav = QuickStepContract.isGesturalMode(mode);
@@ -999,7 +964,7 @@
 
     @Override
     public boolean bouncerIsOrWillBeShowing() {
-        return isBouncerShowing() || mBouncer.getShowingSoon();
+        return isBouncerShowing() || mBouncer.inTransit();
     }
 
     public boolean isFullscreenBouncer() {
@@ -1186,7 +1151,7 @@
 
     @Override
     public boolean shouldSubtleWindowAnimationsForUnlock() {
-        return needsBypassFading();
+        return false;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
index 597c949..cf1edf9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
@@ -483,6 +483,10 @@
         int state = mAnimationScheduler.getAnimationState();
         if (state == IDLE || state == SHOWING_PERSISTENT_DOT) {
             animateShow(mSystemIconArea, animate);
+        } else {
+            // We are in the middle of a system status event animation, which will animate the
+            // alpha (but not the visibility). Allow the view to become visible again
+            mSystemIconArea.setVisibility(View.VISIBLE);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java
index dce2412..250d9d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java
@@ -109,28 +109,15 @@
      * we're bypassing
      */
     default long getShortenedFadingAwayDuration() {
-        if (isBypassFadingAnimation()) {
-            return getKeyguardFadingAwayDuration();
-        } else {
-            return getKeyguardFadingAwayDuration() / 2;
-        }
-    }
-
-    /**
-     * @return {@code true} if the current fading away animation is the fast bypass fading.
-     */
-    default boolean isBypassFadingAnimation() {
-        return false;
+        return getKeyguardFadingAwayDuration() / 2;
     }
 
     /**
      * Notifies that the Keyguard is fading away with the specified timings.
      * @param delay the precalculated animation delay in milliseconds
      * @param fadeoutDuration the duration of the exit animation, in milliseconds
-     * @param isBypassFading is this a fading away animation while bypassing
      */
-    default void notifyKeyguardFadingAway(long delay, long fadeoutDuration,
-            boolean isBypassFading) {
+    default void notifyKeyguardFadingAway(long delay, long fadeoutDuratio) {
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
index 2a225b90..2fb16ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
@@ -72,7 +72,6 @@
     private long mKeyguardFadingAwayDuration;
     private boolean mKeyguardGoingAway;
     private boolean mLaunchTransitionFadingAway;
-    private boolean mBypassFadingAnimation;
     private boolean mTrustManaged;
     private boolean mTrusted;
     private boolean mDebugUnlocked = false;
@@ -203,10 +202,9 @@
     }
 
     @Override
-    public void notifyKeyguardFadingAway(long delay, long fadeoutDuration, boolean isBypassFading) {
+    public void notifyKeyguardFadingAway(long delay, long fadeoutDuration) {
         mKeyguardFadingAwayDelay = delay;
         mKeyguardFadingAwayDuration = fadeoutDuration;
-        mBypassFadingAnimation = isBypassFading;
         setKeyguardFadingAway(true);
     }
 
@@ -284,11 +282,6 @@
     }
 
     @Override
-    public boolean isBypassFadingAnimation() {
-        return mBypassFadingAnimation;
-    }
-
-    @Override
     public long getKeyguardFadingAwayDelay() {
         return mKeyguardFadingAwayDelay;
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
index 92e4947..90609fa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
@@ -50,6 +50,7 @@
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
 import android.graphics.Insets;
+import android.graphics.Path;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
@@ -75,14 +76,19 @@
 import androidx.annotation.Nullable;
 import androidx.test.filters.SmallTest;
 
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.decor.CornerDecorProvider;
 import com.android.systemui.decor.DecorProvider;
 import com.android.systemui.decor.DecorProviderFactory;
+import com.android.systemui.decor.FaceScanningOverlayProviderImpl;
+import com.android.systemui.decor.FaceScanningProviderFactory;
 import com.android.systemui.decor.OverlayWindow;
 import com.android.systemui.decor.PrivacyDotCornerDecorProviderImpl;
 import com.android.systemui.decor.PrivacyDotDecorProviderFactory;
 import com.android.systemui.decor.RoundedCornerResDelegate;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.events.PrivacyDotViewController;
 import com.android.systemui.tuner.TunerService;
@@ -113,6 +119,13 @@
     private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
     private FakeThreadFactory mThreadFactory;
     private ArrayList<DecorProvider> mPrivacyDecorProviders;
+    private ArrayList<DecorProvider> mFaceScanningProviders;
+    @Mock
+    private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    @Mock
+    private StatusBarStateController mStatusBarStateController;
+    @Mock
+    private AuthController mAuthController;
     @Mock
     private Display mDisplay;
     @Mock
@@ -128,6 +141,10 @@
     @Mock
     private PrivacyDotDecorProviderFactory mPrivacyDotDecorProviderFactory;
     @Mock
+    private FaceScanningProviderFactory mFaceScanningProviderFactory;
+    @Mock
+    private FaceScanningOverlayProviderImpl mFaceScanningDecorProvider;
+    @Mock
     private CornerDecorProvider mPrivacyDotTopLeftDecorProvider;
     @Mock
     private CornerDecorProvider mPrivacyDotTopRightDecorProvider;
@@ -189,9 +206,16 @@
                 DisplayCutout.BOUNDS_POSITION_RIGHT,
                 R.layout.privacy_dot_bottom_right));
 
+        mFaceScanningDecorProvider = spy(new FaceScanningOverlayProviderImpl(
+                BOUNDS_POSITION_TOP,
+                mAuthController,
+                mStatusBarStateController,
+                mKeyguardUpdateMonitor,
+                mExecutor));
+
         mScreenDecorations = spy(new ScreenDecorations(mContext, mExecutor, mSecureSettings,
                 mBroadcastDispatcher, mTunerService, mUserTracker, mDotViewController,
-                mThreadFactory, mPrivacyDotDecorProviderFactory) {
+                mThreadFactory, mPrivacyDotDecorProviderFactory, mFaceScanningProviderFactory) {
             @Override
             public void start() {
                 super.start();
@@ -211,9 +235,8 @@
             }
 
             @Override
-            protected void setOverlayWindowVisibilityIfViewExist(@Nullable View view,
-                    @View.Visibility int visibility) {
-                super.setOverlayWindowVisibilityIfViewExist(view, visibility);
+            protected void updateOverlayWindowVisibilityIfViewExists(@Nullable View view) {
+                super.updateOverlayWindowVisibilityIfViewExists(view);
                 mExecutor.runAllReady();
             }
         });
@@ -269,6 +292,16 @@
         }
     }
 
+    private void verifyFaceScanningViewExists(final boolean exists) {
+        final View overlay = mScreenDecorations.mOverlays[BOUNDS_POSITION_TOP].getRootView();
+        final View view = overlay.findViewById(mFaceScanningDecorProvider.getViewId());
+        if (exists) {
+            assertNotNull(view);
+        } else {
+            assertNull(view);
+        }
+    }
+
     @Nullable
     private View findViewFromOverlays(@IdRes int id) {
         for (OverlayWindow overlay: mScreenDecorations.mOverlays) {
@@ -393,10 +426,11 @@
     }
 
     @Test
-    public void testNoRounding_NoCutout_NoPrivacyDot() {
+    public void testNoRounding_NoCutout_NoPrivacyDot_NoFaceScanning() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* fillCutout */, false /* privacyDot */);
+                0 /* roundedPadding */, false /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         // no cutout
         doReturn(null).when(mScreenDecorations).getCutout();
@@ -411,10 +445,11 @@
     }
 
     @Test
-    public void testNoRounding_NoCutout_PrivacyDot() {
+    public void testNoRounding_NoCutout_PrivacyDot_NoFaceScanning() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */);
+                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         // no cutout
         doReturn(null).when(mScreenDecorations).getCutout();
@@ -435,6 +470,9 @@
         // Privacy dots shall exist but invisible
         verifyDotViewsVisibility(View.INVISIBLE);
 
+        // Face scanning doesn't exist
+        verifyFaceScanningViewExists(false);
+
         // One tunable.
         verify(mTunerService, times(1)).addTunable(any(), any());
         // Dot controller init
@@ -443,10 +481,11 @@
     }
 
     @Test
-    public void testRounding_NoCutout_NoPrivacyDot() {
+    public void testRounding_NoCutout_NoPrivacyDot_NoFaceScanning() {
         setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                20 /* roundedPadding */, false /* fillCutout */, false /* privacyDot */);
+                20 /* roundedPadding */, false /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         // no cutout
         doReturn(null).when(mScreenDecorations).getCutout();
@@ -464,6 +503,9 @@
         // Privacy dots shall not exist
         verifyDotViewsNullable(true);
 
+        // Face scanning doesn't exist
+        verifyFaceScanningViewExists(false);
+
         // One tunable.
         verify(mTunerService, times(1)).addTunable(any(), any());
         // No dot controller init
@@ -471,10 +513,11 @@
     }
 
     @Test
-    public void testRounding_NoCutout_PrivacyDot() {
+    public void testRounding_NoCutout_PrivacyDot_NoFaceScanning() {
         setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                20 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */);
+                20 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         // no cutout
         doReturn(null).when(mScreenDecorations).getCutout();
@@ -494,6 +537,9 @@
         // Privacy dots shall exist but invisible
         verifyDotViewsVisibility(View.INVISIBLE);
 
+        // Face scanning doesn't exist
+        verifyFaceScanningViewExists(false);
+
         // One tunable.
         verify(mTunerService, times(1)).addTunable(any(), any());
         // Dot controller init
@@ -509,7 +555,8 @@
                 /* roundedTopDrawable */,
                 getTestsDrawable(com.android.systemui.tests.R.drawable.rounded3px)
                 /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */);
+                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
         // no cutout
         doReturn(null).when(mScreenDecorations).getCutout();
 
@@ -527,7 +574,8 @@
                 /* roundedTopDrawable */,
                 getTestsDrawable(com.android.systemui.tests.R.drawable.rounded3px)
                 /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */);
+                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         // no cutout
         doReturn(null).when(mScreenDecorations).getCutout();
@@ -563,7 +611,8 @@
                 /* roundedTopDrawable */,
                 getTestsDrawable(com.android.systemui.tests.R.drawable.rounded5px)
                 /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */);
+                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         // left cutout
         final Rect[] bounds = {new Rect(0, 50, 1, 60), null, null, null};
@@ -598,7 +647,8 @@
     public void testNoRounding_CutoutShortEdge_NoPrivacyDot() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */);
+                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         // top cutout
         final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
@@ -621,7 +671,8 @@
     public void testNoRounding_CutoutShortEdge_PrivacyDot() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */);
+                0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         // top cutout
         final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
@@ -655,7 +706,8 @@
     public void testNoRounding_CutoutLongEdge_NoPrivacyDot() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */);
+                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         // left cutout
         final Rect[] bounds = {new Rect(0, 50, 1, 60), null, null, null};
@@ -682,7 +734,8 @@
     public void testNoRounding_CutoutLongEdge_PrivacyDot() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */);
+                0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         // left cutout
         final Rect[] bounds = {new Rect(0, 50, 1, 60), null, null, null};
@@ -709,7 +762,8 @@
     public void testRounding_CutoutShortEdge_NoPrivacyDot() {
         setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                20 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */);
+                20 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         // top cutout
         final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
@@ -737,7 +791,8 @@
     public void testRounding_CutoutShortEdge_PrivacyDot() {
         setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                20 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */);
+                20 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         // top cutout
         final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
@@ -768,7 +823,8 @@
     public void testRounding_CutoutLongEdge_NoPrivacyDot() {
         setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                20 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */);
+                20 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         // left cutout
         final Rect[] bounds = {new Rect(0, 50, 1, 60), null, null, null};
@@ -786,7 +842,8 @@
     public void testRounding_CutoutLongEdge_PrivacyDot() {
         setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                20 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */);
+                20 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         // left cutout
         final Rect[] bounds = {new Rect(0, 50, 1, 60), null, null, null};
@@ -806,7 +863,8 @@
     public void testRounding_CutoutShortAndLongEdge_NoPrivacyDot() {
         setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                20 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */);
+                20 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         // top and left cutout
         final Rect[] bounds = {new Rect(0, 50, 1, 60), new Rect(9, 0, 10, 1), null, null};
@@ -825,7 +883,8 @@
     public void testRounding_CutoutShortAndLongEdge_PrivacyDot() {
         setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                20 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */);
+                20 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         // top and left cutout
         final Rect[] bounds = {new Rect(0, 50, 1, 60), new Rect(9, 0, 10, 1), null, null};
@@ -846,7 +905,8 @@
     public void testNoRounding_SwitchFrom_ShortEdgeCutout_To_LongCutout_NoPrivacyDot() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */);
+                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         // Set to short edge cutout(top).
         final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
@@ -869,7 +929,8 @@
     public void testNoRounding_SwitchFrom_ShortEdgeCutout_To_LongCutout_PrivacyDot() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */);
+                0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         // Set to short edge cutout(top).
         final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
@@ -912,7 +973,8 @@
     public void testDelayedCutout_NoPrivacyDot() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* fillCutout */, false /* privacyDot */);
+                0 /* roundedPadding */, false /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         // top cutout
         final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
@@ -935,7 +997,8 @@
     public void testDelayedCutout_PrivacyDot() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */);
+                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         // top cutout
         final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
@@ -980,7 +1043,8 @@
                 /* roundedTopDrawable */,
                 getTestsDrawable(com.android.systemui.tests.R.drawable.rounded4px)
                 /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */);
+                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning*/);
         mDisplayInfo.rotation = Surface.ROTATION_0;
 
         mScreenDecorations.start();
@@ -994,7 +1058,8 @@
                 /* roundedTopDrawable */,
                 getTestsDrawable(com.android.systemui.tests.R.drawable.rounded5px)
                 /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */);
+                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning*/);
         mDisplayInfo.rotation = Surface.ROTATION_270;
 
         mScreenDecorations.onConfigurationChanged(null);
@@ -1007,7 +1072,8 @@
     public void testOnlyRoundedCornerRadiusTop() {
         setupResources(0 /* radius */, 10 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */);
+                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         mScreenDecorations.start();
 
@@ -1028,7 +1094,8 @@
     public void testOnlyRoundedCornerRadiusBottom() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 20 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */);
+                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         mScreenDecorations.start();
 
@@ -1099,7 +1166,8 @@
     public void testSupportHwcLayer_SwitchFrom_NotSupport() {
         setupResources(0 /* radius */, 10 /* radiusTop */, 20 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */);
+                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         // top cutout
         final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
@@ -1127,7 +1195,8 @@
     public void testNotSupportHwcLayer_SwitchFrom_Support() {
         setupResources(0 /* radius */, 10 /* radiusTop */, 20 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */);
+                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
         final DisplayDecorationSupport decorationSupport = new DisplayDecorationSupport();
         decorationSupport.format = PixelFormat.R_8;
         doReturn(decorationSupport).when(mDisplay).getDisplayDecorationSupport();
@@ -1165,7 +1234,8 @@
                 /* roundedTopDrawable */,
                 getTestsDrawable(com.android.systemui.tests.R.drawable.rounded4px)
                 /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */);
+                0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
+                true /* faceScanning */);
         final DisplayDecorationSupport decorationSupport = new DisplayDecorationSupport();
         decorationSupport.format = PixelFormat.R_8;
         doReturn(decorationSupport).when(mDisplay).getDisplayDecorationSupport();
@@ -1182,19 +1252,33 @@
         // Make sure view found and window visibility changed as well
         final View view = mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM].getRootView()
                 .findViewById(R.id.privacy_dot_bottom_right_container);
+        view.setVisibility(View.VISIBLE);
         mPrivacyDotShowingListener.onPrivacyDotShown(view);
         assertEquals(View.VISIBLE,
                 mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM].getRootView().getVisibility());
+        view.setVisibility(View.INVISIBLE);
         mPrivacyDotShowingListener.onPrivacyDotHidden(view);
         assertEquals(View.INVISIBLE,
                 mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM].getRootView().getVisibility());
+
+        // Make sure face scanning view found and window visibility updates on camera protection
+        // update
+        final View faceScanView = mScreenDecorations.mOverlays[BOUNDS_POSITION_TOP].getRootView()
+                .findViewById(mFaceScanningDecorProvider.getViewId());
+        when(mFaceScanningProviderFactory.shouldShowFaceScanningAnim()).thenReturn(true);
+        faceScanView.setVisibility(View.VISIBLE);
+        mScreenDecorations.showCameraProtection(new Path(), new Rect());
+        mExecutor.runAllReady();
+        assertEquals(View.VISIBLE,
+                mScreenDecorations.mOverlays[BOUNDS_POSITION_TOP].getRootView().getVisibility());
     }
 
     @Test
     public void testAutoShowHideOverlayWindowWhenNoRoundedAndNoCutout() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */);
+                0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
+                true /* faceScanning */);
 
         // no cutout
         doReturn(null).when(mScreenDecorations).getCutout();
@@ -1206,19 +1290,33 @@
         // Make sure view found and window visibility changed as well
         final View view = mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM].getRootView()
                 .findViewById(R.id.privacy_dot_bottom_right_container);
+        view.setVisibility(View.VISIBLE);
         mPrivacyDotShowingListener.onPrivacyDotShown(view);
         assertEquals(View.VISIBLE,
                 mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM].getRootView().getVisibility());
+        view.setVisibility(View.INVISIBLE);
         mPrivacyDotShowingListener.onPrivacyDotHidden(view);
         assertEquals(View.INVISIBLE,
                 mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM].getRootView().getVisibility());
+
+        // Make sure face scanning view found and window visibility updates on camera protection
+        // update
+        final View faceScanView = mScreenDecorations.mOverlays[BOUNDS_POSITION_TOP].getRootView()
+                .findViewById(mFaceScanningDecorProvider.getViewId());
+        faceScanView.setVisibility(View.VISIBLE);
+        when(mFaceScanningProviderFactory.shouldShowFaceScanningAnim()).thenReturn(true);
+        mScreenDecorations.showCameraProtection(new Path(), new Rect());
+        mExecutor.runAllReady();
+        assertEquals(View.VISIBLE,
+                mScreenDecorations.mOverlays[BOUNDS_POSITION_TOP].getRootView().getVisibility());
     }
 
     @Test
-    public void testHwcLayer_noPrivacyDot() {
+    public void testHwcLayer_noPrivacyDot_noFaceScanning() {
         setupResources(0 /* radius */, 10 /* radiusTop */, 20 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */);
+                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
         final DisplayDecorationSupport decorationSupport = new DisplayDecorationSupport();
         decorationSupport.format = PixelFormat.R_8;
         doReturn(decorationSupport).when(mDisplay).getDisplayDecorationSupport();
@@ -1236,10 +1334,11 @@
     }
 
     @Test
-    public void testHwcLayer_PrivacyDot() {
+    public void testHwcLayer_PrivacyDot_FaceScanning() {
         setupResources(0 /* radius */, 10 /* radiusTop */, 20 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */);
+                0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
+                true /* faceScanning */);
         final DisplayDecorationSupport decorationSupport = new DisplayDecorationSupport();
         decorationSupport.format = PixelFormat.R_8;
         doReturn(decorationSupport).when(mDisplay).getDisplayDecorationSupport();
@@ -1257,13 +1356,16 @@
         verify(mDotViewController, times(1)).initialize(any(), any(), any(), any());
         verify(mDotViewController, times(1)).setShowingListener(
                 mScreenDecorations.mPrivacyDotShowingListener);
+
+        verifyFaceScanningViewExists(true);
     }
 
     @Test
     public void testOnDisplayChanged_hwcLayer() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */);
+                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
         final DisplayDecorationSupport decorationSupport = new DisplayDecorationSupport();
         decorationSupport.format = PixelFormat.R_8;
         doReturn(decorationSupport).when(mDisplay).getDisplayDecorationSupport();
@@ -1288,7 +1390,8 @@
     public void testOnDisplayChanged_nonHwcLayer() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */);
+                0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         // top cutout
         final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
@@ -1311,7 +1414,8 @@
     public void testHasSameProvidersWithNullOverlays() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, false /* fillCutout */, false /* privacyDot */);
+                0 /* roundedPadding */, false /* fillCutout */, false /* privacyDot */,
+                false /* faceScanning */);
 
         mScreenDecorations.start();
 
@@ -1329,7 +1433,8 @@
     public void testHasSameProvidersWithPrivacyDots() {
         setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
                 null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
-                0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */);
+                0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
+                false /* faceScanning */);
 
         mScreenDecorations.start();
 
@@ -1366,7 +1471,7 @@
 
     private void setupResources(int radius, int radiusTop, int radiusBottom,
             @Nullable Drawable roundedTopDrawable, @Nullable Drawable roundedBottomDrawable,
-            int roundedPadding, boolean fillCutout, boolean privacyDot) {
+            int roundedPadding, boolean fillCutout, boolean privacyDot, boolean faceScanning) {
         mContext.getOrCreateTestableResources().addOverride(
                 com.android.internal.R.array.config_displayUniqueIdArray,
                 new String[]{});
@@ -1418,6 +1523,13 @@
         }
         when(mPrivacyDotDecorProviderFactory.getProviders()).thenReturn(mPrivacyDecorProviders);
         when(mPrivacyDotDecorProviderFactory.getHasProviders()).thenReturn(privacyDot);
+
+        mFaceScanningProviders = new ArrayList<>();
+        if (faceScanning) {
+            mFaceScanningProviders.add(mFaceScanningDecorProvider);
+        }
+        when(mFaceScanningProviderFactory.getProviders()).thenReturn(mFaceScanningProviders);
+        when(mFaceScanningProviderFactory.getHasProviders()).thenReturn(faceScanning);
     }
 
     private DisplayCutout getDisplayCutoutForRotation(Insets safeInsets, Rect[] cutoutBounds) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
index 6a9bb3e..b61fbbe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
@@ -520,6 +520,145 @@
         endAnimation(rootView)
     }
 
+    @Test
+    fun animatesAppearingViewsFadeIn_alphaStartsAtZero_endsAtOne() {
+        rootView.alpha = 0f
+        ViewHierarchyAnimator.animateAddition(rootView, includeFadeIn = true)
+        rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
+
+        advanceFadeInAnimation(rootView, fraction = 1f)
+        endFadeInAnimation(rootView)
+
+        assertNull(rootView.getTag(R.id.tag_alpha_animator))
+        assertEquals(1f, rootView.alpha)
+    }
+
+    @Test
+    fun animatesAppearingViewsFadeIn_alphaStartsAboveZero_endsAtOne() {
+        rootView.alpha = 0.2f
+        ViewHierarchyAnimator.animateAddition(rootView, includeFadeIn = true)
+        rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
+
+        advanceFadeInAnimation(rootView, fraction = 1f)
+        endFadeInAnimation(rootView)
+
+        assertNull(rootView.getTag(R.id.tag_alpha_animator))
+        assertEquals(1f, rootView.alpha)
+    }
+
+    @Test
+    fun animatesAppearingViewsFadeIn_alphaStartsAsZero_alphaUpdatedMidAnimation() {
+        rootView.alpha = 0f
+        ViewHierarchyAnimator.animateAddition(
+            rootView,
+            includeFadeIn = true,
+            fadeInInterpolator = Interpolators.LINEAR
+        )
+        rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
+
+        advanceFadeInAnimation(rootView, fraction = 0.42f)
+
+        assertEquals(0.42f, rootView.alpha)
+    }
+
+    @Test
+    fun animatesAppearingViewsFadeIn_alphaStartsAboveZero_alphaUpdatedMidAnimation() {
+        rootView.alpha = 0.6f
+        ViewHierarchyAnimator.animateAddition(
+            rootView,
+            includeFadeIn = true,
+            fadeInInterpolator = Interpolators.LINEAR
+        )
+        rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
+
+        advanceFadeInAnimation(rootView, fraction = 0.5f)
+
+        assertEquals(0.8f, rootView.alpha)
+    }
+
+    @Test
+    fun animatesAppearingViewsFadeIn_childViewAlphasAlsoAnimated() {
+        rootView.alpha = 0f
+        val firstChild = View(context)
+        firstChild.alpha = 0f
+        val secondChild = View(context)
+        secondChild.alpha = 0f
+        rootView.addView(firstChild)
+        rootView.addView(secondChild)
+
+        ViewHierarchyAnimator.animateAddition(
+            rootView,
+            includeFadeIn = true,
+            fadeInInterpolator = Interpolators.LINEAR
+        )
+        rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
+
+        advanceFadeInAnimation(rootView, fraction = 0.5f)
+
+        assertEquals(0.5f, rootView.alpha)
+        assertEquals(0.5f, firstChild.alpha)
+        assertEquals(0.5f, secondChild.alpha)
+    }
+
+    @Test
+    fun animatesAppearingViewsFadeIn_animatesFromPreviousAnimationProgress() {
+        rootView.alpha = 0f
+        ViewHierarchyAnimator.animateAddition(
+            rootView,
+            includeFadeIn = true,
+            fadeInInterpolator = Interpolators.LINEAR
+        )
+        rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
+
+        advanceFadeInAnimation(rootView, fraction = 0.5f)
+        assertEquals(0.5f, rootView.alpha)
+        assertNotNull(rootView.getTag(R.id.tag_alpha_animator))
+
+        // IF we request animation again
+        ViewHierarchyAnimator.animateAddition(
+            rootView,
+            includeFadeIn = true,
+            fadeInInterpolator = Interpolators.LINEAR
+        )
+
+        // THEN the alpha remains at its current value (it doesn't get reset to 0)
+        assertNotNull(rootView.getTag(R.id.tag_alpha_animator))
+        assertEquals(0.5f, rootView.alpha)
+
+        // IF we advance the new animation to the end
+        advanceFadeInAnimation(rootView, fraction = 1f)
+        endFadeInAnimation(rootView)
+
+        // THEN we still end at the correct value
+        assertNull(rootView.getTag(R.id.tag_alpha_animator))
+        assertEquals(1f, rootView.alpha)
+    }
+
+    @Test
+    fun animatesAppearingViews_fadeInFalse_alphasNotUpdated() {
+        rootView.alpha = 0.3f
+        val firstChild = View(context)
+        firstChild.alpha = 0.4f
+        val secondChild = View(context)
+        secondChild.alpha = 0.5f
+        rootView.addView(firstChild)
+        rootView.addView(secondChild)
+
+        ViewHierarchyAnimator.animateAddition(
+            rootView,
+            includeFadeIn = false,
+            fadeInInterpolator = Interpolators.LINEAR
+        )
+        rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
+
+        advanceFadeInAnimation(rootView, fraction = 1f)
+
+        assertEquals(0.3f, rootView.alpha)
+        assertEquals(0.4f, firstChild.alpha)
+        assertEquals(0.5f, secondChild.alpha)
+    }
+
+    @Test
     fun animatesViewRemovalFromStartToEnd() {
         setUpRootWithChildren()
 
@@ -1003,6 +1142,16 @@
         }
     }
 
+    private fun advanceFadeInAnimation(rootView: View, fraction: Float) {
+        (rootView.getTag(R.id.tag_alpha_animator) as? ObjectAnimator)?.setCurrentFraction(fraction)
+
+        if (rootView is ViewGroup) {
+            for (i in 0 until rootView.childCount) {
+                advanceFadeInAnimation(rootView.getChildAt(i), fraction)
+            }
+        }
+    }
+
     private fun endAnimation(rootView: View) {
         (rootView.getTag(R.id.tag_animator) as? ObjectAnimator)?.end()
 
@@ -1012,4 +1161,14 @@
             }
         }
     }
+
+    private fun endFadeInAnimation(rootView: View) {
+        (rootView.getTag(R.id.tag_alpha_animator) as? ObjectAnimator)?.end()
+
+        if (rootView is ViewGroup) {
+            for (i in 0 until rootView.childCount) {
+                endFadeInAnimation(rootView.getChildAt(i))
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt
new file mode 100644
index 0000000..328ad39
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2022 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.biometrics
+
+import android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE
+import android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.testing.TestableLooper.RunWithLooper
+import android.view.View
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
+
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class AuthBiometricFingerprintAndFaceViewTest : SysuiTestCase() {
+
+    @JvmField @Rule
+    var mockitoRule = MockitoJUnit.rule()
+
+    @Mock
+    private lateinit var callback: AuthBiometricView.Callback
+    @Mock
+    private lateinit var panelController: AuthPanelController
+
+    private lateinit var biometricView: AuthBiometricFingerprintAndFaceView
+
+    @Before
+    fun setup() {
+        biometricView = R.layout.auth_biometric_fingerprint_and_face_view
+                .asTestAuthBiometricView(mContext, callback, panelController)
+        waitForIdleSync()
+    }
+
+    @After
+    fun tearDown() {
+        biometricView.destroyDialog()
+    }
+
+    @Test
+    fun fingerprintSuccessDoesNotRequireExplicitConfirmation() {
+        biometricView.onDialogAnimatedIn()
+        biometricView.onAuthenticationSucceeded(TYPE_FINGERPRINT)
+        waitForIdleSync()
+
+        assertThat(biometricView.isAuthenticated).isTrue()
+        verify(callback).onAction(AuthBiometricView.Callback.ACTION_AUTHENTICATED)
+    }
+
+    @Test
+    fun faceSuccessRequiresExplicitConfirmation() {
+        biometricView.onDialogAnimatedIn()
+        biometricView.onAuthenticationSucceeded(TYPE_FACE)
+        waitForIdleSync()
+
+        assertThat(biometricView.isAuthenticated).isFalse()
+        assertThat(biometricView.isAuthenticating).isFalse()
+        assertThat(biometricView.mConfirmButton.visibility).isEqualTo(View.GONE)
+        verify(callback, never()).onAction(AuthBiometricView.Callback.ACTION_AUTHENTICATED)
+
+        // icon acts as confirm button
+        biometricView.mIconView.performClick()
+        waitForIdleSync()
+
+        assertThat(biometricView.isAuthenticated).isTrue()
+        verify(callback).onAction(AuthBiometricView.Callback.ACTION_AUTHENTICATED)
+    }
+
+    @Test
+    fun ignoresFaceErrors() {
+        biometricView.onDialogAnimatedIn()
+        biometricView.onError(TYPE_FACE, "not a face")
+        waitForIdleSync()
+
+        assertThat(biometricView.isAuthenticating).isTrue()
+        verify(callback, never()).onAction(AuthBiometricView.Callback.ACTION_ERROR)
+
+        biometricView.onError(TYPE_FINGERPRINT, "that's a nope")
+        waitForIdleSync()
+
+        verify(callback).onAction(AuthBiometricView.Callback.ACTION_ERROR)
+    }
+
+    override fun waitForIdleSync() = TestableLooper.get(this).processAllMessages()
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt
new file mode 100644
index 0000000..687cb517
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2022 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.biometrics
+
+import android.hardware.biometrics.BiometricAuthenticator
+import android.os.Bundle
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.testing.TestableLooper.RunWithLooper
+import android.view.View
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
+
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class AuthBiometricFingerprintViewTest : SysuiTestCase() {
+
+    @JvmField @Rule
+    val mockitoRule = MockitoJUnit.rule()
+
+    @Mock
+    private lateinit var callback: AuthBiometricView.Callback
+    @Mock
+    private lateinit var panelController: AuthPanelController
+
+    private lateinit var biometricView: AuthBiometricView
+
+    private fun createView(allowDeviceCredential: Boolean = false): AuthBiometricFingerprintView {
+        val view = R.layout.auth_biometric_fingerprint_view.asTestAuthBiometricView(
+                mContext, callback, panelController, allowDeviceCredential = allowDeviceCredential
+        ) as AuthBiometricFingerprintView
+        waitForIdleSync()
+        return view
+    }
+
+    @Before
+    fun setup() {
+        biometricView = createView()
+    }
+
+    @After
+    fun tearDown() {
+        biometricView.destroyDialog()
+    }
+
+    @Test
+    fun testOnAuthenticationSucceeded_noConfirmationRequired_sendsActionAuthenticated() {
+        biometricView.onAuthenticationSucceeded(BiometricAuthenticator.TYPE_FINGERPRINT)
+        waitForIdleSync()
+
+        assertThat(biometricView.isAuthenticated).isTrue()
+        verify(callback).onAction(AuthBiometricView.Callback.ACTION_AUTHENTICATED)
+    }
+
+    @Test
+    fun testOnAuthenticationSucceeded_confirmationRequired_updatesDialogContents() {
+        biometricView.setRequireConfirmation(true)
+        biometricView.onAuthenticationSucceeded(BiometricAuthenticator.TYPE_FINGERPRINT)
+        waitForIdleSync()
+
+        // TODO: this should be tested in the subclasses
+        if (biometricView.supportsRequireConfirmation()) {
+            verify(callback, never()).onAction(ArgumentMatchers.anyInt())
+            assertThat(biometricView.mNegativeButton.visibility).isEqualTo(View.GONE)
+            assertThat(biometricView.mCancelButton.visibility).isEqualTo(View.VISIBLE)
+            assertThat(biometricView.mCancelButton.isEnabled).isTrue()
+            assertThat(biometricView.mConfirmButton.isEnabled).isTrue()
+            assertThat(biometricView.mIndicatorView.text)
+                    .isEqualTo(mContext.getText(R.string.biometric_dialog_tap_confirm))
+            assertThat(biometricView.mIndicatorView.visibility).isEqualTo(View.VISIBLE)
+        } else {
+            assertThat(biometricView.isAuthenticated).isTrue()
+            verify(callback).onAction(eq(AuthBiometricView.Callback.ACTION_AUTHENTICATED))
+        }
+    }
+
+    @Test
+    fun testPositiveButton_sendsActionAuthenticated() {
+        biometricView.mConfirmButton.performClick()
+        waitForIdleSync()
+
+        verify(callback).onAction(AuthBiometricView.Callback.ACTION_AUTHENTICATED)
+        assertThat(biometricView.isAuthenticated).isTrue()
+    }
+
+    @Test
+    fun testNegativeButton_beforeAuthentication_sendsActionButtonNegative() {
+        biometricView.onDialogAnimatedIn()
+        biometricView.mNegativeButton.performClick()
+        waitForIdleSync()
+
+        verify(callback).onAction(AuthBiometricView.Callback.ACTION_BUTTON_NEGATIVE)
+    }
+
+    @Test
+    fun testCancelButton_whenPendingConfirmation_sendsActionUserCanceled() {
+        biometricView.setRequireConfirmation(true)
+        biometricView.onAuthenticationSucceeded(BiometricAuthenticator.TYPE_FINGERPRINT)
+
+        assertThat(biometricView.mNegativeButton.visibility).isEqualTo(View.GONE)
+        biometricView.mCancelButton.performClick()
+        waitForIdleSync()
+
+        verify(callback).onAction(AuthBiometricView.Callback.ACTION_USER_CANCELED)
+    }
+
+    @Test
+    fun testTryAgainButton_sendsActionTryAgain() {
+        biometricView.mTryAgainButton.performClick()
+        waitForIdleSync()
+
+        verify(callback).onAction(AuthBiometricView.Callback.ACTION_BUTTON_TRY_AGAIN)
+        assertThat(biometricView.mTryAgainButton.visibility).isEqualTo(View.GONE)
+        assertThat(biometricView.isAuthenticating).isTrue()
+    }
+
+    @Test
+    fun testOnErrorSendsActionError() {
+        biometricView.onError(BiometricAuthenticator.TYPE_FACE, "testError")
+        waitForIdleSync()
+
+        verify(callback).onAction(eq(AuthBiometricView.Callback.ACTION_ERROR))
+    }
+
+    @Test
+    fun testOnErrorShowsMessage() {
+        // prevent error state from instantly returning to authenticating in the test
+        biometricView.mAnimationDurationHideDialog = 10_000
+
+        val message = "another error"
+        biometricView.onError(BiometricAuthenticator.TYPE_FACE, message)
+        waitForIdleSync()
+
+        assertThat(biometricView.isAuthenticating).isFalse()
+        assertThat(biometricView.isAuthenticated).isFalse()
+        assertThat(biometricView.mIndicatorView.visibility).isEqualTo(View.VISIBLE)
+        assertThat(biometricView.mIndicatorView.text).isEqualTo(message)
+    }
+
+    @Test
+    fun testBackgroundClicked_sendsActionUserCanceled() {
+        val view = View(mContext)
+        biometricView.setBackgroundView(view)
+        view.performClick()
+
+        verify(callback).onAction(eq(AuthBiometricView.Callback.ACTION_USER_CANCELED))
+    }
+
+    @Test
+    fun testBackgroundClicked_afterAuthenticated_neverSendsUserCanceled() {
+        val view = View(mContext)
+        biometricView.setBackgroundView(view)
+        biometricView.onAuthenticationSucceeded(BiometricAuthenticator.TYPE_FINGERPRINT)
+        view.performClick()
+
+        verify(callback, never())
+                .onAction(eq(AuthBiometricView.Callback.ACTION_USER_CANCELED))
+    }
+
+    @Test
+    fun testBackgroundClicked_whenSmallDialog_neverSendsUserCanceled() {
+        biometricView.mLayoutParams = AuthDialog.LayoutParams(0, 0)
+        biometricView.updateSize(AuthDialog.SIZE_SMALL)
+        val view = View(mContext)
+        biometricView.setBackgroundView(view)
+        view.performClick()
+
+        verify(callback, never()).onAction(eq(AuthBiometricView.Callback.ACTION_USER_CANCELED))
+    }
+
+    @Test
+    fun testIgnoresUselessHelp() {
+        biometricView.mAnimationDurationHideDialog = 10_000
+        biometricView.onDialogAnimatedIn()
+        waitForIdleSync()
+
+        assertThat(biometricView.isAuthenticating).isTrue()
+
+        val helpText = biometricView.mIndicatorView.text
+        biometricView.onHelp(BiometricAuthenticator.TYPE_FINGERPRINT, "")
+        waitForIdleSync()
+
+        // text should not change
+        assertThat(biometricView.mIndicatorView.text).isEqualTo(helpText)
+        verify(callback, never()).onAction(eq(AuthBiometricView.Callback.ACTION_ERROR))
+    }
+
+    @Test
+    fun testRestoresState() {
+        val requireConfirmation = true
+        biometricView.mAnimationDurationHideDialog = 10_000
+        val failureMessage = "testFailureMessage"
+        biometricView.setRequireConfirmation(requireConfirmation)
+        biometricView.onAuthenticationFailed(BiometricAuthenticator.TYPE_FACE, failureMessage)
+        waitForIdleSync()
+
+        val state = Bundle()
+        biometricView.onSaveState(state)
+        assertThat(biometricView.mTryAgainButton.visibility).isEqualTo(View.GONE)
+        assertThat(state.getInt(AuthDialog.KEY_BIOMETRIC_TRY_AGAIN_VISIBILITY))
+            .isEqualTo(View.GONE)
+        assertThat(state.getInt(AuthDialog.KEY_BIOMETRIC_STATE))
+            .isEqualTo(AuthBiometricView.STATE_ERROR)
+        assertThat(biometricView.mIndicatorView.visibility).isEqualTo(View.VISIBLE)
+        assertThat(state.getBoolean(AuthDialog.KEY_BIOMETRIC_INDICATOR_ERROR_SHOWING)).isTrue()
+        assertThat(biometricView.mIndicatorView.text).isEqualTo(failureMessage)
+        assertThat(state.getString(AuthDialog.KEY_BIOMETRIC_INDICATOR_STRING))
+            .isEqualTo(failureMessage)
+
+        // TODO: Test dialog size. Should move requireConfirmation to buildBiometricPromptBundle
+
+        // Create new dialog and restore the previous state into it
+        biometricView.destroyDialog()
+        biometricView = createView()
+        biometricView.restoreState(state)
+        biometricView.mAnimationDurationHideDialog = 10_000
+        biometricView.setRequireConfirmation(requireConfirmation)
+        waitForIdleSync()
+
+        assertThat(biometricView.mTryAgainButton.visibility).isEqualTo(View.GONE)
+        assertThat(biometricView.mIndicatorView.visibility).isEqualTo(View.VISIBLE)
+
+        // TODO: Test restored text. Currently cannot test this, since it gets restored only after
+        // dialog size is known.
+    }
+
+    @Test
+    fun testCredentialButton_whenDeviceCredentialAllowed() {
+        biometricView.destroyDialog()
+        biometricView = createView(allowDeviceCredential = true)
+
+        assertThat(biometricView.mUseCredentialButton.visibility).isEqualTo(View.VISIBLE)
+        assertThat(biometricView.mNegativeButton.visibility).isEqualTo(View.GONE)
+
+        biometricView.mUseCredentialButton.performClick()
+        waitForIdleSync()
+
+        verify(callback).onAction(AuthBiometricView.Callback.ACTION_USE_DEVICE_CREDENTIAL)
+    }
+
+    override fun waitForIdleSync() = TestableLooper.get(this).processAllMessages()
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
deleted file mode 100644
index f99b20d..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
+++ /dev/null
@@ -1,324 +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.biometrics;
-
-import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
-import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
-import static android.hardware.biometrics.BiometricManager.Authenticators;
-
-import static com.android.systemui.biometrics.AuthBiometricView.Callback.ACTION_AUTHENTICATED;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-import android.hardware.biometrics.PromptInfo;
-import android.os.Bundle;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.testing.TestableLooper.RunWithLooper;
-import android.testing.ViewUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-
-import org.junit.After;
-import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-@RunWith(AndroidTestingRunner.class)
-@RunWithLooper
-@SmallTest
-public class AuthBiometricViewTest extends SysuiTestCase {
-
-    @Rule
-    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
-
-    @Mock
-    private AuthBiometricView.Callback mCallback;
-    @Mock
-    private AuthPanelController mPanelController;
-
-    private AuthBiometricView mBiometricView;
-
-    @After
-    public void tearDown() {
-        destroyDialog();
-    }
-
-    @Test
-    public void testOnAuthenticationSucceeded_noConfirmationRequired_sendsActionAuthenticated() {
-        initDialog(false /* allowDeviceCredential */, mCallback);
-
-        // The onAuthenticated runnable is posted when authentication succeeds.
-        mBiometricView.onAuthenticationSucceeded(TYPE_FINGERPRINT);
-        waitForIdleSync();
-        assertEquals(AuthBiometricView.STATE_AUTHENTICATED, mBiometricView.mState);
-        verify(mCallback).onAction(ACTION_AUTHENTICATED);
-    }
-
-    @Test
-    public void testOnAuthenticationSucceeded_confirmationRequired_updatesDialogContents() {
-        initDialog(false /* allowDeviceCredential */, mCallback);
-
-        mBiometricView.setRequireConfirmation(true);
-        mBiometricView.onAuthenticationSucceeded(TYPE_FINGERPRINT);
-        waitForIdleSync();
-
-        // TODO: this should be tested in the subclasses
-        if (mBiometricView.supportsRequireConfirmation()) {
-            assertEquals(AuthBiometricView.STATE_PENDING_CONFIRMATION, mBiometricView.mState);
-
-            verify(mCallback, never()).onAction(anyInt());
-
-            assertEquals(View.GONE, mBiometricView.mNegativeButton.getVisibility());
-            assertEquals(View.VISIBLE, mBiometricView.mCancelButton.getVisibility());
-            assertTrue(mBiometricView.mCancelButton.isEnabled());
-
-            assertTrue(mBiometricView.mConfirmButton.isEnabled());
-            assertEquals(mContext.getText(R.string.biometric_dialog_tap_confirm),
-                    mBiometricView.mIndicatorView.getText());
-            assertEquals(View.VISIBLE, mBiometricView.mIndicatorView.getVisibility());
-        } else {
-            assertEquals(AuthBiometricView.STATE_AUTHENTICATED, mBiometricView.mState);
-            verify(mCallback).onAction(eq(ACTION_AUTHENTICATED));
-        }
-
-    }
-
-    @Test
-    public void testPositiveButton_sendsActionAuthenticated() {
-        initDialog(false /* allowDeviceCredential */, mCallback);
-
-        mBiometricView.mConfirmButton.performClick();
-        waitForIdleSync();
-
-        verify(mCallback).onAction(ACTION_AUTHENTICATED);
-        assertEquals(AuthBiometricView.STATE_AUTHENTICATED, mBiometricView.mState);
-    }
-
-    @Test
-    public void testNegativeButton_beforeAuthentication_sendsActionButtonNegative() {
-        initDialog(false /* allowDeviceCredential */, mCallback);
-
-        mBiometricView.onDialogAnimatedIn();
-        mBiometricView.mNegativeButton.performClick();
-        waitForIdleSync();
-
-        verify(mCallback).onAction(AuthBiometricView.Callback.ACTION_BUTTON_NEGATIVE);
-    }
-
-    @Test
-    public void testCancelButton_whenPendingConfirmation_sendsActionUserCanceled() {
-        initDialog(false /* allowDeviceCredential */, mCallback);
-
-        mBiometricView.setRequireConfirmation(true);
-        mBiometricView.onAuthenticationSucceeded(TYPE_FINGERPRINT);
-
-        assertEquals(View.GONE, mBiometricView.mNegativeButton.getVisibility());
-
-        mBiometricView.mCancelButton.performClick();
-        waitForIdleSync();
-
-        verify(mCallback).onAction(AuthBiometricView.Callback.ACTION_USER_CANCELED);
-    }
-
-    @Test
-    public void testTryAgainButton_sendsActionTryAgain() {
-        initDialog(false /* allowDeviceCredential */, mCallback);
-
-        mBiometricView.mTryAgainButton.performClick();
-        waitForIdleSync();
-
-        verify(mCallback).onAction(AuthBiometricView.Callback.ACTION_BUTTON_TRY_AGAIN);
-        assertEquals(AuthBiometricView.STATE_AUTHENTICATING, mBiometricView.mState);
-    }
-
-    @Test
-    @Ignore("flaky, b/189031816")
-    public void testError_sendsActionError() {
-        initDialog(false /* allowDeviceCredential */, mCallback);
-        final String testError = "testError";
-        mBiometricView.onError(TYPE_FACE, testError);
-        waitForIdleSync();
-
-        verify(mCallback).onAction(eq(AuthBiometricView.Callback.ACTION_ERROR));
-        assertEquals(AuthBiometricView.STATE_IDLE, mBiometricView.mState);
-    }
-
-    @Test
-    public void testBackgroundClicked_sendsActionUserCanceled() {
-        initDialog(false /* allowDeviceCredential */, mCallback);
-
-        View view = new View(mContext);
-        mBiometricView.setBackgroundView(view);
-        view.performClick();
-        verify(mCallback).onAction(eq(AuthBiometricView.Callback.ACTION_USER_CANCELED));
-    }
-
-    @Test
-    public void testBackgroundClicked_afterAuthenticated_neverSendsUserCanceled() {
-        initDialog(false /* allowDeviceCredential */, mCallback);
-
-        View view = new View(mContext);
-        mBiometricView.setBackgroundView(view);
-        mBiometricView.onAuthenticationSucceeded(TYPE_FINGERPRINT);
-        view.performClick();
-        verify(mCallback, never()).onAction(eq(AuthBiometricView.Callback.ACTION_USER_CANCELED));
-    }
-
-    @Test
-    public void testBackgroundClicked_whenSmallDialog_neverSendsUserCanceled() {
-        initDialog(false /* allowDeviceCredential */, mCallback);
-        mBiometricView.mLayoutParams = new AuthDialog.LayoutParams(0, 0);
-        mBiometricView.updateSize(AuthDialog.SIZE_SMALL);
-
-        View view = new View(mContext);
-        mBiometricView.setBackgroundView(view);
-        view.performClick();
-        verify(mCallback, never()).onAction(eq(AuthBiometricView.Callback.ACTION_USER_CANCELED));
-    }
-
-    @Test
-    public void testIgnoresUselessHelp() {
-        initDialog(false /* allowDeviceCredential */, mCallback);
-
-        mBiometricView.onDialogAnimatedIn();
-        waitForIdleSync();
-
-        assertEquals(AuthBiometricView.STATE_AUTHENTICATING, mBiometricView.mState);
-
-        mBiometricView.onHelp(TYPE_FINGERPRINT, "");
-        waitForIdleSync();
-
-        assertEquals("", mBiometricView.mIndicatorView.getText());
-        verify(mCallback, never()).onAction(eq(AuthBiometricView.Callback.ACTION_ERROR));
-        assertEquals(AuthBiometricView.STATE_AUTHENTICATING, mBiometricView.mState);
-    }
-
-    @Test
-    public void testRestoresState() {
-        final boolean requireConfirmation = true;
-
-        initDialog(false /* allowDeviceCredential */, mCallback, null, 10000);
-
-        final String failureMessage = "testFailureMessage";
-        mBiometricView.setRequireConfirmation(requireConfirmation);
-        mBiometricView.onAuthenticationFailed(TYPE_FACE, failureMessage);
-        waitForIdleSync();
-
-        Bundle state = new Bundle();
-        mBiometricView.onSaveState(state);
-
-        assertEquals(View.GONE, mBiometricView.mTryAgainButton.getVisibility());
-        assertEquals(View.GONE, state.getInt(AuthDialog.KEY_BIOMETRIC_TRY_AGAIN_VISIBILITY));
-
-        assertEquals(AuthBiometricView.STATE_ERROR, mBiometricView.mState);
-        assertEquals(AuthBiometricView.STATE_ERROR, state.getInt(AuthDialog.KEY_BIOMETRIC_STATE));
-
-        assertEquals(View.VISIBLE, mBiometricView.mIndicatorView.getVisibility());
-        assertTrue(state.getBoolean(AuthDialog.KEY_BIOMETRIC_INDICATOR_ERROR_SHOWING));
-
-        assertEquals(failureMessage, mBiometricView.mIndicatorView.getText());
-        assertEquals(failureMessage, state.getString(AuthDialog.KEY_BIOMETRIC_INDICATOR_STRING));
-
-        // TODO: Test dialog size. Should move requireConfirmation to buildBiometricPromptBundle
-
-        // Create new dialog and restore the previous state into it
-        destroyDialog();
-        initDialog(false /* allowDeviceCredential */, mCallback, state, 10000);
-        mBiometricView.mAnimationDurationHideDialog = 10000;
-        mBiometricView.setRequireConfirmation(requireConfirmation);
-        waitForIdleSync();
-
-        assertEquals(View.GONE, mBiometricView.mTryAgainButton.getVisibility());
-        assertEquals(AuthBiometricView.STATE_ERROR, mBiometricView.mState);
-        assertEquals(View.VISIBLE, mBiometricView.mIndicatorView.getVisibility());
-
-        // TODO: Test restored text. Currently cannot test this, since it gets restored only after
-        // dialog size is known.
-    }
-
-    @Test
-    public void testCredentialButton_whenDeviceCredentialAllowed() throws InterruptedException {
-        initDialog(true /* allowDeviceCredential */, mCallback);
-
-        assertEquals(View.VISIBLE, mBiometricView.mUseCredentialButton.getVisibility());
-        assertEquals(View.GONE, mBiometricView.mNegativeButton.getVisibility());
-        mBiometricView.mUseCredentialButton.performClick();
-        waitForIdleSync();
-
-        verify(mCallback).onAction(AuthBiometricView.Callback.ACTION_USE_DEVICE_CREDENTIAL);
-    }
-
-    private PromptInfo buildPromptInfo(boolean allowDeviceCredential) {
-        PromptInfo promptInfo = new PromptInfo();
-        promptInfo.setTitle("Title");
-        int authenticators = Authenticators.BIOMETRIC_WEAK;
-        if (allowDeviceCredential) {
-            authenticators |= Authenticators.DEVICE_CREDENTIAL;
-        } else {
-            promptInfo.setNegativeButtonText("Negative");
-        }
-        promptInfo.setAuthenticators(authenticators);
-        return promptInfo;
-    }
-
-    private void initDialog(boolean allowDeviceCredential, AuthBiometricView.Callback callback) {
-        initDialog(allowDeviceCredential, callback,
-                null /* savedState */, 0 /* hideDelay */);
-    }
-
-    private void initDialog(boolean allowDeviceCredential,
-            AuthBiometricView.Callback callback, Bundle savedState, int hideDelay) {
-        final LayoutInflater inflater = LayoutInflater.from(mContext);
-        mBiometricView = (AuthBiometricView) inflater.inflate(
-                R.layout.auth_biometric_view, null, false);
-        mBiometricView.mAnimationDurationLong = 0;
-        mBiometricView.mAnimationDurationShort = 0;
-        mBiometricView.mAnimationDurationHideDialog = hideDelay;
-        mBiometricView.setPromptInfo(buildPromptInfo(allowDeviceCredential));
-        mBiometricView.setCallback(callback);
-        mBiometricView.restoreState(savedState);
-        ViewUtils.attachView(mBiometricView);
-        mBiometricView.setPanelController(mPanelController);
-        waitForIdleSync();
-    }
-
-    private void destroyDialog() {
-        if (mBiometricView != null && mBiometricView.isAttachedToWindow()) {
-            ViewUtils.detachView(mBiometricView);
-        }
-    }
-
-    @Override
-    protected void waitForIdleSync() {
-        TestableLooper.get(this).processAllMessages();
-        super.waitForIdleSync();
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
index 52b5857..bc5a4d3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -16,13 +16,11 @@
 package com.android.systemui.biometrics
 
 import android.app.admin.DevicePolicyManager
+import android.hardware.biometrics.BiometricAuthenticator
 import android.hardware.biometrics.BiometricConstants
 import android.hardware.biometrics.BiometricManager
-import android.hardware.biometrics.ComponentInfoInternal
 import android.hardware.biometrics.PromptInfo
-import android.hardware.biometrics.SensorProperties
 import android.hardware.face.FaceSensorPropertiesInternal
-import android.hardware.fingerprint.FingerprintSensorProperties
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
 import android.os.Handler
 import android.os.IBinder
@@ -36,11 +34,11 @@
 import android.view.WindowManager
 import android.widget.ScrollView
 import androidx.test.filters.SmallTest
+import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.widget.LockPatternUtils
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.WakefulnessLifecycle
-import com.android.systemui.util.concurrency.DelayableExecutor
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
@@ -57,12 +55,12 @@
 import org.mockito.Mockito.`when` as whenever
 
 @RunWith(AndroidTestingRunner::class)
-@RunWithLooper
+@RunWithLooper(setAsMainLooper = true)
 @SmallTest
 class AuthContainerViewTest : SysuiTestCase() {
 
     @JvmField @Rule
-    var rule = MockitoJUnit.rule()
+    var mockitoRule = MockitoJUnit.rule()
 
     @Mock
     lateinit var callback: AuthDialogCallback
@@ -74,6 +72,8 @@
     lateinit var wakefulnessLifecycle: WakefulnessLifecycle
     @Mock
     lateinit var windowToken: IBinder
+    @Mock
+    lateinit var interactionJankMonitor: InteractionJankMonitor
 
     private var authContainer: TestAuthContainerView? = null
 
@@ -86,13 +86,13 @@
 
     @Test
     fun testNotifiesAnimatedIn() {
-        initializeContainer()
+        initializeFingerprintContainer()
         verify(callback).onDialogAnimatedIn()
     }
 
     @Test
     fun testIgnoresAnimatedInWhenDismissed() {
-        val container = initializeContainer(addToView = false)
+        val container = initializeFingerprintContainer(addToView = false)
         container.dismissFromSystemServer()
         waitForIdleSync()
 
@@ -107,7 +107,7 @@
 
     @Test
     fun testDismissesOnFocusLoss() {
-        val container = initializeContainer()
+        val container = initializeFingerprintContainer()
         waitForIdleSync()
 
         verify(callback).onDialogAnimatedIn()
@@ -124,7 +124,7 @@
 
     @Test
     fun testActionAuthenticated_sendsDismissedAuthenticated() {
-        val container = initializeContainer()
+        val container = initializeFingerprintContainer()
         container.mBiometricCallback.onAction(
             AuthBiometricView.Callback.ACTION_AUTHENTICATED
         )
@@ -139,7 +139,7 @@
 
     @Test
     fun testActionUserCanceled_sendsDismissedUserCanceled() {
-        val container = initializeContainer()
+        val container = initializeFingerprintContainer()
         container.mBiometricCallback.onAction(
             AuthBiometricView.Callback.ACTION_USER_CANCELED
         )
@@ -157,7 +157,7 @@
 
     @Test
     fun testActionButtonNegative_sendsDismissedButtonNegative() {
-        val container = initializeContainer()
+        val container = initializeFingerprintContainer()
         container.mBiometricCallback.onAction(
             AuthBiometricView.Callback.ACTION_BUTTON_NEGATIVE
         )
@@ -172,7 +172,9 @@
 
     @Test
     fun testActionTryAgain_sendsTryAgain() {
-        val container = initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
+        val container = initializeFingerprintContainer(
+            authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK
+        )
         container.mBiometricCallback.onAction(
             AuthBiometricView.Callback.ACTION_BUTTON_TRY_AGAIN
         )
@@ -183,8 +185,8 @@
 
     @Test
     fun testActionError_sendsDismissedError() {
-        val container = initializeContainer()
-        authContainer!!.mBiometricCallback.onAction(
+        val container = initializeFingerprintContainer()
+        container.mBiometricCallback.onAction(
             AuthBiometricView.Callback.ACTION_ERROR
         )
         waitForIdleSync()
@@ -198,8 +200,8 @@
 
     @Test
     fun testActionUseDeviceCredential_sendsOnDeviceCredentialPressed() {
-        val container = initializeContainer(
-            BiometricManager.Authenticators.BIOMETRIC_WEAK or
+        val container = initializeFingerprintContainer(
+            authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK or
                     BiometricManager.Authenticators.DEVICE_CREDENTIAL
         )
         container.mBiometricCallback.onAction(
@@ -213,8 +215,8 @@
 
     @Test
     fun testAnimateToCredentialUI_invokesStartTransitionToCredentialUI() {
-        val container = initializeContainer(
-            BiometricManager.Authenticators.BIOMETRIC_WEAK or
+        val container = initializeFingerprintContainer(
+            authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK or
                     BiometricManager.Authenticators.DEVICE_CREDENTIAL
         )
         container.animateToCredentialUI()
@@ -225,7 +227,7 @@
 
     @Test
     fun testShowBiometricUI() {
-        val container = initializeContainer()
+        val container = initializeFingerprintContainer()
 
         waitForIdleSync()
 
@@ -235,7 +237,9 @@
 
     @Test
     fun testShowCredentialUI() {
-        val container = initializeContainer(BiometricManager.Authenticators.DEVICE_CREDENTIAL)
+        val container = initializeFingerprintContainer(
+            authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL
+        )
         waitForIdleSync()
 
         assertThat(container.hasCredentialView()).isTrue()
@@ -249,7 +253,9 @@
             DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
         )
 
-        val container = initializeContainer(BiometricManager.Authenticators.DEVICE_CREDENTIAL)
+        val container = initializeFingerprintContainer(
+            authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL
+        )
         waitForIdleSync()
 
         assertThat(container.hasCredentialPatternView()).isTrue()
@@ -266,7 +272,9 @@
         // In the credential view, clicking on the background (to cancel authentication) is not
         // valid. Thus, the listener should be null, and it should not be in the accessibility
         // hierarchy.
-        val container = initializeContainer(BiometricManager.Authenticators.DEVICE_CREDENTIAL)
+        val container = initializeFingerprintContainer(
+            authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL
+        )
         waitForIdleSync()
 
         assertThat(container.hasCredentialPasswordView()).isTrue()
@@ -294,49 +302,52 @@
         assertThat((layoutParams.fitInsetsTypes and WindowInsets.Type.ime()) == 0).isTrue()
     }
 
-    private fun initializeContainer(
+    @Test
+    fun coexFaceRestartsOnTouch() {
+        val container = initializeCoexContainer()
+
+        container.onPointerDown()
+        waitForIdleSync()
+
+        container.onAuthenticationFailed(BiometricAuthenticator.TYPE_FACE, "failed")
+        waitForIdleSync()
+
+        verify(callback, never()).onTryAgainPressed()
+
+        container.onPointerDown()
+        waitForIdleSync()
+
+        verify(callback).onTryAgainPressed()
+    }
+
+    private fun initializeFingerprintContainer(
         authenticators: Int = BiometricManager.Authenticators.BIOMETRIC_WEAK,
         addToView: Boolean = true
+    ) = initializeContainer(
+        TestAuthContainerView(
+            authenticators = authenticators,
+            fingerprintProps = fingerprintSensorPropertiesInternal()
+        ),
+        addToView
+    )
+
+    private fun initializeCoexContainer(
+        authenticators: Int = BiometricManager.Authenticators.BIOMETRIC_WEAK,
+        addToView: Boolean = true
+    ) = initializeContainer(
+        TestAuthContainerView(
+            authenticators = authenticators,
+            fingerprintProps = fingerprintSensorPropertiesInternal(),
+            faceProps = faceSensorPropertiesInternal()
+        ),
+        addToView
+    )
+
+    private fun initializeContainer(
+        view: TestAuthContainerView,
+        addToView: Boolean
     ): TestAuthContainerView {
-        val config = AuthContainerView.Config()
-        config.mContext = mContext
-        config.mCallback = callback
-        config.mSensorIds = intArrayOf(0)
-        config.mSkipAnimation = true
-        config.mPromptInfo = PromptInfo()
-        config.mPromptInfo.authenticators = authenticators
-        val componentInfo = listOf(
-            ComponentInfoInternal(
-                "faceSensor" /* componentId */,
-                "vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */,
-                "00000001" /* serialNumber */, "" /* softwareVersion */
-            ),
-            ComponentInfoInternal(
-                "matchingAlgorithm" /* componentId */,
-                "" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */,
-                "vendor/version/revision" /* softwareVersion */
-            )
-        )
-        val fpProps = listOf(
-            FingerprintSensorPropertiesInternal(
-                0,
-                SensorProperties.STRENGTH_STRONG,
-                5 /* maxEnrollmentsPerUser */,
-                componentInfo,
-                FingerprintSensorProperties.TYPE_REAR,
-                false /* resetLockoutRequiresHardwareAuthToken */
-            )
-        )
-        authContainer = TestAuthContainerView(
-            config,
-            fpProps,
-            listOf(),
-            wakefulnessLifecycle,
-            userManager,
-            lockPatternUtils,
-            Handler(TestableLooper.get(this).looper),
-            FakeExecutor(FakeSystemClock())
-        )
+        authContainer = view
 
         if (addToView) {
             authContainer!!.addToView()
@@ -346,27 +357,35 @@
     }
 
     private inner class TestAuthContainerView(
-        config: Config,
-        fpProps: List<FingerprintSensorPropertiesInternal>,
-        faceProps: List<FaceSensorPropertiesInternal>,
-        wakefulnessLifecycle: WakefulnessLifecycle,
-        userManager: UserManager,
-        lockPatternUtils: LockPatternUtils,
-        mainHandler: Handler,
-        bgExecutor: DelayableExecutor
+        authenticators: Int = BiometricManager.Authenticators.BIOMETRIC_WEAK,
+        fingerprintProps: List<FingerprintSensorPropertiesInternal> = listOf(),
+        faceProps: List<FaceSensorPropertiesInternal> = listOf()
     ) : AuthContainerView(
-        config, fpProps, faceProps,
-        wakefulnessLifecycle, userManager, lockPatternUtils, mainHandler, bgExecutor
+        Config().apply {
+            mContext = [email protected]
+            mCallback = callback
+            mSensorIds = (fingerprintProps.map { it.sensorId } +
+                faceProps.map { it.sensorId }).toIntArray()
+            mSkipAnimation = true
+            mPromptInfo = PromptInfo().apply {
+                this.authenticators = authenticators
+            }
+        },
+        fingerprintProps,
+        faceProps,
+        wakefulnessLifecycle,
+        userManager,
+        lockPatternUtils,
+        interactionJankMonitor,
+        Handler(TestableLooper.get(this).looper),
+        FakeExecutor(FakeSystemClock())
     ) {
         override fun postOnAnimation(runnable: Runnable) {
             runnable.run()
         }
     }
 
-    override fun waitForIdleSync() {
-        TestableLooper.get(this).processAllMessages()
-        super.waitForIdleSync()
-    }
+    override fun waitForIdleSync() = TestableLooper.get(this).processAllMessages()
 
     private fun AuthContainerView.addToView() {
         ViewUtils.attachView(this)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index eefc412..d948a99 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -77,6 +77,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.R;
+import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
@@ -150,6 +151,8 @@
     private LockPatternUtils mLockPatternUtils;
     @Mock
     private StatusBarStateController mStatusBarStateController;
+    @Mock
+    private InteractionJankMonitor mInteractionJankMonitor;
     @Captor
     ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback> mAuthenticatorsRegisteredCaptor;
     @Captor
@@ -788,8 +791,8 @@
             super(context, execution, commandQueue, activityTaskManager, windowManager,
                     fingerprintManager, faceManager, udfpsControllerFactory,
                     sidefpsControllerFactory, mDisplayManager, mWakefulnessLifecycle,
-                    mUserManager, mLockPatternUtils, statusBarStateController, mHandler,
-                    mBackgroundExecutor);
+                    mUserManager, mLockPatternUtils, statusBarStateController,
+                    mInteractionJankMonitor, mHandler, mBackgroundExecutor);
         }
 
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
index 7f8656c..d6afd6d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
@@ -292,7 +292,7 @@
 
     @Test
     @RunWithLooper(setAsMainLooper = true)
-    fun testAnimatorRunWhenWakeAndUnlock() {
+    fun testAnimatorRunWhenWakeAndUnlock_fingerprint() {
         val fpsLocation = PointF(5f, 5f)
         `when`(authController.fingerprintSensorLocation).thenReturn(fpsLocation)
         controller.onViewAttached()
@@ -309,6 +309,25 @@
     }
 
     @Test
+    @RunWithLooper(setAsMainLooper = true)
+    fun testAnimatorRunWhenWakeAndUnlock_faceUdfpsFingerDown() {
+        val faceLocation = PointF(5f, 5f)
+        `when`(authController.faceAuthSensorLocation).thenReturn(faceLocation)
+        controller.onViewAttached()
+        `when`(keyguardUpdateMonitor.isKeyguardVisible).thenReturn(true)
+        `when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true)
+        `when`(authController.isUdfpsFingerDown).thenReturn(true)
+
+        controller.showUnlockRipple(BiometricSourceType.FACE)
+        assertTrue("reveal didn't start on keyguardFadingAway",
+                controller.startLightRevealScrimOnKeyguardFadingAway)
+        `when`(keyguardStateController.isKeyguardFadingAway).thenReturn(true)
+        controller.onKeyguardFadingAwayChanged()
+        assertFalse("reveal triggers multiple times",
+                controller.startLightRevealScrimOnKeyguardFadingAway)
+    }
+
+    @Test
     fun testUpdateRippleColor() {
         controller.onViewAttached()
         val captor = ArgumentCaptor
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
index 92c2a1b..8820c16 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
@@ -16,29 +16,123 @@
 
 package com.android.systemui.biometrics
 
+import android.annotation.IdRes
+import android.content.Context
+import android.hardware.biometrics.BiometricManager
 import android.hardware.biometrics.ComponentInfoInternal
-import android.hardware.biometrics.SensorLocationInternal
+import android.hardware.biometrics.PromptInfo
 import android.hardware.biometrics.SensorProperties
+import android.hardware.face.FaceSensorPropertiesInternal
+import android.hardware.face.FaceSensorProperties
 import android.hardware.fingerprint.FingerprintSensorProperties
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
+import android.os.Bundle
 
-/** Creates properties from the sensor location with test values. */
-fun SensorLocationInternal.asFingerprintSensorProperties(
-    sensorId: Int = 22,
-    @SensorProperties.Strength sensorStrength: Int = SensorProperties.STRENGTH_WEAK,
-    @FingerprintSensorProperties.SensorType sensorType: Int =
-        FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
-    maxEnrollmentsPerUser: Int = 1,
-    halControlsIllumination: Boolean = true,
-    info: List<ComponentInfoInternal> = listOf(ComponentInfoInternal("a", "b", "c", "d", "e")),
-    resetLockoutRequiresHardwareAuthToken: Boolean = false
-) = FingerprintSensorPropertiesInternal(
-    sensorId,
-    sensorStrength,
-    maxEnrollmentsPerUser,
-    info,
-    sensorType,
-    halControlsIllumination,
-    resetLockoutRequiresHardwareAuthToken,
-    listOf(this)
-)
+import android.testing.ViewUtils
+import android.view.LayoutInflater
+
+/**
+ * Inflate the given BiometricPrompt layout and initialize it with test parameters.
+ *
+ * This attaches the view so be sure to call [destroyDialog] at the end of the test.
+ */
+@IdRes
+internal fun <T : AuthBiometricView> Int.asTestAuthBiometricView(
+    context: Context,
+    callback: AuthBiometricView.Callback,
+    panelController: AuthPanelController,
+    allowDeviceCredential: Boolean = false,
+    savedState: Bundle? = null,
+    hideDelay: Int = 0
+): T {
+    val view = LayoutInflater.from(context).inflate(this, null, false) as T
+    view.mAnimationDurationLong = 0
+    view.mAnimationDurationShort = 0
+    view.mAnimationDurationHideDialog = hideDelay
+    view.setPromptInfo(buildPromptInfo(allowDeviceCredential))
+    view.setCallback(callback)
+    view.restoreState(savedState)
+    view.setPanelController(panelController)
+
+    ViewUtils.attachView(view)
+
+    return view
+}
+
+private fun buildPromptInfo(allowDeviceCredential: Boolean): PromptInfo {
+    val promptInfo = PromptInfo()
+    promptInfo.title = "Title"
+    var authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK
+    if (allowDeviceCredential) {
+        authenticators = authenticators or BiometricManager.Authenticators.DEVICE_CREDENTIAL
+    } else {
+        promptInfo.negativeButtonText = "Negative"
+    }
+    promptInfo.authenticators = authenticators
+    return promptInfo
+}
+
+/** Detach the view, if needed. */
+internal fun AuthBiometricView?.destroyDialog() {
+    if (this != null && isAttachedToWindow) {
+        ViewUtils.detachView(this)
+    }
+}
+
+/** Create [FingerprintSensorPropertiesInternal] for a test. */
+internal fun fingerprintSensorPropertiesInternal(
+    ids: List<Int> = listOf(0)
+): List<FingerprintSensorPropertiesInternal> {
+    val componentInfo = listOf(
+            ComponentInfoInternal(
+                    "fingerprintSensor" /* componentId */,
+                    "vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */,
+                    "00000001" /* serialNumber */, "" /* softwareVersion */
+            ),
+            ComponentInfoInternal(
+                    "matchingAlgorithm" /* componentId */,
+                    "" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */,
+                    "vendor/version/revision" /* softwareVersion */
+            )
+    )
+    return ids.map { id ->
+        FingerprintSensorPropertiesInternal(
+                id,
+                SensorProperties.STRENGTH_STRONG,
+                5 /* maxEnrollmentsPerUser */,
+                componentInfo,
+                FingerprintSensorProperties.TYPE_REAR,
+                false /* resetLockoutRequiresHardwareAuthToken */
+        )
+    }
+}
+
+/** Create [FaceSensorPropertiesInternal] for a test. */
+internal fun faceSensorPropertiesInternal(
+    ids: List<Int> = listOf(1)
+): List<FaceSensorPropertiesInternal> {
+    val componentInfo = listOf(
+            ComponentInfoInternal(
+                    "faceSensor" /* componentId */,
+                    "vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */,
+                    "00000001" /* serialNumber */, "" /* softwareVersion */
+            ),
+            ComponentInfoInternal(
+                    "matchingAlgorithm" /* componentId */,
+                    "" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */,
+                    "vendor/version/revision" /* softwareVersion */
+            )
+    )
+    return ids.map { id ->
+        FaceSensorPropertiesInternal(
+                id,
+                SensorProperties.STRENGTH_STRONG,
+                2 /* maxEnrollmentsPerUser */,
+                componentInfo,
+                FaceSensorProperties.TYPE_RGB,
+                true /* supportsFaceDetection */,
+                true /* supportsSelfIllumination */,
+                false /* resetLockoutRequiresHardwareAuthToken */
+        )
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index 21b8baf..d7a0a0a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -592,6 +592,7 @@
         // Configure UdfpsView to accept the ACTION_DOWN event
         when(mUdfpsView.isIlluminationRequested()).thenReturn(false);
         when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
+        when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
 
         // GIVEN that the overlay is showing
         mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID,
@@ -609,6 +610,7 @@
         mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
         mBiometricsExecutor.runAllReady();
         moveEvent.recycle();
+        mFgExecutor.runAllReady();
         // THEN FingerprintManager is notified about onPointerDown
         verify(mAlternateTouchProvider).onPointerDown(eq(TEST_REQUEST_ID), eq(0), eq(0), eq(0f),
                 eq(0f));
@@ -618,6 +620,7 @@
         // AND illumination begins
         verify(mUdfpsView).startIllumination(mOnIlluminatedRunnableCaptor.capture());
         verify(mLatencyTracker, never()).onActionEnd(eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE));
+        verify(mKeyguardUpdateMonitor).onUdfpsPointerDown(eq((int) TEST_REQUEST_ID));
         // AND onIlluminatedRunnable notifies FingerprintManager about onUiReady
         mOnIlluminatedRunnableCaptor.getValue().run();
         mBiometricsExecutor.runAllReady();
@@ -636,6 +639,7 @@
         when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
         // WHEN fingerprint is requested because of AOD interrupt
         mUdfpsController.onAodInterrupt(0, 0, 2f, 3f);
+        mFgExecutor.runAllReady();
         // THEN illumination begins
         // AND onIlluminatedRunnable that notifies FingerprintManager is set
         verify(mUdfpsView).startIllumination(mOnIlluminatedRunnableCaptor.capture());
@@ -645,6 +649,7 @@
                 eq(0), eq(0), eq(3f) /* minor */, eq(2f) /* major */);
         verify(mFingerprintManager, never()).onPointerDown(anyLong(), anyInt(), anyInt(), anyInt(),
                 anyFloat(), anyFloat());
+        verify(mKeyguardUpdateMonitor).onUdfpsPointerDown(eq((int) TEST_REQUEST_ID));
     }
 
     @Test
@@ -672,6 +677,7 @@
         mFgExecutor.runAllReady();
         when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
         mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
+        mFgExecutor.runAllReady();
         when(mUdfpsView.isIlluminationRequested()).thenReturn(true);
         // WHEN it times out
         mFgExecutor.advanceClockToNext();
@@ -740,12 +746,12 @@
                 anyString(),
                 any(),
                 eq("udfps-onStart-click"),
-                eq(UdfpsController.VIBRATION_ATTRIBUTES));
+                eq(UdfpsController.UDFPS_VIBRATION_ATTRIBUTES));
 
         // THEN make sure vibration attributes has so that it always will play the haptic,
         // even in battery saver mode
         assertEquals(VibrationAttributes.USAGE_COMMUNICATION_REQUEST,
-                UdfpsController.VIBRATION_ATTRIBUTES.getUsage());
+                UdfpsController.UDFPS_VIBRATION_ATTRIBUTES.getUsage());
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java
index cd646c6..78fb5b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java
@@ -70,7 +70,7 @@
         assertEquals(970,
                 UdfpsDialogMeasureAdapter.calculateBottomSpacerHeightForPortrait(
                         props, displayHeightPx, textIndicatorHeightPx, buttonBarHeightPx,
-                        dialogBottomMarginPx, navbarHeightPx
+                        dialogBottomMarginPx, navbarHeightPx, 1.0f /* resolutionScale */
                 ));
     }
 
@@ -135,6 +135,7 @@
 
         assertEquals(1205,
                 UdfpsDialogMeasureAdapter.calculateHorizontalSpacerWidthForLandscape(
-                        props, displayWidthPx, dialogMarginPx, navbarHorizontalInsetPx));
+                        props, displayWidthPx, dialogMarginPx, navbarHorizontalInsetPx,
+                        1.0f /* resolutionScale */));
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
index 0a1e45c..9ffc5a5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
@@ -461,7 +461,8 @@
                     /* reportsTouchCoordinate*/ false,
                     /* requiresTouchscreen */ false,
                     /* ignoresSetting */ false,
-                    requiresTouchScreen);
+                    requiresTouchScreen,
+                    /* immediatelyReRegister */ true);
         }
 
         public TriggerSensor createDozeSensor(
@@ -477,7 +478,8 @@
                     /* reportsTouchCoordinate*/ false,
                     /* requiresTouchscreen */ false,
                     /* ignoresSetting */ false,
-                    /* requiresTouchScreen */false);
+                    /* requiresTouchScreen */ false,
+                    /* immediatelyReRegister*/ true);
         }
 
         /**
@@ -492,7 +494,8 @@
                     /* reportsTouchCoordinate*/ false,
                     /* requiresTouchscreen */ false,
                     /* ignoresSetting */ true,
-                    /* requiresProx */false,
+                    /* requiresProx */ false,
+                    /* immediatelyReRegister */ true,
                     posture);
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index a80aed7..8a36a68 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -186,6 +186,31 @@
     }
 
     @Test
+    @TestableLooper.RunWithLooper(setAsMainLooper = true)
+    public void restoreBouncerWhenSimLockedAndKeyguardIsGoingAway_initiallyNotShowing() {
+        // When showing and provisioned
+        mViewMediator.onSystemReady();
+        when(mUpdateMonitor.isDeviceProvisioned()).thenReturn(true);
+        mViewMediator.setShowingLocked(false);
+
+        // and a SIM becomes locked and requires a PIN
+        mViewMediator.mUpdateCallback.onSimStateChanged(
+                1 /* subId */,
+                0 /* slotId */,
+                TelephonyManager.SIM_STATE_PIN_REQUIRED);
+
+        // and the keyguard goes away
+        mViewMediator.setShowingLocked(false);
+        when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(false);
+        mViewMediator.mUpdateCallback.onKeyguardVisibilityChanged(false);
+
+        TestableLooper.get(this).processAllMessages();
+
+        // then make sure it comes back
+        verify(mStatusBarKeyguardViewManager, atLeast(1)).show(null);
+    }
+
+    @Test
     public void testBouncerPrompt_deviceLockedByAdmin() {
         // GIVEN no trust agents enabled and biometrics aren't enrolled
         when(mUpdateMonitor.isTrustUsuallyManaged(anyInt())).thenReturn(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
index 9a01464..a8c72dd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
@@ -25,9 +25,9 @@
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.View
+import android.view.ViewGroup
 import android.view.WindowManager
 import android.widget.ImageView
-import android.widget.LinearLayout
 import android.widget.TextView
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.testing.UiEventLoggerFake
@@ -620,22 +620,22 @@
         verify(windowManager).removeView(any())
     }
 
-    private fun LinearLayout.getAppIconView() = this.requireViewById<ImageView>(R.id.app_icon)
+    private fun ViewGroup.getAppIconView() = this.requireViewById<ImageView>(R.id.app_icon)
 
-    private fun LinearLayout.getChipText(): String =
+    private fun ViewGroup.getChipText(): String =
         (this.requireViewById<TextView>(R.id.text)).text as String
 
-    private fun LinearLayout.getLoadingIconVisibility(): Int =
+    private fun ViewGroup.getLoadingIconVisibility(): Int =
         this.requireViewById<View>(R.id.loading).visibility
 
-    private fun LinearLayout.getUndoButton(): View = this.requireViewById(R.id.undo)
+    private fun ViewGroup.getUndoButton(): View = this.requireViewById(R.id.undo)
 
-    private fun LinearLayout.getFailureIcon(): View = this.requireViewById(R.id.failure_icon)
+    private fun ViewGroup.getFailureIcon(): View = this.requireViewById(R.id.failure_icon)
 
-    private fun getChipView(): LinearLayout {
+    private fun getChipView(): ViewGroup {
         val viewCaptor = ArgumentCaptor.forClass(View::class.java)
         verify(windowManager).addView(viewCaptor.capture(), any())
-        return viewCaptor.value as LinearLayout
+        return viewCaptor.value as ViewGroup
     }
 
     /** Helper method providing default parameters to not clutter up the tests. */
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index d394d7d..d67e26f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -45,6 +45,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -59,6 +60,7 @@
 import android.content.Intent;
 import android.content.pm.UserInfo;
 import android.graphics.Color;
+import android.hardware.biometrics.BiometricFaceConstants;
 import android.hardware.biometrics.BiometricSourceType;
 import android.hardware.face.FaceManager;
 import android.hardware.fingerprint.FingerprintManager;
@@ -69,6 +71,7 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityManager;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
@@ -106,6 +109,9 @@
 
 import java.text.NumberFormat;
 import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
@@ -119,7 +125,6 @@
 
     private static final int TEST_STRING_RES = R.string.keyguard_indication_trust_unlocked;
 
-    private String mKeyguardTryFingerprintMsg;
     private String mDisclosureWithOrganization;
     private String mDisclosureGeneric;
     private String mFinancedDisclosureWithOrganization;
@@ -159,6 +164,8 @@
     @Mock
     private KeyguardBypassController mKeyguardBypassController;
     @Mock
+    private AccessibilityManager mAccessibilityManager;
+    @Mock
     private ScreenLifecycle mScreenLifecycle;
     @Captor
     private ArgumentCaptor<DockManager.AlignmentStateListener> mAlignmentListener;
@@ -198,7 +205,6 @@
         mContext.addMockSystemService(UserManager.class, mUserManager);
         mContext.addMockSystemService(Context.TRUST_SERVICE, mock(TrustManager.class));
         mContext.addMockSystemService(Context.FINGERPRINT_SERVICE, mock(FingerprintManager.class));
-        mKeyguardTryFingerprintMsg = mContext.getString(R.string.keyguard_try_fingerprint);
         mDisclosureWithOrganization = mContext.getString(R.string.do_disclosure_with_name,
                 ORGANIZATION_NAME);
         mDisclosureGeneric = mContext.getString(R.string.do_disclosure_generic);
@@ -249,7 +255,8 @@
                 mKeyguardStateController, mStatusBarStateController, mKeyguardUpdateMonitor,
                 mDockManager, mBroadcastDispatcher, mDevicePolicyManager, mIBatteryStats,
                 mUserManager, mExecutor, mExecutor,  mFalsingManager, mLockPatternUtils,
-                mScreenLifecycle, mIActivityManager, mKeyguardBypassController);
+                mScreenLifecycle, mIActivityManager, mKeyguardBypassController,
+                mAccessibilityManager);
         mController.init();
         mController.setIndicationArea(mIndicationArea);
         verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
@@ -578,6 +585,106 @@
     }
 
     @Test
+    public void faceErrorTimeout_whenFingerprintEnrolled_doesNotShowMessage() {
+        createController();
+        when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
+                0)).thenReturn(true);
+        String message = "A message";
+
+        mController.setVisible(true);
+        mController.getKeyguardCallback().onBiometricError(
+                FaceManager.FACE_ERROR_TIMEOUT, message, BiometricSourceType.FACE);
+        verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE);
+    }
+
+    @Test
+    public void sendFaceHelpMessages_fingerprintEnrolled() {
+        createController();
+
+        // GIVEN fingerprint enrolled
+        when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
+                0)).thenReturn(true);
+
+        // WHEN help messages received that are allowed to show
+        final String helpString = "helpString";
+        final int[] msgIds = new int[]{
+                BiometricFaceConstants.FACE_ACQUIRED_MOUTH_COVERING_DETECTED,
+                BiometricFaceConstants.FACE_ACQUIRED_DARK_GLASSES_DETECTED
+        };
+        Set<CharSequence> messages = new HashSet<>();
+        for (int msgId : msgIds) {
+            final String message = helpString + msgId;
+            messages.add(message);
+            mKeyguardUpdateMonitorCallback.onBiometricHelp(
+                    msgId, message, BiometricSourceType.FACE);
+        }
+
+        // THEN FACE_ACQUIRED_MOUTH_COVERING_DETECTED and DARK_GLASSES help messages shown
+        verifyIndicationMessages(INDICATION_TYPE_BIOMETRIC_MESSAGE,
+                messages);
+    }
+
+    @Test
+    public void doNotSendMostFaceHelpMessages_fingerprintEnrolled() {
+        createController();
+
+        // GIVEN fingerprint enrolled
+        when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
+                0)).thenReturn(true);
+
+        // WHEN help messages received that aren't supposed to show
+        final String helpString = "helpString";
+        final int[] msgIds = new int[]{
+                BiometricFaceConstants.FACE_ACQUIRED_FACE_OBSCURED,
+                BiometricFaceConstants.FACE_ACQUIRED_TOO_RIGHT,
+                BiometricFaceConstants.FACE_ACQUIRED_TOO_LEFT,
+                BiometricFaceConstants.FACE_ACQUIRED_TOO_HIGH,
+                BiometricFaceConstants.FACE_ACQUIRED_TOO_LOW,
+                BiometricFaceConstants.FACE_ACQUIRED_TOO_BRIGHT,
+                BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK
+        };
+        for (int msgId : msgIds) {
+            mKeyguardUpdateMonitorCallback.onBiometricHelp(
+                    msgId,  helpString + msgId, BiometricSourceType.FACE);
+        }
+
+        // THEN no messages shown
+        verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE);
+    }
+
+    @Test
+    public void sendAllFaceHelpMessages_fingerprintNotEnrolled() {
+        createController();
+
+        // GIVEN fingerprint NOT enrolled
+        when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
+                0)).thenReturn(false);
+
+        // WHEN help messages received
+        final Set<CharSequence> helpStrings = new HashSet<>();
+        final String helpString = "helpString";
+        final int[] msgIds = new int[]{
+                BiometricFaceConstants.FACE_ACQUIRED_FACE_OBSCURED,
+                BiometricFaceConstants.FACE_ACQUIRED_DARK_GLASSES_DETECTED,
+                BiometricFaceConstants.FACE_ACQUIRED_TOO_RIGHT,
+                BiometricFaceConstants.FACE_ACQUIRED_TOO_LEFT,
+                BiometricFaceConstants.FACE_ACQUIRED_TOO_HIGH,
+                BiometricFaceConstants.FACE_ACQUIRED_TOO_LOW,
+                BiometricFaceConstants.FACE_ACQUIRED_TOO_BRIGHT,
+                BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK
+        };
+        for (int msgId : msgIds) {
+            final String numberedHelpString = helpString + msgId;
+            mKeyguardUpdateMonitorCallback.onBiometricHelp(
+                    msgId,  numberedHelpString, BiometricSourceType.FACE);
+            helpStrings.add(numberedHelpString);
+        }
+
+        // THEN message shown for each call
+        verifyIndicationMessages(INDICATION_TYPE_BIOMETRIC_MESSAGE, helpStrings);
+    }
+
+    @Test
     public void updateMonitor_listenerUpdatesIndication() {
         createController();
         String restingIndication = "Resting indication";
@@ -846,10 +953,84 @@
                 trustGrantedMsg);
     }
 
+    @Test
+    public void nonBypassFaceSuccess_touchExplorationEnabled_showsSwipeToOpen() {
+        // GIVEN non bypass face auth and touch exploration is enabled
+        when(mKeyguardBypassController.canBypass()).thenReturn(false);
+        when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+        createController();
+        String swipeToOpen = mContext.getString(R.string.keyguard_unlock);
+        mController.setVisible(true);
+
+        // WHEN face authenticated
+        mController.getKeyguardCallback().onBiometricAuthenticated(0,
+                BiometricSourceType.FACE, false);
+
+        // THEN show 'swipe up to open' message
+        verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, swipeToOpen);
+    }
+
+    @Test
+    public void nonBypassFaceSuccess_a11yEnabled_showsSwipeToOpen() {
+        // GIVEN non bypass face auth and a11y is enabled
+        when(mKeyguardBypassController.canBypass()).thenReturn(false);
+        when(mAccessibilityManager.isEnabled()).thenReturn(true);
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+        createController();
+        String swipeToOpen = mContext.getString(R.string.keyguard_unlock);
+        mController.setVisible(true);
+
+        // WHEN face auth is successful
+        mController.getKeyguardCallback().onBiometricAuthenticated(0,
+                BiometricSourceType.FACE, false);
+
+        // THEN show 'swipe up to open' message
+        verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, swipeToOpen);
+    }
+
+    @Test
+    public void coEx_nonBypassFaceSuccess_showsPressLockIcon() {
+        // GIVEN udfps is supported, non-bypass face auth, and no a11y enabled
+        when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
+        when(mKeyguardBypassController.canBypass()).thenReturn(false);
+        when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true);
+        when(mAccessibilityManager.isEnabled()).thenReturn(false);
+        when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+        when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+                .thenReturn(true);
+        createController();
+        mController.setVisible(true);
+
+        // WHEN face auth succeeds
+        mController.getKeyguardCallback().onBiometricAuthenticated(0,
+                BiometricSourceType.FACE, false);
+
+        // THEN press unlock icon to open message shows
+        String pressLockIcon = mContext.getString(R.string.keyguard_face_successful_unlock_press);
+        verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, pressLockIcon);
+
+        assertThat(mTextView.getText()).isNotEqualTo(pressLockIcon);
+    }
+
     private void sendUpdateDisclosureBroadcast() {
         mBroadcastReceiver.onReceive(mContext, new Intent());
     }
 
+    private void verifyIndicationMessages(int type, Set<CharSequence> messages) {
+        verify(mRotateTextViewController, times(messages.size())).updateIndication(eq(type),
+                mKeyguardIndicationCaptor.capture(), anyBoolean());
+        List<KeyguardIndication> kis = mKeyguardIndicationCaptor.getAllValues();
+
+        for (KeyguardIndication ki : kis) {
+            final CharSequence msg = ki.getMessage();
+            assertTrue(messages.contains(msg)); // check message is shown
+            messages.remove(msg);
+        }
+        assertThat(messages.size()).isEqualTo(0); // check that all messages accounted for (removed)
+    }
+
     private void verifyIndicationMessage(int type, String message) {
         verify(mRotateTextViewController).updateIndication(eq(type),
                 mKeyguardIndicationCaptor.capture(), anyBoolean());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
new file mode 100644
index 0000000..5f57695
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2022 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.notification.row
+
+import android.annotation.ColorInt
+import android.graphics.Color
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import android.view.View
+import androidx.test.filters.SmallTest
+import com.android.settingslib.Utils
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.FakeShadowView
+import com.android.systemui.statusbar.notification.NotificationUtils
+import com.android.systemui.util.mockito.mock
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper
+class ActivatableNotificationViewTest : SysuiTestCase() {
+    private val mContentView: View = mock()
+    private lateinit var mView: ActivatableNotificationView
+
+    @ColorInt
+    private var mNormalColor = 0
+
+    @Before
+    fun setUp() {
+        mView = object : ActivatableNotificationView(mContext, null) {
+
+            init {
+                onFinishInflate()
+            }
+
+            override fun getContentView(): View {
+                return mContentView
+            }
+
+            override fun <T : View> findViewTraversal(id: Int): T? = when (id) {
+                R.id.backgroundNormal -> mock<NotificationBackgroundView>()
+                R.id.fake_shadow -> mock<FakeShadowView>()
+                else -> null
+            } as T?
+        }
+        mNormalColor =
+            Utils.getColorAttrDefaultColor(mContext, com.android.internal.R.attr.colorSurface)
+    }
+
+    @Test
+    fun testBackgroundBehaviors() {
+        // Color starts with the normal color
+        mView.updateBackgroundColors()
+        assertThat(mView.currentBackgroundTint).isEqualTo(mNormalColor)
+
+        // Setting a tint changes the background to that color specifically
+        mView.setTintColor(Color.BLUE)
+        assertThat(mView.currentBackgroundTint).isEqualTo(Color.BLUE)
+
+        // Setting an override tint blends with the previous tint
+        mView.setOverrideTintColor(Color.RED, 0.5f)
+        assertThat(mView.currentBackgroundTint)
+            .isEqualTo(NotificationUtils.interpolateColors(Color.BLUE, Color.RED, 0.5f))
+
+        // Updating the background colors resets tints, as those won't match the latest theme
+        mView.updateBackgroundColors()
+        assertThat(mView.currentBackgroundTint).isEqualTo(mNormalColor)
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
index 6864c65..e5b6286 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
@@ -51,6 +51,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
+import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import org.junit.Before;
@@ -115,6 +116,8 @@
     private LatencyTracker mLatencyTracker;
     @Mock
     private ScreenOffAnimationController mScreenOffAnimationController;
+    @Mock
+    private VibratorHelper mVibratorHelper;
     private BiometricUnlockController mBiometricUnlockController;
 
     @Before
@@ -128,7 +131,6 @@
         when(mKeyguardBypassController.onBiometricAuthenticated(any(), anyBoolean()))
                 .thenReturn(true);
         when(mAuthController.isUdfpsFingerDown()).thenReturn(false);
-        when(mKeyguardBypassController.canPlaySubtleWindowAnimations()).thenReturn(true);
         mDependency.injectTestDependency(NotificationMediaManager.class, mMediaManager);
         mBiometricUnlockController = new BiometricUnlockController(mDozeScrimController,
                 mKeyguardViewMediator, mScrimController, mShadeController,
@@ -137,7 +139,7 @@
                 mMetricsLogger, mDumpManager, mPowerManager,
                 mNotificationMediaManager, mWakefulnessLifecycle, mScreenLifecycle,
                 mAuthController, mStatusBarStateController, mKeyguardUnlockAnimationController,
-                mSessionTracker, mLatencyTracker, mScreenOffAnimationController);
+                mSessionTracker, mLatencyTracker, mScreenOffAnimationController, mVibratorHelper);
         mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
         mBiometricUnlockController.setBiometricModeListener(mBiometricModeListener);
     }
@@ -258,11 +260,9 @@
         mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
                 BiometricSourceType.FACE, true /* isStrongBiometric */);
 
-        verify(mShadeController, never()).animateCollapsePanels(anyInt(), anyBoolean(),
-                anyBoolean(), anyFloat());
         verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(eq(false));
         assertThat(mBiometricUnlockController.getMode())
-                .isEqualTo(BiometricUnlockController.MODE_UNLOCK_FADING);
+                .isEqualTo(BiometricUnlockController.MODE_UNLOCK_COLLAPSING);
     }
 
     @Test
@@ -277,11 +277,9 @@
         mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
                 BiometricSourceType.FACE, true /* isStrongBiometric */);
 
-        verify(mShadeController, never()).animateCollapsePanels(anyInt(), anyBoolean(),
-                anyBoolean(), anyFloat());
         verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(eq(false));
         assertThat(mBiometricUnlockController.getMode())
-            .isEqualTo(BiometricUnlockController.MODE_UNLOCK_FADING);
+            .isEqualTo(BiometricUnlockController.MODE_UNLOCK_COLLAPSING);
     }
 
     @Test
@@ -378,21 +376,6 @@
     }
 
     @Test
-    public void onBiometricAuthenticated_whenBypassOnBouncer_respectsCanPlaySubtleAnim() {
-        when(mUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
-        when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
-        when(mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing()).thenReturn(true);
-        // the value of isStrongBiometric doesn't matter here since we only care about the returned
-        // value of isUnlockingWithBiometricAllowed()
-        mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
-                BiometricSourceType.FACE, true /* isStrongBiometric */);
-
-        verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(eq(false));
-        assertThat(mBiometricUnlockController.getMode())
-                .isEqualTo(BiometricUnlockController.MODE_UNLOCK_FADING);
-    }
-
-    @Test
     public void onBiometricAuthenticated_whenFaceAndPulsing_dontDismissKeyguard() {
         reset(mUpdateMonitor);
         reset(mStatusBarKeyguardViewManager);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index 2faff0c..ef681a5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -129,7 +129,6 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
 import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.init.NotificationsController;
 import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
@@ -159,7 +158,6 @@
 import com.android.systemui.util.concurrency.MessageRouterImpl;
 import com.android.systemui.util.time.FakeSystemClock;
 import com.android.systemui.volume.VolumeComponent;
-import com.android.systemui.wmshell.BubblesManager;
 import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.startingsurface.StartingSurface;
 
@@ -223,7 +221,6 @@
     @Mock private NotificationShadeWindowView mNotificationShadeWindowView;
     @Mock private BroadcastDispatcher mBroadcastDispatcher;
     @Mock private AssistManager mAssistManager;
-    @Mock private NotifShadeEventSource mNotifShadeEventSource;
     @Mock private NotificationEntryManager mNotificationEntryManager;
     @Mock private NotificationGutsManager mNotificationGutsManager;
     @Mock private NotificationMediaManager mNotificationMediaManager;
@@ -240,15 +237,12 @@
     @Mock private StatusBarWindowStateController mStatusBarWindowStateController;
     @Mock private NotificationViewHierarchyManager mNotificationViewHierarchyManager;
     @Mock private UserSwitcherController mUserSwitcherController;
-    @Mock private NetworkController mNetworkController;
-    @Mock private BubblesManager mBubblesManager;
     @Mock private Bubbles mBubbles;
     @Mock private NotificationShadeWindowController mNotificationShadeWindowController;
     @Mock private NotificationIconAreaController mNotificationIconAreaController;
     @Mock private NotificationShadeWindowViewController mNotificationShadeWindowViewController;
     @Mock private DozeParameters mDozeParameters;
     @Mock private Lazy<LockscreenWallpaper> mLockscreenWallpaperLazy;
-    @Mock private LockscreenGestureLogger mLockscreenGestureLogger;
     @Mock private LockscreenWallpaper mLockscreenWallpaper;
     @Mock private DozeServiceHost mDozeServiceHost;
     @Mock private ViewMediatorCallback mKeyguardVieMediatorCallback;
@@ -403,7 +397,6 @@
                 new FalsingManagerFake(),
                 new FalsingCollectorFake(),
                 mBroadcastDispatcher,
-                mNotifShadeEventSource,
                 mNotificationEntryManager,
                 mNotificationGutsManager,
                 notificationLogger,
@@ -418,13 +411,11 @@
                 mLockscreenUserManager,
                 mRemoteInputManager,
                 mUserSwitcherController,
-                mNetworkController,
                 mBatteryController,
                 mColorExtractor,
                 new ScreenLifecycle(mDumpManager),
                 wakefulnessLifecycle,
                 mStatusBarStateController,
-                Optional.of(mBubblesManager),
                 Optional.of(mBubbles),
                 mVisualStabilityManager,
                 mDeviceProvisionedController,
@@ -436,7 +427,6 @@
                 mDozeParameters,
                 mScrimController,
                 mLockscreenWallpaperLazy,
-                mLockscreenGestureLogger,
                 mBiometricUnlockControllerLazy,
                 mDozeServiceHost,
                 mPowerManager, mScreenPinningRequest,
@@ -468,7 +458,6 @@
                 mLockscreenTransitionController,
                 mFeatureFlags,
                 mKeyguardUnlockAnimationController,
-                new Handler(TestableLooper.get(this).getLooper()),
                 mMainExecutor,
                 new MessageRouterImpl(mMainExecutor),
                 mWallpaperManager,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
index 9c02216..39021d8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
@@ -399,9 +399,8 @@
         mBouncer.hide(false /* destroyView */);
         verify(mHandler).removeCallbacks(eq(showRunnable.getValue()));
     }
-
     @Test
-    public void testShow_delaysIfFaceAuthIsRunning_unlessBypass() {
+    public void testShow_delaysIfFaceAuthIsRunning_unlessBypassEnabled() {
         when(mKeyguardStateController.isFaceAuthEnabled()).thenReturn(true);
         when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
         mBouncer.show(true /* reset */);
@@ -410,6 +409,16 @@
     }
 
     @Test
+    public void testShow_delaysIfFaceAuthIsRunning_unlessFingerprintEnrolled() {
+        when(mKeyguardStateController.isFaceAuthEnabled()).thenReturn(true);
+        when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(0))
+                .thenReturn(true);
+        mBouncer.show(true /* reset */);
+
+        verify(mHandler, never()).postDelayed(any(), anyLong());
+    }
+
+    @Test
     public void testRegisterUpdateMonitorCallback() {
         verify(mKeyguardUpdateMonitor).registerCallback(any());
     }
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 09009c6e..32df2d7 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
@@ -833,7 +833,7 @@
     }
 
     @Test
-    public void scrimBlanksWhenUnlockingFromPulse() {
+    public void scrimBlankCallbackWhenUnlockingFromPulse() {
         boolean[] blanked = {false};
         // Simulate unlock with fingerprint
         mScrimController.transitionTo(ScrimState.PULSING);
@@ -846,7 +846,50 @@
                     }
                 });
         finishAnimationsImmediately();
-        Assert.assertTrue("Scrim should blank when unlocking from pulse.", blanked[0]);
+        Assert.assertTrue("Scrim should send display blanked callback when unlocking "
+                + "from pulse.", blanked[0]);
+    }
+
+    @Test
+    public void blankingNotRequired_leavingAoD() {
+        // GIVEN display does NOT need blanking
+        when(mDozeParameters.getDisplayNeedsBlanking()).thenReturn(false);
+
+        mScrimController = new ScrimController(mLightBarController,
+                mDozeParameters, mAlarmManager, mKeyguardStateController, mDelayedWakeLockBuilder,
+                new FakeHandler(mLooper.getLooper()), mKeyguardUpdateMonitor,
+                mDockManager, mConfigurationController, new FakeExecutor(new FakeSystemClock()),
+                mScreenOffAnimationController,
+                mPanelExpansionStateManager,
+                mKeyguardUnlockAnimationController,
+                mStatusBarKeyguardViewManager);
+        mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible);
+        mScrimController.attachViews(mScrimBehind, mNotificationsScrim, mScrimInFront);
+        mScrimController.setAnimatorListener(mAnimatorListener);
+        mScrimController.setHasBackdrop(false);
+        mScrimController.setWallpaperSupportsAmbientMode(false);
+        mScrimController.transitionTo(ScrimState.KEYGUARD);
+        finishAnimationsImmediately();
+
+        // WHEN Simulate unlock with fingerprint
+        mScrimController.transitionTo(ScrimState.AOD);
+        finishAnimationsImmediately();
+
+        // WHEN transitioning to UNLOCKED, onDisplayCallbackBlanked callback called to continue
+        // the transition but the scrim was not actually blanked
+        mScrimController.transitionTo(ScrimState.UNLOCKED,
+                new ScrimController.Callback() {
+                    @Override
+                    public void onDisplayBlanked() {
+                        // Front scrim should not be black nor opaque
+                        Assert.assertTrue("Scrim should NOT be visible during transition."
+                                + " Alpha: " + mScrimInFront.getViewAlpha(),
+                                mScrimInFront.getViewAlpha() == 0f);
+                        Assert.assertSame("Scrim should not be visible during transition.",
+                                mScrimVisibility, TRANSPARENT);
+                    }
+                });
+        finishAnimationsImmediately();
     }
 
     @Test
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 4f2abf2..2dcb2f4 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
@@ -192,12 +192,12 @@
     }
 
     @Test
-    public void onPanelExpansionChanged_propagatesToBouncer_evenAfterHidden() {
+    public void onPanelExpansionChanged_hideBouncer_afterKeyguardHidden() {
         mStatusBarKeyguardViewManager.hide(0, 0);
         when(mBouncer.inTransit()).thenReturn(true);
 
         mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
-        verify(mBouncer).setExpansion(eq(EXPANSION_EVENT.getFraction()));
+        verify(mBouncer).setExpansion(eq(KeyguardBouncer.EXPANSION_HIDDEN));
     }
 
     @Test
@@ -239,6 +239,23 @@
     }
 
     @Test
+    public void onPanelExpansionChanged_neverTranslatesBouncerWhenDismissBouncer() {
+        // Since KeyguardBouncer.EXPANSION_VISIBLE = 0 panel expansion, if the unlock is dismissing
+        // the bouncer, there may be an onPanelExpansionChanged(0) call to collapse the panel
+        // which would mistakenly cause the bouncer to show briefly before its visibility
+        // is set to hide. Therefore, we don't want to propagate panelExpansionChanged to the
+        // bouncer if the bouncer is dismissing as a result of a biometric unlock.
+        when(mBiometricUnlockController.getMode())
+                .thenReturn(BiometricUnlockController.MODE_DISMISS_BOUNCER);
+        mStatusBarKeyguardViewManager.onPanelExpansionChanged(
+                expansionEvent(
+                        /* fraction= */ KeyguardBouncer.EXPANSION_VISIBLE,
+                        /* expanded= */ true,
+                        /* tracking= */ false));
+        verify(mBouncer, never()).setExpansion(anyFloat());
+    }
+
+    @Test
     public void onPanelExpansionChanged_neverTranslatesBouncerWhenLaunchingApp() {
         when(mCentralSurfaces.isInLaunchTransition()).thenReturn(true);
         mStatusBarKeyguardViewManager.onPanelExpansionChanged(
@@ -381,6 +398,16 @@
     }
 
     @Test
+    public void testBouncerIsOrWillBeShowing_whenBouncerIsInTransit() {
+        when(mBouncer.isShowing()).thenReturn(false);
+        when(mBouncer.inTransit()).thenReturn(true);
+
+        assertTrue(
+                "Is or will be showing should be true when bouncer is in transit",
+                mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing());
+    }
+
+    @Test
     public void testShowAltAuth_unlockingWithBiometricNotAllowed() {
         // GIVEN alt auth exists, unlocking with biometric isn't allowed
         mStatusBarKeyguardViewManager.setAlternateAuthInterceptor(mAlternateAuthInterceptor);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
index 6abc687..034e06d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
@@ -16,6 +16,11 @@
 
 import static android.view.Display.DEFAULT_DISPLAY;
 
+import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.ANIMATING_IN;
+import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.ANIMATING_OUT;
+import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.IDLE;
+import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.RUNNING_CHIP_ANIM;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -25,6 +30,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import android.animation.Animator;
 import android.app.Fragment;
 import android.app.StatusBarManager;
 import android.content.Context;
@@ -127,7 +133,8 @@
     }
 
     @Test
-    public void testDisableSystemInfo() {
+    public void testDisableSystemInfo_systemAnimationIdle_doesHide() {
+        when(mAnimationScheduler.getAnimationState()).thenReturn(IDLE);
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         fragment.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_SYSTEM_INFO, 0, false);
@@ -140,6 +147,98 @@
     }
 
     @Test
+    public void testSystemStatusAnimation_startedDisabled_finishedWithAnimator_showsSystemInfo() {
+        // GIVEN the status bar hides the system info via disable flags, while there is no event
+        CollapsedStatusBarFragment fragment = resumeAndGetFragment();
+        when(mAnimationScheduler.getAnimationState()).thenReturn(IDLE);
+        fragment.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_SYSTEM_INFO, 0, false);
+        assertEquals(View.INVISIBLE, getSystemIconAreaView().getVisibility());
+
+        // WHEN the disable flags are cleared during a system event animation
+        when(mAnimationScheduler.getAnimationState()).thenReturn(RUNNING_CHIP_ANIM);
+        fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
+
+        // THEN the view is made visible again, but still low alpha
+        assertEquals(View.VISIBLE, getSystemIconAreaView().getVisibility());
+        assertEquals(0, getSystemIconAreaView().getAlpha(), 0.01);
+
+        // WHEN the system event animation finishes
+        when(mAnimationScheduler.getAnimationState()).thenReturn(ANIMATING_OUT);
+        Animator anim = fragment.onSystemEventAnimationFinish(false);
+        anim.start();
+        processAllMessages();
+        anim.end();
+
+        // THEN the system info is full alpha
+        assertEquals(1, getSystemIconAreaView().getAlpha(), 0.01);
+    }
+
+    @Test
+    public void testSystemStatusAnimation_systemInfoDisabled_staysInvisible() {
+        // GIVEN the status bar hides the system info via disable flags, while there is no event
+        CollapsedStatusBarFragment fragment = resumeAndGetFragment();
+        when(mAnimationScheduler.getAnimationState()).thenReturn(IDLE);
+        fragment.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_SYSTEM_INFO, 0, false);
+        assertEquals(View.INVISIBLE, getSystemIconAreaView().getVisibility());
+
+        // WHEN the system event animation finishes
+        when(mAnimationScheduler.getAnimationState()).thenReturn(ANIMATING_OUT);
+        Animator anim = fragment.onSystemEventAnimationFinish(false);
+        anim.start();
+        processAllMessages();
+        anim.end();
+
+        // THEN the system info is at full alpha, but still INVISIBLE (since the disable flag is
+        // still set)
+        assertEquals(1, getSystemIconAreaView().getAlpha(), 0.01);
+        assertEquals(View.INVISIBLE, getSystemIconAreaView().getVisibility());
+    }
+
+
+    @Test
+    public void testSystemStatusAnimation_notDisabled_animatesAlphaZero() {
+        // GIVEN the status bar is not disabled
+        CollapsedStatusBarFragment fragment = resumeAndGetFragment();
+        when(mAnimationScheduler.getAnimationState()).thenReturn(ANIMATING_IN);
+        // WHEN the system event animation begins
+        Animator anim = fragment.onSystemEventAnimationBegin();
+        anim.start();
+        processAllMessages();
+        anim.end();
+
+        // THEN the system info is visible but alpha 0
+        assertEquals(View.VISIBLE, getSystemIconAreaView().getVisibility());
+        assertEquals(0, getSystemIconAreaView().getAlpha(), 0.01);
+    }
+
+    @Test
+    public void testSystemStatusAnimation_notDisabled_animatesBackToAlphaOne() {
+        // GIVEN the status bar is not disabled
+        CollapsedStatusBarFragment fragment = resumeAndGetFragment();
+        when(mAnimationScheduler.getAnimationState()).thenReturn(ANIMATING_IN);
+        // WHEN the system event animation begins
+        Animator anim = fragment.onSystemEventAnimationBegin();
+        anim.start();
+        processAllMessages();
+        anim.end();
+
+        // THEN the system info is visible but alpha 0
+        assertEquals(View.VISIBLE, getSystemIconAreaView().getVisibility());
+        assertEquals(0, getSystemIconAreaView().getAlpha(), 0.01);
+
+        // WHEN the system event animation finishes
+        when(mAnimationScheduler.getAnimationState()).thenReturn(ANIMATING_OUT);
+        anim = fragment.onSystemEventAnimationFinish(false);
+        anim.start();
+        processAllMessages();
+        anim.end();
+
+        // THEN the syste info is full alpha and VISIBLE
+        assertEquals(View.VISIBLE, getSystemIconAreaView().getVisibility());
+        assertEquals(1, getSystemIconAreaView().getAlpha(), 0.01);
+    }
+
+    @Test
     public void testDisableNotifications() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
index e78c8d1..76df8b9 100644
--- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
@@ -24,10 +24,8 @@
 import static com.android.server.backup.UserBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
 import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
 
-import android.annotation.NonNull;
 import android.app.ApplicationThreadConstants;
 import android.app.IBackupAgent;
-import android.app.backup.BackupAgent;
 import android.app.backup.BackupManager;
 import android.app.backup.FullBackup;
 import android.app.backup.IBackupManagerMonitor;
@@ -40,12 +38,10 @@
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.provider.Settings;
-import android.system.OsConstants;
 import android.text.TextUtils;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.LocalServices;
 import com.android.server.backup.BackupAgentTimeoutParameters;
 import com.android.server.backup.BackupRestoreTask;
@@ -61,7 +57,6 @@
 import com.android.server.backup.utils.RestoreUtils;
 import com.android.server.backup.utils.TarBackupReader;
 
-import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -140,8 +135,6 @@
     private boolean mPipesClosed;
     private final BackupEligibilityRules mBackupEligibilityRules;
 
-    private FileMetadata mReadOnlyParent = null;
-
     public FullRestoreEngine(
             UserBackupManagerService backupManagerService, OperationStorage operationStorage,
             BackupRestoreTask monitorTask, IFullBackupRestoreObserver observer,
@@ -165,22 +158,6 @@
         mBackupEligibilityRules = backupEligibilityRules;
     }
 
-    @VisibleForTesting
-    FullRestoreEngine() {
-        mIsAdbRestore = false;
-        mAllowApks = false;
-        mEphemeralOpToken = 0;
-        mUserId = 0;
-        mBackupEligibilityRules = null;
-        mAgentTimeoutParameters = null;
-        mBuffer = null;
-        mBackupManagerService = null;
-        mOperationStorage = null;
-        mMonitor = null;
-        mMonitorTask = null;
-        mOnlyPackage = null;
-    }
-
     public IBackupAgent getAgent() {
         return mAgent;
     }
@@ -420,11 +397,6 @@
                         okay = false;
                     }
 
-                    if (shouldSkipReadOnlyDir(info)) {
-                        // b/194894879: We don't support restore of read-only dirs.
-                        okay = false;
-                    }
-
                     // At this point we have an agent ready to handle the full
                     // restore data as well as a pipe for sending data to
                     // that agent.  Tell the agent to start reading from the
@@ -601,45 +573,6 @@
         return (info != null);
     }
 
-    boolean shouldSkipReadOnlyDir(FileMetadata info) {
-        if (isValidParent(mReadOnlyParent, info)) {
-            // This file has a read-only parent directory, we shouldn't
-            // restore it.
-            return true;
-        } else {
-            // We're now in a different branch of the file tree, update the parent
-            // value.
-            if (isReadOnlyDir(info)) {
-                // Current directory is read-only. Remember it so that we can skip all
-                // of its contents.
-                mReadOnlyParent = info;
-                Slog.w(TAG, "Skipping restore of " + info.path + " and its contents as "
-                        + "read-only dirs are currently not supported.");
-                return true;
-            } else {
-                mReadOnlyParent = null;
-            }
-        }
-
-        return false;
-    }
-
-    private static boolean isValidParent(FileMetadata parentDir, @NonNull FileMetadata childDir) {
-        return parentDir != null
-                && childDir.packageName.equals(parentDir.packageName)
-                && childDir.domain.equals(parentDir.domain)
-                && childDir.path.startsWith(getPathWithTrailingSeparator(parentDir.path));
-    }
-
-    private static String getPathWithTrailingSeparator(String path) {
-        return path.endsWith(File.separator) ? path : path + File.separator;
-    }
-
-    private static boolean isReadOnlyDir(FileMetadata file) {
-        // Check if owner has 'write' bit in the file's mode value (see 'man -7 inode' for details).
-        return file.type == BackupAgent.TYPE_DIRECTORY && (file.mode & OsConstants.S_IWUSR) == 0;
-    }
-
     private void setUpPipes() throws IOException {
         synchronized (mPipesLock) {
             mPipes = ParcelFileDescriptor.createPipe();
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index c678a67..1fab28e 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -160,6 +160,8 @@
     public static final String[] AIDL_INTERFACE_PREFIXES_OF_INTEREST = new String[] {
             "android.hardware.biometrics.face.IFace/",
             "android.hardware.biometrics.fingerprint.IFingerprint/",
+            "android.hardware.graphics.composer3.IComposer/",
+            "android.hardware.input.processor.IInputProcessor/",
             "android.hardware.light.ILights/",
             "android.hardware.power.IPower/",
             "android.hardware.power.stats.IPowerStats/",
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 82d0b67..869c6a4d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -185,7 +185,7 @@
     private boolean mAsync;
     private BroadcastOptions mBroadcastOptions;
     private boolean mShowSplashScreen;
-    private boolean mDismissKeyguardIfInsecure;
+    private boolean mDismissKeyguard;
 
     final boolean mDumping;
 
@@ -449,8 +449,8 @@
                     mAsync = true;
                 } else if (opt.equals("--splashscreen-show-icon")) {
                     mShowSplashScreen = true;
-                } else if (opt.equals("--dismiss-keyguard-if-insecure")) {
-                    mDismissKeyguardIfInsecure = true;
+                } else if (opt.equals("--dismiss-keyguard")) {
+                    mDismissKeyguard = true;
                 } else {
                     return false;
                 }
@@ -601,11 +601,11 @@
                 }
                 options.setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON);
             }
-            if (mDismissKeyguardIfInsecure) {
+            if (mDismissKeyguard) {
                 if (options == null) {
                     options = ActivityOptions.makeBasic();
                 }
-                options.setDismissKeyguardIfInsecure();
+                options.setDismissKeyguard();
             }
             if (mWaitOption) {
                 result = mInternal.startActivityAndWait(null, SHELL_PACKAGE_NAME, null, intent,
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index f7fbbe4..e9658db 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -1556,14 +1556,22 @@
 
         boolean foregroundActivities = false;
         boolean hasVisibleActivities = false;
-        if (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP && app == topApp) {
+        if (app == topApp && (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP
+                || PROCESS_STATE_CUR_TOP == PROCESS_STATE_IMPORTANT_FOREGROUND)) {
             // The last app on the list is the foreground app.
             adj = ProcessList.FOREGROUND_APP_ADJ;
-            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
-            state.setAdjType("top-activity");
+            if (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP) {
+                schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
+                state.setAdjType("top-activity");
+            } else {
+                // Demote the scheduling group to avoid CPU contention if there is another more
+                // important process which also uses top-app, such as if SystemUI is animating.
+                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
+                state.setAdjType("intermediate-top-activity");
+            }
             foregroundActivities = true;
             hasVisibleActivities = true;
-            procState = PROCESS_STATE_CUR_TOP;
+            procState = PROCESS_STATE_TOP;
             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top: " + app);
             }
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 666f9cc..6323160 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -346,6 +346,8 @@
     private static final int MSG_REMOVE_ASSISTANT_SERVICE_UID = 45;
     private static final int MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID = 46;
     private static final int MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR = 47;
+    private static final int MSG_ROTATION_UPDATE = 48;
+    private static final int MSG_FOLD_UPDATE = 49;
 
     // start of messages handled under wakelock
     //   these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
@@ -1214,7 +1216,9 @@
 
         intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
         if (mMonitorRotation) {
-            RotationHelper.init(mContext, mAudioHandler);
+            RotationHelper.init(mContext, mAudioHandler,
+                    rotationParam -> onRotationUpdate(rotationParam),
+                    foldParam -> onFoldUpdate(foldParam));
         }
 
         intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
@@ -1361,6 +1365,20 @@
     }
 
     //-----------------------------------------------------------------
+    // rotation/fold updates coming from RotationHelper
+    void onRotationUpdate(String rotationParameter) {
+        // use REPLACE as only the last rotation matters
+        sendMsg(mAudioHandler, MSG_ROTATION_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0,
+                /*obj*/ rotationParameter, /*delay*/ 0);
+    }
+
+    void onFoldUpdate(String foldParameter) {
+        // use REPLACE as only the last fold state matters
+        sendMsg(mAudioHandler, MSG_FOLD_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0,
+                /*obj*/ foldParameter, /*delay*/ 0);
+    }
+
+    //-----------------------------------------------------------------
     // monitoring requests for volume range initialization
     @Override // AudioSystemAdapter.OnVolRangeInitRequestListener
     public void onVolumeRangeInitRequestFromNative() {
@@ -8310,6 +8328,16 @@
                 case MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR:
                     dispatchDeviceVolumeBehavior((AudioDeviceAttributes) msg.obj, msg.arg1);
                     break;
+
+                case MSG_ROTATION_UPDATE:
+                    // rotation parameter format: "rotation=x" where x is one of 0, 90, 180, 270
+                    mAudioSystem.setParameters((String) msg.obj);
+                    break;
+
+                case MSG_FOLD_UPDATE:
+                    // fold parameter format: "device_folded=x" where x is one of on, off
+                    mAudioSystem.setParameters((String) msg.obj);
+                    break;
             }
         }
     }
diff --git a/services/core/java/com/android/server/audio/RotationHelper.java b/services/core/java/com/android/server/audio/RotationHelper.java
index eb8387f..5cdf58b 100644
--- a/services/core/java/com/android/server/audio/RotationHelper.java
+++ b/services/core/java/com/android/server/audio/RotationHelper.java
@@ -21,13 +21,14 @@
 import android.hardware.devicestate.DeviceStateManager.FoldStateListener;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManagerGlobal;
-import android.media.AudioSystem;
 import android.os.Handler;
 import android.os.HandlerExecutor;
 import android.util.Log;
 import android.view.Display;
 import android.view.Surface;
 
+import java.util.function.Consumer;
+
 /**
  * Class to handle device rotation events for AudioService, and forward device rotation
  * and folded state to the audio HALs through AudioSystem.
@@ -53,6 +54,10 @@
 
     private static AudioDisplayListener sDisplayListener;
     private static FoldStateListener sFoldStateListener;
+    /** callback to send rotation updates to AudioSystem */
+    private static Consumer<String> sRotationUpdateCb;
+    /** callback to send folded state updates to AudioSystem */
+    private static Consumer<String> sFoldUpdateCb;
 
     private static final Object sRotationLock = new Object();
     private static final Object sFoldStateLock = new Object();
@@ -67,13 +72,16 @@
      * - sDisplayListener != null
      * - sContext != null
      */
-    static void init(Context context, Handler handler) {
+    static void init(Context context, Handler handler,
+            Consumer<String> rotationUpdateCb, Consumer<String> foldUpdateCb) {
         if (context == null) {
             throw new IllegalArgumentException("Invalid null context");
         }
         sContext = context;
         sHandler = handler;
         sDisplayListener = new AudioDisplayListener();
+        sRotationUpdateCb = rotationUpdateCb;
+        sFoldUpdateCb = foldUpdateCb;
         enable();
     }
 
@@ -115,21 +123,26 @@
         if (DEBUG_ROTATION) {
             Log.i(TAG, "publishing device rotation =" + rotation + " (x90deg)");
         }
+        String rotationParam;
         switch (rotation) {
             case Surface.ROTATION_0:
-                AudioSystem.setParameters("rotation=0");
+                rotationParam = "rotation=0";
                 break;
             case Surface.ROTATION_90:
-                AudioSystem.setParameters("rotation=90");
+                rotationParam = "rotation=90";
                 break;
             case Surface.ROTATION_180:
-                AudioSystem.setParameters("rotation=180");
+                rotationParam = "rotation=180";
                 break;
             case Surface.ROTATION_270:
-                AudioSystem.setParameters("rotation=270");
+                rotationParam = "rotation=270";
                 break;
             default:
                 Log.e(TAG, "Unknown device rotation");
+                rotationParam = null;
+        }
+        if (rotationParam != null) {
+            sRotationUpdateCb.accept(rotationParam);
         }
     }
 
@@ -140,11 +153,13 @@
         synchronized (sFoldStateLock) {
             if (sDeviceFold != newFolded) {
                 sDeviceFold = newFolded;
+                String foldParam;
                 if (newFolded) {
-                    AudioSystem.setParameters("device_folded=on");
+                    foldParam = "device_folded=on";
                 } else {
-                    AudioSystem.setParameters("device_folded=off");
+                    foldParam = "device_folded=off";
                 }
+                sFoldUpdateCb.accept(foldParam);
             }
         }
     }
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 0d9b754..4767969 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -958,7 +958,7 @@
 
         public boolean isCoexFaceNonBypassHapticsDisabled(Context context) {
             return Settings.Secure.getInt(context.getContentResolver(),
-                    CoexCoordinator.FACE_HAPTIC_DISABLE, 1) != 0;
+                    CoexCoordinator.FACE_HAPTIC_DISABLE, 0) != 0;
         }
 
         public Supplier<Long> getRequestGenerator() {
diff --git a/services/core/java/com/android/server/biometrics/OWNERS b/services/core/java/com/android/server/biometrics/OWNERS
index f05f403..cd281e0 100644
--- a/services/core/java/com/android/server/biometrics/OWNERS
+++ b/services/core/java/com/android/server/biometrics/OWNERS
@@ -1,9 +1,14 @@
 set noparent
 
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
 [email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
+
[email protected]
[email protected]
[email protected]
[email protected]
+
diff --git a/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java b/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java
index 5aa9b79..c8a90e7 100644
--- a/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java
@@ -92,7 +92,7 @@
         void sendHapticFeedback();
     }
 
-    private static CoexCoordinator sInstance;
+    private static final CoexCoordinator sInstance = new CoexCoordinator();
 
     @VisibleForTesting
     public static class SuccessfulAuth {
@@ -147,14 +147,9 @@
         }
     }
 
-    /**
-     * @return a singleton instance.
-     */
+    /** The singleton instance. */
     @NonNull
     public static CoexCoordinator getInstance() {
-        if (sInstance == null) {
-            sInstance = new CoexCoordinator();
-        }
         return sInstance;
     }
 
@@ -339,18 +334,8 @@
                         auth.mCallback.sendHapticFeedback();
                         auth.mCallback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
                         auth.mCallback.handleLifecycleAfterAuth();
-                    } else if (isFaceScanning()) {
-                        // UDFPS rejected but face is still scanning
-                        Slog.d(TAG, "UDFPS rejected in multi-sensor auth, face: " + face);
-                        callback.handleLifecycleAfterAuth();
-
-                        // TODO(b/193089985): Enforce/ensure that face auth finishes (whether
-                        //  accept/reject) within X amount of time. Otherwise users will be stuck
-                        //  waiting with their finger down for a long time.
                     } else {
-                        // Face not scanning, and was not found in the queue. Most likely, face
-                        // auth was too long ago.
-                        Slog.d(TAG, "UDFPS rejected in multi-sensor auth, face not scanning");
+                        Slog.d(TAG, "UDFPS rejected in multi-sensor auth");
                         callback.sendHapticFeedback();
                         callback.handleLifecycleAfterAuth();
                     }
diff --git a/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java
index a099977..ae75b7d 100644
--- a/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java
@@ -67,6 +67,14 @@
         public void onClientFinished(@NonNull BaseClientMonitor clientMonitor, boolean success) {
             mHandler.post(() -> {
                 Slog.d(getTag(), "[Client finished] " + clientMonitor + ", success: " + success);
+
+                // Set mStopUserClient to null when StopUserClient fails. Otherwise it's possible
+                // for that the queue will wait indefinitely until the field is cleared.
+                if (clientMonitor instanceof StopUserClient<?> && !success) {
+                    Slog.w(getTag(),
+                            "StopUserClient failed(), is the HAL stuck? Clearing mStopUserClient");
+                    mStopUserClient = null;
+                }
                 if (mCurrentOperation != null && mCurrentOperation.isFor(mOwner)) {
                     mCurrentOperation = null;
                 } else {
@@ -166,4 +174,9 @@
         mStopUserClient.onUserStopped();
         mStopUserClient = null;
     }
+
+    @VisibleForTesting
+    @Nullable public StopUserClient<?> getStopUserClient() {
+        return mStopUserClient;
+    }
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
index 9ae6750..d0c58fd 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
@@ -99,7 +99,10 @@
         super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
                 owner, cookie, requireConfirmation, sensorId, logger, biometricContext,
                 isStrongBiometric, null /* taskStackListener */, lockoutCache,
-                allowBackgroundAuthentication, true /* shouldVibrate */,
+                allowBackgroundAuthentication,
+                context.getResources().getBoolean(
+                        com.android.internal.R.bool.system_server_plays_face_haptics)
+                /* shouldVibrate */,
                 isKeyguardBypassEnabled);
         setRequestId(requestId);
         mUsageStats = usageStats;
diff --git a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
index e222c64..d238dae 100644
--- a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
+++ b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
@@ -27,8 +27,6 @@
 import android.view.SurfaceControl;
 import android.view.WindowManager;
 
-import com.android.server.policy.WindowManagerPolicy;
-
 /**
  * An internal implementation of an {@link InputMonitor} that uses a spy window.
  *
@@ -69,9 +67,7 @@
 
         final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
         t.setInputWindowInfo(mInputSurface, mWindowHandle);
-        // Gesture monitor should be above handwriting event surface, hence setting it to
-        // WindowManagerPolicy.INPUT_DISPLAY_OVERLAY_LAYER + 1
-        t.setLayer(mInputSurface, WindowManagerPolicy.INPUT_DISPLAY_OVERLAY_LAYER + 1);
+        t.setLayer(mInputSurface, Integer.MAX_VALUE);
         t.setPosition(mInputSurface, 0, 0);
         t.setCrop(mInputSurface, null /* crop to parent surface */);
         t.show(mInputSurface);
diff --git a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
index 5438faa..8180e66 100644
--- a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
+++ b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
@@ -27,8 +27,6 @@
 import android.view.SurfaceControl;
 import android.view.WindowManager;
 
-import com.android.server.policy.WindowManagerPolicy;
-
 final class HandwritingEventReceiverSurface {
 
     public static final String TAG = HandwritingEventReceiverSurface.class.getSimpleName();
@@ -38,8 +36,7 @@
     // is above gesture monitors, then edge-back and swipe-up gestures won't work when this surface
     // is intercepting.
     // TODO(b/217538817): Specify the ordering in WM by usage.
-    private static final int HANDWRITING_SURFACE_LAYER =
-            WindowManagerPolicy.INPUT_DISPLAY_OVERLAY_LAYER;
+    private static final int HANDWRITING_SURFACE_LAYER = Integer.MAX_VALUE - 1;
 
     private final InputWindowHandle mWindowHandle;
     private final InputChannel mClientChannel;
diff --git a/services/core/java/com/android/server/location/gnss/GnssConfiguration.java b/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
index 12f8776..1435016 100644
--- a/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
+++ b/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
@@ -21,6 +21,7 @@
 import android.os.SystemProperties;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -73,6 +74,8 @@
     static final String CONFIG_NFW_PROXY_APPS = "NFW_PROXY_APPS";
     private static final String CONFIG_ENABLE_PSDS_PERIODIC_DOWNLOAD =
             "ENABLE_PSDS_PERIODIC_DOWNLOAD";
+    private static final String CONFIG_ENABLE_ACTIVE_SIM_EMERGENCY_SUPL =
+            "ENABLE_ACTIVE_SIM_EMERGENCY_SUPL";
     static final String CONFIG_LONGTERM_PSDS_SERVER_1 = "LONGTERM_PSDS_SERVER_1";
     static final String CONFIG_LONGTERM_PSDS_SERVER_2 = "LONGTERM_PSDS_SERVER_2";
     static final String CONFIG_LONGTERM_PSDS_SERVER_3 = "LONGTERM_PSDS_SERVER_3";
@@ -207,6 +210,14 @@
     }
 
     /**
+     * Returns true if during an emergency call, the GnssConfiguration of the activeSubId will be
+     * injected for the emergency SUPL flow; Returns false otherwise. Default false if not set.
+     */
+    boolean isActiveSimEmergencySuplEnabled() {
+        return getBooleanConfig(CONFIG_ENABLE_ACTIVE_SIM_EMERGENCY_SUPL, false);
+    }
+
+    /**
      * Returns true if a long-term PSDS server is configured.
      */
     boolean isLongTermPsdsServerConfigured() {
@@ -232,16 +243,31 @@
 
     /**
      * Loads the GNSS properties from carrier config file followed by the properties from
-     * gps debug config file.
+     * gps debug config file, and injects the GNSS properties into the HAL.
      */
     void reloadGpsProperties() {
-        if (DEBUG) Log.d(TAG, "Reset GPS properties, previous size = " + mProperties.size());
-        loadPropertiesFromCarrierConfig();
+        reloadGpsProperties(/* inEmergency= */ false, /* activeSubId= */ -1);
+    }
 
-        String lpp_prof = SystemProperties.get(LPP_PROFILE);
-        if (!TextUtils.isEmpty(lpp_prof)) {
-            // override default value of this if lpp_prof is not empty
-            mProperties.setProperty(CONFIG_LPP_PROFILE, lpp_prof);
+    /**
+     * Loads the GNSS properties from carrier config file followed by the properties from
+     * gps debug config file, and injects the GNSS properties into the HAL.
+     */
+    void reloadGpsProperties(boolean inEmergency, int activeSubId) {
+        if (DEBUG) {
+            Log.d(TAG,
+                    "Reset GPS properties, previous size = " + mProperties.size() + ", inEmergency:"
+                            + inEmergency + ", activeSubId=" + activeSubId);
+        }
+        loadPropertiesFromCarrierConfig(inEmergency, activeSubId);
+
+        if (isSimAbsent(mContext)) {
+            // Use the default SIM's LPP profile when SIM is absent.
+            String lpp_prof = SystemProperties.get(LPP_PROFILE);
+            if (!TextUtils.isEmpty(lpp_prof)) {
+                // override default value of this if lpp_prof is not empty
+                mProperties.setProperty(CONFIG_LPP_PROFILE, lpp_prof);
+            }
         }
 
         /*
@@ -322,16 +348,19 @@
     /**
      * Loads GNSS properties from carrier config file.
      */
-    void loadPropertiesFromCarrierConfig() {
+    void loadPropertiesFromCarrierConfig(boolean inEmergency, int activeSubId) {
         CarrierConfigManager configManager = (CarrierConfigManager)
                 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
         if (configManager == null) {
             return;
         }
 
-        int ddSubId = SubscriptionManager.getDefaultDataSubscriptionId();
-        PersistableBundle configs = SubscriptionManager.isValidSubscriptionId(ddSubId)
-                ? configManager.getConfigForSubId(ddSubId) : configManager.getConfig();
+        int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+        if (inEmergency && activeSubId >= 0) {
+            subId = activeSubId;
+        }
+        PersistableBundle configs = SubscriptionManager.isValidSubscriptionId(subId)
+                ? configManager.getConfigForSubId(subId) : configManager.getConfig();
         if (configs == null) {
             if (DEBUG) Log.d(TAG, "SIM not ready, use default carrier config.");
             configs = CarrierConfigManager.getDefaultConfig();
@@ -422,6 +451,12 @@
         return gnssConfiguartionIfaceVersion.mMajor < 2;
     }
 
+    private static boolean isSimAbsent(Context context) {
+        TelephonyManager phone = (TelephonyManager) context.getSystemService(
+                Context.TELEPHONY_SERVICE);
+        return phone.getSimState() == TelephonyManager.SIM_STATE_ABSENT;
+    }
+
     private static native HalInterfaceVersion native_get_gnss_configuration_version();
 
     private static native boolean native_set_supl_version(int version);
diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
index f5c2bbc..a6a3db1 100644
--- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
@@ -126,6 +126,7 @@
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
 
 /**
  * A GNSS implementation of LocationProvider used by LocationManager.
@@ -359,8 +360,9 @@
                 }
             }
             if (isKeepLppProfile) {
-                // load current properties for the carrier
-                mGnssConfiguration.loadPropertiesFromCarrierConfig();
+                // load current properties for the carrier of ddSubId
+                mGnssConfiguration.loadPropertiesFromCarrierConfig(/* inEmergency= */ false,
+                        /* activeSubId= */ -1);
                 String lpp_profile = mGnssConfiguration.getLppProfile();
                 // set the persist property LPP_PROFILE for the value
                 if (lpp_profile != null) {
@@ -431,13 +433,38 @@
         // this approach is just fine because events are posted to our handler anyway
         mGnssConfiguration = mGnssNative.getConfiguration();
         // Create a GPS net-initiated handler (also needed by handleInitialize)
+        GpsNetInitiatedHandler.EmergencyCallCallback emergencyCallCallback =
+                new GpsNetInitiatedHandler.EmergencyCallCallback() {
+
+                    @Override
+                    public void onEmergencyCallStart(int subId) {
+                        if (!mGnssConfiguration.isActiveSimEmergencySuplEnabled()) {
+                            return;
+                        }
+                        mHandler.post(() -> mGnssConfiguration.reloadGpsProperties(
+                                mNIHandler.getInEmergency(), subId));
+                    }
+
+                    @Override
+                    public void onEmergencyCallEnd() {
+                        if (!mGnssConfiguration.isActiveSimEmergencySuplEnabled()) {
+                            return;
+                        }
+                        mHandler.postDelayed(() -> mGnssConfiguration.reloadGpsProperties(
+                                        /* inEmergency= */ false,
+                                        SubscriptionManager.getDefaultDataSubscriptionId()),
+                                TimeUnit.SECONDS.toMillis(mGnssConfiguration.getEsExtensionSec()));
+                    }
+                };
         mNIHandler = new GpsNetInitiatedHandler(context,
                 mNetInitiatedListener,
+                emergencyCallCallback,
                 mSuplEsEnabled);
         // Trigger PSDS data download when the network comes up after booting.
         mPendingDownloadPsdsTypes.add(GnssPsdsDownloader.LONG_TERM_PSDS_SERVER_INDEX);
         mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler(context,
-                GnssLocationProvider.this::onNetworkAvailable, mHandler.getLooper(), mNIHandler);
+                GnssLocationProvider.this::onNetworkAvailable,
+                mHandler.getLooper(), mNIHandler);
 
         mNtpTimeHelper = new NtpTimeHelper(mContext, mHandler.getLooper(), this);
         mGnssSatelliteBlocklistHelper =
@@ -1694,9 +1721,12 @@
         int type = AGPS_SETID_TYPE_NONE;
         String setId = null;
 
-        int ddSubId = SubscriptionManager.getDefaultDataSubscriptionId();
-        if (SubscriptionManager.isValidSubscriptionId(ddSubId)) {
-            phone = phone.createForSubscriptionId(ddSubId);
+        int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+        if (mNIHandler.getInEmergency() && mNetworkConnectivityHandler.getActiveSubId() >= 0) {
+            subId = mNetworkConnectivityHandler.getActiveSubId();
+        }
+        if (SubscriptionManager.isValidSubscriptionId(subId)) {
+            phone = phone.createForSubscriptionId(subId);
         }
         if ((flags & AGPS_REQUEST_SETID_IMSI) == AGPS_REQUEST_SETID_IMSI) {
             setId = phone.getSubscriberId();
diff --git a/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java b/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
index d9ca4d3..dc1f4ddb 100644
--- a/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
+++ b/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java
@@ -190,7 +190,7 @@
         mContext = context;
         mGnssNetworkListener = gnssNetworkListener;
 
-    SubscriptionManager subManager = mContext.getSystemService(SubscriptionManager.class);
+        SubscriptionManager subManager = mContext.getSystemService(SubscriptionManager.class);
         if (subManager != null) {
             subManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangeListener);
         }
@@ -311,6 +311,13 @@
     }
 
     /**
+     * Returns the active Sub ID for emergency SUPL connection.
+     */
+    int getActiveSubId() {
+        return mActiveSubId;
+    }
+
+    /**
      * Called from native code to update AGPS connection status, or to request or release a SUPL
      * connection.
      *
diff --git a/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerService.java b/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerService.java
index 03e568c..88b4a94 100644
--- a/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerService.java
@@ -413,8 +413,8 @@
                 return result;
             }
             mContext.getSystemService(AppOpsManager.class).noteOpNoThrow(
-                    AppOpsManager.OP_RECORD_AUDIO_HOTWORD, uid, packageName, attributionTag,
-                    reason);
+                    AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO, uid, packageName,
+                    attributionTag, reason);
             return result;
         }
     }
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java
index ebd9126..a6d148c 100644
--- a/services/core/java/com/android/server/policy/AppOpsPolicy.java
+++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java
@@ -202,8 +202,9 @@
     }
 
     private static boolean isHotwordDetectionServiceRequired(PackageManager pm) {
-        // Usage of the HotwordDetectionService won't be enforced until a later release.
-        return false;
+        // The HotwordDetectionService APIs aren't ready yet for Auto or TV.
+        return !(pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
+                || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK));
     }
 
     @Override
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 8917813..7ca09ab 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -156,10 +156,6 @@
     int FINISH_LAYOUT_REDO_ANIM = 0x0008;
     /** Layer for the screen off animation */
     int COLOR_FADE_LAYER = 0x40000001;
-    /** Layer for Input overlays for capturing inputs for gesture detection, etc. */
-    int INPUT_DISPLAY_OVERLAY_LAYER = 0x7f000000;
-    /** Layer for Screen Decoration: The top most visible layer just below input overlay layers */
-    int SCREEN_DECOR_DISPLAY_OVERLAY_LAYER = INPUT_DISPLAY_OVERLAY_LAYER - 1;
 
     /**
      * Register shortcuts for window manager to dispatch.
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 83687e9..026e5d2 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -874,7 +874,7 @@
 
     boolean mEnteringAnimation;
     boolean mOverrideTaskTransition;
-    boolean mDismissKeyguardIfInsecure;
+    boolean mDismissKeyguard;
 
     boolean mAppStopped;
     // A hint to override the window specified rotation animation, or -1 to use the window specified
@@ -1993,7 +1993,7 @@
             }
 
             mOverrideTaskTransition = options.getOverrideTaskTransition();
-            mDismissKeyguardIfInsecure = options.getDismissKeyguardIfInsecure();
+            mDismissKeyguard = options.getDismissKeyguard();
         }
 
         ColorDisplayService.ColorDisplayServiceInternal cds = LocalServices.getService(
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index d190b4f..39a0611 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -64,8 +64,8 @@
 import static android.provider.Settings.System.FONT_SCALE;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
-import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT;
 import static android.view.WindowManager.TRANSIT_WAKE;
+import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS;
@@ -400,6 +400,26 @@
     /** The time at which the previous process was last visible. */
     private long mPreviousProcessVisibleTime;
 
+    /** It is set from keyguard-going-away to set-keyguard-shown. */
+    static final int DEMOTE_TOP_REASON_DURING_UNLOCKING = 1;
+    /** It is set if legacy recents animation is running. */
+    static final int DEMOTE_TOP_REASON_ANIMATING_RECENTS = 1 << 1;
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+            DEMOTE_TOP_REASON_DURING_UNLOCKING,
+            DEMOTE_TOP_REASON_ANIMATING_RECENTS,
+    })
+    @interface DemoteTopReason {}
+
+    /**
+     * If non-zero, getTopProcessState() will
+     * return {@link ActivityManager#PROCESS_STATE_IMPORTANT_FOREGROUND} to avoid top app from
+     * preempting CPU while another process is running an important animation.
+     */
+    @DemoteTopReason
+    volatile int mDemoteTopAppReasons;
+
     /** List of intents that were used to start the most recent tasks. */
     private RecentTasks mRecentTasks;
     /** State of external calls telling us if the device is awake or asleep. */
@@ -2839,12 +2859,24 @@
                         keyguardShowing);
                 mH.sendMessage(msg);
             }
+            // Always reset the state regardless of keyguard-showing change, because that means the
+            // unlock is either completed or canceled.
+            if ((mDemoteTopAppReasons & DEMOTE_TOP_REASON_DURING_UNLOCKING) != 0) {
+                mDemoteTopAppReasons &= ~DEMOTE_TOP_REASON_DURING_UNLOCKING;
+                // The scheduling group of top process was demoted by unlocking, so recompute
+                // to restore its real top priority if possible.
+                if (mTopApp != null) {
+                    mTopApp.scheduleUpdateOomAdj();
+                }
+            }
             try {
+                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "setLockScreenShown");
                 mRootWindowContainer.forAllDisplays(displayContent -> {
                     mKeyguardController.setKeyguardShown(displayContent.getDisplayId(),
                             keyguardShowing, aodShowing);
                 });
             } finally {
+                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                 Binder.restoreCallingIdentity(ident);
             }
         }
@@ -2871,6 +2903,7 @@
         // animation of system UI. Even if AOD is not enabled, it should be no harm.
         final WindowProcessController proc;
         synchronized (mGlobalLockWithoutBoost) {
+            mDemoteTopAppReasons &= ~DEMOTE_TOP_REASON_DURING_UNLOCKING;
             final WindowState notificationShade = mRootWindowContainer.getDefaultDisplay()
                     .getDisplayPolicy().getNotificationShade();
             proc = notificationShade != null
@@ -3408,8 +3441,11 @@
         try {
             synchronized (mGlobalLock) {
                 // Keyguard asked us to clear the home task snapshot before going away, so do that.
-                if ((flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT) != 0) {
+                if ((flags & KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT) != 0) {
                     mActivityClientController.invalidateHomeTaskSnapshot(null /* token */);
+                } else if (mKeyguardShown) {
+                    // Only set if it is not unlocking to launcher which may also animate.
+                    mDemoteTopAppReasons |= DEMOTE_TOP_REASON_DURING_UNLOCKING;
                 }
 
                 mRootWindowContainer.forAllDisplays(displayContent -> {
@@ -3977,6 +4013,9 @@
             mTaskOrganizerController.dump(pw, "  ");
             mVisibleActivityProcessTracker.dump(pw, "  ");
             mActiveUids.dump(pw, "  ");
+            if (mDemoteTopAppReasons != 0) {
+                pw.println("  mDemoteTopAppReasons=" + mDemoteTopAppReasons);
+            }
         }
 
         if (!printedAnything) {
@@ -5604,12 +5643,17 @@
         @HotPath(caller = HotPath.OOM_ADJUSTMENT)
         @Override
         public int getTopProcessState() {
+            final int topState = mTopProcessState;
+            if (mDemoteTopAppReasons != 0 && topState == ActivityManager.PROCESS_STATE_TOP) {
+                // There may be a more important UI/animation than the top app.
+                return ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+            }
             if (mRetainPowerModeAndTopProcessState) {
                 // There is a launching app while device may be sleeping, force the top state so
                 // the launching process can have top-app scheduling group.
                 return ActivityManager.PROCESS_STATE_TOP;
             }
-            return mTopProcessState;
+            return topState;
         }
 
         @HotPath(caller = HotPath.PROCESS_CHANGE)
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index a03dce3..79aef00 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3233,10 +3233,11 @@
     }
 
     public void setRotationAnimation(ScreenRotationAnimation screenRotationAnimation) {
-        if (mScreenRotationAnimation != null) {
-            mScreenRotationAnimation.kill();
-        }
+        final ScreenRotationAnimation prev = mScreenRotationAnimation;
         mScreenRotationAnimation = screenRotationAnimation;
+        if (prev != null) {
+            prev.kill();
+        }
 
         // Hide the windows which are not significant in rotation animation. So that the windows
         // don't need to block the unfreeze time.
@@ -5395,7 +5396,7 @@
     SurfaceControl[] findRoundedCornerOverlays() {
         List<SurfaceControl> roundedCornerOverlays = new ArrayList<>();
         for (WindowToken token : mTokenMap.values()) {
-            if (token.mRoundedCornerOverlay) {
+            if (token.mRoundedCornerOverlay && token.isVisible()) {
                 roundedCornerOverlays.add(token.mSurfaceControl);
             }
         }
diff --git a/services/core/java/com/android/server/wm/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java
index b7ddbd0..33cdd2e 100644
--- a/services/core/java/com/android/server/wm/InputManagerCallback.java
+++ b/services/core/java/com/android/server/wm/InputManagerCallback.java
@@ -265,7 +265,7 @@
                     .setContainerLayer()
                     .setName(name)
                     .setCallsite("createSurfaceForGestureMonitor")
-                    .setParent(dc.getOverlayLayer())
+                    .setParent(dc.getSurfaceControl())
                     .build();
         }
     }
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index f36dbfa..a4c05ee 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -41,6 +41,7 @@
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
 import static com.android.server.wm.KeyguardControllerProto.AOD_SHOWING;
+import static com.android.server.wm.KeyguardControllerProto.KEYGUARD_GOING_AWAY;
 import static com.android.server.wm.KeyguardControllerProto.KEYGUARD_PER_DISPLAY;
 import static com.android.server.wm.KeyguardControllerProto.KEYGUARD_SHOWING;
 
@@ -589,13 +590,12 @@
                     mTopTurnScreenOnActivity = top;
                 }
 
-                final boolean isKeyguardSecure = controller.mWindowManager.isKeyguardSecure(
-                        controller.mService.getCurrentUserId());
-                if (top.mDismissKeyguardIfInsecure && mKeyguardShowing && !isKeyguardSecure) {
+                if (top.mDismissKeyguard && mKeyguardShowing) {
                     mKeyguardGoingAway = true;
                 } else if (top.canShowWhenLocked()) {
                     mTopOccludesActivity = top;
                 }
+                top.mDismissKeyguard = false;
 
                 // Only the top activity may control occluded, as we can't occlude the Keyguard
                 // if the top app doesn't want to occlude it.
@@ -673,6 +673,7 @@
             proto.write(KeyguardPerDisplayProto.KEYGUARD_SHOWING, mKeyguardShowing);
             proto.write(KeyguardPerDisplayProto.AOD_SHOWING, mAodShowing);
             proto.write(KeyguardPerDisplayProto.KEYGUARD_OCCLUDED, mOccluded);
+            proto.write(KeyguardPerDisplayProto.KEYGUARD_GOING_AWAY, mKeyguardGoingAway);
             proto.end(token);
         }
     }
@@ -693,6 +694,7 @@
         final long token = proto.start(fieldId);
         proto.write(AOD_SHOWING, default_state.mAodShowing);
         proto.write(KEYGUARD_SHOWING, default_state.mKeyguardShowing);
+        proto.write(KEYGUARD_GOING_AWAY, default_state.mKeyguardGoingAway);
         writeDisplayStatesToProto(proto, KEYGUARD_PER_DISPLAY);
         proto.end(token);
     }
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index eca201d..f840171 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -203,9 +203,7 @@
         final LaunchingState launchingState =
                 mTaskSupervisor.getActivityMetricsLogger().notifyActivityLaunching(mTargetIntent);
 
-        if (mCaller != null) {
-            mCaller.setRunningRecentsAnimation(true);
-        }
+        setProcessAnimating(true);
 
         mService.deferWindowLayout();
         try {
@@ -409,15 +407,33 @@
                     if (mWindowManager.mRoot.isLayoutNeeded()) {
                         mWindowManager.mRoot.performSurfacePlacement();
                     }
-                    if (mCaller != null) {
-                        mCaller.setRunningRecentsAnimation(false);
-                    }
+                    setProcessAnimating(false);
                     Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                 }
             });
         }
     }
 
+    /** Gives the owner of recents animation higher priority. */
+    private void setProcessAnimating(boolean animating) {
+        if (mCaller == null) return;
+        // Apply the top-app scheduling group to who runs the animation.
+        mCaller.setRunningRecentsAnimation(animating);
+        int demoteReasons = mService.mDemoteTopAppReasons;
+        if (animating) {
+            demoteReasons |= ActivityTaskManagerService.DEMOTE_TOP_REASON_ANIMATING_RECENTS;
+        } else {
+            demoteReasons &= ~ActivityTaskManagerService.DEMOTE_TOP_REASON_ANIMATING_RECENTS;
+        }
+        mService.mDemoteTopAppReasons = demoteReasons;
+        // Make the demotion of the real top app take effect. No need to restore top app state for
+        // finishing recents because addToStopping -> scheduleIdle -> activityIdleInternal ->
+        // trimApplications will have a full update.
+        if (animating && mService.mTopApp != null) {
+            mService.mTopApp.scheduleUpdateOomAdj();
+        }
+    }
+
     @Override
     public void onAnimationFinished(@RecentsAnimationController.ReorderMode int reorderMode,
             boolean sendUserLeaveHint) {
diff --git a/services/core/java/com/android/server/wm/SafeActivityOptions.java b/services/core/java/com/android/server/wm/SafeActivityOptions.java
index 66d0230..9856ebf 100644
--- a/services/core/java/com/android/server/wm/SafeActivityOptions.java
+++ b/services/core/java/com/android/server/wm/SafeActivityOptions.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.Manifest.permission.CONTROL_KEYGUARD;
 import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
 import static android.Manifest.permission.STATUS_BAR_SERVICE;
@@ -316,6 +317,20 @@
             }
         }
 
+        // Check if the caller is allowed to dismiss keyguard.
+        final boolean dismissKeyguard = options.getDismissKeyguard();
+        if (aInfo != null && dismissKeyguard) {
+            final int controlKeyguardPerm = ActivityTaskManagerService.checkPermission(
+                    CONTROL_KEYGUARD, callingPid, callingUid);
+            if (controlKeyguardPerm != PERMISSION_GRANTED) {
+                final String msg = "Permission Denial: starting " + getIntentString(intent)
+                        + " from " + callerApp + " (pid=" + callingPid
+                        + ", uid=" + callingUid + ") with dismissKeyguard=true";
+                Slog.w(TAG, msg);
+                throw new SecurityException(msg);
+            }
+        }
+
         // Check permission for remote animations
         final RemoteAnimationAdapter adapter = options.getRemoteAnimationAdapter();
         if (adapter != null && supervisor.mService.checkPermission(
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index 2ef1932..f31a3cc 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -40,9 +40,11 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.hardware.HardwareBuffer;
+import android.os.IBinder;
 import android.os.Trace;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
+import android.view.DisplayAddress;
 import android.view.DisplayInfo;
 import android.view.Surface;
 import android.view.Surface.OutOfResourcesException;
@@ -102,6 +104,7 @@
     private SurfaceControl mEnterBlackFrameLayer;
     /** This layer contains the actual screenshot that is to be faded out. */
     private SurfaceControl mScreenshotLayer;
+    private SurfaceControl[] mRoundedCornerOverlay;
     /**
      * Only used for screen rotation and not custom animations. Layered behind all other layers
      * to avoid showing any "empty" spots
@@ -151,6 +154,11 @@
         final boolean flipped = delta == Surface.ROTATION_90 || delta == Surface.ROTATION_270;
         mOriginalWidth = flipped ? height : width;
         mOriginalHeight = flipped ? width : height;
+        final int logicalWidth = displayInfo.logicalWidth;
+        final int logicalHeight = displayInfo.logicalHeight;
+        final boolean isSizeChanged =
+                logicalWidth > mOriginalWidth == logicalHeight > mOriginalHeight
+                && (logicalWidth != mOriginalWidth || logicalHeight != mOriginalHeight);
         mSurfaceRotationAnimationController = new SurfaceRotationAnimationController();
 
         // Check whether the current screen contains any secure content.
@@ -159,18 +167,43 @@
         final SurfaceControl.Transaction t = mService.mTransactionFactory.get();
 
         try {
-            SurfaceControl.LayerCaptureArgs args =
-                    new SurfaceControl.LayerCaptureArgs.Builder(displayContent.getSurfaceControl())
-                            .setCaptureSecureLayers(true)
-                            .setAllowProtected(true)
-                            .setSourceCrop(new Rect(0, 0, width, height))
-                            // Exclude rounded corner overlay from screenshot buffer. Rounded
-                            // corner overlay windows are un-rotated during rotation animation
-                            // for a seamless transition.
-                            .setExcludeLayers(displayContent.findRoundedCornerOverlays())
-                            .build();
-            SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
-                    SurfaceControl.captureLayers(args);
+            final SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer;
+            if (isSizeChanged) {
+                final DisplayAddress address = displayInfo.address;
+                if (!(address instanceof DisplayAddress.Physical)) {
+                    Slog.e(TAG, "Display does not have a physical address: " + displayId);
+                    return;
+                }
+                final DisplayAddress.Physical physicalAddress =
+                        (DisplayAddress.Physical) address;
+                final IBinder displayToken = SurfaceControl.getPhysicalDisplayToken(
+                        physicalAddress.getPhysicalDisplayId());
+                if (displayToken == null) {
+                    Slog.e(TAG, "Display token is null.");
+                    return;
+                }
+                // Temporarily not skip screenshot for the rounded corner overlays and screenshot
+                // the whole display to include the rounded corner overlays.
+                setSkipScreenshotForRoundedCornerOverlays(false, t);
+                mRoundedCornerOverlay = displayContent.findRoundedCornerOverlays();
+                final SurfaceControl.DisplayCaptureArgs captureArgs =
+                        new SurfaceControl.DisplayCaptureArgs.Builder(displayToken)
+                                .setSourceCrop(new Rect(0, 0, width, height))
+                                .setAllowProtected(true)
+                                .setCaptureSecureLayers(true)
+                                .build();
+                screenshotBuffer = SurfaceControl.captureDisplay(captureArgs);
+            } else {
+                SurfaceControl.LayerCaptureArgs captureArgs =
+                        new SurfaceControl.LayerCaptureArgs.Builder(
+                                displayContent.getSurfaceControl())
+                                .setCaptureSecureLayers(true)
+                                .setAllowProtected(true)
+                                .setSourceCrop(new Rect(0, 0, width, height))
+                                .build();
+                screenshotBuffer = SurfaceControl.captureLayers(captureArgs);
+            }
+
             if (screenshotBuffer == null) {
                 Slog.w(TAG, "Unable to take screenshot of display " + displayId);
                 return;
@@ -232,6 +265,14 @@
             t.show(mScreenshotLayer);
             t.show(mBackColorSurface);
 
+            if (mRoundedCornerOverlay != null) {
+                for (SurfaceControl sc : mRoundedCornerOverlay) {
+                    if (sc.isValid()) {
+                        t.hide(sc);
+                    }
+                }
+            }
+
         } catch (OutOfResourcesException e) {
             Slog.w(TAG, "Unable to allocate freeze surface", e);
         }
@@ -240,10 +281,7 @@
         // the new logical display size. Currently pending transaction and RWC#mDisplayTransaction
         // are merged to global transaction, so it can be synced with display change when calling
         // DisplayManagerInternal#performTraversal(transaction).
-        final int logicalWidth = displayInfo.logicalWidth;
-        final int logicalHeight = displayInfo.logicalHeight;
-        if (logicalWidth > mOriginalWidth == logicalHeight > mOriginalHeight
-                && (logicalWidth != mOriginalWidth || logicalHeight != mOriginalHeight)) {
+        if (mScreenshotLayer != null && isSizeChanged) {
             displayContent.getPendingTransaction().setGeometry(mScreenshotLayer,
                     new Rect(0, 0, mOriginalWidth, mOriginalHeight),
                     new Rect(0, 0, logicalWidth, logicalHeight), Surface.ROTATION_0);
@@ -264,6 +302,21 @@
         t.apply();
     }
 
+    void setSkipScreenshotForRoundedCornerOverlays(
+            boolean skipScreenshot, SurfaceControl.Transaction t) {
+        mDisplayContent.forAllWindows(w -> {
+            if (!w.mToken.mRoundedCornerOverlay || !w.isVisible() || !w.mWinAnimator.hasSurface()) {
+                return;
+            }
+            t.setSkipScreenshot(w.mWinAnimator.mSurfaceController.mSurfaceControl, skipScreenshot);
+        }, false);
+        if (!skipScreenshot) {
+            // Use sync apply to apply the change immediately, so that the next
+            // SC.captureDisplay can capture the screen decor layers.
+            t.apply(true /* sync */);
+        }
+    }
+
     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
         final long token = proto.start(fieldId);
         proto.write(STARTED, mStarted);
@@ -472,6 +525,19 @@
                 }
                 mBackColorSurface = null;
             }
+
+            if (mRoundedCornerOverlay != null) {
+                if (mDisplayContent.getRotationAnimation() == null
+                        || mDisplayContent.getRotationAnimation() == this) {
+                    setSkipScreenshotForRoundedCornerOverlays(true, t);
+                    for (SurfaceControl sc : mRoundedCornerOverlay) {
+                        if (sc.isValid()) {
+                            t.show(sc);
+                        }
+                    }
+                }
+                mRoundedCornerOverlay = null;
+            }
             t.apply();
         }
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 52af39e..9022186 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -8215,7 +8215,7 @@
                         .setContainerLayer()
                         .setName("IME Handwriting Surface")
                         .setCallsite("getHandwritingSurfaceForDisplay")
-                        .setParent(dc.getOverlayLayer())
+                        .setParent(dc.getSurfaceControl())
                         .build();
             }
         }
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 40417a4..215bcb0 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -1126,6 +1126,13 @@
         mAtm.mH.sendMessage(m);
     }
 
+    /** Refreshes oom adjustment and process state of this process. */
+    void scheduleUpdateOomAdj() {
+        mAtm.mH.sendMessage(PooledLambda.obtainMessage(WindowProcessListener::updateProcessInfo,
+                mListener, false /* updateServiceConnectionActivities */,
+                false /* activityChange */, true /* updateOomAdj */));
+    }
+
     /** Makes the process have top state before oom-adj is computed from a posted message. */
     void addToPendingTop() {
         mAtm.mAmInternal.addPendingTopUid(mUid, mPid, mThread);
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 18f60b1..d2e56fa 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -368,7 +368,7 @@
             super.assignRelativeLayer(t,
                     mDisplayContent.getDefaultTaskDisplayArea().getSplitScreenDividerAnchor(), 1);
         } else if (mRoundedCornerOverlay) {
-            super.assignLayer(t, WindowManagerPolicy.SCREEN_DECOR_DISPLAY_OVERLAY_LAYER);
+            super.assignLayer(t, WindowManagerPolicy.COLOR_FADE_LAYER + 1);
         } else {
             super.assignLayer(t, layer);
         }
@@ -378,7 +378,7 @@
     SurfaceControl.Builder makeSurface() {
         final SurfaceControl.Builder builder = super.makeSurface();
         if (mRoundedCornerOverlay) {
-            builder.setParent(getDisplayContent().getOverlayLayer());
+            builder.setParent(null);
         }
         return builder;
     }
diff --git a/services/tests/servicestests/src/com/android/server/backup/restore/FullRestoreEngineTest.java b/services/tests/servicestests/src/com/android/server/backup/restore/FullRestoreEngineTest.java
deleted file mode 100644
index 049c745..0000000
--- a/services/tests/servicestests/src/com/android/server/backup/restore/FullRestoreEngineTest.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.backup.restore;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.app.backup.BackupAgent;
-import android.platform.test.annotations.Presubmit;
-import android.system.OsConstants;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.server.backup.FileMetadata;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@Presubmit
-@RunWith(AndroidJUnit4.class)
-public class FullRestoreEngineTest {
-    private static final String DEFAULT_PACKAGE_NAME = "package";
-    private static final String DEFAULT_DOMAIN_NAME = "domain";
-    private static final String NEW_PACKAGE_NAME = "new_package";
-    private static final String NEW_DOMAIN_NAME = "new_domain";
-
-    private FullRestoreEngine mRestoreEngine;
-
-    @Before
-    public void setUp() {
-        mRestoreEngine = new FullRestoreEngine();
-    }
-
-    @Test
-    public void shouldSkipReadOnlyDir_skipsAllReadonlyDirsAndTheirChildren() {
-        // Create the file tree.
-        TestFile[] testFiles = new TestFile[] {
-                TestFile.dir("root"),
-                TestFile.file("root/auth_token"),
-                TestFile.dir("root/media"),
-                TestFile.file("root/media/picture1.png"),
-                TestFile.file("root/push_token.txt"),
-                TestFile.dir("root/read-only-dir-1").markReadOnly().expectSkipped(),
-                TestFile.dir("root/read-only-dir-1/writable-subdir").expectSkipped(),
-                TestFile.file("root/read-only-dir-1/writable-subdir/writable-file").expectSkipped(),
-                TestFile.dir("root/read-only-dir-1/writable-subdir/read-only-subdir-2")
-                        .markReadOnly().expectSkipped(),
-                TestFile.file("root/read-only-dir-1/writable-file").expectSkipped(),
-                TestFile.file("root/random-stuff.txt"),
-                TestFile.dir("root/database"),
-                TestFile.file("root/database/users.db"),
-                TestFile.dir("root/read-only-dir-2").markReadOnly().expectSkipped(),
-                TestFile.file("root/read-only-dir-2/writable-file-1").expectSkipped(),
-                TestFile.file("root/read-only-dir-2/writable-file-2").expectSkipped(),
-        };
-
-        assertCorrectItemsAreSkipped(testFiles);
-    }
-
-    @Test
-    public void shouldSkipReadOnlyDir_onlySkipsChildrenUnderTheSamePackage() {
-        TestFile[] testFiles = new TestFile[]{
-                TestFile.dir("read-only-dir").markReadOnly().expectSkipped(),
-                TestFile.file("read-only-dir/file").expectSkipped(),
-                TestFile.file("read-only-dir/file-from-different-package")
-                        .setPackage(NEW_PACKAGE_NAME),
-        };
-
-        assertCorrectItemsAreSkipped(testFiles);
-    }
-
-    @Test
-    public void shouldSkipReadOnlyDir_onlySkipsChildrenUnderTheSameDomain() {
-        TestFile[] testFiles = new TestFile[]{
-                TestFile.dir("read-only-dir").markReadOnly().expectSkipped(),
-                TestFile.file("read-only-dir/file").expectSkipped(),
-                TestFile.file("read-only-dir/file-from-different-domain")
-                        .setDomain(NEW_DOMAIN_NAME),
-        };
-
-        assertCorrectItemsAreSkipped(testFiles);
-    }
-
-    private void assertCorrectItemsAreSkipped(TestFile[] testFiles) {
-        // Verify all directories marked with .expectSkipped are skipped.
-        for (TestFile testFile : testFiles) {
-            boolean actualExcluded = mRestoreEngine.shouldSkipReadOnlyDir(testFile.mMetadata);
-            boolean expectedExcluded = testFile.mShouldSkip;
-            assertWithMessage(testFile.mMetadata.path).that(actualExcluded).isEqualTo(
-                    expectedExcluded);
-        }
-    }
-
-    private static class TestFile {
-        private final FileMetadata mMetadata;
-        private boolean mShouldSkip;
-
-        static TestFile dir(String path) {
-            return new TestFile(path, BackupAgent.TYPE_DIRECTORY);
-        }
-
-        static TestFile file(String path) {
-            return new TestFile(path, BackupAgent.TYPE_FILE);
-        }
-
-        TestFile markReadOnly() {
-            mMetadata.mode = 0;
-            return this;
-        }
-
-        TestFile expectSkipped() {
-            mShouldSkip = true;
-            return this;
-        }
-
-        TestFile setPackage(String packageName) {
-            mMetadata.packageName = packageName;
-            return this;
-        }
-
-        TestFile setDomain(String domain) {
-            mMetadata.domain = domain;
-            return this;
-        }
-
-        private TestFile(String path, int type) {
-            FileMetadata metadata = new FileMetadata();
-            metadata.path = path;
-            metadata.type = type;
-            metadata.packageName = DEFAULT_PACKAGE_NAME;
-            metadata.domain = DEFAULT_DOMAIN_NAME;
-            metadata.mode = OsConstants.S_IWUSR; // Mark as writable.
-            mMetadata = metadata;
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java
index f40b31a..abf992b 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java
@@ -415,7 +415,7 @@
         // Auth was attempted
         when(mUdfpsClient.getState())
                 .thenReturn(AuthenticationClient.STATE_STARTED_PAUSED_ATTEMPTED);
-        verify(mCallback, never()).sendHapticFeedback();
+        verify(mCallback).sendHapticFeedback();
         verify(mCallback).handleLifecycleAfterAuth();
 
         // Then face rejected. Note that scheduler leaves UDFPS in the CoexCoordinator since
@@ -425,7 +425,7 @@
                 LockoutTracker.LOCKOUT_NONE, faceCallback);
         verify(faceCallback).sendHapticFeedback();
         verify(faceCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
-        verify(mCallback, never()).sendHapticFeedback();
+        verify(mCallback).sendHapticFeedback();
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java
index 8391914..0df3028 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java
@@ -80,6 +80,11 @@
     @Mock
     private BiometricContext mBiometricContext;
 
+    private boolean mShouldFailStopUser = false;
+    private final StopUserClientShouldFail mStopUserClientShouldFail =
+            () -> {
+                return mShouldFailStopUser;
+            };
     private final TestUserStartedCallback mUserStartedCallback = new TestUserStartedCallback();
     private final TestUserStoppedCallback mUserStoppedCallback = new TestUserStoppedCallback();
     private int mCurrentUserId = UserHandle.USER_NULL;
@@ -88,6 +93,7 @@
 
     @Before
     public void setUp() {
+        mShouldFailStopUser = false;
         mHandler = new Handler(TestableLooper.get(this).getLooper());
         mScheduler = new UserAwareBiometricScheduler(TAG,
                 mHandler,
@@ -101,7 +107,7 @@
                     public StopUserClient<?> getStopUserClient(int userId) {
                         return new TestStopUserClient(mContext, Object::new, mToken, userId,
                                 TEST_SENSOR_ID, mBiometricLogger, mBiometricContext,
-                                mUserStoppedCallback);
+                                mUserStoppedCallback, mStopUserClientShouldFail);
                     }
 
                     @NonNull
@@ -240,6 +246,36 @@
         assertThat(mUserStoppedCallback.mNumInvocations).isEqualTo(1);
     }
 
+    @Test
+    public void testStartUser_failsClearsStopUserClient() {
+        // When a stop user client fails, check that mStopUserClient
+        // is set to null to prevent the scheduler from getting stuck.
+        BaseClientMonitor nextClient = mock(BaseClientMonitor.class);
+        when(nextClient.getTargetUserId()).thenReturn(10);
+
+        mScheduler.scheduleClientMonitor(nextClient);
+
+        waitForIdle();
+        verify(nextClient).start(any());
+
+        // finish first operation
+        mScheduler.getInternalCallback().onClientFinished(nextClient, true /* success */);
+        waitForIdle();
+
+        // schedule second operation but swap out the current operation
+        // before it runs so that it's not current when it's completion callback runs
+        nextClient = mock(BaseClientMonitor.class);
+        when(nextClient.getTargetUserId()).thenReturn(11);
+        mUserStartedCallback.mAfterStart = () -> mScheduler.mCurrentOperation = null;
+        mShouldFailStopUser = true;
+        mScheduler.scheduleClientMonitor(nextClient);
+
+        waitForIdle();
+        assertThat(mUserStartedCallback.mStartedUsers).containsExactly(10, 11).inOrder();
+        assertThat(mUserStoppedCallback.mNumInvocations).isEqualTo(0);
+        assertThat(mScheduler.getStopUserClient()).isEqualTo(null);
+    }
+
     private void waitForIdle() {
         TestableLooper.get(this).processAllMessages();
     }
@@ -268,13 +304,19 @@
         }
     }
 
-    private static class TestStopUserClient extends StopUserClient<Object> {
+    private interface StopUserClientShouldFail {
+        boolean shouldFail();
+    }
+
+    private class TestStopUserClient extends StopUserClient<Object> {
+        private StopUserClientShouldFail mShouldFailClient;
         public TestStopUserClient(@NonNull Context context,
                 @NonNull Supplier<Object> lazyDaemon, @Nullable IBinder token, int userId,
                 int sensorId, @NonNull BiometricLogger logger,
                 @NonNull BiometricContext biometricContext,
-                @NonNull UserStoppedCallback callback) {
+                @NonNull UserStoppedCallback callback, StopUserClientShouldFail shouldFail) {
             super(context, lazyDaemon, token, userId, sensorId, logger, biometricContext, callback);
+            mShouldFailClient = shouldFail;
         }
 
         @Override
@@ -285,7 +327,14 @@
         @Override
         public void start(@NonNull ClientMonitorCallback callback) {
             super.start(callback);
-            onUserStopped();
+            if (mShouldFailClient.shouldFail()) {
+                getCallback().onClientFinished(this, false /* success */);
+                // When the above fails, it means that the HAL has died, in this case we
+                // need to ensure the UserSwitchCallback correctly returns the NULL user handle.
+                mCurrentUserId = UserHandle.USER_NULL;
+            } else {
+                onUserStopped();
+            }
         }
 
         @Override
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index 1b19a28..28fb015 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -37,13 +37,13 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 
-import android.app.IApplicationThread;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -91,9 +91,15 @@
         TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
         Task recentsStack = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
                 ACTIVITY_TYPE_RECENTS, true /* onTop */);
+        final WindowProcessController wpc = mSystemServicesTestRule.addProcess(
+                mRecentsComponent.getPackageName(), mRecentsComponent.getPackageName(),
+                // Use real pid/uid of the test so the corresponding process can be mapped by
+                // Binder.getCallingPid/Uid.
+                android.os.Process.myPid(), android.os.Process.myUid());
         ActivityRecord recentActivity = new ActivityBuilder(mAtm)
                 .setComponent(mRecentsComponent)
                 .setTask(recentsStack)
+                .setUseProcess(wpc)
                 .build();
         ActivityRecord topActivity = new ActivityBuilder(mAtm).setCreateTask(true).build();
         topActivity.getRootTask().moveToFront("testRecentsActivityVisiblility");
@@ -106,11 +112,14 @@
                 mRecentsComponent, true /* getRecentsAnimation */);
         // The launch-behind state should make the recents activity visible.
         assertTrue(recentActivity.mVisibleRequested);
+        assertEquals(ActivityTaskManagerService.DEMOTE_TOP_REASON_ANIMATING_RECENTS,
+                mAtm.mDemoteTopAppReasons);
 
         // Simulate the animation is cancelled without changing the stack order.
         recentsAnimation.onAnimationFinished(REORDER_KEEP_IN_PLACE, false /* sendUserLeaveHint */);
         // The non-top recents activity should be invisible by the restored launch-behind state.
         assertFalse(recentActivity.mVisibleRequested);
+        assertEquals(0, mAtm.mDemoteTopAppReasons);
     }
 
     @Test
@@ -138,11 +147,8 @@
                 anyInt() /* startFlags */, any() /* profilerInfo */);
 
         // Assume its process is alive because the caller should be the recents service.
-        WindowProcessController wpc = new WindowProcessController(mAtm, aInfo.applicationInfo,
-                aInfo.processName, aInfo.applicationInfo.uid, 0 /* userId */,
-                mock(Object.class) /* owner */, mock(WindowProcessListener.class));
-        wpc.setThread(mock(IApplicationThread.class));
-        doReturn(wpc).when(mAtm).getProcessController(eq(wpc.mName), eq(wpc.mUid));
+        mSystemServicesTestRule.addProcess(aInfo.packageName, aInfo.processName, 12345 /* pid */,
+                aInfo.applicationInfo.uid);
 
         Intent recentsIntent = new Intent().setComponent(mRecentsComponent);
         // Null animation indicates to preload.
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index dc9a625..258625c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -43,12 +43,14 @@
 
 import android.app.ActivityManagerInternal;
 import android.app.AppOpsManager;
+import android.app.IApplicationThread;
 import android.app.usage.UsageStatsManagerInternal;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.database.ContentObserver;
@@ -454,8 +456,32 @@
                 .spiedInstance(sWakeLock).stubOnly());
     }
 
-    void setSurfaceFactory(Supplier<Surface> factory) {
-        mSurfaceFactory = factory;
+    WindowProcessController addProcess(String pkgName, String procName, int pid, int uid) {
+        return addProcess(mAtmService, pkgName, procName, pid, uid);
+    }
+
+    static WindowProcessController addProcess(ActivityTaskManagerService atmService, String pkgName,
+            String procName, int pid, int uid) {
+        final ApplicationInfo info = new ApplicationInfo();
+        info.uid = uid;
+        info.packageName = pkgName;
+        return addProcess(atmService, info, procName, pid);
+    }
+
+    static WindowProcessController addProcess(ActivityTaskManagerService atmService,
+            ApplicationInfo info, String procName, int pid) {
+        final WindowProcessListener mockListener = mock(WindowProcessListener.class,
+                withSettings().stubOnly());
+        final int uid = info.uid;
+        final WindowProcessController proc = new WindowProcessController(atmService,
+                info, procName, uid, UserHandle.getUserId(uid), mockListener, mockListener);
+        proc.setThread(mock(IApplicationThread.class, withSettings().stubOnly()));
+        atmService.mProcessNames.put(procName, uid, proc);
+        if (pid > 0) {
+            proc.setPid(pid);
+            atmService.mProcessMap.put(pid, proc);
+        }
+        return proc;
     }
 
     void cleanupWindowManagerHandlers() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 20fbda4..7347f88 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -64,7 +64,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityOptions;
-import android.app.IApplicationThread;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -915,13 +914,15 @@
      */
     protected static class ActivityBuilder {
         static final int DEFAULT_FAKE_UID = 12345;
+        static final String DEFAULT_PROCESS_NAME = "procName";
+        static int sProcNameSeq;
 
         private final ActivityTaskManagerService mService;
 
         private ComponentName mComponent;
         private String mTargetActivity;
         private Task mTask;
-        private String mProcessName = "name";
+        private String mProcessName = DEFAULT_PROCESS_NAME;
         private String mAffinity;
         private int mUid = DEFAULT_FAKE_UID;
         private boolean mCreateTask = false;
@@ -1109,6 +1110,9 @@
             aInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
             aInfo.applicationInfo.packageName = mComponent.getPackageName();
             aInfo.applicationInfo.uid = mUid;
+            if (DEFAULT_PROCESS_NAME.equals(mProcessName)) {
+                mProcessName += ++sProcNameSeq;
+            }
             aInfo.processName = mProcessName;
             aInfo.packageName = mComponent.getPackageName();
             aInfo.name = mComponent.getClassName();
@@ -1173,16 +1177,11 @@
             if (mWpc != null) {
                 wpc = mWpc;
             } else {
-                wpc = new WindowProcessController(mService,
-                        aInfo.applicationInfo, mProcessName, mUid,
-                        UserHandle.getUserId(mUid), mock(Object.class),
-                        mock(WindowProcessListener.class));
-                wpc.setThread(mock(IApplicationThread.class));
+                final WindowProcessController p = mService.getProcessController(mProcessName, mUid);
+                wpc = p != null ? p : SystemServicesTestRule.addProcess(
+                        mService, aInfo.applicationInfo, mProcessName, 0 /* pid */);
             }
-            wpc.setThread(mock(IApplicationThread.class));
             activity.setProcess(wpc);
-            doReturn(wpc).when(mService).getProcessController(
-                    activity.processName, activity.info.applicationInfo.uid);
 
             // Resume top activities to make sure all other signals in the system are connected.
             mService.mRootWindowContainer.resumeFocusedTasksTopActivities();
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 434663b..42d446d 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -46,9 +46,11 @@
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED;
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED_FROM_RESTART;
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECT_UNEXPECTED_CALLBACK;
+import static com.android.server.voiceinteraction.SoundTriggerSessionPermissionsDecorator.enforcePermissionForPreflight;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.AppOpsManager;
 import android.content.ComponentName;
 import android.content.ContentCaptureOptions;
 import android.content.Context;
@@ -1160,12 +1162,11 @@
     // TODO: Share this code with SoundTriggerMiddlewarePermission.
     private void enforcePermissionsForDataDelivery() {
         Binder.withCleanCallingIdentity(() -> {
-            // Hack to make sure we show the mic privacy-indicator since the Trusted Hotword
-            // requirement isn't being enforced for now. Normally, we would note the HOTWORD op here
-            // instead.
-            enforcePermissionForDataDelivery(mContext, mVoiceInteractorIdentity,
-                    RECORD_AUDIO, OP_MESSAGE);
-
+            enforcePermissionForPreflight(mContext, mVoiceInteractorIdentity, RECORD_AUDIO);
+            int hotwordOp = AppOpsManager.strOpToOp(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD);
+            mContext.getSystemService(AppOpsManager.class).noteOpNoThrow(hotwordOp,
+                    mVoiceInteractorIdentity.uid, mVoiceInteractorIdentity.packageName,
+                    mVoiceInteractorIdentity.attributionTag, OP_MESSAGE);
             enforcePermissionForDataDelivery(mContext, mVoiceInteractorIdentity,
                     CAPTURE_AUDIO_HOTWORD, OP_MESSAGE);
         });
diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java
index 5f7cfd1..23835a7 100644
--- a/telephony/java/android/telephony/DataFailCause.java
+++ b/telephony/java/android/telephony/DataFailCause.java
@@ -125,6 +125,12 @@
     public static final int UNSUPPORTED_QCI_VALUE = 0x3B;
     /** Procedure requested by the UE was rejected because the bearer handling is not supported. */
     public static final int BEARER_HANDLING_NOT_SUPPORTED = 0x3C;
+    /**
+     * This cause is used to report a service or option not available event only when no other
+     * cause in the service or option not available class applies.
+     * @hide // TODO: Unhide in U.
+     */
+    public static final int SERVICE_OR_OPTION_NOT_AVAILABLE = 0x3F;
     /** Max number of Packet Data Protocol (PDP) context reached. */
     public static final int ACTIVE_PDP_CONTEXT_MAX_NUMBER_REACHED = 0x41;
     /** Unsupported APN in current public land mobile network (PLMN). */
@@ -1142,6 +1148,7 @@
         sFailCauseMap.put(ONLY_NON_IP_ALLOWED, "ONLY_NON_IP_ALLOWED");
         sFailCauseMap.put(UNSUPPORTED_QCI_VALUE, "UNSUPPORTED_QCI_VALUE");
         sFailCauseMap.put(BEARER_HANDLING_NOT_SUPPORTED, "BEARER_HANDLING_NOT_SUPPORTED");
+        sFailCauseMap.put(SERVICE_OR_OPTION_NOT_AVAILABLE, "SERVICE_OR_OPTION_NOT_AVAILABLE");
         sFailCauseMap.put(ACTIVE_PDP_CONTEXT_MAX_NUMBER_REACHED,
                 "ACTIVE_PDP_CONTEXT_MAX_NUMBER_REACHED");
         sFailCauseMap.put(UNSUPPORTED_APN_IN_CURRENT_PLMN,