Merge "Fixed that silent notifications weren't showing on AOD" into qt-r1-dev
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 475dccb..f66448f 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -8101,8 +8101,7 @@
          */
         @Override
         public RemoteViews makeHeadsUpContentView(boolean increasedHeight) {
-            RemoteViews expanded = makeMediaBigContentView();
-            return expanded != null ? expanded : makeMediaContentView();
+            return makeMediaContentView();
         }
 
         /** @hide */
diff --git a/core/java/android/hardware/biometrics/IBiometricEnabledOnKeyguardCallback.aidl b/core/java/android/hardware/biometrics/IBiometricEnabledOnKeyguardCallback.aidl
index d22e7e2..62d727c 100644
--- a/core/java/android/hardware/biometrics/IBiometricEnabledOnKeyguardCallback.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricEnabledOnKeyguardCallback.aidl
@@ -22,5 +22,5 @@
  * @hide
  */
 oneway interface IBiometricEnabledOnKeyguardCallback {
-    void onChanged(in BiometricSourceType type, boolean enabled);
+    void onChanged(in BiometricSourceType type, boolean enabled, int userId);
 }
\ No newline at end of file
diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java
index c3c2c0d..2bf1ba5 100644
--- a/core/java/android/widget/ArrayAdapter.java
+++ b/core/java/android/widget/ArrayAdapter.java
@@ -50,7 +50,7 @@
  * override {@link #getView(int, View, ViewGroup)}
  * and inflate a view resource.
  * For a code example, see
- * the <a href="https://developer.android.com/samples/CustomChoiceList/index.html">
+ * the <a href="https://github.com/googlesamples/android-CustomChoiceList/#readme">
  * CustomChoiceList</a> sample.
  * </p>
  * <p>
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index d985528..6b324a5 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -1202,13 +1202,13 @@
      * determine where to position the view on the screen.  If the view is not contained
      * within a relative layout, these attributes are ignored.
      *
-     * See the <a href="/guide/topics/ui/layout/relative.html">
-     * Relative Layout</a> guide for example code demonstrating how to use relative layout’s
+     * See the <a href="{@docRoot}guide/topics/ui/layout/relative.html">Relative
+     * Layout</a> guide for example code demonstrating how to use relative layout's
      * layout parameters in a layout XML.
      *
      * To learn more about layout parameters and how they differ from typical view attributes,
-     * see the <a href="/guide/topics/ui/declaring-layout.html#attributes">
-     *     Layouts guide</a>.
+     * see the <a href="{@docRoot}guide/topics/ui/declaring-layout.html#attributes">Layouts
+     * guide</a>.
      *
      *
      * @attr ref android.R.styleable#RelativeLayout_Layout_layout_alignWithParentIfMissing
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index 55e21a4..e91a0ea 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -191,6 +191,89 @@
      */
     public static final String BRIGHTLINE_FALSING_MANAGER_ENABLED =
             "brightline_falsing_manager_enabled";
+    /**
+     * (float) Maximum fraction of the screen required to qualify as a real swipe.
+     */
+    public static final String BRIGHTLINE_FALSING_DISTANCE_SCREEN_FRACTION_MAX_DISTANCE =
+            "brightline_falsing_distance_screen_fraction_max_distance";
+
+    /**
+     * (float) Multiplier for swipe velocity to convert it to pixels for a fling.
+     */
+    public static final String BRIGHTLINE_FALSING_DISTANCE_VELOCITY_TO_DISTANCE =
+            "brightline_falsing_distance_velcoity_to_distance";
+
+    /**
+     * (float) How far, in inches, must a fling travel horizontally to qualify as intentional.
+     */
+    public static final String BRIGHTLINE_FALSING_DISTANCE_HORIZONTAL_FLING_THRESHOLD_IN =
+            "brightline_falsing_distance_horizontal_fling_threshold_in";
+
+    /**
+     * (float) Maximum fraction of the screen required to qualify as a real swipe.
+     */
+    public static final String BRIGHTLINE_FALSING_DISTANCE_VERTICAL_FLING_THRESHOLD_IN =
+            "brightline_falsing_distance_vertical_fling_threshold_in";
+
+    /**
+     * (float) How far, in inches, must a continuous swipe travel horizontally to be intentional.
+     */
+    public static final String BRIGHTLINE_FALSING_DISTANCE_HORIZONTAL_SWIPE_THRESHOLD_IN =
+            "brightline_falsing_distance_horizontal_swipe_threshold_in";
+
+    /**
+     * (float) How far, in inches, must a continuous swipe travel vertically to be intentional.
+     */
+    public static final String BRIGHTLINE_FALSING_DISTANCE_VERTICAL_SWIPE_THRESHOLD_IN =
+            "brightline_falsing_distance_horizontal_swipe_threshold_in";
+
+    /**
+     * (float) Percentage of swipe with the proximity sensor covered that triggers a higher
+     * swipe distance requirement.
+     */
+    public static final String BRIGHTLINE_FALSING_PROXIMITY_PERCENT_COVERED_THRESHOLD =
+            "brightline_falsing_proximity_percent_covered_threshold";
+
+    /**
+     * (float) Angle, in radians, that a swipe can vary from horizontal and sill be intentional.
+     */
+    public static final String BRIGHTLINE_FALSING_DIAGONAL_HORIZONTAL_ANGLE_RANGE =
+            "brightline_falsing_diagonal_horizontal_angle_range";
+
+    /**
+     * (float) Angle, in radians, that a swipe can vary from vertical and sill be intentional.
+     */
+    public static final String BRIGHTLINE_FALSING_DIAGONAL_VERTICAL_ANGLE_RANGE =
+            "brightline_falsing_diagonal_horizontal_angle_range";
+
+    /**
+     * (float) Distance, in inches, that a swipe is allowed to vary in the horizontal direction for
+     * horizontal swipes.
+     */
+    public static final String BRIGHTLINE_FALSING_ZIGZAG_X_PRIMARY_DEVIANCE =
+            "brightline_falsing_zigzag_x_primary_deviance";
+
+    /**
+     * (float) Distance, in inches, that a swipe is allowed to vary in the vertical direction for
+     * vertical swipes.
+     */
+    public static final String BRIGHTLINE_FALSING_ZIGZAG_Y_PRIMARY_DEVIANCE =
+            "brightline_falsing_zigzag_y_primary_deviance";
+
+    /**
+     * (float) Distance, in inches, that a swipe is allowed to vary in the horizontal direction for
+     * horizontal swipes.
+     */
+    public static final String BRIGHTLINE_FALSING_ZIGZAG_X_SECONDARY_DEVIANCE =
+            "brightline_falsing_zigzag_x_secondary_deviance";
+
+    /**
+     * (float) Distance, in inches, that a swipe is allowed to vary in the vertical direction for
+     * vertical swipes.
+     */
+    public static final String BRIGHTLINE_FALSING_ZIGZAG_Y_SECONDARY_DEVIANCE =
+            "brightline_falsing_zigzag_y_secondary_deviance";
+
 
     private SystemUiDeviceConfigFlags() { }
 }
diff --git a/core/res/res/layout/notification_template_material_media.xml b/core/res/res/layout/notification_template_material_media.xml
index 13fef67..575295b 100644
--- a/core/res/res/layout/notification_template_material_media.xml
+++ b/core/res/res/layout/notification_template_material_media.xml
@@ -15,7 +15,7 @@
   ~ limitations under the License
   -->
 
-<FrameLayout
+<com.android.internal.widget.MediaNotificationView
     android:id="@+id/status_bar_latest_event_content"
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
@@ -24,8 +24,8 @@
     android:tag="media"
     >
     <ImageView android:id="@+id/right_icon"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
         android:adjustViewBounds="true"
         android:layout_gravity="top|end"
         android:scaleType="centerCrop"
@@ -91,4 +91,4 @@
             android:layout_alignParentBottom="true"
         />
     </LinearLayout>
-</FrameLayout>
+</com.android.internal.widget.MediaNotificationView>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 619af24..b13f506 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -594,7 +594,7 @@
   </string-array>
     <string name="face_icon_content_description" msgid="4024817159806482191">"Icona facial"</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"llegir la configuració de sincronització"</string>
-    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permet que l\'aplicació llegeixi la configuració de sincronització d\'un compte. Per exemple, això pot determinar que l\'aplicació Persones estigui sincronitzada amb un compte."</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permet que l\'aplicació llegeixi la configuració de sincronització d\'un compte. Per exemple, això pot determinar que l\'aplicació Contactes estigui sincronitzada amb un compte."</string>
     <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"activar o desactivar la sincronització"</string>
     <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Permet que una aplicació modifiqui la configuració de sincronització d\'un compte. Per exemple, aquesta acció es pot fer servir per activar la sincronització de l\'aplicació Persones amb un compte."</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"llegir les estadístiques de sincronització"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 1ab77cc..754b019 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -428,7 +428,7 @@
     <string name="permdesc_recordAudio" msgid="4245930455135321433">"Diese App kann jederzeit Audio über das Mikrofon aufnehmen."</string>
     <string name="permlab_sim_communication" msgid="2935852302216852065">"Befehle an die SIM senden"</string>
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"Ermöglicht der App das Senden von Befehlen an die SIM-Karte. Dies ist äußerst risikoreich."</string>
-    <string name="permlab_activityRecognition" msgid="3634590230567608356">"körperlichen Aktivitäten erkennen"</string>
+    <string name="permlab_activityRecognition" msgid="3634590230567608356">"Körperliche Aktivitäten erkennen"</string>
     <string name="permdesc_activityRecognition" msgid="3143453925156552894">"Diese App kann deine körperliche Aktivität erkennen."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"Bilder und Videos aufnehmen"</string>
     <string name="permdesc_camera" msgid="5392231870049240670">"Diese App kann mit der Kamera jederzeit Bilder und Videos aufnehmen."</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 4c8cc64..7a1b265 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -1984,7 +1984,7 @@
     <string name="harmful_app_warning_uninstall" msgid="4837672735619532931">"DESINSTALAR"</string>
     <string name="harmful_app_warning_open_anyway" msgid="596432803680914321">"ABRIR IGUALMENTE"</string>
     <string name="harmful_app_warning_title" msgid="8982527462829423432">"Detectouse unha aplicación daniña"</string>
-    <string name="slices_permission_request" msgid="8484943441501672932">"A aplicación <xliff:g id="APP_0">%1$s</xliff:g> quere mostrar partes de <xliff:g id="APP_2">%2$s</xliff:g>"</string>
+    <string name="slices_permission_request" msgid="8484943441501672932">"<xliff:g id="APP_0">%1$s</xliff:g> quere mostrar fragmentos de aplicación de <xliff:g id="APP_2">%2$s</xliff:g>"</string>
     <string name="screenshot_edit" msgid="7867478911006447565">"Editar"</string>
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="8902050240801159042">"As chamadas e as notificacións vibrarán"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="2128975224280276122">"As chamadas e as notificacións estarán silenciadas"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index c615356..3377d3b 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1613,7 +1613,7 @@
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Ներկառուցված էկրան"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI էկրան"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Վերածածկ #<xliff:g id="ID">%1$d</xliff:g>"</string>
-    <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>. <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> կմվ"</string>
+    <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>. <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> կմչ"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", անվտանգ"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Մոռացել եմ սխեման"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Սխալ սխեմա"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 962ad51..4937ced 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1711,7 +1711,7 @@
     <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"Gdy skrót jest włączony, jednoczesne naciśnięcie przez trzy sekundy obu klawiszy sterowania głośnością uruchomi funkcję ułatwień dostępu.\n\nBieżąca funkcja ułatwień dostępu:\n<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\nFunkcję możesz zmienić, wybierając Ustawienia &gt; Ułatwienia dostępu."</string>
     <string name="disable_accessibility_shortcut" msgid="627625354248453445">"Wyłącz skrót"</string>
     <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"Użyj skrótu"</string>
-    <string name="color_inversion_feature_name" msgid="4231186527799958644">"Inwersja kolorów"</string>
+    <string name="color_inversion_feature_name" msgid="4231186527799958644">"Odwrócenie kolorów"</string>
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Korekcja kolorów"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Skrót ułatwień dostępu wyłączył usługę <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Skrót ułatwień dostępu wyłączył usługę <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 305dca0..429861b 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -520,7 +520,7 @@
     <string name="permdesc_imagesWrite" msgid="7073662756617474375">"Cho phép ứng dụng này sửa đổi bộ sưu tập ảnh của bạn."</string>
     <string name="permlab_mediaLocation" msgid="8675148183726247864">"đọc vị trí từ bộ sưu tập phương tiện"</string>
     <string name="permdesc_mediaLocation" msgid="2237023389178865130">"Cho phép ứng dụng này đọc vị trí từ bộ sưu tập phương tiện của bạn."</string>
-    <string name="biometric_dialog_default_title" msgid="881952973720613213">"Hãy xác minh đó là bạn"</string>
+    <string name="biometric_dialog_default_title" msgid="881952973720613213">"Xác minh danh tính của bạn"</string>
     <string name="biometric_error_hw_unavailable" msgid="645781226537551036">"Không có phần cứng sinh trắc học"</string>
     <string name="biometric_error_user_canceled" msgid="2260175018114348727">"Đã hủy xác thực"</string>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Không nhận dạng được"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 85d5cf9..ef50a39 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -297,7 +297,7 @@
     <string name="permgrouplab_microphone" msgid="171539900250043464">"麦克风"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"录制音频"</string>
     <string name="permgrouprequest_microphone" msgid="9167492350681916038">"允许&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;录音吗?"</string>
-    <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"健身运动"</string>
+    <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"身体活动"</string>
     <string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"访问您的健身运动"</string>
     <string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"允许&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;访问您的健身运动吗?"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"相机"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 42b7900..cce909a4 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -550,11 +550,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"指紋圖示"</string>
-    <string name="permlab_manageFace" msgid="7262837876352591553">"管理臉容解鎖硬件"</string>
+    <string name="permlab_manageFace" msgid="7262837876352591553">"管理臉孔解鎖硬件"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"允許應用程式調用方法,以加入和刪除可用的臉孔範本。"</string>
-    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"使用臉容解鎖硬件"</string>
-    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"允許應用程式使用臉容解鎖硬件來驗證"</string>
-    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"臉容解鎖"</string>
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"使用臉孔解鎖硬件"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"允許應用程式使用臉孔解鎖硬件來驗證"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"臉孔解鎖"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"重新註冊臉孔"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"如要提高識別能力,請重新註冊您的臉孔"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"無法擷取準確的臉容資料。請再試一次。"</string>
@@ -580,15 +580,15 @@
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"無法驗證臉孔,硬件無法使用。"</string>
-    <string name="face_error_timeout" msgid="981512090365729465">"請再次嘗試「臉容解鎖」。"</string>
+    <string name="face_error_timeout" msgid="981512090365729465">"請再次嘗試「臉孔解鎖」。"</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"無法儲存新的臉容資料,請先刪除舊資料。"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"臉孔操作已取消。"</string>
-    <string name="face_error_user_canceled" msgid="5317030072349668946">"使用者已取消「臉容解鎖」。"</string>
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"使用者已取消「臉孔解鎖」。"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"嘗試次數過多,請稍後再試。"</string>
-    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"嘗試次數過多,「臉容解鎖」已停用。"</string>
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"嘗試次數過多,「臉孔解鎖」已停用。"</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"無法驗證臉孔。請再試一次。"</string>
-    <string name="face_error_not_enrolled" msgid="4016937174832839540">"您尚未設定「臉容解鎖」。"</string>
-    <string name="face_error_hw_not_present" msgid="8302690289757559738">"此裝置不支援「臉容解鎖」。"</string>
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"您尚未設定「臉孔解鎖」。"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"此裝置不支援「臉孔解鎖」。"</string>
     <string name="face_name_template" msgid="7004562145809595384">"臉孔 <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -817,7 +817,7 @@
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"再試一次"</string>
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"再試一次"</string>
     <string name="lockscreen_storage_locked" msgid="9167551160010625200">"解鎖即可使用所有功能和資料"</string>
-    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"已超過臉容解鎖嘗試次數上限"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"已超過臉孔解鎖嘗試次數上限"</string>
     <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"找不到 SIM 卡"</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"平板電腦中沒有 SIM 卡。"</string>
     <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"電視沒有 SIM 卡。"</string>
@@ -887,7 +887,7 @@
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"展開解鎖區域。"</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"滑動解鎖。"</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"圖案解鎖。"</string>
-    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"臉容解鎖。"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"臉孔解鎖。"</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN 解鎖。"</string>
     <string name="keyguard_accessibility_sim_pin_unlock" msgid="9149698847116962307">"SIM 卡 PIN 碼解鎖。"</string>
     <string name="keyguard_accessibility_sim_puk_unlock" msgid="9106899279724723341">"SIM 卡 PUK 解鎖。"</string>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 039bc4d..6653879 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -279,7 +279,7 @@
     <dimen name="notification_expand_button_padding_top">1dp</dimen>
 
     <!-- Height of a small notification in the status bar -->
-    <dimen name="notification_min_height">92dp</dimen>
+    <dimen name="notification_min_height">106dp</dimen>
 
     <!-- The width of the big icons in notifications. -->
     <dimen name="notification_large_icon_width">64dp</dimen>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index d13c715..1f5a010 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3797,6 +3797,7 @@
   <java-symbol type="string" name="config_displayLightSensorType" />
 
   <java-symbol type="drawable" name="iconfactory_adaptive_icon_drawable_wrapper"/>
+  <java-symbol type="dimen" name="notification_min_height" />
   <java-symbol type="dimen" name="resolver_icon_size"/>
   <java-symbol type="dimen" name="resolver_badge_size"/>
   <java-symbol type="dimen" name="resolver_button_bar_spacing"/>
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index f326ce8..9898a1c 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -148,7 +148,8 @@
 
     if (surface) {
         mNativeSurface = new ReliableSurface{std::move(surface)};
-        mNativeSurface->setDequeueTimeout(500_ms);
+        // TODO: Fix error handling & re-shorten timeout
+        mNativeSurface->setDequeueTimeout(4000_ms);
     } else {
         mNativeSurface = nullptr;
     }
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 08fb0b3..90ead35 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -255,8 +255,8 @@
     <string name="accessibility_quick_settings_flashlight_on" msgid="2003479320007841077">"Lommelygten er tændt."</string>
     <string name="accessibility_quick_settings_flashlight_changed_off" msgid="3303701786768224304">"Lommelygten er slukket."</string>
     <string name="accessibility_quick_settings_flashlight_changed_on" msgid="6531793301533894686">"Lommelygten er tændt."</string>
-    <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="4406577213290173911">"Invertering af farver er slået fra."</string>
-    <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"Invertering af farver er slået til."</string>
+    <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="4406577213290173911">"Ombytning af farver er slået fra."</string>
+    <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"Ombytning af farver er slået til."</string>
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobilhotspot er slået fra."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobilhotspot er slået til."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Casting af din skærm er stoppet."</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index b25f2fc..75a76ae 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -376,7 +376,7 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Jusqu\'à l\'aube"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"À partir de <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Jusqu\'à <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Thème foncé"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Thème sombre"</string>
     <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Thème foncé\nÉconomiseur de batterie"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"La technologie NFC est désactivée"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 1a914e0..3268ed0 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -894,10 +894,10 @@
     <string name="mobile_data_disable_message" msgid="4756541658791493506">"Non terás acceso aos datos nin a Internet a través de <xliff:g id="CARRIER">%s</xliff:g>. Internet só estará dispoñible mediante a wifi."</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6078110473451946831">"o teu operador"</string>
     <string name="touch_filtered_warning" msgid="8671693809204767551">"Dado que unha aplicación se superpón sobre unha solicitude de permiso, a configuración non pode verificar a túa resposta."</string>
-    <string name="slice_permission_title" msgid="7465009437851044444">"Queres permitir que a aplicación <xliff:g id="APP_0">%1$s</xliff:g> mostre partes de <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
+    <string name="slice_permission_title" msgid="7465009437851044444">"Queres permitir que <xliff:g id="APP_0">%1$s</xliff:g> mostre fragmentos de aplicación de <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
     <string name="slice_permission_text_1" msgid="3514586565609596523">"- Pode ler información da aplicación <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="slice_permission_text_2" msgid="3146758297471143723">"- Pode levar a cabo accións dentro da aplicación <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="slice_permission_checkbox" msgid="7986504458640562900">"Permitir que a aplicación <xliff:g id="APP">%1$s</xliff:g> mostre partes de calquera aplicación"</string>
+    <string name="slice_permission_checkbox" msgid="7986504458640562900">"Permitir que <xliff:g id="APP">%1$s</xliff:g> mostre fragmentos de calquera aplicación"</string>
     <string name="slice_permission_allow" msgid="2340244901366722709">"Permitir"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Denegar"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Tocar para programar a función Aforro de batería"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 08816c7..83a7aaa 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -614,7 +614,7 @@
     <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Të hiqet Sintonizuesi i Sistemit të Ndërfaqes së Përdoruesit nga Cilësimet dhe të ndërpritet përdorimi i të gjitha funksioneve të tij?"</string>
     <string name="activity_not_found" msgid="348423244327799974">"Aplikacioni nuk është instaluar në pajisjen tënde."</string>
     <string name="clock_seconds" msgid="7689554147579179507">"Trego sekondat e orës"</string>
-    <string name="clock_seconds_desc" msgid="6282693067130470675">"Trego sekondat e orës në shiritin e statusit. Mund të ndikojë te jeta e baterisë."</string>
+    <string name="clock_seconds_desc" msgid="6282693067130470675">"Trego sekondat e orës në shiritin e statusit. Mund të ndikojë te kohëzgjatja e baterisë."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Risistemo Cilësimet e shpejta"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Shfaq ndriçimin te Cilësimet e shpejta"</string>
     <string name="experimental" msgid="6198182315536726162">"Eksperimentale"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index aa25cf9..bef1fc2 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -112,7 +112,7 @@
     <dimen name="status_bar_connected_device_bt_indicator_size">17dp</dimen>
 
     <!-- Height of a small notification in the status bar-->
-    <dimen name="notification_min_height">106dp</dimen>
+    <dimen name="notification_min_height">@*android:dimen/notification_min_height</dimen>
 
     <!-- Increased height of a small notification in the status bar -->
     <dimen name="notification_min_height_increased">146dp</dimen>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 2eb93d3..fd618b0 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -377,14 +377,15 @@
         }
     };
 
-    private boolean mFaceSettingEnabledForUser;
+    private SparseBooleanArray mFaceSettingEnabledForUser = new SparseBooleanArray();
     private BiometricManager mBiometricManager;
     private IBiometricEnabledOnKeyguardCallback mBiometricEnabledCallback =
             new IBiometricEnabledOnKeyguardCallback.Stub() {
         @Override
-        public void onChanged(BiometricSourceType type, boolean enabled) throws RemoteException {
+        public void onChanged(BiometricSourceType type, boolean enabled, int userId)
+                throws RemoteException {
             if (type == BiometricSourceType.FACE) {
-                mFaceSettingEnabledForUser = enabled;
+                mFaceSettingEnabledForUser.put(userId, enabled);
                 updateFaceListeningState();
             }
         }
@@ -1711,7 +1712,7 @@
         // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
         return (mBouncer || mAuthInterruptActive || awakeKeyguard || shouldListenForFaceAssistant())
                 && !mSwitchingUser && !isFaceDisabled(user) && becauseCannotSkipBouncer
-                && !mKeyguardGoingAway && mFaceSettingEnabledForUser && !mLockIconPressed
+                && !mKeyguardGoingAway && mFaceSettingEnabledForUser.get(user) && !mLockIconPressed
                 && strongAuthAllowsScanning && mIsPrimaryUser
                 && !mSecureCameraLaunched;
     }
@@ -1783,13 +1784,14 @@
     }
 
     /**
-     * If face hardware is available and user has enrolled. Not considering encryption or
-     * lockdown state.
+     * If face hardware is available, user has enrolled and enabled auth via setting.
+     * Not considering encryption or lock down state.
      */
     public boolean isUnlockWithFacePossible(int userId) {
         return mFaceManager != null && mFaceManager.isHardwareDetected()
                 && !isFaceDisabled(userId)
-                && mFaceManager.hasEnrolledTemplates(userId);
+                && mFaceManager.hasEnrolledTemplates(userId)
+                && mFaceSettingEnabledForUser.get(userId);
     }
 
     private void stopListeningForFingerprint() {
@@ -2657,7 +2659,7 @@
             pw.println("    possible=" + isUnlockWithFacePossible(userId));
             pw.println("    strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
             pw.println("    trustManaged=" + getUserTrustIsManaged(userId));
-            pw.println("    enabledByUser=" + mFaceSettingEnabledForUser);
+            pw.println("    enabledByUser=" + mFaceSettingEnabledForUser.get(userId));
             pw.println("    mSecureCameraLaunched=" + mSecureCameraLaunched);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
index 8210951..128cc61 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
@@ -92,7 +92,11 @@
     @VisibleForTesting
     public void setupFalsingManager(Context context) {
         boolean brightlineEnabled = DeviceConfig.getBoolean(
-                DeviceConfig.NAMESPACE_SYSTEMUI, BRIGHTLINE_FALSING_MANAGER_ENABLED, false);
+                DeviceConfig.NAMESPACE_SYSTEMUI, BRIGHTLINE_FALSING_MANAGER_ENABLED, true);
+
+        if (mInternalFalsingManager != null) {
+            mInternalFalsingManager.cleanup();
+        }
         if (!brightlineEnabled) {
             mInternalFalsingManager = new FalsingManagerImpl(context);
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java
index 730907e..cc66454 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java
@@ -16,9 +16,13 @@
 
 package com.android.systemui.classifier.brightline;
 
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DIAGONAL_HORIZONTAL_ANGLE_RANGE;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DIAGONAL_VERTICAL_ANGLE_RANGE;
 import static com.android.systemui.classifier.Classifier.LEFT_AFFORDANCE;
 import static com.android.systemui.classifier.Classifier.RIGHT_AFFORDANCE;
 
+import android.provider.DeviceConfig;
+
 /**
  * False on swipes that are too close to 45 degrees.
  *
@@ -35,8 +39,20 @@
     private static final float ONE_HUNDRED_EIGHTY_DEG = (float) (Math.PI);
     private static final float THREE_HUNDRED_SIXTY_DEG = (float) (2 * Math.PI);
 
+    private final float mHorizontalAngleRange;
+    private final float mVerticalAngleRange;
+
     DiagonalClassifier(FalsingDataProvider dataProvider) {
         super(dataProvider);
+
+        mHorizontalAngleRange = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_DIAGONAL_HORIZONTAL_ANGLE_RANGE,
+                HORIZONTAL_ANGLE_RANGE);
+        mVerticalAngleRange = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_DIAGONAL_VERTICAL_ANGLE_RANGE,
+                VERTICAL_ANGLE_RANGE);
     }
 
     @Override
@@ -52,11 +68,11 @@
             return false;
         }
 
-        float minAngle = DIAGONAL - HORIZONTAL_ANGLE_RANGE;
-        float maxAngle = DIAGONAL + HORIZONTAL_ANGLE_RANGE;
+        float minAngle = DIAGONAL - mHorizontalAngleRange;
+        float maxAngle = DIAGONAL + mHorizontalAngleRange;
         if (isVertical()) {
-            minAngle = DIAGONAL - VERTICAL_ANGLE_RANGE;
-            maxAngle = DIAGONAL + VERTICAL_ANGLE_RANGE;
+            minAngle = DIAGONAL - mVerticalAngleRange;
+            maxAngle = DIAGONAL + mVerticalAngleRange;
         }
 
         return angleBetween(angle, minAngle, maxAngle)
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java
index 005ee12..a6a617d 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java
@@ -16,6 +16,14 @@
 
 package com.android.systemui.classifier.brightline;
 
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DISTANCE_HORIZONTAL_FLING_THRESHOLD_IN;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DISTANCE_HORIZONTAL_SWIPE_THRESHOLD_IN;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DISTANCE_SCREEN_FRACTION_MAX_DISTANCE;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DISTANCE_VELOCITY_TO_DISTANCE;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DISTANCE_VERTICAL_FLING_THRESHOLD_IN;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DISTANCE_VERTICAL_SWIPE_THRESHOLD_IN;
+
+import android.provider.DeviceConfig;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 
@@ -31,12 +39,13 @@
     private static final float HORIZONTAL_SWIPE_THRESHOLD_DISTANCE_IN = 3;
     private static final float VERTICAL_SWIPE_THRESHOLD_DISTANCE_IN = 3;
     private static final float VELOCITY_TO_DISTANCE = 80f;
-    private static final float SCREEN_FRACTION_MIN_DISTANCE = 0.8f;
+    private static final float SCREEN_FRACTION_MAX_DISTANCE = 0.8f;
 
     private final float mVerticalFlingThresholdPx;
     private final float mHorizontalFlingThresholdPx;
     private final float mVerticalSwipeThresholdPx;
     private final float mHorizontalSwipeThresholdPx;
+    private final float mVelocityToDistanceMultiplier;
 
     private boolean mDistanceDirty;
     private DistanceVectors mCachedDistance;
@@ -44,18 +53,48 @@
     DistanceClassifier(FalsingDataProvider dataProvider) {
         super(dataProvider);
 
+        mVelocityToDistanceMultiplier = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_DISTANCE_VELOCITY_TO_DISTANCE,
+                VELOCITY_TO_DISTANCE);
+
+        float horizontalFlingThresholdIn = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_DISTANCE_HORIZONTAL_FLING_THRESHOLD_IN,
+                HORIZONTAL_FLING_THRESHOLD_DISTANCE_IN);
+
+        float verticalFlingThresholdIn = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_DISTANCE_VERTICAL_FLING_THRESHOLD_IN,
+                VERTICAL_FLING_THRESHOLD_DISTANCE_IN);
+
+        float horizontalSwipeThresholdIn = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_DISTANCE_HORIZONTAL_SWIPE_THRESHOLD_IN,
+                HORIZONTAL_SWIPE_THRESHOLD_DISTANCE_IN);
+
+        float verticalSwipeThresholdIn = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_DISTANCE_VERTICAL_SWIPE_THRESHOLD_IN,
+                VERTICAL_SWIPE_THRESHOLD_DISTANCE_IN);
+
+        float screenFractionMaxDistance = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_DISTANCE_SCREEN_FRACTION_MAX_DISTANCE,
+                SCREEN_FRACTION_MAX_DISTANCE);
+
         mHorizontalFlingThresholdPx = Math
-                .min(getWidthPixels() * SCREEN_FRACTION_MIN_DISTANCE,
-                        HORIZONTAL_FLING_THRESHOLD_DISTANCE_IN * getXdpi());
+                .min(getWidthPixels() * screenFractionMaxDistance,
+                        horizontalFlingThresholdIn * getXdpi());
         mVerticalFlingThresholdPx = Math
-                .min(getHeightPixels() * SCREEN_FRACTION_MIN_DISTANCE,
-                        VERTICAL_FLING_THRESHOLD_DISTANCE_IN * getYdpi());
+                .min(getHeightPixels() * screenFractionMaxDistance,
+                        verticalFlingThresholdIn * getYdpi());
         mHorizontalSwipeThresholdPx = Math
-                .min(getWidthPixels() * SCREEN_FRACTION_MIN_DISTANCE,
-                        HORIZONTAL_SWIPE_THRESHOLD_DISTANCE_IN * getXdpi());
+                .min(getWidthPixels() * screenFractionMaxDistance,
+                        horizontalSwipeThresholdIn * getXdpi());
         mVerticalSwipeThresholdPx = Math
-                .min(getHeightPixels() * SCREEN_FRACTION_MIN_DISTANCE,
-                        VERTICAL_SWIPE_THRESHOLD_DISTANCE_IN * getYdpi());
+                .min(getHeightPixels() * screenFractionMaxDistance,
+                        verticalSwipeThresholdIn * getYdpi());
         mDistanceDirty = true;
     }
 
@@ -139,18 +178,18 @@
         }
 
         boolean getPassedFlingThreshold() {
-            float dX = this.mDx + this.mVx * VELOCITY_TO_DISTANCE;
-            float dY = this.mDy + this.mVy * VELOCITY_TO_DISTANCE;
+            float dX = this.mDx + this.mVx * mVelocityToDistanceMultiplier;
+            float dY = this.mDy + this.mVy * mVelocityToDistanceMultiplier;
 
             if (isHorizontal()) {
                 logDebug("Horizontal swipe and fling distance: " + this.mDx + ", "
-                        + this.mVx * VELOCITY_TO_DISTANCE);
+                        + this.mVx * mVelocityToDistanceMultiplier);
                 logDebug("Threshold: " + mHorizontalFlingThresholdPx);
                 return Math.abs(dX) >= mHorizontalFlingThresholdPx;
             }
 
             logDebug("Vertical swipe and fling distance: " + this.mDy + ", "
-                    + this.mVy * VELOCITY_TO_DISTANCE);
+                    + this.mVy * mVelocityToDistanceMultiplier);
             logDebug("Threshold: " + mVerticalFlingThresholdPx);
             return Math.abs(dY) >= mVerticalFlingThresholdPx;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java
index 94a8ac85..2644bf9 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java
@@ -16,10 +16,12 @@
 
 package com.android.systemui.classifier.brightline;
 
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_PROXIMITY_PERCENT_COVERED_THRESHOLD;
 import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
 
 import android.hardware.Sensor;
 import android.hardware.SensorEvent;
+import android.provider.DeviceConfig;
 import android.view.MotionEvent;
 
 
@@ -31,8 +33,9 @@
  */
 class ProximityClassifier extends FalsingClassifier {
 
-    private static final double PERCENT_COVERED_THRESHOLD = 0.1;
+    private static final float PERCENT_COVERED_THRESHOLD = 0.1f;
     private final DistanceClassifier mDistanceClassifier;
+    private final float mPercentCoveredThreshold;
 
     private boolean mNear;
     private long mGestureStartTimeNs;
@@ -44,6 +47,11 @@
             FalsingDataProvider dataProvider) {
         super(dataProvider);
         this.mDistanceClassifier = distanceClassifier;
+
+        mPercentCoveredThreshold = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_PROXIMITY_PERCENT_COVERED_THRESHOLD,
+                PERCENT_COVERED_THRESHOLD);
     }
 
     @Override
@@ -107,7 +115,7 @@
 
         logInfo("Percent of gesture in proximity: " + mPercentNear);
 
-        if (mPercentNear > PERCENT_COVERED_THRESHOLD) {
+        if (mPercentNear > mPercentCoveredThreshold) {
             return !mDistanceClassifier.isLongSwipe();
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java
index a62574f..c58b7db 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java
@@ -16,7 +16,13 @@
 
 package com.android.systemui.classifier.brightline;
 
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_ZIGZAG_X_PRIMARY_DEVIANCE;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_ZIGZAG_X_SECONDARY_DEVIANCE;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_ZIGZAG_Y_PRIMARY_DEVIANCE;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_ZIGZAG_Y_SECONDARY_DEVIANCE;
+
 import android.graphics.Point;
+import android.provider.DeviceConfig;
 import android.view.MotionEvent;
 
 import java.util.ArrayList;
@@ -37,8 +43,34 @@
     private static final float MAX_X_SECONDARY_DEVIANCE = .3f;
     private static final float MAX_Y_SECONDARY_DEVIANCE = .3f;
 
+    private final float mMaxXPrimaryDeviance;
+    private final float mMaxYPrimaryDeviance;
+    private final float mMaxXSecondaryDeviance;
+    private final float mMaxYSecondaryDeviance;
+
     ZigZagClassifier(FalsingDataProvider dataProvider) {
         super(dataProvider);
+
+        mMaxXPrimaryDeviance = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_ZIGZAG_X_PRIMARY_DEVIANCE,
+                MAX_X_PRIMARY_DEVIANCE);
+
+        mMaxYPrimaryDeviance = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_ZIGZAG_Y_PRIMARY_DEVIANCE,
+                MAX_Y_PRIMARY_DEVIANCE);
+
+        mMaxXSecondaryDeviance = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_ZIGZAG_X_SECONDARY_DEVIANCE,
+                MAX_X_SECONDARY_DEVIANCE);
+
+        mMaxYSecondaryDeviance = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_ZIGZAG_Y_SECONDARY_DEVIANCE,
+                MAX_Y_SECONDARY_DEVIANCE);
+
     }
 
     @Override
@@ -98,11 +130,11 @@
         float maxXDeviance;
         float maxYDeviance;
         if (actualDx > actualDy) {
-            maxXDeviance = MAX_X_PRIMARY_DEVIANCE * totalDistanceIn * getXdpi();
-            maxYDeviance = MAX_Y_SECONDARY_DEVIANCE * totalDistanceIn * getYdpi();
+            maxXDeviance = mMaxXPrimaryDeviance * totalDistanceIn * getXdpi();
+            maxYDeviance = mMaxYSecondaryDeviance * totalDistanceIn * getYdpi();
         } else {
-            maxXDeviance = MAX_X_SECONDARY_DEVIANCE * totalDistanceIn * getXdpi();
-            maxYDeviance = MAX_Y_PRIMARY_DEVIANCE * totalDistanceIn * getYdpi();
+            maxXDeviance = mMaxXSecondaryDeviance * totalDistanceIn * getXdpi();
+            maxYDeviance = mMaxYPrimaryDeviance * totalDistanceIn * getYdpi();
         }
 
         logDebug("Straightness Deviance: (" + devianceX + "," + devianceY + ") vs "
diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
index 0e93f42..d3e8b3d 100644
--- a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
+++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
@@ -77,7 +77,7 @@
     protected void extractWallpaperColors() {
         super.extractWallpaperColors();
         // mTonal is final but this method will be invoked by the base class during its ctor.
-        if (mTonal == null) {
+        if (mTonal == null || mNeutralColorsLock == null) {
             return;
         }
         mTonal.applyFallback(mLockColors == null ? mSystemColors : mLockColors, mNeutralColorsLock);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 6918501..f6a921d 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -43,6 +43,7 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
+import com.android.systemui.R;
 import com.android.systemui.plugins.SensorManagerPlugin;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.util.AlarmTimeout;
@@ -290,12 +291,21 @@
         long mLastNear;
         final AlarmTimeout mCooldownTimer;
         final AlwaysOnDisplayPolicy mPolicy;
-
+        final Sensor mSensor;
 
         public ProxSensor(AlwaysOnDisplayPolicy policy) {
             mPolicy = policy;
             mCooldownTimer = new AlarmTimeout(mAlarmManager, this::updateRegistered,
                     "prox_cooldown", mHandler);
+
+            // The default prox sensor can be noisy, so let's use a prox gated brightness sensor
+            // if available.
+            Sensor sensor = DozeSensors.findSensorWithType(mSensorManager,
+                    mContext.getString(R.string.doze_brightness_sensor_type));
+            if (sensor == null) {
+                sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
+            }
+            mSensor = sensor;
         }
 
         void setRequested(boolean requested) {
@@ -359,8 +369,9 @@
 
         @Override
         public String toString() {
-            return String.format("{registered=%s, requested=%s, coolingDown=%s, currentlyFar=%s}",
-                    mRegistered, mRequested, mCooldownTimer.isScheduled(), mCurrentlyFar);
+            return String.format("{registered=%s, requested=%s, coolingDown=%s, currentlyFar=%s,"
+                    + " sensor=%s}", mRegistered, mRequested, mCooldownTimer.isScheduled(),
+                    mCurrentlyFar, mSensor);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index e877d44..1f33af8 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.doze;
 
+import static com.android.systemui.doze.DozeMachine.State.DOZE;
 import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_PAUSED;
 
 import android.app.AlarmManager;
@@ -116,7 +117,7 @@
     public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
         switch (newState) {
             case DOZE_AOD:
-                if (oldState == DOZE_AOD_PAUSED) {
+                if (oldState == DOZE_AOD_PAUSED || oldState == DOZE) {
                     // Whenever turning on the display, it's necessary to push a new frame.
                     // The display buffers will be empty and need to be filled.
                     mHost.dozeTimeTick();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java
index cc1170f..b444fa5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java
@@ -83,6 +83,11 @@
         bindContents();
     }
 
+    @Override
+    public boolean isTransparent() {
+        return true;
+    }
+
     /** Must be called whenever the UI mode changes (i.e. when we enter night mode). */
     void onUiModeChanged() {
         updateBackgroundColors();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 01e2b28..7655056 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -159,15 +159,13 @@
         float drawStart = !ambientState.isOnKeyguard() ? ambientState.getTopPadding()
                 + ambientState.getStackTranslation() + ambientState.getExpandAnimationTopChange()
                 : 0;
-        float previousNotificationEnd = 0;
-        float previousNotificationStart = 0;
+        float clipStart = 0;
         int childCount = algorithmState.visibleChildren.size();
         for (int i = 0; i < childCount; i++) {
             ExpandableView child = algorithmState.visibleChildren.get(i);
             ExpandableViewState state = child.getViewState();
             if (!child.mustStayOnScreen() || state.headsUpIsVisible) {
-                previousNotificationEnd = Math.max(drawStart, previousNotificationEnd);
-                previousNotificationStart = Math.max(drawStart, previousNotificationStart);
+                clipStart = Math.max(drawStart, clipStart);
             }
             float newYTranslation = state.yTranslation;
             float newHeight = state.height;
@@ -175,10 +173,10 @@
             boolean isHeadsUp = (child instanceof ExpandableNotificationRow)
                     && ((ExpandableNotificationRow) child).isPinned();
             if (mClipNotificationScrollToTop
-                    && !state.inShelf && newYTranslation < previousNotificationEnd
-                    && (!isHeadsUp || ambientState.isShadeExpanded())) {
+                    && (!state.inShelf || isHeadsUp)
+                    && newYTranslation < clipStart) {
                 // The previous view is overlapping on top, clip!
-                float overlapAmount = previousNotificationEnd - newYTranslation;
+                float overlapAmount = clipStart - newYTranslation;
                 state.clipTopAmount = (int) overlapAmount;
             } else {
                 state.clipTopAmount = 0;
@@ -187,8 +185,7 @@
             if (!child.isTransparent()) {
                 // Only update the previous values if we are not transparent,
                 // otherwise we would clip to a transparent view.
-                previousNotificationEnd = newNotificationEnd;
-                previousNotificationStart = newYTranslation;
+                clipStart = Math.max(clipStart, isHeadsUp ? newYTranslation : newNotificationEnd);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index 680e522..a7e7f08 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -363,12 +363,15 @@
     }
 
     public Region calculateTouchableRegion() {
-        if (!hasPinnedHeadsUp()) {
+        NotificationEntry topEntry = getTopEntry();
+        // This call could be made in an inconsistent state while the pinnedMode hasn't been
+        // updated yet, but callbacks leading out of the headsUp manager, querying it. Let's
+        // therefore also check if the topEntry is null.
+        if (!hasPinnedHeadsUp() || topEntry == null) {
             mTouchableRegion.set(0, 0, mStatusBarWindowView.getWidth(), mStatusBarHeight);
             updateRegionForNotch(mTouchableRegion);
 
         } else {
-            NotificationEntry topEntry = getTopEntry();
             if (topEntry.isChildInGroup()) {
                 final NotificationEntry groupSummary =
                         mGroupManager.getGroupSummary(topEntry.notification);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
index f36c56f..a71fcdb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
@@ -107,6 +107,9 @@
         mListeners.remove(listener);
     }
 
+    /**
+     * If there are faces enrolled and user enabled face auth on keyguard.
+     */
     public boolean isUnlockingWithFacePossible() {
         return mIsUnlockingWithFacePossible;
     }
@@ -119,15 +122,16 @@
                 || (Build.IS_DEBUGGABLE && DEBUG_AUTH_WITH_ADB && mDebugUnlocked);
         boolean trustManaged = mKeyguardUpdateMonitor.getUserTrustIsManaged(user);
         boolean trusted = mKeyguardUpdateMonitor.getUserHasTrust(user);
-        boolean hasEnrolledFaces = mKeyguardUpdateMonitor.isUnlockWithFacePossible(user);
-        boolean changed = secure != mSecure || canSkipBouncer != mCanSkipBouncer ||
-                trustManaged != mTrustManaged || mIsUnlockingWithFacePossible != hasEnrolledFaces;
+        boolean isUnlockingWithFacePossible = mKeyguardUpdateMonitor.isUnlockWithFacePossible(user);
+        boolean changed = secure != mSecure || canSkipBouncer != mCanSkipBouncer
+                || trustManaged != mTrustManaged
+                || mIsUnlockingWithFacePossible != isUnlockingWithFacePossible;
         if (changed || updateAlways) {
             mSecure = secure;
             mCanSkipBouncer = canSkipBouncer;
             mTrusted = trusted;
             mTrustManaged = trustManaged;
-            mIsUnlockingWithFacePossible = hasEnrolledFaces;
+            mIsUnlockingWithFacePossible = isUnlockingWithFacePossible;
             notifyListeners();
         }
         Trace.endSection();
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index bdc6341..db6177a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -103,7 +103,8 @@
         when(context.getPackageManager()).thenReturn(mPackageManager);
         doAnswer(invocation -> {
             IBiometricEnabledOnKeyguardCallback callback = invocation.getArgument(0);
-            callback.onChanged(BiometricSourceType.FACE, true /* enabled */);
+            callback.onChanged(BiometricSourceType.FACE, true /* enabled */,
+                    KeyguardUpdateMonitor.getCurrentUser());
             return null;
         }).when(mBiometricManager).registerEnabledOnKeyguardCallback(any());
         when(mFaceManager.isHardwareDetected()).thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java
index 329ef1c..7ea6493 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java
@@ -56,6 +56,9 @@
         mHandler = new Handler(mTestableLooper.getLooper());
         mDefaultConfigValue = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
                 BRIGHTLINE_FALSING_MANAGER_ENABLED, false);
+        // In case it runs on a device where it's been set to true, set it to false by hand.
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_MANAGER_ENABLED, "false", false);
     }
 
     @After
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index df6f73b..bd3cd54 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -521,8 +521,8 @@
             List<EnabledOnKeyguardCallback> callbacks = mEnabledOnKeyguardCallbacks;
             for (int i = 0; i < callbacks.size(); i++) {
                 callbacks.get(i).notify(BiometricSourceType.FACE,
-                        mFaceEnabledOnKeyguard.getOrDefault(userId,
-                                DEFAULT_KEYGUARD_ENABLED));
+                        mFaceEnabledOnKeyguard.getOrDefault(userId, DEFAULT_KEYGUARD_ENABLED),
+                        userId);
             }
         }
     }
@@ -540,9 +540,9 @@
             }
         }
 
-        void notify(BiometricSourceType sourceType, boolean enabled) {
+        void notify(BiometricSourceType sourceType, boolean enabled, int userId) {
             try {
-                mCallback.onChanged(sourceType, enabled);
+                mCallback.onChanged(sourceType, enabled, userId);
             } catch (DeadObjectException e) {
                 Slog.w(TAG, "Death while invoking notify", e);
                 mEnabledOnKeyguardCallbacks.remove(this);
@@ -796,7 +796,8 @@
             mEnabledOnKeyguardCallbacks.add(new EnabledOnKeyguardCallback(callback));
             try {
                 callback.onChanged(BiometricSourceType.FACE,
-                        mSettingObserver.getFaceEnabledOnKeyguard());
+                        mSettingObserver.getFaceEnabledOnKeyguard(),
+                        UserHandle.getCallingUserId());
             } catch (RemoteException e) {
                 Slog.w(TAG, "Remote exception", e);
             }
diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
index f08423e..20eb618 100644
--- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
+++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
@@ -665,8 +665,12 @@
         mMetricsLogger.count(getConstants().tagHalDied(), 1);
         mHALDeathCount++;
         mCurrentUserId = UserHandle.USER_NULL;
-        handleError(getHalDeviceId(), BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
-                0 /*vendorCode */);
+
+        // All client lifecycle must be managed on the handler.
+        mHandler.post(() -> {
+            handleError(getHalDeviceId(), BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
+                    0 /*vendorCode */);
+        });
 
         StatsLog.write(StatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED, statsModality(),
                 BiometricsProtoEnums.ISSUE_HAL_DEATH);
diff --git a/services/core/java/com/android/server/om/IdmapDaemon.java b/services/core/java/com/android/server/om/IdmapDaemon.java
deleted file mode 100644
index 55fbcb4..0000000
--- a/services/core/java/com/android/server/om/IdmapDaemon.java
+++ /dev/null
@@ -1,193 +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.server.om;
-
-import static android.content.Context.IDMAP_SERVICE;
-
-import static com.android.server.om.OverlayManagerService.DEBUG;
-import static com.android.server.om.OverlayManagerService.TAG;
-
-import android.os.IBinder;
-import android.os.IIdmap2;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemProperties;
-import android.util.Slog;
-
-import com.android.server.IoThread;
-
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * To prevent idmap2d from continuously running, the idmap daemon will terminate after 10
- * seconds without a transaction.
- **/
-class IdmapDaemon {
-    // The amount of time in milliseconds to wait after a transaction to the idmap service is made
-    // before stopping the service.
-    private static final int SERVICE_TIMEOUT_MS = 10000;
-
-    // The amount of time in milliseconds to wait when attempting to connect to idmap service.
-    private static final int SERVICE_CONNECT_TIMEOUT_MS = 5000;
-
-    private static final Object IDMAP_TOKEN = new Object();
-    private static final String IDMAP_DAEMON = "idmap2d";
-
-    private static IdmapDaemon sInstance;
-    private volatile IIdmap2 mService;
-    private final AtomicInteger mOpenedCount = new AtomicInteger();
-
-    /**
-     * An {@link AutoCloseable} connection to the idmap service. When the connection is closed or
-     * finalized, the idmap service will be stopped after a period of time unless another connection
-     * to the service is open.
-     **/
-    private class Connection implements AutoCloseable {
-        private boolean mOpened = true;
-
-        private Connection() {
-            synchronized (IDMAP_TOKEN) {
-                mOpenedCount.incrementAndGet();
-            }
-        }
-
-        @Override
-        public void close() {
-            synchronized (IDMAP_TOKEN) {
-                if (!mOpened) {
-                    return;
-                }
-
-                mOpened = false;
-                if (mOpenedCount.decrementAndGet() != 0) {
-                    // Only post the callback to stop the service if the service does not have an
-                    // open connection.
-                    return;
-                }
-
-                IoThread.getHandler().postDelayed(() -> {
-                    synchronized (IDMAP_TOKEN) {
-                        // Only stop the service if the service does not have an open connection.
-                        if (mService == null || mOpenedCount.get() != 0) {
-                            return;
-                        }
-
-                        stopIdmapService();
-                        mService = null;
-                    }
-                }, IDMAP_TOKEN, SERVICE_TIMEOUT_MS);
-            }
-        }
-    }
-
-    static IdmapDaemon getInstance() {
-        if (sInstance == null) {
-            sInstance = new IdmapDaemon();
-        }
-        return sInstance;
-    }
-
-    String createIdmap(String targetPath, String overlayPath, int policies, boolean enforce,
-            int userId) throws Exception {
-        try (Connection connection = connect()) {
-            return mService.createIdmap(targetPath, overlayPath, policies, enforce, userId);
-        }
-    }
-
-    boolean removeIdmap(String overlayPath, int userId) throws Exception {
-        try (Connection connection = connect()) {
-            return mService.removeIdmap(overlayPath, userId);
-        }
-    }
-
-    boolean verifyIdmap(String overlayPath, int policies, boolean enforce, int userId)
-            throws Exception {
-        try (Connection connection = connect()) {
-            return mService.verifyIdmap(overlayPath, policies, enforce, userId);
-        }
-    }
-
-    String getIdmapPath(String overlayPath, int userId) throws Exception {
-        try (Connection connection = connect()) {
-            return mService.getIdmapPath(overlayPath, userId);
-        }
-    }
-
-    static void startIdmapService() {
-        SystemProperties.set("ctl.start", IDMAP_DAEMON);
-    }
-
-    static void stopIdmapService() {
-        SystemProperties.set("ctl.stop", IDMAP_DAEMON);
-    }
-
-    private Connection connect() throws Exception {
-        synchronized (IDMAP_TOKEN) {
-            IoThread.getHandler().removeCallbacksAndMessages(IDMAP_TOKEN);
-            if (mService != null) {
-                // Not enough time has passed to stop the idmap service. Reuse the existing
-                // interface.
-                return new Connection();
-            }
-
-            // Start the idmap service if it is not currently running.
-            startIdmapService();
-
-            // Block until the service is found.
-            FutureTask<IBinder> bindIdmap = new FutureTask<>(() -> {
-                IBinder binder = null;
-                while (binder == null) {
-                    try {
-                        binder = ServiceManager.getService(IDMAP_SERVICE);
-                        Thread.sleep(100);
-                    } catch (Exception e) {
-                        Slog.e(TAG, "service '" + IDMAP_SERVICE + "' not retrieved; "
-                                + e.getMessage());
-                    }
-                }
-                return binder;
-            });
-
-            IBinder binder;
-            try {
-                IoThread.getHandler().postAtFrontOfQueue(bindIdmap);
-                binder = bindIdmap.get(SERVICE_CONNECT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
-            } catch (Exception rethrow) {
-                Slog.e(TAG, "service '" + IDMAP_SERVICE + "' not found;");
-                throw rethrow;
-            }
-
-            try {
-                binder.linkToDeath(() -> {
-                    Slog.w(TAG, "service '" + IDMAP_SERVICE + "' died");
-                }, 0);
-            } catch (RemoteException rethrow) {
-                Slog.e(TAG, "service '" + IDMAP_SERVICE + "' failed to be bound");
-                throw rethrow;
-            }
-
-            mService = IIdmap2.Stub.asInterface(binder);
-            if (DEBUG) {
-                Slog.d(TAG, "service '" + IDMAP_SERVICE + "' connected");
-            }
-
-            return new Connection();
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java
index 9b6d986..b604aa8 100644
--- a/services/core/java/com/android/server/om/IdmapManager.java
+++ b/services/core/java/com/android/server/om/IdmapManager.java
@@ -16,6 +16,9 @@
 
 package com.android.server.om;
 
+import static android.content.Context.IDMAP_SERVICE;
+import static android.text.format.DateUtils.SECOND_IN_MILLIS;
+
 import static com.android.server.om.OverlayManagerService.DEBUG;
 import static com.android.server.om.OverlayManagerService.TAG;
 
@@ -24,11 +27,15 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.os.Build.VERSION_CODES;
+import android.os.IBinder;
 import android.os.IIdmap2;
+import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.util.Slog;
 
+import com.android.internal.os.BackgroundThread;
 import com.android.server.om.OverlayManagerServiceImpl.PackageManagerHelper;
 import com.android.server.pm.Installer;
 
@@ -44,6 +51,11 @@
  */
 class IdmapManager {
     private static final boolean FEATURE_FLAG_IDMAP2 = true;
+
+    private final Installer mInstaller;
+    private final PackageManagerHelper mPackageManager;
+    private IIdmap2 mIdmap2Service;
+
     private static final boolean VENDOR_IS_Q_OR_LATER;
     static {
         final String value = SystemProperties.get("ro.vndk.version", "29");
@@ -58,14 +70,12 @@
         VENDOR_IS_Q_OR_LATER = isQOrLater;
     }
 
-    private final Installer mInstaller;
-    private final PackageManagerHelper mPackageManager;
-    private final IdmapDaemon mIdmapDaemon;
-
     IdmapManager(final Installer installer, final PackageManagerHelper packageManager) {
         mInstaller = installer;
         mPackageManager = packageManager;
-        mIdmapDaemon = IdmapDaemon.getInstance();
+        if (FEATURE_FLAG_IDMAP2) {
+            connectToIdmap2d();
+        }
     }
 
     boolean createIdmap(@NonNull final PackageInfo targetPackage,
@@ -81,11 +91,11 @@
             if (FEATURE_FLAG_IDMAP2) {
                 int policies = calculateFulfilledPolicies(targetPackage, overlayPackage, userId);
                 boolean enforce = enforceOverlayable(overlayPackage);
-                if (mIdmapDaemon.verifyIdmap(overlayPath, policies, enforce, userId)) {
+                if (mIdmap2Service.verifyIdmap(overlayPath, policies, enforce, userId)) {
                     return true;
                 }
-                return mIdmapDaemon.createIdmap(targetPath, overlayPath, policies,
-                        enforce, userId) != null;
+                return mIdmap2Service.createIdmap(targetPath, overlayPath, policies, enforce,
+                    userId) != null;
             } else {
                 mInstaller.idmap(targetPath, overlayPath, sharedGid);
                 return true;
@@ -103,7 +113,7 @@
         }
         try {
             if (FEATURE_FLAG_IDMAP2) {
-                return mIdmapDaemon.removeIdmap(oi.baseCodePath, userId);
+                return mIdmap2Service.removeIdmap(oi.baseCodePath, userId);
             } else {
                 mInstaller.removeIdmap(oi.baseCodePath);
                 return true;
@@ -127,7 +137,7 @@
             final int userId) {
         if (FEATURE_FLAG_IDMAP2) {
             try {
-                return mIdmapDaemon.getIdmapPath(overlayPackagePath, userId);
+                return mIdmap2Service.getIdmapPath(overlayPackagePath, userId);
             } catch (Exception e) {
                 Slog.w(TAG, "failed to get idmap path for " + overlayPackagePath + ": "
                         + e.getMessage());
@@ -141,6 +151,35 @@
         }
     }
 
+    private void connectToIdmap2d() {
+        IBinder binder = ServiceManager.getService(IDMAP_SERVICE);
+        if (binder != null) {
+            try {
+                binder.linkToDeath(new IBinder.DeathRecipient() {
+                    @Override
+                    public void binderDied() {
+                        Slog.w(TAG, "service '" + IDMAP_SERVICE + "' died; reconnecting...");
+                        connectToIdmap2d();
+                    }
+
+                }, 0);
+            } catch (RemoteException e) {
+                binder = null;
+            }
+        }
+        if (binder != null) {
+            mIdmap2Service = IIdmap2.Stub.asInterface(binder);
+            if (DEBUG) {
+                Slog.d(TAG, "service '" + IDMAP_SERVICE + "' connected");
+            }
+        } else {
+            Slog.w(TAG, "service '" + IDMAP_SERVICE + "' not found; trying again...");
+            BackgroundThread.getHandler().postDelayed(() -> {
+                connectToIdmap2d();
+            }, SECOND_IN_MILLIS);
+        }
+    }
+
     /**
      * Checks if overlayable and policies should be enforced on the specified overlay for backwards
      * compatibility with pre-Q overlays.
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index ce95181..da69986 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -262,7 +262,6 @@
 
             initIfNeeded();
             onSwitchUser(UserHandle.USER_SYSTEM);
-            IdmapDaemon.stopIdmapService();
 
             publishBinderService(Context.OVERLAY_SERVICE, mService);
             publishLocalService(OverlayManagerService.class, this);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 9f5fc92..7fce445 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -16590,13 +16590,13 @@
                                 && compareSignatures(sharedUserSignatures,
                                         pkg.mSigningDetails.signatures)
                                         != PackageManager.SIGNATURE_MATCH) {
-                            if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 28) {
+                            if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 29) {
                                 // Mismatched signatures is an error and silently skipping system
                                 // packages will likely break the device in unforeseen ways.
-                                // However,
-                                // we allow the device to boot anyway because, prior to P,
-                                // vendors were
-                                // not expecting the platform to crash in this situation.
+                                // However, we allow the device to boot anyway because, prior to Q,
+                                // vendors were not expecting the platform to crash in this
+                                // situation.
+                                // This WILL be a hard failure on any new API levels after Q.
                                 throw new ReconcileFailure(
                                         INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
                                         "Signature mismatch for shared user: "
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 3550ebf..4f91081 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -1202,7 +1202,8 @@
         final PackageInfo packageInfo;
         try {
             packageInfo = mService.mContext.getPackageManager()
-                    .getPackageInfo(callingPackage, PackageManager.GET_PERMISSIONS);
+                    .getPackageInfoAsUser(callingPackage, PackageManager.GET_PERMISSIONS,
+                            UserHandle.getUserId(callingUid));
         } catch (PackageManager.NameNotFoundException e) {
             Slog.i(TAG, "Cannot find package info for " + callingPackage);
             return ACTIVITY_RESTRICTION_NONE;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 8a9dfc7..7186ed1 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -1015,6 +1015,7 @@
     public final int startActivities(IApplicationThread caller, String callingPackage,
             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
             int userId) {
+        assertPackageMatchesCallingUid(callingPackage);
         final String reason = "startActivities";
         enforceNotIsolatedCaller(reason);
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
@@ -1034,10 +1035,11 @@
                 true /*validateIncomingUser*/);
     }
 
-    int startActivityAsUser(IApplicationThread caller, String callingPackage,
+    private int startActivityAsUser(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
             boolean validateIncomingUser) {
+        assertPackageMatchesCallingUid(callingPackage);
         enforceNotIsolatedCaller("startActivityAsUser");
 
         userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
@@ -1210,6 +1212,7 @@
     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
+        assertPackageMatchesCallingUid(callingPackage);
         final WaitResult res = new WaitResult();
         synchronized (mGlobalLock) {
             enforceNotIsolatedCaller("startActivityAndWait");
@@ -1237,6 +1240,7 @@
     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
             int startFlags, Configuration config, Bundle bOptions, int userId) {
+        assertPackageMatchesCallingUid(callingPackage);
         synchronized (mGlobalLock) {
             enforceNotIsolatedCaller("startActivityWithConfig");
             userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
@@ -1286,6 +1290,7 @@
             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, IBinder permissionToken,
             boolean ignoreTargetSecurity, int userId) {
+        assertPackageMatchesCallingUid(callingPackage);
         // This is very dangerous -- it allows you to perform a start activity (including
         // permission grants) as any app that may launch one of your own activities.  So we only
         // allow this in two cases:
@@ -1415,6 +1420,7 @@
             Intent intent, String resolvedType, IVoiceInteractionSession session,
             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
             Bundle bOptions, int userId) {
+        assertPackageMatchesCallingUid(callingPackage);
         mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
         if (session == null || interactor == null) {
             throw new NullPointerException("null session or interactor");
@@ -1438,6 +1444,7 @@
     @Override
     public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
             Intent intent, String resolvedType, Bundle bOptions, int userId) {
+        assertPackageMatchesCallingUid(callingPackage);
         mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
         userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
 
@@ -2363,15 +2370,9 @@
     void moveTaskToFrontLocked(@Nullable IApplicationThread appThread,
             @Nullable String callingPackage, int taskId, int flags, SafeActivityOptions options,
             boolean fromRecents) {
-
         final int callingPid = Binder.getCallingPid();
         final int callingUid = Binder.getCallingUid();
-        if (!isSameApp(callingUid, callingPackage)) {
-            String msg = "Permission Denial: moveTaskToFrontLocked() from pid="
-                    + Binder.getCallingPid() + " as package " + callingPackage;
-            Slog.w(TAG, msg);
-            throw new SecurityException(msg);
-        }
+        assertPackageMatchesCallingUid(callingPackage);
         if (!checkAppSwitchAllowedLocked(callingPid, callingUid, -1, -1, "Task to front")) {
             SafeActivityOptions.abort(options);
             return;
@@ -2423,7 +2424,7 @@
     /**
      * Return true if callingUid is system, or packageName belongs to that callingUid.
      */
-    boolean isSameApp(int callingUid, @Nullable String packageName) {
+    private boolean isSameApp(int callingUid, @Nullable String packageName) {
         try {
             if (callingUid != 0 && callingUid != SYSTEM_UID) {
                 if (packageName == null) {
@@ -2440,6 +2441,21 @@
         return true;
     }
 
+    /**
+     * Checks that the provided package name matches the current calling UID, throws a security
+     * exception if it doesn't.
+     */
+    void assertPackageMatchesCallingUid(@Nullable String packageName) {
+        final int callingUid = Binder.getCallingUid();
+        if (isSameApp(callingUid, packageName)) {
+            return;
+        }
+        final String msg = "Permission Denial: package=" + packageName
+                + " does not belong to uid=" + callingUid;
+        Slog.w(TAG, msg);
+        throw new SecurityException(msg);
+    }
+
     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
             int callingPid, int callingUid, String name) {
         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
@@ -2973,6 +2989,7 @@
     @Override
     public List<IBinder> getAppTasks(String callingPackage) {
         int callingUid = Binder.getCallingUid();
+        assertPackageMatchesCallingUid(callingPackage);
         long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
@@ -6193,6 +6210,7 @@
                 SafeActivityOptions options, int userId, boolean validateIncomingUser,
                 PendingIntentRecord originatingPendingIntent,
                 boolean allowBackgroundActivityStart) {
+            assertPackageMatchesCallingUid(callingPackage);
             synchronized (mGlobalLock) {
                 return getActivityStartController().startActivitiesInPackage(uid, realCallingPid,
                         realCallingUid, callingPackage, intents, resolvedTypes, resultTo, options,
@@ -6208,6 +6226,7 @@
                 int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
                 PendingIntentRecord originatingPendingIntent,
                 boolean allowBackgroundActivityStart) {
+            assertPackageMatchesCallingUid(callingPackage);
             synchronized (mGlobalLock) {
                 return getActivityStartController().startActivityInPackage(uid, realCallingPid,
                         realCallingUid, callingPackage, intent, resolvedType, resultTo, resultWho,
diff --git a/services/core/java/com/android/server/wm/AppTaskImpl.java b/services/core/java/com/android/server/wm/AppTaskImpl.java
index 1eb7455..a8f7768 100644
--- a/services/core/java/com/android/server/wm/AppTaskImpl.java
+++ b/services/core/java/com/android/server/wm/AppTaskImpl.java
@@ -27,7 +27,6 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.UserHandle;
-import android.util.Slog;
 
 /**
  * An implementation of IAppTask, that allows an app to manage its own tasks via
@@ -97,12 +96,7 @@
         // Will bring task to front if it already has a root activity.
         final int callingPid = Binder.getCallingPid();
         final int callingUid = Binder.getCallingUid();
-        if (!mService.isSameApp(callingUid, callingPackage)) {
-            String msg = "Permission Denial: moveToFront() from pid="
-                    + Binder.getCallingPid() + " as package " + callingPackage;
-            Slog.w(TAG, msg);
-            throw new SecurityException(msg);
-        }
+        mService.assertPackageMatchesCallingUid(callingPackage);
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (mService.mGlobalLock) {
@@ -134,6 +128,7 @@
     public int startActivity(IBinder whoThread, String callingPackage,
             Intent intent, String resolvedType, Bundle bOptions) {
         checkCaller();
+        mService.assertPackageMatchesCallingUid(callingPackage);
 
         int callingUser = UserHandle.getCallingUserId();
         TaskRecord tr;