Merge "Only enable UDFPS display mode for optical sensors" into tm-qpr-dev
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 6d54270..540ca04 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -223,6 +223,7 @@
         "androidx.test.rules",
         "androidx.test.uiautomator",
         "mockito-target-extended-minus-junit4",
+        "androidx.test.ext.junit",
         "testables",
         "truth-prebuilt",
         "monet",
diff --git a/packages/SystemUI/res/drawable/user_switcher_fullscreen_button_bg.xml b/packages/SystemUI/res/drawable/user_switcher_fullscreen_button_bg.xml
new file mode 100644
index 0000000..ae0f4b2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/user_switcher_fullscreen_button_bg.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+    android:insetTop="@dimen/dialog_button_vertical_inset"
+    android:insetBottom="@dimen/dialog_button_vertical_inset">
+    <ripple android:color="?android:attr/colorControlHighlight">
+        <item android:id="@android:id/mask">
+            <shape android:shape="rectangle">
+                <solid android:color="@android:color/white"/>
+                <corners android:radius="20dp"/>
+            </shape>
+        </item>
+        <item>
+            <shape android:shape="rectangle">
+                <corners android:radius="20dp"/>
+                <solid android:color="@android:color/transparent"/>
+                <stroke android:color="?androidprv:attr/colorAccentPrimaryVariant"
+                    android:width="1dp"
+                    />
+                <padding android:left="@dimen/dialog_button_horizontal_padding"
+                    android:top="@dimen/dialog_button_vertical_padding"
+                    android:right="@dimen/dialog_button_horizontal_padding"
+                    android:bottom="@dimen/dialog_button_vertical_padding"/>
+            </shape>
+        </item>
+    </ripple>
+</inset>
diff --git a/packages/SystemUI/res/layout/user_switcher_fullscreen.xml b/packages/SystemUI/res/layout/user_switcher_fullscreen.xml
index 78884ff..fa9d739 100644
--- a/packages/SystemUI/res/layout/user_switcher_fullscreen.xml
+++ b/packages/SystemUI/res/layout/user_switcher_fullscreen.xml
@@ -80,7 +80,7 @@
 
     <TextView
         android:id="@+id/add"
-        style="@style/Widget.Dialog.Button.BorderButton"
+        android:background="@drawable/user_switcher_fullscreen_button_bg"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center"
diff --git a/packages/SystemUI/res/raw/biometricprompt_folded_base_bottomright.json b/packages/SystemUI/res/raw/biometricprompt_folded_base_bottomright.json
new file mode 100644
index 0000000..2797996
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_folded_base_bottomright.json
@@ -0,0 +1 @@
+{"v":"5.9.0","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"biometricprompt_portrait_base_bottomright","ddd":0,"assets":[{"id":"comp_0","nm":"biometricprompt_landscape_base","fr":60,"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 16","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[170,170,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":3,"nm":"Null_Circle","parent":1,"sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-108,"s":[70.333,-88.75,0],"to":[-11.722,17.639,0],"ti":[11.722,-17.639,0]},{"t":-48,"s":[0,17.083,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".grey600","cl":"grey600","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.501960784314,0.525490196078,0.545098039216,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"circle mask 3","parent":2,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Finger","parent":2,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":-60,"s":[55]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":110,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":140,"s":[10]},{"t":170,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-60,"s":[92.146,-65.896,0],"to":[1.361,6.667,0],"ti":[-1.361,-6.667,0]},{"i":{"x":0.2,"y":0.2},"o":{"x":0.167,"y":0.167},"t":0,"s":[100.313,-25.896,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":0.2},"o":{"x":0.7,"y":0.7},"t":110,"s":[100.313,-25.896,0],"to":[0,0,0],"ti":[0,0,0]},{"t":170,"s":[100.313,-25.896,0]}],"ix":2,"l":2},"a":{"a":0,"k":[160.315,58.684,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-11.013,2.518],[5.251,5.023],[8.982,-2.829],[-0.264,-5.587]],"o":[[12.768,-2.854],[-14.961,2.071],[-6.004,1.89],[8.052,1.403]],"v":[[5.115,7.499],[19.814,-10.087],[-16.489,-3.588],[-24.801,8.684]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.760784373564,0.478431402468,0.400000029919,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[34.67,28.053],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[22.231,-7],[-27.395,-1.197],[-26.792,4.092],[14.179,15.736]],"o":[[-17.931,5.646],[56.062,2.45],[-1.765,-22.396],[-51.819,17.744]],"v":[[-62.102,-8.314],[-39.958,30.079],[80.033,25.905],[54.879,-32.529]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.678431372549,0.403921598547,0.305882352941,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[80.283,32.779],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"circle mask 7","parent":2,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".grey600","cl":"grey600","parent":2,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-0.25,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[114.218,-17.096],[-112.938,-17.096]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.501960784314,0.525490196078,0.545098039216,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":36.9,"ix":2},"o":{"a":0,"k":114.2,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"circle mask","parent":2,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".grey800","cl":"grey800","parent":2,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-0.5,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[114.218,-17.096],[-112.938,-17.096]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.235294117647,0.250980392157,0.262745098039,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"circle mask 6","parent":2,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".grey900","cl":"grey900","parent":2,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":377,"s":[-180]},{"t":417,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":377,"s":[-1.137,1.771,0],"to":[0.375,0,0],"ti":[-0.375,0,0]},{"t":417,"s":[1.113,1.771,0]}],"ix":2,"l":2},"a":{"a":0,"k":[6.238,5.063,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":77,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,-4.637],[-10.23,-3.195],[-2.196,4.813],[5.988,-3.371],[4.545,-4.813],[-2.196,1.918]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":107,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,0.393],[-10.23,1.835],[-2.196,9.843],[5.988,1.659],[4.545,0.217],[-2.196,6.948]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":137,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,-4.637],[-10.23,-3.195],[-2.196,4.813],[5.988,-3.371],[4.545,-4.813],[-2.196,1.918]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":167,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,0.393],[-10.23,1.835],[-2.196,9.843],[5.988,1.659],[4.545,0.217],[-2.196,6.948]],"c":false}]},{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"t":197,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,-4.637],[-10.23,-3.195],[-2.196,4.813],[5.988,-3.371],[4.545,-4.813],[-2.196,1.918]],"c":false}]},{"i":{"x":0.833,"y":1},"o":{"x":0.7,"y":0},"t":232,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,0.393],[-10.23,1.835],[-2.196,9.843],[5.988,1.659],[4.545,0.217],[-2.196,6.948]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":562,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,0.393],[-10.23,1.835],[-2.196,9.843],[5.988,1.659],[4.545,0.217],[-2.196,6.948]],"c":false}]},{"t":602,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-4.546,-0.421],[-5.988,1.021],[-2.196,4.813],[5.988,-3.371],[4.545,-4.813],[-2.196,1.918]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.125490196078,0.129411764706,0.141176470588,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[6.238,5.063],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"circle mask 2","parent":2,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".blue400","cl":"blue400","parent":2,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.308,0],"ix":2,"l":2},"a":{"a":0,"k":[41.706,20.979,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[18.645,0],[0,18.645]],"o":[[0,18.645],[-18.644,0],[0,0]],"v":[[33.76,-16.88],[-0.001,16.88],[-33.76,-16.88]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.400000029919,0.61568627451,0.964705942191,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[41.706,17.13],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[22.896,0],[0,22.896]],"o":[[0,22.896],[-22.896,0],[0,0]],"v":[[41.457,-20.729],[-0.001,20.729],[-41.457,-20.729]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.400000029919,0.61568627451,0.964705942191,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[41.706,20.979],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"circle mask 4","parent":2,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":15,"ty":1,"nm":".grey900","cl":"grey900","parent":2,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,66,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,0],"ix":1,"l":2},"s":{"a":0,"k":[52,52,100],"ix":6,"l":2}},"ao":0,"sw":412,"sh":300,"sc":"#202124","ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"circle mask 5","parent":2,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":17,"ty":1,"nm":".black","cl":"black","parent":2,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,-17.333,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,0],"ix":1,"l":2},"s":{"a":0,"k":[72,72,100],"ix":6,"l":2}},"ao":0,"sw":412,"sh":300,"sc":"#000000","ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".grey800","cl":"grey800","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-108,"s":[-192.25,99.933,0],"to":[5,3.333,0],"ti":[-5,-3.333,0]},{"t":-48,"s":[-162.25,119.933,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-163,100.85,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.833],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.167],"y":[0,0,0]},"t":-108,"s":[100,100,100]},{"t":-48,"s":[59,59,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[326,201.699],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":8,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.235294117647,0.250980392157,0.262745098039,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".grey900","cl":"grey900","parent":23,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-239,"s":[0,18.167,0],"to":[0,-1.25,0],"ti":[0,1.25,0]},{"t":-199,"s":[0,10.667,0]}],"ix":2,"l":2},"a":{"a":0,"k":[5.5,4,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.7,"y":0},"t":-239,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-0.07,1.5],[0,-1.5],[-0.047,1.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":-199,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-3,1.5],[0,-1.5],[3,1.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":-171,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-3,1.5],[0,-1.5],[3,1.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":-141,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-3,3.512],[0,0.512],[3,3.512]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":-111,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-3,1.5],[0,-1.5],[3,1.5]],"c":false}]},{"t":-81,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-3,3.967],[0,0.967],[3,3.967]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.125490196078,0.129411764706,0.141176470588,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[5.5,4],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-199,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"Shape Layer 4","parent":1,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-239,"s":[71,-116.083,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.7,"y":0},"t":-199,"s":[71,-101.083,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":365,"s":[71,-101.083,0],"to":[0,0,0],"ti":[16.833,-14.361,0]},{"t":405,"s":[-30,-14.917,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-239,"s":[29,29]},{"i":{"x":[0.833,0.833],"y":[1,0.833]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-199,"s":[29,38]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":365,"s":[29,36]},{"t":405,"s":[83,83]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":365,"s":[50]},{"t":405,"s":[50]}],"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.400000029919,0.61568627451,0.964705942191,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":".grey900","cl":"grey900","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-239,"s":[71,-82.917,0],"to":[0,-1.25,0],"ti":[0,1.25,0]},{"t":-199,"s":[71,-90.417,0]}],"ix":2,"l":2},"a":{"a":0,"k":[5.5,4,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-239,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-0.07,1.5],[0,-1.5],[-0.047,1.5]],"c":false}]},{"t":-199,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-3,1.5],[0,-1.5],[3,1.5]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.125490196078,0.129411764706,0.141176470588,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[5.5,4],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":-199,"st":-255,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":"device frame mask","parent":24,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,1.167,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[326,201.699],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":8,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":23,"ty":4,"nm":".blue400","cl":"blue400","parent":18,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-239,"s":[100.25,-115.167,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-199,"s":[100.25,-100.167,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.7,"y":0},"t":-159,"s":[100.25,-105.667,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":365,"s":[100.25,-100.167,0],"to":[0,0,0],"ti":[16.833,-14.361,0]},{"t":405,"s":[-0.75,-14,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-239,"s":[29,29]},{"i":{"x":[0.833,0.833],"y":[1,0.833]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-199,"s":[29,38]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":365,"s":[29,36]},{"t":405,"s":[83,83]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":365,"s":[50]},{"t":405,"s":[50]}],"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.400000029919,0.61568627451,0.964705942191,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":24,"ty":3,"nm":"device frame mask 5","parent":18,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":-165,"op":6.00000000000001,"st":-271,"bm":0},{"ddd":0,"ind":28,"ty":4,"nm":"device frame mask 9","parent":1,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-29.25,-0.917,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[326,201.699],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":8,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-181,"op":-62,"st":-181,"bm":0},{"ddd":0,"ind":29,"ty":4,"nm":".blue400","cl":"blue400","parent":23,"tt":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":-145,"s":[50]},{"t":-75,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-165,"s":[0,0]},{"t":-75,"s":[94,94]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":73,"s":[50]},{"t":113,"s":[50]}],"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-181,"op":-62,"st":-181,"bm":0},{"ddd":0,"ind":30,"ty":4,"nm":"device frame mask 8","parent":1,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-29.25,-0.917,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[326,201.699],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":8,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-211,"op":-92,"st":-211,"bm":0},{"ddd":0,"ind":31,"ty":4,"nm":".blue400","cl":"blue400","parent":23,"tt":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":-165,"s":[50]},{"t":-95,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-195,"s":[0,0]},{"t":-105,"s":[94,94]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":43,"s":[50]},{"t":83,"s":[50]}],"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-211,"op":-92,"st":-211,"bm":0},{"ddd":0,"ind":32,"ty":4,"nm":"device frame mask 7","parent":1,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-29.25,-0.917,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[326,201.699],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":8,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-241,"op":-122,"st":-241,"bm":0},{"ddd":0,"ind":33,"ty":4,"nm":".blue400","cl":"blue400","parent":23,"tt":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":-195,"s":[50]},{"t":-125,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-225,"s":[0,0]},{"t":-135,"s":[94,94]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":13,"s":[50]},{"t":53,"s":[50]}],"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-241,"op":-122,"st":-241,"bm":0},{"ddd":0,"ind":34,"ty":4,"nm":"device frame mask 6","parent":1,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-29.25,-0.917,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[326,201.699],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":8,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-271,"op":-152,"st":-271,"bm":0},{"ddd":0,"ind":35,"ty":4,"nm":".blue400","cl":"blue400","parent":23,"tt":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":-225,"s":[50]},{"t":-155,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-255,"s":[0,0]},{"t":-165,"s":[94,94]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":-17,"s":[50]},{"t":23,"s":[50]}],"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-271,"op":-152,"st":-271,"bm":0}]}],"layers":[{"ddd":0,"ind":6,"ty":0,"nm":"biometricprompt_landscape_base","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[170,170,0],"ix":2,"l":2},"a":{"a":0,"k":[170,170,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":340,"h":340,"ip":0,"op":900,"st":0,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]}
diff --git a/packages/SystemUI/res/raw/biometricprompt_folded_base_default.json b/packages/SystemUI/res/raw/biometricprompt_folded_base_default.json
new file mode 100644
index 0000000..bf65b34
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_folded_base_default.json
@@ -0,0 +1 @@
+{"v":"5.9.0","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"biometricprompt_landscape_base","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 16","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[170,170,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":3,"nm":"Null_Circle","parent":1,"sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-108,"s":[70.333,-88.75,0],"to":[-11.722,17.639,0],"ti":[11.722,-17.639,0]},{"t":-48,"s":[0,17.083,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".grey600","cl":"grey600","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.501960784314,0.525490196078,0.545098039216,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"circle mask 3","parent":2,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Finger","parent":2,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":-60,"s":[55]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":110,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":140,"s":[10]},{"t":170,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-60,"s":[92.146,-65.896,0],"to":[1.361,6.667,0],"ti":[-1.361,-6.667,0]},{"i":{"x":0.2,"y":0.2},"o":{"x":0.167,"y":0.167},"t":0,"s":[100.313,-25.896,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":0.2},"o":{"x":0.7,"y":0.7},"t":110,"s":[100.313,-25.896,0],"to":[0,0,0],"ti":[0,0,0]},{"t":170,"s":[100.313,-25.896,0]}],"ix":2,"l":2},"a":{"a":0,"k":[160.315,58.684,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-11.013,2.518],[5.251,5.023],[8.982,-2.829],[-0.264,-5.587]],"o":[[12.768,-2.854],[-14.961,2.071],[-6.004,1.89],[8.052,1.403]],"v":[[5.115,7.499],[19.814,-10.087],[-16.489,-3.588],[-24.801,8.684]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.760784373564,0.478431402468,0.400000029919,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[34.67,28.053],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[22.231,-7],[-27.395,-1.197],[-26.792,4.092],[14.179,15.736]],"o":[[-17.931,5.646],[56.062,2.45],[-1.765,-22.396],[-51.819,17.744]],"v":[[-62.102,-8.314],[-39.958,30.079],[80.033,25.905],[54.879,-32.529]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.678431372549,0.403921598547,0.305882352941,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[80.283,32.779],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"circle mask 7","parent":2,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".grey600","cl":"grey600","parent":2,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-0.25,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[114.218,-17.096],[-112.938,-17.096]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.501960784314,0.525490196078,0.545098039216,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":36.9,"ix":2},"o":{"a":0,"k":114.2,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"circle mask","parent":2,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".grey800","cl":"grey800","parent":2,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-0.5,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[114.218,-17.096],[-112.938,-17.096]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.235294117647,0.250980392157,0.262745098039,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"circle mask 6","parent":2,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".grey900","cl":"grey900","parent":2,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":377,"s":[-180]},{"t":417,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":377,"s":[-1.137,1.771,0],"to":[0.375,0,0],"ti":[-0.375,0,0]},{"t":417,"s":[1.113,1.771,0]}],"ix":2,"l":2},"a":{"a":0,"k":[6.238,5.063,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":77,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,-4.637],[-10.23,-3.195],[-2.196,4.813],[5.988,-3.371],[4.545,-4.813],[-2.196,1.918]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":107,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,0.393],[-10.23,1.835],[-2.196,9.843],[5.988,1.659],[4.545,0.217],[-2.196,6.948]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":137,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,-4.637],[-10.23,-3.195],[-2.196,4.813],[5.988,-3.371],[4.545,-4.813],[-2.196,1.918]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":167,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,0.393],[-10.23,1.835],[-2.196,9.843],[5.988,1.659],[4.545,0.217],[-2.196,6.948]],"c":false}]},{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"t":197,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,-4.637],[-10.23,-3.195],[-2.196,4.813],[5.988,-3.371],[4.545,-4.813],[-2.196,1.918]],"c":false}]},{"i":{"x":0.833,"y":1},"o":{"x":0.7,"y":0},"t":232,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,0.393],[-10.23,1.835],[-2.196,9.843],[5.988,1.659],[4.545,0.217],[-2.196,6.948]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":562,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,0.393],[-10.23,1.835],[-2.196,9.843],[5.988,1.659],[4.545,0.217],[-2.196,6.948]],"c":false}]},{"t":602,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-4.546,-0.421],[-5.988,1.021],[-2.196,4.813],[5.988,-3.371],[4.545,-4.813],[-2.196,1.918]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.125490196078,0.129411764706,0.141176470588,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[6.238,5.063],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"circle mask 2","parent":2,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".blue400","cl":"blue400","parent":2,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.308,0],"ix":2,"l":2},"a":{"a":0,"k":[41.706,20.979,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[18.645,0],[0,18.645]],"o":[[0,18.645],[-18.644,0],[0,0]],"v":[[33.76,-16.88],[-0.001,16.88],[-33.76,-16.88]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.400000029919,0.61568627451,0.964705942191,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[41.706,17.13],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[22.896,0],[0,22.896]],"o":[[0,22.896],[-22.896,0],[0,0]],"v":[[41.457,-20.729],[-0.001,20.729],[-41.457,-20.729]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.400000029919,0.61568627451,0.964705942191,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[41.706,20.979],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"circle mask 4","parent":2,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":15,"ty":1,"nm":".grey900","cl":"grey900","parent":2,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,66,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,0],"ix":1,"l":2},"s":{"a":0,"k":[52,52,100],"ix":6,"l":2}},"ao":0,"sw":412,"sh":300,"sc":"#202124","ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"circle mask 5","parent":2,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":17,"ty":1,"nm":".black","cl":"black","parent":2,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,-17.333,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,0],"ix":1,"l":2},"s":{"a":0,"k":[72,72,100],"ix":6,"l":2}},"ao":0,"sw":412,"sh":300,"sc":"#000000","ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".grey800","cl":"grey800","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-108,"s":[-192.25,99.933,0],"to":[5,3.333,0],"ti":[-5,-3.333,0]},{"t":-48,"s":[-162.25,119.933,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-163,100.85,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.833],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.167],"y":[0,0,0]},"t":-108,"s":[100,100,100]},{"t":-48,"s":[59,59,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[326,201.699],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":8,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.235294117647,0.250980392157,0.262745098039,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".grey900","cl":"grey900","parent":23,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-239,"s":[0,18.167,0],"to":[0,-1.25,0],"ti":[0,1.25,0]},{"t":-199,"s":[0,10.667,0]}],"ix":2,"l":2},"a":{"a":0,"k":[5.5,4,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.7,"y":0},"t":-239,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-0.07,1.5],[0,-1.5],[-0.047,1.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":-199,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-3,1.5],[0,-1.5],[3,1.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":-171,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-3,1.5],[0,-1.5],[3,1.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":-141,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-3,3.512],[0,0.512],[3,3.512]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":-111,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-3,1.5],[0,-1.5],[3,1.5]],"c":false}]},{"t":-81,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-3,3.967],[0,0.967],[3,3.967]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.125490196078,0.129411764706,0.141176470588,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[5.5,4],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-199,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"Shape Layer 4","parent":1,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-239,"s":[71,-116.083,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.7,"y":0},"t":-199,"s":[71,-101.083,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":365,"s":[71,-101.083,0],"to":[0,0,0],"ti":[16.833,-14.361,0]},{"t":405,"s":[-30,-14.917,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-239,"s":[29,29]},{"i":{"x":[0.833,0.833],"y":[1,0.833]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-199,"s":[29,38]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":365,"s":[29,36]},{"t":405,"s":[83,83]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":365,"s":[50]},{"t":405,"s":[50]}],"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.400000029919,0.61568627451,0.964705942191,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":".grey900","cl":"grey900","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-239,"s":[71,-82.917,0],"to":[0,-1.25,0],"ti":[0,1.25,0]},{"t":-199,"s":[71,-90.417,0]}],"ix":2,"l":2},"a":{"a":0,"k":[5.5,4,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-239,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-0.07,1.5],[0,-1.5],[-0.047,1.5]],"c":false}]},{"t":-199,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-3,1.5],[0,-1.5],[3,1.5]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.125490196078,0.129411764706,0.141176470588,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[5.5,4],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":-199,"st":-255,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":"device frame mask","parent":24,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,1.167,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[326,201.699],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":8,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":23,"ty":4,"nm":".blue400","cl":"blue400","parent":18,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-239,"s":[100.25,-115.167,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-199,"s":[100.25,-100.167,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.7,"y":0},"t":-159,"s":[100.25,-105.667,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":365,"s":[100.25,-100.167,0],"to":[0,0,0],"ti":[16.833,-14.361,0]},{"t":405,"s":[-0.75,-14,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-239,"s":[29,29]},{"i":{"x":[0.833,0.833],"y":[1,0.833]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-199,"s":[29,38]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":365,"s":[29,36]},{"t":405,"s":[83,83]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":365,"s":[50]},{"t":405,"s":[50]}],"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.400000029919,0.61568627451,0.964705942191,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":24,"ty":3,"nm":"device frame mask 5","parent":18,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":-165,"op":6.00000000000001,"st":-271,"bm":0},{"ddd":0,"ind":28,"ty":4,"nm":"device frame mask 9","parent":1,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-29.25,-0.917,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[326,201.699],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":8,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-181,"op":-62,"st":-181,"bm":0},{"ddd":0,"ind":29,"ty":4,"nm":".blue400","cl":"blue400","parent":23,"tt":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":-145,"s":[50]},{"t":-75,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-165,"s":[0,0]},{"t":-75,"s":[94,94]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":73,"s":[50]},{"t":113,"s":[50]}],"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-181,"op":-62,"st":-181,"bm":0},{"ddd":0,"ind":30,"ty":4,"nm":"device frame mask 8","parent":1,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-29.25,-0.917,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[326,201.699],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":8,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-211,"op":-92,"st":-211,"bm":0},{"ddd":0,"ind":31,"ty":4,"nm":".blue400","cl":"blue400","parent":23,"tt":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":-165,"s":[50]},{"t":-95,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-195,"s":[0,0]},{"t":-105,"s":[94,94]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":43,"s":[50]},{"t":83,"s":[50]}],"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-211,"op":-92,"st":-211,"bm":0},{"ddd":0,"ind":32,"ty":4,"nm":"device frame mask 7","parent":1,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-29.25,-0.917,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[326,201.699],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":8,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-241,"op":-122,"st":-241,"bm":0},{"ddd":0,"ind":33,"ty":4,"nm":".blue400","cl":"blue400","parent":23,"tt":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":-195,"s":[50]},{"t":-125,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-225,"s":[0,0]},{"t":-135,"s":[94,94]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":13,"s":[50]},{"t":53,"s":[50]}],"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-241,"op":-122,"st":-241,"bm":0},{"ddd":0,"ind":34,"ty":4,"nm":"device frame mask 6","parent":1,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-29.25,-0.917,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[326,201.699],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":8,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-271,"op":-152,"st":-271,"bm":0},{"ddd":0,"ind":35,"ty":4,"nm":".blue400","cl":"blue400","parent":23,"tt":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":-225,"s":[50]},{"t":-155,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-255,"s":[0,0]},{"t":-165,"s":[94,94]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":-17,"s":[50]},{"t":23,"s":[50]}],"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-271,"op":-152,"st":-271,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]}
diff --git a/packages/SystemUI/res/raw/biometricprompt_folded_base_topleft.json b/packages/SystemUI/res/raw/biometricprompt_folded_base_topleft.json
new file mode 100644
index 0000000..7351d7c
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_folded_base_topleft.json
@@ -0,0 +1 @@
+{"v":"5.9.0","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"BiometricPrompt_Portrait_Base_TopLeft","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":6,"ty":3,"nm":"Null 16","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[170,170,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":3,"nm":"Null_Circle","parent":6,"sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-108,"s":[70.333,-88.75,0],"to":[-11.722,17.639,0],"ti":[11.722,-17.639,0]},{"t":-48,"s":[0,17.083,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".grey600","cl":"grey600","parent":7,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.501960784314,0.525490196078,0.545098039216,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"circle mask 3","parent":7,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Finger_Flipped","parent":6,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[-24.98,-35.709,0],"ix":2,"l":2},"a":{"a":0,"k":[31.791,75.23,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[5.03,5.25],[-2.83,8.98],[-5.59,-0.26],[2.52,-11.02]],"o":[[-2.85,12.77],[2.07,-14.96],[1.9,-6],[1.4,8.05],[0,0]],"v":[[7.5,4.99],[-10.09,19.69],[-3.59,-16.61],[8.69,-24.92],[7.5,5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.760784373564,0.478431402468,0.400000029919,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[27.8,24.94],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-7.01,22.23],[-1.2,-27.39],[4.09,-26.79],[15.73,14.18]],"o":[[5.64,-17.93],[2.45,56.06],[-22.4,-1.77],[17.73,-51.82]],"v":[[-7.57,-66.9],[30.82,-44.76],[26.65,75.23],[-31.78,50.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.678431372549,0.403921598547,0.305882352941,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[31.79,75.23],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"circle mask 7","parent":7,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".grey600","cl":"grey600","parent":7,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-0.25,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[114.218,-17.096],[-112.938,-17.096]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.501960784314,0.525490196078,0.545098039216,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":36.9,"ix":2},"o":{"a":0,"k":114.2,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"circle mask","parent":7,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".grey900","cl":"grey900","parent":7,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-0.5,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[114.218,-17.096],[-112.938,-17.096]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.235294117647,0.250980392157,0.262745098039,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"circle mask 6","parent":7,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".grey900","cl":"grey900","parent":7,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":377,"s":[-180]},{"t":417,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":377,"s":[-1.137,1.771,0],"to":[0.375,0,0],"ti":[-0.375,0,0]},{"t":417,"s":[1.113,1.771,0]}],"ix":2,"l":2},"a":{"a":0,"k":[6.238,5.063,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":77,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,-4.637],[-10.23,-3.195],[-2.196,4.813],[5.988,-3.371],[4.545,-4.813],[-2.196,1.918]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":107,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,0.393],[-10.23,1.835],[-2.196,9.843],[5.988,1.659],[4.545,0.217],[-2.196,6.948]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":137,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,-4.637],[-10.23,-3.195],[-2.196,4.813],[5.988,-3.371],[4.545,-4.813],[-2.196,1.918]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":167,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,0.393],[-10.23,1.835],[-2.196,9.843],[5.988,1.659],[4.545,0.217],[-2.196,6.948]],"c":false}]},{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"t":197,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,-4.637],[-10.23,-3.195],[-2.196,4.813],[5.988,-3.371],[4.545,-4.813],[-2.196,1.918]],"c":false}]},{"i":{"x":0.833,"y":1},"o":{"x":0.7,"y":0},"t":232,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,0.393],[-10.23,1.835],[-2.196,9.843],[5.988,1.659],[4.545,0.217],[-2.196,6.948]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":562,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.788,0.393],[-10.23,1.835],[-2.196,9.843],[5.988,1.659],[4.545,0.217],[-2.196,6.948]],"c":false}]},{"t":602,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-4.546,-0.421],[-5.988,1.021],[-2.196,4.813],[5.988,-3.371],[4.545,-4.813],[-2.196,1.918]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.125490196078,0.129411764706,0.141176470588,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[6.238,5.063],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"circle mask 2","parent":7,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":7,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.308,0],"ix":2,"l":2},"a":{"a":0,"k":[41.706,20.979,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[18.645,0],[0,18.645]],"o":[[0,18.645],[-18.644,0],[0,0]],"v":[[33.76,-16.88],[-0.001,16.88],[-33.76,-16.88]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.400000029919,0.61568627451,0.964705942191,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[41.706,17.13],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[22.896,0],[0,22.896]],"o":[[0,22.896],[-22.896,0],[0,0]],"v":[[41.457,-20.729],[-0.001,20.729],[-41.457,-20.729]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.400000029919,0.61568627451,0.964705942191,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[41.706,20.979],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"circle mask 4","parent":7,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":20,"ty":1,"nm":".grey900","cl":"grey900","parent":7,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,66,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,0],"ix":1,"l":2},"s":{"a":0,"k":[52,52,100],"ix":6,"l":2}},"ao":0,"sw":412,"sh":300,"sc":"#202124","ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":"circle mask 5","parent":7,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0.333,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-108,"s":[0,0]},{"t":-48,"s":[202,202]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.250980392157,0.282352941176,0.294117647059,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078246000701,0.610494037703,0.787910970052,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-17.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":22,"ty":1,"nm":".black","cl":"black","parent":7,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,-17.333,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,0],"ix":1,"l":2},"s":{"a":0,"k":[72,72,100],"ix":6,"l":2}},"ao":0,"sw":412,"sh":300,"sc":"#000000","ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":23,"ty":4,"nm":".grey800","cl":"grey800","parent":6,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-108,"s":[-192.25,99.933,0],"to":[5,3.333,0],"ti":[-5,-3.333,0]},{"t":-48,"s":[-162.25,119.933,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-163,100.85,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.833],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.167],"y":[0,0,0]},"t":-108,"s":[100,100,100]},{"t":-48,"s":[59,59,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[326,201.699],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":8,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.235294117647,0.250980392157,0.262745098039,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":24,"ty":4,"nm":".grey900","cl":"grey900","parent":23,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-239,"s":[100.25,-87.156,0],"to":[0,-1.25,0],"ti":[0,1.25,0]},{"t":-199,"s":[100.25,-94.656,0]}],"ix":2,"l":2},"a":{"a":0,"k":[5.5,4,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.7,"y":0},"t":-239,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-0.07,1.5],[0,-1.5],[-0.047,1.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":-199,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-3,1.5],[0,-1.5],[3,1.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":-171,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-3,1.5],[0,-1.5],[3,1.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":-141,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-3,3.512],[0,0.512],[3,3.512]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":-111,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-3,1.5],[0,-1.5],[3,1.5]],"c":false}]},{"t":-81,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-3,3.967],[0,0.967],[3,3.967]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.125490196078,0.129411764706,0.141176470588,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[5.5,4],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-199,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":25,"ty":4,"nm":"Shape Layer 4","parent":6,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-239,"s":[71,-116.083,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.7,"y":0},"t":-199,"s":[71,-101.083,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":365,"s":[71,-101.083,0],"to":[0,0,0],"ti":[16.833,-14.361,0]},{"t":405,"s":[-30,-14.917,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-239,"s":[29,29]},{"i":{"x":[0.833,0.833],"y":[1,0.833]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":-199,"s":[29,38]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":365,"s":[29,36]},{"t":405,"s":[83,83]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":365,"s":[50]},{"t":405,"s":[50]}],"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.400000029919,0.61568627451,0.964705942191,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":645,"st":-255,"bm":0},{"ddd":0,"ind":26,"ty":4,"nm":".grey900","cl":"grey900","parent":6,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-239,"s":[71,-82.917,0],"to":[0,-1.25,0],"ti":[0,1.25,0]},{"t":-199,"s":[71,-90.417,0]}],"ix":2,"l":2},"a":{"a":0,"k":[5.5,4,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":-239,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-0.07,1.5],[0,-1.5],[-0.047,1.5]],"c":false}]},{"t":-199,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-3,1.5],[0,-1.5],[3,1.5]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.125490196078,0.129411764706,0.141176470588,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[5.5,4],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-255,"op":-199,"st":-255,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]}
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 40d96ea..93926ef9 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -762,7 +762,7 @@
     <dimen name="keyguard_lock_padding">20dp</dimen>
 
     <dimen name="keyguard_indication_margin_bottom">32dp</dimen>
-    <dimen name="lock_icon_margin_bottom">74dp</dimen>
+    <dimen name="lock_icon_margin_bottom">110dp</dimen>
     <dimen name="ambient_indication_margin_bottom">71dp</dimen>
 
 
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index a7f8cb6..c88da18 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -403,6 +403,8 @@
     <string name="keyguard_face_failed">Can\u2019t recognize face</string>
     <!-- Message shown to suggest using fingerprint sensor to authenticate after another biometric failed. [CHAR LIMIT=25] -->
     <string name="keyguard_suggest_fingerprint">Use fingerprint instead</string>
+    <!-- Message shown to inform the user that face unlock is not available. [CHAR LIMIT=25] -->
+    <string name="keyguard_face_unlock_unavailable">Face unlock unavailable.</string>
 
     <!-- Content description of the bluetooth icon when connected for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_bluetooth_connected">Bluetooth connected.</string>
diff --git a/packages/SystemUI/shared/Android.bp b/packages/SystemUI/shared/Android.bp
index 91fd6a6..ebc41861 100644
--- a/packages/SystemUI/shared/Android.bp
+++ b/packages/SystemUI/shared/Android.bp
@@ -52,6 +52,11 @@
         "SystemUIUnfoldLib",
         "androidx.dynamicanimation_dynamicanimation",
         "androidx.concurrent_concurrent-futures",
+        "androidx.lifecycle_lifecycle-runtime-ktx",
+        "androidx.lifecycle_lifecycle-viewmodel-ktx",
+        "androidx.recyclerview_recyclerview",
+        "kotlinx_coroutines_android",
+        "kotlinx_coroutines",
         "gson-prebuilt-jar",
         "dagger2",
         "jsr330",
@@ -64,6 +69,7 @@
     },
     min_sdk_version: "current",
     plugins: ["dagger2-compiler"],
+    kotlincflags: ["-Xjvm-default=enable"],
 }
 
 java_library {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index fbb114c..7a49926 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -58,7 +58,8 @@
 import com.android.settingslib.utils.ThreadUtils;
 import com.android.systemui.Gefingerpoken;
 import com.android.systemui.R;
-import com.android.systemui.biometrics.SidefpsController;
+import com.android.systemui.biometrics.SideFpsController;
+import com.android.systemui.biometrics.SideFpsUiRequestSource;
 import com.android.systemui.classifier.FalsingA11yDelegate;
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.flags.FeatureFlags;
@@ -100,7 +101,7 @@
     private final GlobalSettings mGlobalSettings;
     private final FeatureFlags mFeatureFlags;
     private final SessionTracker mSessionTracker;
-    private final Optional<SidefpsController> mSidefpsController;
+    private final Optional<SideFpsController> mSideFpsController;
     private final FalsingA11yDelegate mFalsingA11yDelegate;
 
     private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED;
@@ -290,7 +291,7 @@
             FeatureFlags featureFlags,
             GlobalSettings globalSettings,
             SessionTracker sessionTracker,
-            Optional<SidefpsController> sidefpsController,
+            Optional<SideFpsController> sideFpsController,
             FalsingA11yDelegate falsingA11yDelegate) {
         super(view);
         mLockPatternUtils = lockPatternUtils;
@@ -311,7 +312,7 @@
         mFeatureFlags = featureFlags;
         mGlobalSettings = globalSettings;
         mSessionTracker = sessionTracker;
-        mSidefpsController = sidefpsController;
+        mSideFpsController = sideFpsController;
         mFalsingA11yDelegate = falsingA11yDelegate;
     }
 
@@ -351,7 +352,7 @@
     }
 
     private void updateSideFpsVisibility() {
-        if (!mSidefpsController.isPresent()) {
+        if (!mSideFpsController.isPresent()) {
             return;
         }
         final boolean sfpsEnabled = getResources().getBoolean(
@@ -369,9 +370,9 @@
                     + "needsStrongAuth=" + needsStrongAuth);
         }
         if (toShow) {
-            mSidefpsController.get().show();
+            mSideFpsController.get().show(SideFpsUiRequestSource.PRIMARY_BOUNCER);
         } else {
-            mSidefpsController.get().hide();
+            mSideFpsController.get().hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
         }
     }
 
@@ -745,7 +746,7 @@
         private final FeatureFlags mFeatureFlags;
         private final UserSwitcherController mUserSwitcherController;
         private final SessionTracker mSessionTracker;
-        private final Optional<SidefpsController> mSidefpsController;
+        private final Optional<SideFpsController> mSidefpsController;
         private final FalsingA11yDelegate mFalsingA11yDelegate;
 
         @Inject
@@ -766,7 +767,7 @@
                 FeatureFlags featureFlags,
                 GlobalSettings globalSettings,
                 SessionTracker sessionTracker,
-                Optional<SidefpsController> sidefpsController,
+                Optional<SideFpsController> sidefpsController,
                 FalsingA11yDelegate falsingA11yDelegate) {
             mView = view;
             mAdminSecondaryLockScreenControllerFactory = adminSecondaryLockScreenControllerFactory;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 558869c..1bb83f4 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -798,7 +798,7 @@
         mFingerprintCancelSignal = null;
         updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE,
                 FACE_AUTH_UPDATED_FP_AUTHENTICATED);
-        mLogger.d("onFingerprintAuthenticated");
+        mLogger.logFingerprintSuccess(userId, isStrongBiometric);
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
@@ -2716,7 +2716,7 @@
                         || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_TIMEOUT);
 
         // TODO: always disallow when fp is already locked out?
-        final boolean fpLockedout = mFingerprintLockedOut || mFingerprintLockedOutPermanent;
+        final boolean fpLockedOut = mFingerprintLockedOut || mFingerprintLockedOutPermanent;
 
         final boolean canBypass = mKeyguardBypassController != null
                 && mKeyguardBypassController.canBypass();
@@ -2745,7 +2745,6 @@
         final boolean faceDisabledForUser = isFaceDisabled(user);
         final boolean biometricEnabledForUser = mBiometricEnabledForUser.get(user);
         final boolean shouldListenForFaceAssistant = shouldListenForFaceAssistant();
-        final boolean fpOrFaceIsLockedOut = isFaceLockedOut() || fpLockedout;
 
         // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
         // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
@@ -2763,7 +2762,10 @@
                 && (!mSecureCameraLaunched || mOccludingAppRequestingFace)
                 && !faceAuthenticated
                 && !mGoingToSleep
-                && !fpOrFaceIsLockedOut;
+                // We only care about fp locked out state and not face because we still trigger
+                // face auth even when face is locked out to show the user a message that face
+                // unlock was supposed to run but didn't
+                && !fpLockedOut;
 
         // Aggregate relevant fields for debug logging.
         maybeLogListenerModelData(
@@ -2778,7 +2780,7 @@
                     faceAuthenticated,
                     faceDisabledForUser,
                     isFaceLockedOut(),
-                    fpLockedout,
+                    fpLockedOut,
                     mGoingToSleep,
                     awakeKeyguard,
                     mKeyguardGoingAway,
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconView.java b/packages/SystemUI/src/com/android/keyguard/LockIconView.java
index 34a5ef7..0a82968 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconView.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconView.java
@@ -158,10 +158,6 @@
         return mLockIconCenter.y - mRadius;
     }
 
-    float getLocationBottom() {
-        return mLockIconCenter.y + mRadius;
-    }
-
     /**
      * Updates the icon its default state where no visual is shown.
      */
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index c7cc059..fe7c70a 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -280,10 +280,6 @@
         return mView.getLocationTop();
     }
 
-    public float getBottom() {
-        return mView.getLocationBottom();
-    }
-
     private void updateVisibility() {
         if (mCancelDelayedUpdateVisibilityRunnable != null) {
             mCancelDelayedUpdateVisibilityRunnable.run();
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java
index 49e9783..ef067b8 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java
@@ -16,7 +16,7 @@
 
 package com.android.keyguard.dagger;
 
-import static com.android.systemui.biometrics.SidefpsControllerKt.hasSideFpsSensor;
+import static com.android.systemui.biometrics.SideFpsControllerKt.hasSideFpsSensor;
 
 import android.annotation.Nullable;
 import android.hardware.fingerprint.FingerprintManager;
@@ -27,7 +27,7 @@
 import com.android.keyguard.KeyguardSecurityContainer;
 import com.android.keyguard.KeyguardSecurityViewFlipper;
 import com.android.systemui.R;
-import com.android.systemui.biometrics.SidefpsController;
+import com.android.systemui.biometrics.SideFpsController;
 import com.android.systemui.dagger.qualifiers.RootView;
 import com.android.systemui.statusbar.phone.KeyguardBouncer;
 
@@ -70,12 +70,12 @@
         return containerView.findViewById(R.id.view_flipper);
     }
 
-    /** Provides {@link SidefpsController} if the device has the side fingerprint sensor. */
+    /** Provides {@link SideFpsController} if the device has the side fingerprint sensor. */
     @Provides
     @KeyguardBouncerScope
-    static Optional<SidefpsController> providesOptionalSidefpsController(
+    static Optional<SideFpsController> providesOptionalSidefpsController(
             @Nullable FingerprintManager fingerprintManager,
-            Provider<SidefpsController> sidefpsControllerProvider) {
+            Provider<SideFpsController> sidefpsControllerProvider) {
         if (!hasSideFpsSensor(fingerprintManager)) {
             return Optional.empty();
         }
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
index 3308f55..6276142d 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
@@ -153,6 +153,13 @@
                 { "fingerprintRunningState: $int1" })
     }
 
+    fun logFingerprintSuccess(userId: Int, isStrongBiometric: Boolean) {
+        logBuffer.log(TAG, DEBUG, {
+            int1 = userId
+            bool1 = isStrongBiometric
+        }, {"Fingerprint auth successful: userId: $int1, isStrongBiometric: $bool1"})
+    }
+
     fun logInvalidSubId(subId: Int) {
         logBuffer.log(TAG, INFO,
                 { int1 = subId },
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt b/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt
index 8920c92..8aa3040 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt
@@ -17,7 +17,7 @@
 package com.android.systemui
 
 import android.content.Context
-import com.android.systemui.dagger.DaggerGlobalRootComponent
+import com.android.systemui.dagger.DaggerReferenceGlobalRootComponent
 import com.android.systemui.dagger.GlobalRootComponent
 
 /**
@@ -25,6 +25,6 @@
  */
 class SystemUIInitializerImpl(context: Context) : SystemUIInitializer(context) {
     override fun getGlobalRootComponentBuilder(): GlobalRootComponent.Builder {
-        return DaggerGlobalRootComponent.builder()
+        return DaggerReferenceGlobalRootComponent.builder()
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
index b40b356..b2a2a67 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
@@ -18,6 +18,7 @@
 
 import android.annotation.RawRes
 import android.content.Context
+import android.content.res.Configuration
 import android.hardware.fingerprint.FingerprintManager
 import android.view.DisplayInfo
 import android.view.Surface
@@ -33,15 +34,19 @@
 import com.android.systemui.biometrics.AuthBiometricView.STATE_HELP
 import com.android.systemui.biometrics.AuthBiometricView.STATE_IDLE
 import com.android.systemui.biometrics.AuthBiometricView.STATE_PENDING_CONFIRMATION
+import com.android.systemui.unfold.compat.ScreenSizeFoldProvider
+import com.android.systemui.unfold.updates.FoldProvider
 
 /** Fingerprint only icon animator for BiometricPrompt.  */
 open class AuthBiometricFingerprintIconController(
         context: Context,
         iconView: LottieAnimationView,
         protected val iconViewOverlay: LottieAnimationView
-) : AuthIconController(context, iconView) {
+) : AuthIconController(context, iconView), FoldProvider.FoldCallback {
 
+    private var isDeviceFolded: Boolean = false
     private val isSideFps: Boolean
+    private val screenSizeFoldProvider: ScreenSizeFoldProvider = ScreenSizeFoldProvider(context)
     var iconLayoutParamSize: Pair<Int, Int> = Pair(1, 1)
         set(value) {
             if (field == value) {
@@ -74,6 +79,8 @@
         if (isSideFps && displayInfo.rotation == Surface.ROTATION_180) {
             iconView.rotation = 180f
         }
+        screenSizeFoldProvider.registerCallback(this, context.mainExecutor)
+        screenSizeFoldProvider.onConfigurationChange(context.resources.configuration)
     }
 
     private fun updateIconSideFps(@BiometricState lastState: Int, @BiometricState newState: Int) {
@@ -124,6 +131,10 @@
         LottieColorUtils.applyDynamicColors(context, iconView)
     }
 
+    override fun onConfigurationChanged(newConfig: Configuration) {
+        screenSizeFoldProvider.onConfigurationChange(newConfig)
+    }
+
     override fun updateIcon(@BiometricState lastState: Int, @BiometricState newState: Int) {
         if (isSideFps) {
             updateIconSideFps(lastState, newState)
@@ -191,11 +202,21 @@
 
     @RawRes
     private fun getSideFpsAnimationForTransition(rotation: Int): Int = when (rotation) {
-        Surface.ROTATION_0 -> R.raw.biometricprompt_landscape_base
-        Surface.ROTATION_90 -> R.raw.biometricprompt_portrait_base_topleft
-        Surface.ROTATION_180 -> R.raw.biometricprompt_landscape_base
-        Surface.ROTATION_270 -> R.raw.biometricprompt_portrait_base_bottomright
-        else -> R.raw.biometricprompt_landscape_base
+        Surface.ROTATION_90 -> if (isDeviceFolded) {
+            R.raw.biometricprompt_folded_base_topleft
+        } else {
+            R.raw.biometricprompt_portrait_base_topleft
+        }
+        Surface.ROTATION_270 -> if (isDeviceFolded) {
+            R.raw.biometricprompt_folded_base_bottomright
+        } else {
+            R.raw.biometricprompt_portrait_base_bottomright
+        }
+        else -> if (isDeviceFolded) {
+            R.raw.biometricprompt_folded_base_default
+        } else {
+            R.raw.biometricprompt_landscape_base
+        }
     }
 
     @RawRes
@@ -273,4 +294,8 @@
         }
         else -> null
     }
+
+    override fun onFoldUpdated(isFolded: Boolean) {
+        isDeviceFolded = isFolded
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricIconController.kt
index 15f487b..b3b6fa2 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricIconController.kt
@@ -18,6 +18,7 @@
 
 import android.annotation.DrawableRes
 import android.content.Context
+import android.content.res.Configuration
 import android.graphics.drawable.Animatable2
 import android.graphics.drawable.AnimatedVectorDrawable
 import android.graphics.drawable.Drawable
@@ -91,4 +92,6 @@
 
     /** Called during [onAnimationEnd] if the controller is not [deactivated]. */
     open fun handleAnimationEnd(drawable: Drawable) {}
+
+    open fun onConfigurationChanged(newConfig: Configuration) {}
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
index 0ac71c4..e12c170 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
@@ -27,6 +27,7 @@
 import android.annotation.Nullable;
 import android.annotation.StringRes;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.hardware.biometrics.BiometricAuthenticator.Modality;
 import android.hardware.biometrics.BiometricPrompt;
 import android.hardware.biometrics.PromptInfo;
@@ -654,6 +655,12 @@
     }
 
     @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        mIconController.onConfigurationChanged(newConfig);
+    }
+
+    @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index b817098..eedf423 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -119,7 +119,7 @@
     @Nullable private final FingerprintManager mFingerprintManager;
     @Nullable private final FaceManager mFaceManager;
     private final Provider<UdfpsController> mUdfpsControllerFactory;
-    private final Provider<SidefpsController> mSidefpsControllerFactory;
+    private final Provider<SideFpsController> mSidefpsControllerFactory;
 
     private final Display mDisplay;
     private float mScaleFactor = 1f;
@@ -141,7 +141,7 @@
     @NonNull private final DisplayManager mDisplayManager;
     @Nullable private UdfpsController mUdfpsController;
     @Nullable private IUdfpsHbmListener mUdfpsHbmListener;
-    @Nullable private SidefpsController mSidefpsController;
+    @Nullable private SideFpsController mSideFpsController;
     @Nullable private IBiometricContextListener mBiometricContextListener;
     @VisibleForTesting IBiometricSysuiReceiver mReceiver;
     @VisibleForTesting @NonNull final BiometricDisplayListener mOrientationListener;
@@ -316,7 +316,7 @@
 
         mSidefpsProps = !sidefpsProps.isEmpty() ? sidefpsProps : null;
         if (mSidefpsProps != null) {
-            mSidefpsController = mSidefpsControllerFactory.get();
+            mSideFpsController = mSidefpsControllerFactory.get();
         }
 
         updateSensorLocations();
@@ -677,7 +677,7 @@
             @Nullable FingerprintManager fingerprintManager,
             @Nullable FaceManager faceManager,
             Provider<UdfpsController> udfpsControllerFactory,
-            Provider<SidefpsController> sidefpsControllerFactory,
+            Provider<SideFpsController> sidefpsControllerFactory,
             @NonNull DisplayManager displayManager,
             @NonNull WakefulnessLifecycle wakefulnessLifecycle,
             @NonNull UserManager userManager,
@@ -1057,7 +1057,7 @@
      * Whether the passed userId has enrolled SFPS.
      */
     public boolean isSfpsEnrolled(int userId) {
-        if (mSidefpsController == null) {
+        if (mSideFpsController == null) {
             return false;
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
new file mode 100644
index 0000000..1c3dd45
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
@@ -0,0 +1,397 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.biometrics
+
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.app.ActivityTaskManager
+import android.content.Context
+import android.graphics.PixelFormat
+import android.graphics.PorterDuff
+import android.graphics.PorterDuffColorFilter
+import android.graphics.Rect
+import android.hardware.biometrics.BiometricOverlayConstants
+import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD
+import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_SETTINGS
+import android.hardware.biometrics.SensorLocationInternal
+import android.hardware.display.DisplayManager
+import android.hardware.fingerprint.FingerprintManager
+import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
+import android.hardware.fingerprint.ISidefpsController
+import android.os.Handler
+import android.util.Log
+import android.util.RotationUtils
+import android.view.Display
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.Surface
+import android.view.View
+import android.view.View.AccessibilityDelegate
+import android.view.ViewPropertyAnimator
+import android.view.WindowInsets
+import android.view.WindowManager
+import android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION
+import android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY
+import android.view.accessibility.AccessibilityEvent
+import androidx.annotation.RawRes
+import com.airbnb.lottie.LottieAnimationView
+import com.airbnb.lottie.LottieProperty
+import com.airbnb.lottie.model.KeyPath
+import com.android.internal.annotations.VisibleForTesting
+import com.android.systemui.Dumpable
+import com.android.systemui.R
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.recents.OverviewProxyService
+import com.android.systemui.util.concurrency.DelayableExecutor
+import java.io.PrintWriter
+import javax.inject.Inject
+
+private const val TAG = "SideFpsController"
+
+/**
+ * Shows and hides the side fingerprint sensor (side-fps) overlay and handles side fps touch events.
+ */
+@SysUISingleton
+class SideFpsController
+@Inject
+constructor(
+    private val context: Context,
+    private val layoutInflater: LayoutInflater,
+    fingerprintManager: FingerprintManager?,
+    private val windowManager: WindowManager,
+    private val activityTaskManager: ActivityTaskManager,
+    overviewProxyService: OverviewProxyService,
+    displayManager: DisplayManager,
+    @Main private val mainExecutor: DelayableExecutor,
+    @Main private val handler: Handler,
+    dumpManager: DumpManager
+) : Dumpable {
+    val requests: HashSet<SideFpsUiRequestSource> = HashSet()
+
+    @VisibleForTesting
+    val sensorProps: FingerprintSensorPropertiesInternal =
+        fingerprintManager?.sideFpsSensorProperties
+            ?: throw IllegalStateException("no side fingerprint sensor")
+
+    @VisibleForTesting
+    val orientationListener =
+        BiometricDisplayListener(
+            context,
+            displayManager,
+            handler,
+            BiometricDisplayListener.SensorType.SideFingerprint(sensorProps)
+        ) { onOrientationChanged() }
+
+    @VisibleForTesting
+    val overviewProxyListener =
+        object : OverviewProxyService.OverviewProxyListener {
+            override fun onTaskbarStatusUpdated(visible: Boolean, stashed: Boolean) {
+                overlayView?.let { view ->
+                    handler.postDelayed({ updateOverlayVisibility(view) }, 500)
+                }
+            }
+        }
+
+    private val animationDuration =
+        context.resources.getInteger(android.R.integer.config_mediumAnimTime).toLong()
+
+    private var overlayHideAnimator: ViewPropertyAnimator? = null
+
+    private var overlayView: View? = null
+        set(value) {
+            field?.let { oldView ->
+                windowManager.removeView(oldView)
+                orientationListener.disable()
+            }
+            overlayHideAnimator?.cancel()
+            overlayHideAnimator = null
+
+            field = value
+            field?.let { newView ->
+                windowManager.addView(newView, overlayViewParams)
+                updateOverlayVisibility(newView)
+                orientationListener.enable()
+            }
+        }
+    @VisibleForTesting
+    internal var overlayOffsets: SensorLocationInternal = SensorLocationInternal.DEFAULT
+
+    private val overlayViewParams =
+        WindowManager.LayoutParams(
+                WindowManager.LayoutParams.WRAP_CONTENT,
+                WindowManager.LayoutParams.WRAP_CONTENT,
+                WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
+                Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS,
+                PixelFormat.TRANSLUCENT
+            )
+            .apply {
+                title = TAG
+                fitInsetsTypes = 0 // overrides default, avoiding status bars during layout
+                gravity = Gravity.TOP or Gravity.LEFT
+                layoutInDisplayCutoutMode =
+                    WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
+                privateFlags = PRIVATE_FLAG_TRUSTED_OVERLAY or PRIVATE_FLAG_NO_MOVE_ANIMATION
+            }
+
+    init {
+        fingerprintManager?.setSidefpsController(
+            object : ISidefpsController.Stub() {
+                override fun show(
+                    sensorId: Int,
+                    @BiometricOverlayConstants.ShowReason reason: Int
+                ) =
+                    if (reason.isReasonToAutoShow(activityTaskManager)) {
+                        show(SideFpsUiRequestSource.AUTO_SHOW)
+                    } else {
+                        hide(SideFpsUiRequestSource.AUTO_SHOW)
+                    }
+
+                override fun hide(sensorId: Int) = hide(SideFpsUiRequestSource.AUTO_SHOW)
+            }
+        )
+        overviewProxyService.addCallback(overviewProxyListener)
+        dumpManager.registerDumpable(this)
+    }
+
+    /** Shows the side fps overlay if not already shown. */
+    fun show(request: SideFpsUiRequestSource) {
+        requests.add(request)
+        mainExecutor.execute {
+            if (overlayView == null) {
+                createOverlayForDisplay()
+            } else {
+                Log.v(TAG, "overlay already shown")
+            }
+        }
+    }
+
+    /** Hides the fps overlay if shown. */
+    fun hide(request: SideFpsUiRequestSource) {
+        requests.remove(request)
+        mainExecutor.execute {
+            if (requests.isEmpty()) {
+                overlayView = null
+            }
+        }
+    }
+
+    override fun dump(pw: PrintWriter, args: Array<out String>) {
+        pw.println("requests:")
+        for (requestSource in requests) {
+            pw.println("     $requestSource.name")
+        }
+    }
+
+    private fun onOrientationChanged() {
+        if (overlayView != null) {
+            createOverlayForDisplay()
+        }
+    }
+
+    private fun createOverlayForDisplay() {
+        val view = layoutInflater.inflate(R.layout.sidefps_view, null, false)
+        overlayView = view
+        val display = context.display!!
+        val offsets =
+            sensorProps.getLocation(display.uniqueId).let { location ->
+                if (location == null) {
+                    Log.w(TAG, "No location specified for display: ${display.uniqueId}")
+                }
+                location ?: sensorProps.location
+            }
+        overlayOffsets = offsets
+
+        val lottie = view.findViewById(R.id.sidefps_animation) as LottieAnimationView
+        view.rotation = display.asSideFpsAnimationRotation(offsets.isYAligned())
+        lottie.setAnimation(display.asSideFpsAnimation(offsets.isYAligned()))
+        lottie.addLottieOnCompositionLoadedListener {
+            // Check that view is not stale, and that overlayView has not been hidden/removed
+            if (overlayView != null && overlayView == view) {
+                updateOverlayParams(display, it.bounds)
+            }
+        }
+        lottie.addOverlayDynamicColor(context)
+
+        /**
+         * Intercepts TYPE_WINDOW_STATE_CHANGED accessibility event, preventing Talkback from
+         * speaking @string/accessibility_fingerprint_label twice when sensor location indicator is
+         * in focus
+         */
+        view.setAccessibilityDelegate(
+            object : AccessibilityDelegate() {
+                override fun dispatchPopulateAccessibilityEvent(
+                    host: View,
+                    event: AccessibilityEvent
+                ): Boolean {
+                    return if (
+                        event.getEventType() === AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
+                    ) {
+                        true
+                    } else {
+                        super.dispatchPopulateAccessibilityEvent(host, event)
+                    }
+                }
+            }
+        )
+    }
+
+    @VisibleForTesting
+    internal fun updateOverlayParams(display: Display, bounds: Rect) {
+        val isNaturalOrientation = display.isNaturalOrientation()
+        val size = windowManager.maximumWindowMetrics.bounds
+        val displayWidth = if (isNaturalOrientation) size.width() else size.height()
+        val displayHeight = if (isNaturalOrientation) size.height() else size.width()
+        val boundsWidth = if (isNaturalOrientation) bounds.width() else bounds.height()
+        val boundsHeight = if (isNaturalOrientation) bounds.height() else bounds.width()
+        val sensorBounds =
+            if (overlayOffsets.isYAligned()) {
+                Rect(
+                    displayWidth - boundsWidth,
+                    overlayOffsets.sensorLocationY,
+                    displayWidth,
+                    overlayOffsets.sensorLocationY + boundsHeight
+                )
+            } else {
+                Rect(
+                    overlayOffsets.sensorLocationX,
+                    0,
+                    overlayOffsets.sensorLocationX + boundsWidth,
+                    boundsHeight
+                )
+            }
+
+        RotationUtils.rotateBounds(
+            sensorBounds,
+            Rect(0, 0, displayWidth, displayHeight),
+            display.rotation
+        )
+
+        overlayViewParams.x = sensorBounds.left
+        overlayViewParams.y = sensorBounds.top
+        windowManager.updateViewLayout(overlayView, overlayViewParams)
+    }
+
+    private fun updateOverlayVisibility(view: View) {
+        if (view != overlayView) {
+            return
+        }
+        // hide after a few seconds if the sensor is oriented down and there are
+        // large overlapping system bars
+        val rotation = context.display?.rotation
+        if (
+            windowManager.currentWindowMetrics.windowInsets.hasBigNavigationBar() &&
+                ((rotation == Surface.ROTATION_270 && overlayOffsets.isYAligned()) ||
+                    (rotation == Surface.ROTATION_180 && !overlayOffsets.isYAligned()))
+        ) {
+            overlayHideAnimator =
+                view
+                    .animate()
+                    .alpha(0f)
+                    .setStartDelay(3_000)
+                    .setDuration(animationDuration)
+                    .setListener(
+                        object : AnimatorListenerAdapter() {
+                            override fun onAnimationEnd(animation: Animator) {
+                                view.visibility = View.GONE
+                                overlayHideAnimator = null
+                            }
+                        }
+                    )
+        } else {
+            overlayHideAnimator?.cancel()
+            overlayHideAnimator = null
+            view.alpha = 1f
+            view.visibility = View.VISIBLE
+        }
+    }
+}
+
+private val FingerprintManager?.sideFpsSensorProperties: FingerprintSensorPropertiesInternal?
+    get() = this?.sensorPropertiesInternal?.firstOrNull { it.isAnySidefpsType }
+
+/** Returns [True] when the device has a side fingerprint sensor. */
+fun FingerprintManager?.hasSideFpsSensor(): Boolean = this?.sideFpsSensorProperties != null
+
+@BiometricOverlayConstants.ShowReason
+private fun Int.isReasonToAutoShow(activityTaskManager: ActivityTaskManager): Boolean =
+    when (this) {
+        REASON_AUTH_KEYGUARD -> false
+        REASON_AUTH_SETTINGS ->
+            when (activityTaskManager.topClass()) {
+                // TODO(b/186176653): exclude fingerprint overlays from this list view
+                "com.android.settings.biometrics.fingerprint.FingerprintSettings" -> false
+                else -> true
+            }
+        else -> true
+    }
+
+private fun ActivityTaskManager.topClass(): String =
+    getTasks(1).firstOrNull()?.topActivity?.className ?: ""
+
+@RawRes
+private fun Display.asSideFpsAnimation(yAligned: Boolean): Int =
+    when (rotation) {
+        Surface.ROTATION_0 -> if (yAligned) R.raw.sfps_pulse else R.raw.sfps_pulse_landscape
+        Surface.ROTATION_180 -> if (yAligned) R.raw.sfps_pulse else R.raw.sfps_pulse_landscape
+        else -> if (yAligned) R.raw.sfps_pulse_landscape else R.raw.sfps_pulse
+    }
+
+private fun Display.asSideFpsAnimationRotation(yAligned: Boolean): Float =
+    when (rotation) {
+        Surface.ROTATION_90 -> if (yAligned) 0f else 180f
+        Surface.ROTATION_180 -> 180f
+        Surface.ROTATION_270 -> if (yAligned) 180f else 0f
+        else -> 0f
+    }
+
+private fun SensorLocationInternal.isYAligned(): Boolean = sensorLocationY != 0
+
+private fun Display.isNaturalOrientation(): Boolean =
+    rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180
+
+private fun WindowInsets.hasBigNavigationBar(): Boolean =
+    getInsets(WindowInsets.Type.navigationBars()).bottom >= 70
+
+private fun LottieAnimationView.addOverlayDynamicColor(context: Context) {
+    fun update() {
+        val c = context.getColor(R.color.biometric_dialog_accent)
+        for (key in listOf(".blue600", ".blue400")) {
+            addValueCallback(KeyPath(key, "**"), LottieProperty.COLOR_FILTER) {
+                PorterDuffColorFilter(c, PorterDuff.Mode.SRC_ATOP)
+            }
+        }
+    }
+
+    if (composition != null) {
+        update()
+    } else {
+        addLottieOnCompositionLoadedListener { update() }
+    }
+}
+
+/**
+ * The source of a request to show the side fps visual indicator. This is distinct from
+ * [BiometricOverlayConstants] which corrresponds with the reason fingerprint authentication is
+ * requested.
+ */
+enum class SideFpsUiRequestSource {
+    /** see [isReasonToAutoShow] */
+    AUTO_SHOW,
+    /** Pin, pattern or password bouncer */
+    PRIMARY_BOUNCER,
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt
deleted file mode 100644
index d03106b..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.biometrics
-
-import android.animation.Animator
-import android.animation.AnimatorListenerAdapter
-import android.app.ActivityTaskManager
-import android.content.Context
-import android.graphics.PixelFormat
-import android.graphics.PorterDuff
-import android.graphics.PorterDuffColorFilter
-import android.graphics.Rect
-import android.hardware.biometrics.BiometricOverlayConstants
-import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD
-import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_SETTINGS
-import android.hardware.biometrics.SensorLocationInternal
-import android.hardware.display.DisplayManager
-import android.hardware.fingerprint.FingerprintManager
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
-import android.hardware.fingerprint.ISidefpsController
-import android.os.Handler
-import android.util.Log
-import android.util.RotationUtils
-import android.view.Display
-import android.view.Gravity
-import android.view.LayoutInflater
-import android.view.Surface
-import android.view.View
-import android.view.View.AccessibilityDelegate
-import android.view.ViewPropertyAnimator
-import android.view.WindowInsets
-import android.view.WindowManager
-import android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION
-import android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY
-import android.view.accessibility.AccessibilityEvent
-import androidx.annotation.RawRes
-import com.airbnb.lottie.LottieAnimationView
-import com.airbnb.lottie.LottieProperty
-import com.airbnb.lottie.model.KeyPath
-import com.android.internal.annotations.VisibleForTesting
-import com.android.systemui.R
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.recents.OverviewProxyService
-import com.android.systemui.util.concurrency.DelayableExecutor
-import javax.inject.Inject
-
-private const val TAG = "SidefpsController"
-
-/**
- * Shows and hides the side fingerprint sensor (side-fps) overlay and handles side fps touch events.
- */
-@SysUISingleton
-class SidefpsController @Inject constructor(
-    private val context: Context,
-    private val layoutInflater: LayoutInflater,
-    fingerprintManager: FingerprintManager?,
-    private val windowManager: WindowManager,
-    private val activityTaskManager: ActivityTaskManager,
-    overviewProxyService: OverviewProxyService,
-    displayManager: DisplayManager,
-    @Main private val mainExecutor: DelayableExecutor,
-    @Main private val handler: Handler
-) {
-    @VisibleForTesting
-    val sensorProps: FingerprintSensorPropertiesInternal = fingerprintManager
-        ?.sideFpsSensorProperties
-        ?: throw IllegalStateException("no side fingerprint sensor")
-
-    @VisibleForTesting
-    val orientationListener = BiometricDisplayListener(
-        context,
-        displayManager,
-        handler,
-        BiometricDisplayListener.SensorType.SideFingerprint(sensorProps)
-    ) { onOrientationChanged() }
-
-    @VisibleForTesting
-    val overviewProxyListener = object : OverviewProxyService.OverviewProxyListener {
-        override fun onTaskbarStatusUpdated(visible: Boolean, stashed: Boolean) {
-            overlayView?.let { view ->
-                handler.postDelayed({ updateOverlayVisibility(view) }, 500)
-            }
-        }
-    }
-
-    private val animationDuration =
-        context.resources.getInteger(android.R.integer.config_mediumAnimTime).toLong()
-
-    private var overlayHideAnimator: ViewPropertyAnimator? = null
-
-    private var overlayView: View? = null
-        set(value) {
-            field?.let { oldView ->
-                windowManager.removeView(oldView)
-                orientationListener.disable()
-            }
-            overlayHideAnimator?.cancel()
-            overlayHideAnimator = null
-
-            field = value
-            field?.let { newView ->
-                windowManager.addView(newView, overlayViewParams)
-                updateOverlayVisibility(newView)
-                orientationListener.enable()
-            }
-        }
-    @VisibleForTesting
-    internal var overlayOffsets: SensorLocationInternal = SensorLocationInternal.DEFAULT
-
-    private val overlayViewParams = WindowManager.LayoutParams(
-        WindowManager.LayoutParams.WRAP_CONTENT,
-        WindowManager.LayoutParams.WRAP_CONTENT,
-        WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
-        Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS,
-        PixelFormat.TRANSLUCENT
-    ).apply {
-        title = TAG
-        fitInsetsTypes = 0 // overrides default, avoiding status bars during layout
-        gravity = Gravity.TOP or Gravity.LEFT
-        layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
-        privateFlags = PRIVATE_FLAG_TRUSTED_OVERLAY or PRIVATE_FLAG_NO_MOVE_ANIMATION
-    }
-
-    init {
-        fingerprintManager?.setSidefpsController(
-            object : ISidefpsController.Stub() {
-                override fun show(
-                    sensorId: Int,
-                    @BiometricOverlayConstants.ShowReason reason: Int
-                ) = if (reason.isReasonToShow(activityTaskManager)) show() else hide()
-
-                override fun hide(sensorId: Int) = hide()
-            })
-        overviewProxyService.addCallback(overviewProxyListener)
-    }
-
-    /** Shows the side fps overlay if not already shown. */
-    fun show() {
-        mainExecutor.execute {
-            if (overlayView == null) {
-                createOverlayForDisplay()
-            } else {
-                Log.v(TAG, "overlay already shown")
-            }
-        }
-    }
-
-    /** Hides the fps overlay if shown. */
-    fun hide() {
-        mainExecutor.execute { overlayView = null }
-    }
-
-    private fun onOrientationChanged() {
-        if (overlayView != null) {
-            createOverlayForDisplay()
-        }
-    }
-
-    private fun createOverlayForDisplay() {
-        val view = layoutInflater.inflate(R.layout.sidefps_view, null, false)
-        overlayView = view
-        val display = context.display!!
-        val offsets = sensorProps.getLocation(display.uniqueId).let { location ->
-            if (location == null) {
-                Log.w(TAG, "No location specified for display: ${display.uniqueId}")
-            }
-            location ?: sensorProps.location
-        }
-        overlayOffsets = offsets
-
-        val lottie = view.findViewById(R.id.sidefps_animation) as LottieAnimationView
-        view.rotation = display.asSideFpsAnimationRotation(offsets.isYAligned())
-        lottie.setAnimation(display.asSideFpsAnimation(offsets.isYAligned()))
-        lottie.addLottieOnCompositionLoadedListener {
-            // Check that view is not stale, and that overlayView has not been hidden/removed
-            if (overlayView != null && overlayView == view) {
-                updateOverlayParams(display, it.bounds)
-            }
-        }
-        lottie.addOverlayDynamicColor(context)
-
-        /**
-         * Intercepts TYPE_WINDOW_STATE_CHANGED accessibility event, preventing Talkback from
-         * speaking @string/accessibility_fingerprint_label twice when sensor location indicator
-         * is in focus
-         */
-        view.setAccessibilityDelegate(object : AccessibilityDelegate() {
-            override fun dispatchPopulateAccessibilityEvent(
-                host: View,
-                event: AccessibilityEvent
-            ): Boolean {
-                return if (event.getEventType() === AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
-                    true
-                } else {
-                    super.dispatchPopulateAccessibilityEvent(host, event)
-                }
-            }
-        })
-    }
-
-    @VisibleForTesting
-    internal fun updateOverlayParams(display: Display, bounds: Rect) {
-        val isNaturalOrientation = display.isNaturalOrientation()
-        val size = windowManager.maximumWindowMetrics.bounds
-        val displayWidth = if (isNaturalOrientation) size.width() else size.height()
-        val displayHeight = if (isNaturalOrientation) size.height() else size.width()
-        val boundsWidth = if (isNaturalOrientation) bounds.width() else bounds.height()
-        val boundsHeight = if (isNaturalOrientation) bounds.height() else bounds.width()
-        val sensorBounds = if (overlayOffsets.isYAligned()) {
-            Rect(
-                displayWidth - boundsWidth,
-                overlayOffsets.sensorLocationY,
-                displayWidth,
-                overlayOffsets.sensorLocationY + boundsHeight
-            )
-        } else {
-            Rect(
-                overlayOffsets.sensorLocationX,
-                0,
-                overlayOffsets.sensorLocationX + boundsWidth,
-                boundsHeight
-            )
-        }
-
-        RotationUtils.rotateBounds(
-            sensorBounds,
-            Rect(0, 0, displayWidth, displayHeight),
-            display.rotation
-        )
-
-        overlayViewParams.x = sensorBounds.left
-        overlayViewParams.y = sensorBounds.top
-        windowManager.updateViewLayout(overlayView, overlayViewParams)
-    }
-
-    private fun updateOverlayVisibility(view: View) {
-        if (view != overlayView) {
-            return
-        }
-        // hide after a few seconds if the sensor is oriented down and there are
-        // large overlapping system bars
-        val rotation = context.display?.rotation
-        if (windowManager.currentWindowMetrics.windowInsets.hasBigNavigationBar() &&
-            ((rotation == Surface.ROTATION_270 && overlayOffsets.isYAligned()) ||
-                    (rotation == Surface.ROTATION_180 && !overlayOffsets.isYAligned()))) {
-            overlayHideAnimator = view.animate()
-                .alpha(0f)
-                .setStartDelay(3_000)
-                .setDuration(animationDuration)
-                .setListener(object : AnimatorListenerAdapter() {
-                    override fun onAnimationEnd(animation: Animator) {
-                        view.visibility = View.GONE
-                        overlayHideAnimator = null
-                    }
-                })
-        } else {
-            overlayHideAnimator?.cancel()
-            overlayHideAnimator = null
-            view.alpha = 1f
-            view.visibility = View.VISIBLE
-        }
-    }
-}
-
-private val FingerprintManager?.sideFpsSensorProperties: FingerprintSensorPropertiesInternal?
-    get() = this?.sensorPropertiesInternal?.firstOrNull { it.isAnySidefpsType }
-
-/** Returns [True] when the device has a side fingerprint sensor. */
-fun FingerprintManager?.hasSideFpsSensor(): Boolean = this?.sideFpsSensorProperties != null
-
-@BiometricOverlayConstants.ShowReason
-private fun Int.isReasonToShow(activityTaskManager: ActivityTaskManager): Boolean = when (this) {
-    REASON_AUTH_KEYGUARD -> false
-    REASON_AUTH_SETTINGS -> when (activityTaskManager.topClass()) {
-        // TODO(b/186176653): exclude fingerprint overlays from this list view
-        "com.android.settings.biometrics.fingerprint.FingerprintSettings" -> false
-        else -> true
-    }
-    else -> true
-}
-
-private fun ActivityTaskManager.topClass(): String =
-    getTasks(1).firstOrNull()?.topActivity?.className ?: ""
-
-@RawRes
-private fun Display.asSideFpsAnimation(yAligned: Boolean): Int = when (rotation) {
-    Surface.ROTATION_0 -> if (yAligned) R.raw.sfps_pulse else R.raw.sfps_pulse_landscape
-    Surface.ROTATION_180 -> if (yAligned) R.raw.sfps_pulse else R.raw.sfps_pulse_landscape
-    else -> if (yAligned) R.raw.sfps_pulse_landscape else R.raw.sfps_pulse
-}
-
-private fun Display.asSideFpsAnimationRotation(yAligned: Boolean): Float = when (rotation) {
-    Surface.ROTATION_90 -> if (yAligned) 0f else 180f
-    Surface.ROTATION_180 -> 180f
-    Surface.ROTATION_270 -> if (yAligned) 180f else 0f
-    else -> 0f
-}
-
-private fun SensorLocationInternal.isYAligned(): Boolean = sensorLocationY != 0
-
-private fun Display.isNaturalOrientation(): Boolean =
-    rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180
-
-private fun WindowInsets.hasBigNavigationBar(): Boolean =
-    getInsets(WindowInsets.Type.navigationBars()).bottom >= 70
-
-private fun LottieAnimationView.addOverlayDynamicColor(context: Context) {
-    fun update() {
-        val c = context.getColor(R.color.biometric_dialog_accent)
-        for (key in listOf(".blue600", ".blue400")) {
-            addValueCallback(
-                KeyPath(key, "**"),
-                LottieProperty.COLOR_FILTER
-            ) { PorterDuffColorFilter(c, PorterDuff.Mode.SRC_ATOP) }
-        }
-    }
-
-    if (composition != null) {
-        update()
-    } else {
-        addLottieOnCompositionLoadedListener { update() }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java
index 9e33ee1..fe89c9a 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java
@@ -27,7 +27,9 @@
 import dagger.Component;
 
 /**
- * Root component for Dagger injection.
+ * Base root component for Dagger injection.
+ *
+ * See {@link ReferenceGlobalRootComponent} for the one actually used by AOSP.
  */
 @Singleton
 @Component(modules = {GlobalModule.class})
@@ -51,7 +53,7 @@
     WMComponent.Builder getWMComponentBuilder();
 
     /**
-     * Builder for a {@link SysUIComponent}, which makes it a subcomponent of this class.
+     * Builder for a {@link ReferenceSysUIComponent}, which makes it a subcomponent of this class.
      */
     SysUIComponent.Builder getSysUIComponent();
 
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceGlobalRootComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceGlobalRootComponent.java
new file mode 100644
index 0000000..be93c9f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceGlobalRootComponent.java
@@ -0,0 +1,42 @@
+/*
+ * 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.dagger;
+
+import javax.inject.Singleton;
+
+import dagger.Component;
+
+/**
+ * Root component for Dagger injection used in AOSP.
+ */
+@Singleton
+@Component(modules = {GlobalModule.class})
+public interface ReferenceGlobalRootComponent extends GlobalRootComponent {
+
+    /**
+     * Builder for a ReferenceGlobalRootComponent.
+     */
+    @Component.Builder
+    interface Builder extends GlobalRootComponent.Builder {
+        ReferenceGlobalRootComponent build();
+    }
+
+    /**
+     * Builder for a {@link ReferenceSysUIComponent}, which makes it a subcomponent of this class.
+     */
+    ReferenceSysUIComponent.Builder getSysUIComponent();
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java
new file mode 100644
index 0000000..7ab36e8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java
@@ -0,0 +1,45 @@
+/*
+ * 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.dagger;
+
+import com.android.systemui.statusbar.QsFrameTranslateModule;
+
+import dagger.Subcomponent;
+
+/**
+ * Dagger Subcomponent for Core SysUI used in AOSP.
+ */
+@SysUISingleton
+@Subcomponent(modules = {
+        DefaultComponentBinder.class,
+        DependencyProvider.class,
+        QsFrameTranslateModule.class,
+        SystemUIBinder.class,
+        SystemUIModule.class,
+        SystemUICoreStartableModule.class,
+        ReferenceSystemUIModule.class})
+public interface ReferenceSysUIComponent extends SysUIComponent {
+
+    /**
+     * Builder for a ReferenceSysUIComponent.
+     */
+    @SysUISingleton
+    @Subcomponent.Builder
+    interface Builder extends SysUIComponent.Builder {
+        ReferenceSysUIComponent build();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
index c260b7d..a14b0ee 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
@@ -57,7 +57,9 @@
 import dagger.Subcomponent;
 
 /**
- * Dagger Subcomponent for Core SysUI.
+ * An example Dagger Subcomponent for Core SysUI.
+ *
+ * See {@link ReferenceSysUIComponent} for the one actually used by AOSP.
  */
 @SysUISingleton
 @Subcomponent(modules = {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
index ca25282..c867c6e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui.keyguard.data.repository
 
-import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.common.shared.model.Position
@@ -124,11 +123,6 @@
      * Sets the relative offset of the lock-screen clock from its natural position on the screen.
      */
     fun setClockPosition(x: Int, y: Int)
-
-    /**
-     * Returns whether the keyguard bottom area should be constrained to the top of the lock icon
-     */
-    fun isUdfpsSupported(): Boolean
 }
 
 /** Encapsulates application state for the keyguard. */
@@ -136,12 +130,11 @@
 class KeyguardRepositoryImpl
 @Inject
 constructor(
-        statusBarStateController: StatusBarStateController,
-        dozeHost: DozeHost,
-        wakefulnessLifecycle: WakefulnessLifecycle,
-        biometricUnlockController: BiometricUnlockController,
-        private val keyguardStateController: KeyguardStateController,
-        private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
+    statusBarStateController: StatusBarStateController,
+    private val keyguardStateController: KeyguardStateController,
+    dozeHost: DozeHost,
+    wakefulnessLifecycle: WakefulnessLifecycle,
+    biometricUnlockController: BiometricUnlockController,
 ) : KeyguardRepository {
     private val _animateBottomAreaDozingTransitions = MutableStateFlow(false)
     override val animateBottomAreaDozingTransitions =
@@ -318,8 +311,6 @@
         _clockPosition.value = Position(x, y)
     }
 
-    override fun isUdfpsSupported(): Boolean = keyguardUpdateMonitor.isUdfpsSupported
-
     private fun statusBarStateIntToObject(value: Int): StatusBarState {
         return when (value) {
             0 -> StatusBarState.SHADE
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBottomAreaInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBottomAreaInteractor.kt
index d2a7486..ede50b0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBottomAreaInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBottomAreaInteractor.kt
@@ -48,9 +48,4 @@
     fun setAnimateDozingTransitions(animate: Boolean) {
         repository.setAnimateDozingTransitions(animate)
     }
-
-    /**
-     * Returns whether the keyguard bottom area should be constrained to the top of the lock icon
-     */
-    fun shouldConstrainToTopOfLockIcon(): Boolean = repository.isUdfpsSupported()
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
index 3276b6d..2c99ca5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
@@ -27,8 +27,6 @@
 import androidx.core.view.updateLayoutParams
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
-import com.android.keyguard.KeyguardUpdateMonitor
-import com.android.keyguard.LockIconViewController
 import com.android.settingslib.Utils
 import com.android.systemui.R
 import com.android.systemui.animation.Expandable
@@ -71,11 +69,6 @@
 
         /** Notifies that device configuration has changed. */
         fun onConfigurationChanged()
-
-        /**
-         * Returns whether the keyguard bottom area should be constrained to the top of the lock icon
-         */
-        fun shouldConstrainToTopOfLockIcon(): Boolean
     }
 
     /** Binds the view to the view-model, continuing to update the former based on the latter. */
@@ -215,9 +208,6 @@
             override fun onConfigurationChanged() {
                 configurationBasedDimensions.value = loadFromResources(view)
             }
-
-            override fun shouldConstrainToTopOfLockIcon(): Boolean =
-                    viewModel.shouldConstrainToTopOfLockIcon()
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
index 227796f..b6b2304 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
@@ -90,12 +90,6 @@
             .distinctUntilChanged()
     }
 
-    /**
-     * Returns whether the keyguard bottom area should be constrained to the top of the lock icon
-     */
-    fun shouldConstrainToTopOfLockIcon(): Boolean =
-            bottomAreaInteractor.shouldConstrainToTopOfLockIcon()
-
     private fun button(
         position: KeyguardQuickAffordancePosition
     ): Flow<KeyguardQuickAffordanceViewModel> {
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
index 662d059..8bddffc 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
@@ -45,6 +45,7 @@
 import com.android.systemui.util.animation.AnimationUtil.Companion.frames
 import com.android.systemui.util.concurrency.DelayableExecutor
 import com.android.systemui.util.view.ViewUtil
+import com.android.systemui.util.wakelock.WakeLock
 import javax.inject.Inject
 
 /**
@@ -68,6 +69,7 @@
         private val mediaTttFlags: MediaTttFlags,
         private val uiEventLogger: MediaTttReceiverUiEventLogger,
         private val viewUtil: ViewUtil,
+        wakeLockBuilder: WakeLock.Builder,
 ) : TemporaryViewDisplayController<ChipReceiverInfo, MediaTttLogger>(
         context,
         logger,
@@ -77,6 +79,7 @@
         configurationController,
         powerManager,
         R.layout.media_ttt_chip_receiver,
+        wakeLockBuilder,
 ) {
     @SuppressLint("WrongConstant") // We're allowed to use LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
     override val windowLayoutParams = commonWindowLayoutParams.apply {
diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
index 47bed46..28da38b 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
@@ -108,6 +108,7 @@
 
         val filter = IntentFilter().apply {
             addAction(Intent.ACTION_USER_SWITCHED)
+            addAction(Intent.ACTION_USER_INFO_CHANGED)
             // These get called when a managed profile goes in or out of quiet mode.
             addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE)
             addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)
@@ -125,6 +126,7 @@
             Intent.ACTION_USER_SWITCHED -> {
                 handleSwitchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL))
             }
+            Intent.ACTION_USER_INFO_CHANGED,
             Intent.ACTION_MANAGED_PROFILE_AVAILABLE,
             Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE,
             Intent.ACTION_MANAGED_PROFILE_REMOVED,
diff --git a/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
index 5d7df0d..6b540aa 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
@@ -19,7 +19,6 @@
 import android.annotation.IdRes
 import android.app.StatusBarManager
 import android.content.res.Configuration
-import android.os.Bundle
 import android.os.Trace
 import android.os.Trace.TRACE_TAG_APP
 import android.util.Pair
@@ -35,8 +34,6 @@
 import com.android.systemui.animation.ShadeInterpolation
 import com.android.systemui.battery.BatteryMeterView
 import com.android.systemui.battery.BatteryMeterViewController
-import com.android.systemui.demomode.DemoMode
-import com.android.systemui.demomode.DemoModeController
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
@@ -56,7 +53,6 @@
 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
 import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.LARGE_SCREEN_BATTERY_CONTROLLER
 import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.LARGE_SCREEN_SHADE_HEADER
-import com.android.systemui.statusbar.policy.Clock
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.VariableDateView
 import com.android.systemui.statusbar.policy.VariableDateViewController
@@ -93,8 +89,7 @@
     private val dumpManager: DumpManager,
     private val featureFlags: FeatureFlags,
     private val qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder,
-    private val combinedShadeHeadersConstraintManager: CombinedShadeHeadersConstraintManager,
-    private val demoModeController: DemoModeController
+    private val combinedShadeHeadersConstraintManager: CombinedShadeHeadersConstraintManager
 ) : ViewController<View>(header), Dumpable {
 
     companion object {
@@ -131,7 +126,7 @@
     private lateinit var qsCarrierGroupController: QSCarrierGroupController
 
     private val batteryIcon: BatteryMeterView = header.findViewById(R.id.batteryRemainingIcon)
-    private val clock: Clock = header.findViewById(R.id.clock)
+    private val clock: TextView = header.findViewById(R.id.clock)
     private val date: TextView = header.findViewById(R.id.date)
     private val iconContainer: StatusIconContainer = header.findViewById(R.id.statusIcons)
     private val qsCarrierGroup: QSCarrierGroup = header.findViewById(R.id.carrier_group)
@@ -217,14 +212,6 @@
         view.onApplyWindowInsets(insets)
     }
 
-    private val demoModeReceiver = object : DemoMode {
-        override fun demoCommands() = listOf(DemoMode.COMMAND_CLOCK)
-        override fun dispatchDemoCommand(command: String, args: Bundle) =
-            clock.dispatchDemoCommand(command, args)
-        override fun onDemoModeStarted() = clock.onDemoModeStarted()
-        override fun onDemoModeFinished() = clock.onDemoModeFinished()
-    }
-
     private val chipVisibilityListener: ChipVisibilityListener = object : ChipVisibilityListener {
         override fun onChipVisibilityRefreshed(visible: Boolean) {
             if (header is MotionLayout) {
@@ -311,7 +298,6 @@
 
         dumpManager.registerDumpable(this)
         configurationController.addCallback(configurationControllerListener)
-        demoModeController.addCallback(demoModeReceiver)
 
         updateVisibility()
         updateTransition()
@@ -321,7 +307,6 @@
         privacyIconsController.chipVisibilityListener = null
         dumpManager.unregisterDumpable(this::class.java.simpleName)
         configurationController.removeCallback(configurationControllerListener)
-        demoModeController.removeCallback(demoModeReceiver)
     }
 
     fun disable(state1: Int, state2: Int, animate: Boolean) {
@@ -539,7 +524,4 @@
             updateConstraints(LARGE_SCREEN_HEADER_CONSTRAINT, updates.largeScreenConstraintsChanges)
         }
     }
-
-    @VisibleForTesting
-    internal fun simulateViewDetached() = this.onViewDetached()
 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 7262b80..350f49b 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -1308,11 +1308,7 @@
     }
 
     private void initBottomArea() {
-        mKeyguardBottomArea.init(
-                mKeyguardBottomAreaViewModel,
-                mFalsingManager,
-                mLockIconViewController
-        );
+        mKeyguardBottomArea.init(mKeyguardBottomAreaViewModel, mFalsingManager);
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 073ab8b..f2b8603 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -21,6 +21,7 @@
 import static android.app.admin.DevicePolicyResources.Strings.SystemUi.KEYGUARD_NAMED_MANAGEMENT_DISCLOSURE;
 import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK;
 import static android.hardware.biometrics.BiometricSourceType.FACE;
+import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
 import static android.view.View.GONE;
 import static android.view.View.VISIBLE;
 
@@ -50,7 +51,6 @@
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.graphics.Color;
-import android.hardware.biometrics.BiometricFaceConstants;
 import android.hardware.biometrics.BiometricSourceType;
 import android.hardware.face.FaceManager;
 import android.hardware.fingerprint.FingerprintManager;
@@ -74,12 +74,12 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.ViewClippingUtil;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.settingslib.Utils;
 import com.android.settingslib.fuelgauge.BatteryStatus;
 import com.android.systemui.R;
+import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.biometrics.FaceHelpMessageDeferral;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.SysUISingleton;
@@ -138,6 +138,7 @@
     private final KeyguardStateController mKeyguardStateController;
     protected final StatusBarStateController mStatusBarStateController;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    private final AuthController mAuthController;
     private ViewGroup mIndicationArea;
     private KeyguardIndicationTextView mTopIndicationView;
     private KeyguardIndicationTextView mLockScreenIndicationView;
@@ -188,14 +189,7 @@
     private KeyguardUpdateMonitorCallback mUpdateMonitorCallback;
 
     private boolean mDozing;
-    private final ViewClippingUtil.ClippingParameters mClippingParams =
-            new ViewClippingUtil.ClippingParameters() {
-                @Override
-                public boolean shouldFinish(View view) {
-                    return view == mIndicationArea;
-                }
-            };
-    private ScreenLifecycle mScreenLifecycle;
+    private final ScreenLifecycle mScreenLifecycle;
     private final ScreenLifecycle.Observer mScreenObserver =
             new ScreenLifecycle.Observer() {
         @Override
@@ -209,6 +203,7 @@
             }
         }
     };
+    private boolean mFaceLockedOutThisAuthSession;
 
     /**
      * Creates a new KeyguardIndicationController and registers callbacks.
@@ -229,6 +224,7 @@
             @Main DelayableExecutor executor,
             @Background DelayableExecutor bgExecutor,
             FalsingManager falsingManager,
+            AuthController authController,
             LockPatternUtils lockPatternUtils,
             ScreenLifecycle screenLifecycle,
             KeyguardBypassController keyguardBypassController,
@@ -248,6 +244,7 @@
         mExecutor = executor;
         mBackgroundExecutor = bgExecutor;
         mLockPatternUtils = lockPatternUtils;
+        mAuthController = authController;
         mFalsingManager = falsingManager;
         mKeyguardBypassController = keyguardBypassController;
         mAccessibilityManager = accessibilityManager;
@@ -619,7 +616,6 @@
                                 if (mFalsingManager.isFalseTap(LOW_PENALTY)) {
                                     return;
                                 }
-                                int currentUserId = getCurrentUser();
                                 mDevicePolicyManager.logoutUser();
                             })
                             .build(),
@@ -676,7 +672,7 @@
                 hideTransientIndication();
             }
             updateDeviceEntryIndication(false);
-        } else if (!visible) {
+        } else {
             // If we unlock and return to keyguard quickly, previous error should not be shown
             hideTransientIndication();
         }
@@ -764,7 +760,7 @@
      * logic.
      */
     private void showBiometricMessage(CharSequence biometricMessage,
-            CharSequence biometricMessageFollowUp) {
+            @Nullable CharSequence biometricMessageFollowUp) {
         if (TextUtils.equals(biometricMessage, mBiometricMessage)) {
             return;
         }
@@ -1072,17 +1068,12 @@
                     && msgId != BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
             final boolean faceAuthFailed = biometricSourceType == FACE
                     && msgId == BIOMETRIC_HELP_FACE_NOT_RECOGNIZED; // ran through matcher & failed
-            final boolean isUnlockWithFingerprintPossible =
-                    mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
-                            getCurrentUser());
+            final boolean isUnlockWithFingerprintPossible = canUnlockWithFingerprint();
             final boolean isCoExFaceAcquisitionMessage =
                     faceAuthSoftError && isUnlockWithFingerprintPossible;
             if (isCoExFaceAcquisitionMessage && !mCoExFaceAcquisitionMsgIdsToShow.contains(msgId)) {
-                if (DEBUG) {
-                    Log.d(TAG, "skip showing msgId=" + msgId + " helpString=" + helpString
-                            + ", due to co-ex logic");
-                }
-                return;
+                debugLog("skip showing msgId=" + msgId + " helpString=" + helpString
+                        + ", due to co-ex logic");
             } else if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
                 mStatusBarKeyguardViewManager.setKeyguardMessage(helpString,
                         mInitialTextColorState);
@@ -1120,74 +1111,45 @@
         }
 
         @Override
-        public void onBiometricError(int msgId, String errString,
-                BiometricSourceType biometricSourceType) {
-            CharSequence deferredFaceMessage = null;
-            if (biometricSourceType == FACE) {
-                if (msgId == BiometricFaceConstants.FACE_ERROR_TIMEOUT) {
-                    deferredFaceMessage = mFaceAcquiredMessageDeferral.getDeferredMessage();
-                    if (DEBUG) {
-                        Log.d(TAG, "showDeferredFaceMessage msgId=" + deferredFaceMessage);
-                    }
-                }
-                mFaceAcquiredMessageDeferral.reset();
-            }
-
-            if (shouldSuppressBiometricError(msgId, biometricSourceType, mKeyguardUpdateMonitor)) {
-                if (DEBUG) {
-                    Log.d(TAG, "suppressingBiometricError msgId=" + msgId
-                            + " source=" + biometricSourceType);
-                }
-            } else if (biometricSourceType == FACE && msgId == FaceManager.FACE_ERROR_TIMEOUT) {
-                // Co-ex: show deferred message OR nothing
-                if (mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
-                        KeyguardUpdateMonitor.getCurrentUser())) {
-                    // if we're on the lock screen (bouncer isn't showing), show the deferred msg
-                    if (deferredFaceMessage != null
-                            && !mStatusBarKeyguardViewManager.isBouncerShowing()) {
-                        showBiometricMessage(
-                                deferredFaceMessage,
-                                mContext.getString(R.string.keyguard_suggest_fingerprint)
-                        );
-                        return;
-                    }
-
-                    // otherwise, don't show any message
-                    if (DEBUG) {
-                        Log.d(TAG, "skip showing FACE_ERROR_TIMEOUT due to co-ex logic");
-                    }
-                    return;
-                }
-
-                // Face-only: The face timeout message is not very actionable, let's ask the user to
-                // manually retry.
-                if (deferredFaceMessage != null) {
-                    showBiometricMessage(
-                            deferredFaceMessage,
-                            mContext.getString(R.string.keyguard_unlock)
-                    );
-                } else {
-                    // suggest swiping up to unlock (try face auth again or swipe up to bouncer)
-                    showActionToUnlock();
-                }
-            } else if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
-                mStatusBarKeyguardViewManager.setKeyguardMessage(errString, mInitialTextColorState);
-            } else if (mScreenLifecycle.getScreenState() == SCREEN_ON) {
-                showBiometricMessage(errString);
-            } else {
-                mBiometricErrorMessageToShowOnScreenOn = errString;
+        public void onLockedOutStateChanged(BiometricSourceType biometricSourceType) {
+            if (biometricSourceType == FACE && !mKeyguardUpdateMonitor.isFaceLockedOut()) {
+                mFaceLockedOutThisAuthSession = false;
             }
         }
 
-        private boolean shouldSuppressBiometricError(int msgId,
-                BiometricSourceType biometricSourceType, KeyguardUpdateMonitor updateMonitor) {
-            if (biometricSourceType == BiometricSourceType.FINGERPRINT) {
-                return shouldSuppressFingerprintError(msgId, updateMonitor);
-            }
+        @Override
+        public void onBiometricError(int msgId, String errString,
+                BiometricSourceType biometricSourceType) {
             if (biometricSourceType == FACE) {
-                return shouldSuppressFaceError(msgId, updateMonitor);
+                onFaceAuthError(msgId, errString);
+            } else if (biometricSourceType == FINGERPRINT) {
+                onFingerprintAuthError(msgId, errString);
             }
-            return false;
+        }
+
+        private void onFaceAuthError(int msgId, String errString) {
+            CharSequence deferredFaceMessage = mFaceAcquiredMessageDeferral.getDeferredMessage();
+            mFaceAcquiredMessageDeferral.reset();
+            if (shouldSuppressFaceError(msgId, mKeyguardUpdateMonitor)) {
+                debugLog("suppressingFaceError msgId=" + msgId + " errString= " + errString);
+                return;
+            }
+            if (msgId == FaceManager.FACE_ERROR_TIMEOUT) {
+                handleFaceAuthTimeoutError(deferredFaceMessage);
+            } else if (isLockoutError(msgId)) {
+                handleFaceLockoutError(errString);
+            } else {
+                showErrorMessageNowOrLater(errString, null);
+            }
+        }
+
+        private void onFingerprintAuthError(int msgId, String errString) {
+            if (shouldSuppressFingerprintError(msgId, mKeyguardUpdateMonitor)) {
+                debugLog("suppressingFingerprintError msgId=" + msgId
+                        + " errString= " + errString);
+            } else {
+                showErrorMessageNowOrLater(errString, null);
+            }
         }
 
         private boolean shouldSuppressFingerprintError(int msgId,
@@ -1197,7 +1159,7 @@
             // pass true for isStrongBiometric to isUnlockingWithBiometricAllowed() to bypass the
             // check of whether non-strong biometric is allowed
             return ((!updateMonitor.isUnlockingWithBiometricAllowed(true /* isStrongBiometric */)
-                    && msgId != FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT)
+                    && !isLockoutError(msgId))
                     || msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
                     || msgId == FingerprintManager.FINGERPRINT_ERROR_USER_CANCELED
                     || msgId == FingerprintManager.BIOMETRIC_ERROR_POWER_PRESSED);
@@ -1286,7 +1248,82 @@
         }
     }
 
-    private StatusBarStateController.StateListener mStatusBarStateListener =
+    private void handleFaceLockoutError(String errString) {
+        int followupMsgId = canUnlockWithFingerprint() ? R.string.keyguard_suggest_fingerprint
+                : R.string.keyguard_unlock;
+        String followupMessage = mContext.getString(followupMsgId);
+        // Lockout error can happen multiple times in a session because we trigger face auth
+        // even when it is locked out so that the user is aware that face unlock would have
+        // triggered but didn't because it is locked out.
+
+        // On first lockout we show the error message from FaceManager, which tells the user they
+        // had too many unsuccessful attempts.
+        if (!mFaceLockedOutThisAuthSession) {
+            mFaceLockedOutThisAuthSession = true;
+            showErrorMessageNowOrLater(errString, followupMessage);
+        } else if (!mAuthController.isUdfpsFingerDown()) {
+            // On subsequent lockouts, we show a more generic locked out message.
+            showBiometricMessage(mContext.getString(R.string.keyguard_face_unlock_unavailable),
+                    followupMessage);
+        }
+    }
+
+    private static boolean isLockoutError(int msgId) {
+        return msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT
+                || msgId == FaceManager.FACE_ERROR_LOCKOUT;
+    }
+
+    private void handleFaceAuthTimeoutError(@Nullable CharSequence deferredFaceMessage) {
+        debugLog("showDeferredFaceMessage msgId=" + deferredFaceMessage);
+        if (canUnlockWithFingerprint()) {
+            // Co-ex: show deferred message OR nothing
+            // if we're on the lock screen (bouncer isn't showing), show the deferred msg
+            if (deferredFaceMessage != null
+                    && !mStatusBarKeyguardViewManager.isBouncerShowing()) {
+                showBiometricMessage(
+                        deferredFaceMessage,
+                        mContext.getString(R.string.keyguard_suggest_fingerprint)
+                );
+            } else {
+                // otherwise, don't show any message
+                debugLog("skip showing FACE_ERROR_TIMEOUT due to co-ex logic");
+            }
+        } else if (deferredFaceMessage != null) {
+            // Face-only: The face timeout message is not very actionable, let's ask the
+            // user to manually retry.
+            showBiometricMessage(
+                    deferredFaceMessage,
+                    mContext.getString(R.string.keyguard_unlock)
+            );
+        } else {
+            // Face-only
+            // suggest swiping up to unlock (try face auth again or swipe up to bouncer)
+            showActionToUnlock();
+        }
+    }
+
+    private boolean canUnlockWithFingerprint() {
+        return mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
+                KeyguardUpdateMonitor.getCurrentUser());
+    }
+
+    private void debugLog(String logMsg) {
+        if (DEBUG) {
+            Log.d(TAG, logMsg);
+        }
+    }
+
+    private void showErrorMessageNowOrLater(String errString, @Nullable String followUpMsg) {
+        if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
+            mStatusBarKeyguardViewManager.setKeyguardMessage(errString, mInitialTextColorState);
+        } else if (mScreenLifecycle.getScreenState() == SCREEN_ON) {
+            showBiometricMessage(errString, followUpMsg);
+        } else {
+            mBiometricErrorMessageToShowOnScreenOn = errString;
+        }
+    }
+
+    private final StatusBarStateController.StateListener mStatusBarStateListener =
             new StatusBarStateController.StateListener() {
         @Override
         public void onStateChanged(int newState) {
@@ -1307,7 +1344,7 @@
         }
     };
 
-    private KeyguardStateController.Callback mKeyguardStateCallback =
+    private final KeyguardStateController.Callback mKeyguardStateCallback =
             new KeyguardStateController.Callback() {
         @Override
         public void onUnlockedChanged() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 408293c..815b86e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -805,7 +805,7 @@
         iconState.hidden = isAppearing
                 || (view instanceof ExpandableNotificationRow
                 && ((ExpandableNotificationRow) view).isLowPriority()
-                && mShelfIcons.hasMaxNumDot())
+                && mShelfIcons.areIconsOverflowing())
                 || (transitionAmount == 0.0f && !iconState.isAnimating(icon))
                 || row.isAboveShelf()
                 || row.showingPulsing()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt
index 78b28d2..4897c52 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt
@@ -23,8 +23,6 @@
 import android.view.ViewPropertyAnimator
 import android.view.WindowInsets
 import android.widget.FrameLayout
-import com.android.keyguard.KeyguardUpdateMonitor
-import com.android.keyguard.LockIconViewController
 import com.android.systemui.R
 import com.android.systemui.keyguard.ui.binder.KeyguardBottomAreaViewBinder
 import com.android.systemui.keyguard.ui.binder.KeyguardBottomAreaViewBinder.bind
@@ -53,20 +51,13 @@
 
     private var ambientIndicationArea: View? = null
     private lateinit var binding: KeyguardBottomAreaViewBinder.Binding
-    private lateinit var lockIconViewController: LockIconViewController
 
     /** Initializes the view. */
     fun init(
         viewModel: KeyguardBottomAreaViewModel,
         falsingManager: FalsingManager,
-        lockIconViewController: LockIconViewController,
     ) {
-        binding = bind(
-                this,
-                viewModel,
-                falsingManager,
-        )
-        this.lockIconViewController = lockIconViewController
+        binding = bind(this, viewModel, falsingManager)
     }
 
     /**
@@ -123,29 +114,4 @@
         }
         return insets
     }
-
-    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
-        super.onLayout(changed, left, top, right, bottom)
-        findViewById<View>(R.id.ambient_indication_container)?.let {
-            val (ambientLeft, ambientTop) = it.locationOnScreen
-            if (binding.shouldConstrainToTopOfLockIcon()) {
-                //make top of ambient indication view the bottom of the lock icon
-                it.layout(
-                        ambientLeft,
-                        lockIconViewController.bottom.toInt(),
-                        right - ambientLeft,
-                        ambientTop + it.measuredHeight
-                )
-            } else {
-                //make bottom of ambient indication view the top of the lock icon
-                val lockLocationTop = lockIconViewController.top
-                it.layout(
-                        ambientLeft,
-                        lockLocationTop.toInt() - it.measuredHeight,
-                        right - ambientLeft,
-                        lockLocationTop.toInt()
-                )
-            }
-        }
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index c189ace..4ee2de1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -141,7 +141,6 @@
     /* Maximum number of icons in short shelf on lockscreen when also showing overflow dot. */
     public static final int MAX_ICONS_ON_LOCKSCREEN = 3;
     public static final int MAX_STATIC_ICONS = 4;
-    private static final int MAX_DOTS = 1;
 
     private boolean mIsStaticLayout = true;
     private final HashMap<View, IconState> mIconStates = new HashMap<>();
@@ -166,8 +165,7 @@
     private IconState mLastVisibleIconState;
     private IconState mFirstVisibleIconState;
     private float mVisualOverflowStart;
-    // Keep track of overflow in range [0, 3]
-    private int mNumDots;
+    private boolean mIsShowingOverflowDot;
     private StatusBarIconView mIsolatedIcon;
     private Rect mIsolatedIconLocation;
     private int[] mAbsolutePosition = new int[2];
@@ -387,8 +385,8 @@
         }
     }
 
-    public boolean hasMaxNumDot() {
-        return mNumDots >= MAX_DOTS;
+    public boolean areIconsOverflowing() {
+        return mIsShowingOverflowDot;
     }
 
     private boolean areAnimationsEnabled(StatusBarIconView icon) {
@@ -494,7 +492,7 @@
                     : 1f;
             translationX += iconState.iconAppearAmount * view.getWidth() * drawingScale;
         }
-        mNumDots = 0;
+        mIsShowingOverflowDot = false;
         if (firstOverflowIndex != -1) {
             translationX = mVisualOverflowStart;
             for (int i = firstOverflowIndex; i < childCount; i++) {
@@ -502,15 +500,14 @@
                 IconState iconState = mIconStates.get(view);
                 int dotWidth = mStaticDotDiameter + mDotPadding;
                 iconState.setXTranslation(translationX);
-                if (mNumDots < MAX_DOTS) {
-                    if (mNumDots == 0 && iconState.iconAppearAmount < 0.8f) {
+                if (!mIsShowingOverflowDot) {
+                    if (iconState.iconAppearAmount < 0.8f) {
                         iconState.visibleState = StatusBarIconView.STATE_ICON;
                     } else {
                         iconState.visibleState = StatusBarIconView.STATE_DOT;
-                        mNumDots++;
+                        mIsShowingOverflowDot = true;
                     }
-                    translationX += (mNumDots == MAX_DOTS ? MAX_DOTS * dotWidth : dotWidth)
-                            * iconState.iconAppearAmount;
+                    translationX += dotWidth * iconState.iconAppearAmount;
                     mLastVisibleIconState = iconState;
                 } else {
                     iconState.visibleState = StatusBarIconView.STATE_HIDDEN;
@@ -618,10 +615,6 @@
         return Math.min(getWidth(), translation);
     }
 
-    private float getMaxOverflowStart() {
-        return getLayoutEnd() - mIconSize;
-    }
-
     public void setChangingViewPositions(boolean changingViewPositions) {
         mChangingViewPositions = changingViewPositions;
     }
@@ -645,25 +638,6 @@
         mSpeedBumpIndex = speedBumpIndex;
     }
 
-    public boolean hasOverflow() {
-        return mNumDots > 0;
-    }
-
-    // Give some extra room for btw notifications if we can
-    public int getNoOverflowExtraPadding() {
-        if (mNumDots != 0) {
-            return 0;
-        }
-
-        int collapsedPadding = mIconSize;
-
-        if (collapsedPadding + getFinalTranslationX() > getWidth()) {
-            collapsedPadding = getWidth() - getFinalTranslationX();
-        }
-
-        return collapsedPadding;
-    }
-
     public int getIconSize() {
         return mIconSize;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
index 637fac0..4cb41f3 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
@@ -22,7 +22,6 @@
 import android.graphics.Rect
 import android.graphics.drawable.Drawable
 import android.os.PowerManager
-import android.os.SystemClock
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
@@ -35,6 +34,7 @@
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.wakelock.WakeLock
 
 /**
  * A generic controller that can temporarily display a new view in a new window.
@@ -54,6 +54,7 @@
     private val configurationController: ConfigurationController,
     private val powerManager: PowerManager,
     @LayoutRes private val viewLayoutRes: Int,
+    private val wakeLockBuilder: WakeLock.Builder,
 ) : CoreStartable {
     /**
      * Window layout params that will be used as a starting point for the [windowLayoutParams] of
@@ -64,7 +65,8 @@
         height = WindowManager.LayoutParams.WRAP_CONTENT
         type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR
         flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
-            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
+            WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
         format = PixelFormat.TRANSLUCENT
         setTrustedOverlay()
     }
@@ -84,6 +86,15 @@
     private var cancelViewTimeout: Runnable? = null
 
     /**
+     * A wakelock that is acquired when view is displayed and screen off,
+     * then released when view is removed.
+     */
+    private var wakeLock: WakeLock? = null
+
+    /** A string that keeps track of wakelock reason once it is acquired till it gets released */
+    private var wakeReasonAcquired: String? = null
+
+    /**
      * Displays the view with the provided [newInfo].
      *
      * This method handles inflating and attaching the view, then delegates to [updateView] to
@@ -113,11 +124,15 @@
             // the view to show over the dream state, so we should only wake up if the screen is
             // completely off.)
             if (!powerManager.isScreenOn) {
-                powerManager.wakeUp(
-                    SystemClock.uptimeMillis(),
-                    PowerManager.WAKE_REASON_APPLICATION,
-                    "com.android.systemui:${newInfo.wakeReason}",
-                )
+                wakeLock = wakeLockBuilder
+                    .setTag(newInfo.windowTitle)
+                    .setLevelsAndFlags(
+                        PowerManager.FULL_WAKE_LOCK or
+                        PowerManager.ACQUIRE_CAUSES_WAKEUP
+                    )
+                    .build()
+                wakeLock?.acquire(newInfo.wakeReason)
+                wakeReasonAcquired = newInfo.wakeReason
             }
             logger.logViewAddition(newInfo.windowTitle)
             inflateAndUpdateView(newInfo)
@@ -155,6 +170,7 @@
             it.copyFrom(windowLayoutParams)
             it.title = newInfo.windowTitle
         }
+        newView.keepScreenOn = true
         windowManager.addView(newView, paramsWithTitle)
         animateViewIn(newView)
     }
@@ -183,7 +199,10 @@
         val currentDisplayInfo = displayInfo ?: return
 
         val currentView = currentDisplayInfo.view
-        animateViewOut(currentView) { windowManager.removeView(currentView) }
+        animateViewOut(currentView) {
+            windowManager.removeView(currentView)
+            wakeLock?.release(wakeReasonAcquired)
+        }
 
         logger.logViewRemoval(removalReason)
         configurationController.removeCallback(displayScaleListener)
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
index 87b6e8d..44e5ce8 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
@@ -44,6 +44,7 @@
 import com.android.systemui.temporarydisplay.TemporaryViewDisplayController
 import com.android.systemui.util.concurrency.DelayableExecutor
 import com.android.systemui.util.view.ViewUtil
+import com.android.systemui.util.wakelock.WakeLock
 import javax.inject.Inject
 
 /**
@@ -75,6 +76,7 @@
         private val falsingCollector: FalsingCollector,
         private val viewUtil: ViewUtil,
         private val vibratorHelper: VibratorHelper,
+        wakeLockBuilder: WakeLock.Builder,
 ) : TemporaryViewDisplayController<ChipbarInfo, ChipbarLogger>(
         context,
         logger,
@@ -84,6 +86,7 @@
         configurationController,
         powerManager,
         R.layout.chipbar,
+        wakeLockBuilder,
 ) {
 
     private lateinit var parent: ChipbarRootView
@@ -92,8 +95,6 @@
         gravity = Gravity.TOP.or(Gravity.CENTER_HORIZONTAL)
     }
 
-    override fun start() {}
-
     override fun updateView(
         newInfo: ChipbarInfo,
         currentView: ViewGroup
@@ -192,6 +193,8 @@
         )
     }
 
+    override fun start() {}
+
     override fun getTouchableRegion(view: View, outRect: Rect) {
         viewUtil.setRectToViewWindowLocation(view, outRect)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java b/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java
index f017126..b56c403 100644
--- a/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java
@@ -25,6 +25,8 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.util.Log;
+import android.window.OnBackInvokedCallback;
+import android.window.OnBackInvokedDispatcher;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -59,6 +61,7 @@
     private final ActivityStarter mActivityStarter;
 
     private Dialog mSetupUserDialog;
+    private final OnBackInvokedCallback mBackCallback = this::onBackInvoked;
 
     @Inject
     public CreateUserActivity(UserCreator userCreator,
@@ -82,6 +85,10 @@
 
         mSetupUserDialog = createDialog();
         mSetupUserDialog.show();
+
+        getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
+                        OnBackInvokedDispatcher.PRIORITY_DEFAULT,
+                        mBackCallback);
     }
 
     @Override
@@ -125,10 +132,20 @@
 
     @Override
     public void onBackPressed() {
-        super.onBackPressed();
+        onBackInvoked();
+    }
+
+    private void onBackInvoked() {
         if (mSetupUserDialog != null) {
             mSetupUserDialog.dismiss();
         }
+        finish();
+    }
+
+    @Override
+    protected void onDestroy() {
+        getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(mBackCallback);
+        super.onDestroy();
     }
 
     private void addUserNow(String userName, Drawable userIcon) {
diff --git a/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt b/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt
index 6a23260..ffaf524 100644
--- a/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt
@@ -250,6 +250,10 @@
                         override fun onUserChanged(newUser: Int, userContext: Context) {
                             send()
                         }
+
+                        override fun onProfilesChanged(profiles: List<UserInfo>) {
+                            send()
+                        }
                     }
 
                 tracker.addCallback(callback, mainDispatcher.asExecutor())
diff --git a/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java b/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java
index 8d77c4a..f320d07 100644
--- a/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java
+++ b/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java
@@ -38,6 +38,11 @@
     long DEFAULT_MAX_TIMEOUT = 20000;
 
     /**
+     * Default wake-lock levels and flags.
+     */
+    int DEFAULT_LEVELS_AND_FLAGS = PowerManager.PARTIAL_WAKE_LOCK;
+
+    /**
      * @param why A tag that will be saved for sysui dumps.
      * @see android.os.PowerManager.WakeLock#acquire()
      **/
@@ -60,13 +65,21 @@
      * Creates a {@link WakeLock} that has a default release timeout.
      * @see android.os.PowerManager.WakeLock#acquire(long) */
     static WakeLock createPartial(Context context, String tag, long maxTimeout) {
-        return wrap(createPartialInner(context, tag), maxTimeout);
+        return wrap(createWakeLockInner(context, tag, DEFAULT_LEVELS_AND_FLAGS), maxTimeout);
+    }
+
+    /**
+     * Creates a {@link WakeLock} that has a default release timeout and flags.
+     */
+    static WakeLock createWakeLock(Context context, String tag, int flags, long maxTimeout) {
+        return wrap(createWakeLockInner(context, tag, flags), maxTimeout);
     }
 
     @VisibleForTesting
-    static PowerManager.WakeLock createPartialInner(Context context, String tag) {
+    static PowerManager.WakeLock createWakeLockInner(
+            Context context, String tag, int levelsAndFlags) {
         return context.getSystemService(PowerManager.class)
-                    .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, tag);
+                    .newWakeLock(levelsAndFlags, tag);
     }
 
     static Runnable wrapImpl(WakeLock w, Runnable r) {
@@ -131,6 +144,7 @@
     class Builder {
         private final Context mContext;
         private String mTag;
+        private int mLevelsAndFlags = DEFAULT_LEVELS_AND_FLAGS;
         private long mMaxTimeout = DEFAULT_MAX_TIMEOUT;
 
         @Inject
@@ -143,13 +157,18 @@
             return this;
         }
 
+        public Builder setLevelsAndFlags(int levelsAndFlags) {
+            this.mLevelsAndFlags = levelsAndFlags;
+            return this;
+        }
+
         public Builder setMaxTimeout(long maxTimeout) {
             this.mMaxTimeout = maxTimeout;
             return this;
         }
 
         public WakeLock build() {
-            return WakeLock.createPartial(mContext, mTag, mMaxTimeout);
+            return WakeLock.createWakeLock(mContext, mTag, mLevelsAndFlags, mMaxTimeout);
         }
     }
 }
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index 1b404a8..e51236b 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -106,6 +106,12 @@
                   android:finishOnCloseSystemDialogs="true"
                   android:excludeFromRecents="true" />
 
+        <activity android:name=".user.CreateUserActivityTest$CreateUserActivityTestable"
+            android:exported="false"
+            android:theme="@style/Theme.SystemUI.Dialog.Alert"
+            android:finishOnCloseSystemDialogs="true"
+            android:excludeFromRecents="true" />
+
         <provider
             android:name="androidx.startup.InitializationProvider"
             tools:replace="android:authorities"
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
index 0a2b3d8..aa4469f 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
@@ -54,7 +54,8 @@
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.biometrics.SidefpsController;
+import com.android.systemui.biometrics.SideFpsController;
+import com.android.systemui.biometrics.SideFpsUiRequestSource;
 import com.android.systemui.classifier.FalsingA11yDelegate;
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.flags.FeatureFlags;
@@ -141,7 +142,7 @@
     @Mock
     private KeyguardViewController mKeyguardViewController;
     @Mock
-    private SidefpsController mSidefpsController;
+    private SideFpsController mSideFpsController;
     @Mock
     private KeyguardPasswordViewController mKeyguardPasswordViewControllerMock;
     @Mock
@@ -189,7 +190,7 @@
                 mKeyguardStateController, mKeyguardSecurityViewFlipperController,
                 mConfigurationController, mFalsingCollector, mFalsingManager,
                 mUserSwitcherController, mFeatureFlags, mGlobalSettings,
-                mSessionTracker, Optional.of(mSidefpsController), mFalsingA11yDelegate).create(
+                mSessionTracker, Optional.of(mSideFpsController), mFalsingA11yDelegate).create(
                 mSecurityCallback);
     }
 
@@ -345,48 +346,48 @@
     @Test
     public void onBouncerVisibilityChanged_allConditionsGood_sideFpsHintShown() {
         setupConditionsToEnableSideFpsHint();
-        reset(mSidefpsController);
+        reset(mSideFpsController);
 
         mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
 
-        verify(mSidefpsController).show();
-        verify(mSidefpsController, never()).hide();
+        verify(mSideFpsController).show(SideFpsUiRequestSource.PRIMARY_BOUNCER);
+        verify(mSideFpsController, never()).hide(any());
     }
 
     @Test
     public void onBouncerVisibilityChanged_fpsSensorNotRunning_sideFpsHintHidden() {
         setupConditionsToEnableSideFpsHint();
         setFingerprintDetectionRunning(false);
-        reset(mSidefpsController);
+        reset(mSideFpsController);
 
         mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
 
-        verify(mSidefpsController).hide();
-        verify(mSidefpsController, never()).show();
+        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
+        verify(mSideFpsController, never()).show(any());
     }
 
     @Test
     public void onBouncerVisibilityChanged_withoutSidedSecurity_sideFpsHintHidden() {
         setupConditionsToEnableSideFpsHint();
         setSideFpsHintEnabledFromResources(false);
-        reset(mSidefpsController);
+        reset(mSideFpsController);
 
         mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
 
-        verify(mSidefpsController).hide();
-        verify(mSidefpsController, never()).show();
+        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
+        verify(mSideFpsController, never()).show(any());
     }
 
     @Test
     public void onBouncerVisibilityChanged_needsStrongAuth_sideFpsHintHidden() {
         setupConditionsToEnableSideFpsHint();
         setNeedsStrongAuth(true);
-        reset(mSidefpsController);
+        reset(mSideFpsController);
 
         mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
 
-        verify(mSidefpsController).hide();
-        verify(mSidefpsController, never()).show();
+        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
+        verify(mSideFpsController, never()).show(any());
     }
 
     @Test
@@ -394,13 +395,13 @@
         setupGetSecurityView();
         setupConditionsToEnableSideFpsHint();
         mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
-        verify(mSidefpsController, atLeastOnce()).show();
-        reset(mSidefpsController);
+        verify(mSideFpsController, atLeastOnce()).show(SideFpsUiRequestSource.PRIMARY_BOUNCER);
+        reset(mSideFpsController);
 
         mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.INVISIBLE);
 
-        verify(mSidefpsController).hide();
-        verify(mSidefpsController, never()).show();
+        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
+        verify(mSideFpsController, never()).show(any());
     }
 
     @Test
@@ -408,13 +409,13 @@
         setupGetSecurityView();
         setupConditionsToEnableSideFpsHint();
         mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
-        verify(mSidefpsController, atLeastOnce()).show();
-        reset(mSidefpsController);
+        verify(mSideFpsController, atLeastOnce()).show(SideFpsUiRequestSource.PRIMARY_BOUNCER);
+        reset(mSideFpsController);
 
         mKeyguardSecurityContainerController.onStartingToHide();
 
-        verify(mSidefpsController).hide();
-        verify(mSidefpsController, never()).show();
+        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
+        verify(mSideFpsController, never()).show(any());
     }
 
     @Test
@@ -422,13 +423,13 @@
         setupGetSecurityView();
         setupConditionsToEnableSideFpsHint();
         mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
-        verify(mSidefpsController, atLeastOnce()).show();
-        reset(mSidefpsController);
+        verify(mSideFpsController, atLeastOnce()).show(SideFpsUiRequestSource.PRIMARY_BOUNCER);
+        reset(mSideFpsController);
 
         mKeyguardSecurityContainerController.onPause();
 
-        verify(mSidefpsController).hide();
-        verify(mSidefpsController, never()).show();
+        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
+        verify(mSideFpsController, never()).show(any());
     }
 
     @Test
@@ -436,12 +437,12 @@
         setupGetSecurityView();
         setupConditionsToEnableSideFpsHint();
         mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
-        reset(mSidefpsController);
+        reset(mSideFpsController);
 
         mKeyguardSecurityContainerController.onResume(0);
 
-        verify(mSidefpsController).show();
-        verify(mSidefpsController, never()).hide();
+        verify(mSideFpsController).show(SideFpsUiRequestSource.PRIMARY_BOUNCER);
+        verify(mSideFpsController, never()).hide(any());
     }
 
     @Test
@@ -450,12 +451,12 @@
         setupConditionsToEnableSideFpsHint();
         setSideFpsHintEnabledFromResources(false);
         mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
-        reset(mSidefpsController);
+        reset(mSideFpsController);
 
         mKeyguardSecurityContainerController.onResume(0);
 
-        verify(mSidefpsController).hide();
-        verify(mSidefpsController, never()).show();
+        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
+        verify(mSideFpsController, never()).show(any());
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index a8284d2..9c14ee6 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -1621,7 +1621,7 @@
     }
 
     @Test
-    public void testShouldListenForFace_whenFaceIsLockedOut_returnsFalse()
+    public void testShouldListenForFace_whenFaceIsLockedOut_returnsTrue()
             throws RemoteException {
         // Preconditions for face auth to run
         keyguardNotGoingAway();
@@ -1638,7 +1638,9 @@
         faceAuthLockedOut();
         mTestableLooper.processAllMessages();
 
-        assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isFalse();
+        // This is needed beccause we want to show face locked out error message whenever face auth
+        // is supposed to run.
+        assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isTrue();
     }
 
     @Test
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 a275c8d..83bf183 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -145,7 +145,7 @@
     @Mock
     private UdfpsController mUdfpsController;
     @Mock
-    private SidefpsController mSidefpsController;
+    private SideFpsController mSideFpsController;
     @Mock
     private DisplayManager mDisplayManager;
     @Mock
@@ -225,7 +225,7 @@
 
         mAuthController = new TestableAuthController(mContextSpy, mExecution, mCommandQueue,
                 mActivityTaskManager, mWindowManager, mFingerprintManager, mFaceManager,
-                () -> mUdfpsController, () -> mSidefpsController, mStatusBarStateController,
+                () -> mUdfpsController, () -> mSideFpsController, mStatusBarStateController,
                 mVibratorHelper);
 
         mAuthController.start();
@@ -256,7 +256,7 @@
         // This test requires an uninitialized AuthController.
         AuthController authController = new TestableAuthController(mContextSpy, mExecution,
                 mCommandQueue, mActivityTaskManager, mWindowManager, mFingerprintManager,
-                mFaceManager, () -> mUdfpsController, () -> mSidefpsController,
+                mFaceManager, () -> mUdfpsController, () -> mSideFpsController,
                 mStatusBarStateController, mVibratorHelper);
         authController.start();
 
@@ -282,7 +282,7 @@
         // This test requires an uninitialized AuthController.
         AuthController authController = new TestableAuthController(mContextSpy, mExecution,
                 mCommandQueue, mActivityTaskManager, mWindowManager, mFingerprintManager,
-                mFaceManager, () -> mUdfpsController, () -> mSidefpsController,
+                mFaceManager, () -> mUdfpsController, () -> mSideFpsController,
                 mStatusBarStateController, mVibratorHelper);
         authController.start();
 
@@ -936,7 +936,7 @@
                 FingerprintManager fingerprintManager,
                 FaceManager faceManager,
                 Provider<UdfpsController> udfpsControllerFactory,
-                Provider<SidefpsController> sidefpsControllerFactory,
+                Provider<SideFpsController> sidefpsControllerFactory,
                 StatusBarStateController statusBarStateController,
                 VibratorHelper vibratorHelper) {
             super(context, execution, commandQueue, activityTaskManager, windowManager,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
new file mode 100644
index 0000000..e7d5632
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
@@ -0,0 +1,472 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics
+
+import android.animation.Animator
+import android.app.ActivityManager
+import android.app.ActivityTaskManager
+import android.content.ComponentName
+import android.graphics.Insets
+import android.graphics.Rect
+import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD
+import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_SETTINGS
+import android.hardware.biometrics.BiometricOverlayConstants.REASON_UNKNOWN
+import android.hardware.biometrics.SensorLocationInternal
+import android.hardware.biometrics.SensorProperties
+import android.hardware.display.DisplayManager
+import android.hardware.display.DisplayManagerGlobal
+import android.hardware.fingerprint.FingerprintManager
+import android.hardware.fingerprint.FingerprintSensorProperties
+import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
+import android.hardware.fingerprint.ISidefpsController
+import android.os.Handler
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.Display
+import android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS
+import android.view.DisplayInfo
+import android.view.LayoutInflater
+import android.view.Surface
+import android.view.View
+import android.view.ViewPropertyAnimator
+import android.view.WindowInsets
+import android.view.WindowManager
+import android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION
+import android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY
+import android.view.WindowMetrics
+import androidx.test.filters.SmallTest
+import com.airbnb.lottie.LottieAnimationView
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.recents.OverviewProxyService
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.any
+import org.mockito.Mockito.anyFloat
+import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.anyLong
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.reset
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenEver
+import org.mockito.junit.MockitoJUnit
+
+private const val DISPLAY_ID = 2
+private const val SENSOR_ID = 1
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class SideFpsControllerTest : SysuiTestCase() {
+
+    @JvmField @Rule var rule = MockitoJUnit.rule()
+
+    @Mock lateinit var layoutInflater: LayoutInflater
+    @Mock lateinit var fingerprintManager: FingerprintManager
+    @Mock lateinit var windowManager: WindowManager
+    @Mock lateinit var activityTaskManager: ActivityTaskManager
+    @Mock lateinit var sideFpsView: View
+    @Mock lateinit var displayManager: DisplayManager
+    @Mock lateinit var overviewProxyService: OverviewProxyService
+    @Mock lateinit var handler: Handler
+    @Mock lateinit var dumpManager: DumpManager
+    @Captor lateinit var overlayCaptor: ArgumentCaptor<View>
+    @Captor lateinit var overlayViewParamsCaptor: ArgumentCaptor<WindowManager.LayoutParams>
+
+    private val executor = FakeExecutor(FakeSystemClock())
+    private lateinit var overlayController: ISidefpsController
+    private lateinit var sideFpsController: SideFpsController
+
+    enum class DeviceConfig {
+        X_ALIGNED,
+        Y_ALIGNED_UNFOLDED,
+        Y_ALIGNED_FOLDED
+    }
+
+    private lateinit var deviceConfig: DeviceConfig
+    private lateinit var indicatorBounds: Rect
+    private lateinit var displayBounds: Rect
+    private lateinit var sensorLocation: SensorLocationInternal
+    private var displayWidth: Int = 0
+    private var displayHeight: Int = 0
+    private var boundsWidth: Int = 0
+    private var boundsHeight: Int = 0
+
+    @Before
+    fun setup() {
+        context.addMockSystemService(DisplayManager::class.java, displayManager)
+        context.addMockSystemService(WindowManager::class.java, windowManager)
+
+        whenEver(layoutInflater.inflate(R.layout.sidefps_view, null, false)).thenReturn(sideFpsView)
+        whenEver(sideFpsView.findViewById<LottieAnimationView>(eq(R.id.sidefps_animation)))
+            .thenReturn(mock(LottieAnimationView::class.java))
+        with(mock(ViewPropertyAnimator::class.java)) {
+            whenEver(sideFpsView.animate()).thenReturn(this)
+            whenEver(alpha(anyFloat())).thenReturn(this)
+            whenEver(setStartDelay(anyLong())).thenReturn(this)
+            whenEver(setDuration(anyLong())).thenReturn(this)
+            whenEver(setListener(any())).thenAnswer {
+                (it.arguments[0] as Animator.AnimatorListener).onAnimationEnd(
+                    mock(Animator::class.java)
+                )
+                this
+            }
+        }
+    }
+
+    private fun testWithDisplay(
+        deviceConfig: DeviceConfig = DeviceConfig.X_ALIGNED,
+        initInfo: DisplayInfo.() -> Unit = {},
+        windowInsets: WindowInsets = insetsForSmallNavbar(),
+        block: () -> Unit
+    ) {
+        this.deviceConfig = deviceConfig
+
+        when (deviceConfig) {
+            DeviceConfig.X_ALIGNED -> {
+                displayWidth = 2560
+                displayHeight = 1600
+                sensorLocation = SensorLocationInternal("", 2325, 0, 0)
+                boundsWidth = 160
+                boundsHeight = 84
+            }
+            DeviceConfig.Y_ALIGNED_UNFOLDED -> {
+                displayWidth = 2208
+                displayHeight = 1840
+                sensorLocation = SensorLocationInternal("", 0, 510, 0)
+                boundsWidth = 110
+                boundsHeight = 210
+            }
+            DeviceConfig.Y_ALIGNED_FOLDED -> {
+                displayWidth = 1080
+                displayHeight = 2100
+                sensorLocation = SensorLocationInternal("", 0, 590, 0)
+                boundsWidth = 110
+                boundsHeight = 210
+            }
+        }
+        indicatorBounds = Rect(0, 0, boundsWidth, boundsHeight)
+        displayBounds = Rect(0, 0, displayWidth, displayHeight)
+        var locations = listOf(sensorLocation)
+
+        whenEver(fingerprintManager.sensorPropertiesInternal)
+            .thenReturn(
+                listOf(
+                    FingerprintSensorPropertiesInternal(
+                        SENSOR_ID,
+                        SensorProperties.STRENGTH_STRONG,
+                        5 /* maxEnrollmentsPerUser */,
+                        listOf() /* componentInfo */,
+                        FingerprintSensorProperties.TYPE_POWER_BUTTON,
+                        true /* halControlsIllumination */,
+                        true /* resetLockoutRequiresHardwareAuthToken */,
+                        locations
+                    )
+                )
+            )
+
+        val displayInfo = DisplayInfo()
+        displayInfo.initInfo()
+        val dmGlobal = mock(DisplayManagerGlobal::class.java)
+        val display = Display(dmGlobal, DISPLAY_ID, displayInfo, DEFAULT_DISPLAY_ADJUSTMENTS)
+        whenEver(dmGlobal.getDisplayInfo(eq(DISPLAY_ID))).thenReturn(displayInfo)
+        whenEver(windowManager.defaultDisplay).thenReturn(display)
+        whenEver(windowManager.maximumWindowMetrics)
+            .thenReturn(WindowMetrics(displayBounds, WindowInsets.CONSUMED))
+        whenEver(windowManager.currentWindowMetrics)
+            .thenReturn(WindowMetrics(displayBounds, windowInsets))
+
+        sideFpsController =
+            SideFpsController(
+                context.createDisplayContext(display),
+                layoutInflater,
+                fingerprintManager,
+                windowManager,
+                activityTaskManager,
+                overviewProxyService,
+                displayManager,
+                executor,
+                handler,
+                dumpManager
+            )
+
+        overlayController =
+            ArgumentCaptor.forClass(ISidefpsController::class.java)
+                .apply { verify(fingerprintManager).setSidefpsController(capture()) }
+                .value
+
+        block()
+    }
+
+    @Test
+    fun testSubscribesToOrientationChangesWhenShowingOverlay() = testWithDisplay {
+        overlayController.show(SENSOR_ID, REASON_UNKNOWN)
+        executor.runAllReady()
+
+        verify(displayManager).registerDisplayListener(any(), eq(handler), anyLong())
+
+        overlayController.hide(SENSOR_ID)
+        executor.runAllReady()
+        verify(displayManager).unregisterDisplayListener(any())
+    }
+
+    @Test
+    fun testShowsAndHides() = testWithDisplay {
+        overlayController.show(SENSOR_ID, REASON_UNKNOWN)
+        executor.runAllReady()
+
+        verify(windowManager).addView(overlayCaptor.capture(), any())
+
+        reset(windowManager)
+        overlayController.hide(SENSOR_ID)
+        executor.runAllReady()
+
+        verify(windowManager, never()).addView(any(), any())
+        verify(windowManager).removeView(eq(overlayCaptor.value))
+    }
+
+    @Test
+    fun testShowsOnce() = testWithDisplay {
+        repeat(5) {
+            overlayController.show(SENSOR_ID, REASON_UNKNOWN)
+            executor.runAllReady()
+        }
+
+        verify(windowManager).addView(any(), any())
+        verify(windowManager, never()).removeView(any())
+    }
+
+    @Test
+    fun testHidesOnce() = testWithDisplay {
+        overlayController.show(SENSOR_ID, REASON_UNKNOWN)
+        executor.runAllReady()
+
+        repeat(5) {
+            overlayController.hide(SENSOR_ID)
+            executor.runAllReady()
+        }
+
+        verify(windowManager).addView(any(), any())
+        verify(windowManager).removeView(any())
+    }
+
+    @Test fun testIgnoredForKeyguard() = testWithDisplay { testIgnoredFor(REASON_AUTH_KEYGUARD) }
+
+    @Test
+    fun testShowsForMostSettings() = testWithDisplay {
+        whenEver(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpEnrollTask()))
+        testIgnoredFor(REASON_AUTH_SETTINGS, ignored = false)
+    }
+
+    @Test
+    fun testIgnoredForVerySpecificSettings() = testWithDisplay {
+        whenEver(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpSettingsTask()))
+        testIgnoredFor(REASON_AUTH_SETTINGS)
+    }
+
+    private fun testIgnoredFor(reason: Int, ignored: Boolean = true) {
+        overlayController.show(SENSOR_ID, reason)
+        executor.runAllReady()
+
+        verify(windowManager, if (ignored) never() else times(1)).addView(any(), any())
+    }
+
+    @Test
+    fun showsWithTaskbar() =
+        testWithDisplay(deviceConfig = DeviceConfig.X_ALIGNED, { rotation = Surface.ROTATION_0 }) {
+            hidesWithTaskbar(visible = true)
+        }
+
+    @Test
+    fun showsWithTaskbarOnY() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED,
+            { rotation = Surface.ROTATION_0 }
+        ) { hidesWithTaskbar(visible = true) }
+
+    @Test
+    fun showsWithTaskbar90() =
+        testWithDisplay(deviceConfig = DeviceConfig.X_ALIGNED, { rotation = Surface.ROTATION_90 }) {
+            hidesWithTaskbar(visible = true)
+        }
+
+    @Test
+    fun showsWithTaskbar90OnY() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED,
+            { rotation = Surface.ROTATION_90 }
+        ) { hidesWithTaskbar(visible = true) }
+
+    @Test
+    fun showsWithTaskbar180() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.X_ALIGNED,
+            { rotation = Surface.ROTATION_180 }
+        ) { hidesWithTaskbar(visible = true) }
+
+    @Test
+    fun showsWithTaskbar270OnY() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED,
+            { rotation = Surface.ROTATION_270 }
+        ) { hidesWithTaskbar(visible = true) }
+
+    @Test
+    fun showsWithTaskbarCollapsedDown() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.X_ALIGNED,
+            { rotation = Surface.ROTATION_270 },
+            windowInsets = insetsForSmallNavbar()
+        ) { hidesWithTaskbar(visible = true) }
+
+    @Test
+    fun showsWithTaskbarCollapsedDownOnY() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED,
+            { rotation = Surface.ROTATION_180 },
+            windowInsets = insetsForSmallNavbar()
+        ) { hidesWithTaskbar(visible = true) }
+
+    @Test
+    fun hidesWithTaskbarDown() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.X_ALIGNED,
+            { rotation = Surface.ROTATION_180 },
+            windowInsets = insetsForLargeNavbar()
+        ) { hidesWithTaskbar(visible = false) }
+
+    @Test
+    fun hidesWithTaskbarDownOnY() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED,
+            { rotation = Surface.ROTATION_270 },
+            windowInsets = insetsForLargeNavbar()
+        ) { hidesWithTaskbar(visible = true) }
+
+    private fun hidesWithTaskbar(visible: Boolean) {
+        overlayController.show(SENSOR_ID, REASON_UNKNOWN)
+        executor.runAllReady()
+
+        sideFpsController.overviewProxyListener.onTaskbarStatusUpdated(visible, false)
+        executor.runAllReady()
+
+        verify(windowManager).addView(any(), any())
+        verify(windowManager, never()).removeView(any())
+        verify(sideFpsView).visibility = if (visible) View.VISIBLE else View.GONE
+    }
+
+    @Test
+    fun testIndicatorPlacementForXAlignedSensor() =
+        testWithDisplay(deviceConfig = DeviceConfig.X_ALIGNED) {
+            overlayController.show(SENSOR_ID, REASON_UNKNOWN)
+            sideFpsController.overlayOffsets = sensorLocation
+            sideFpsController.updateOverlayParams(windowManager.defaultDisplay, indicatorBounds)
+            executor.runAllReady()
+
+            verify(windowManager).updateViewLayout(any(), overlayViewParamsCaptor.capture())
+
+            assertThat(overlayViewParamsCaptor.value.x).isEqualTo(sensorLocation.sensorLocationX)
+            assertThat(overlayViewParamsCaptor.value.y).isEqualTo(0)
+        }
+
+    @Test
+    fun testIndicatorPlacementForYAlignedSensor() =
+        testWithDisplay(deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED) {
+            sideFpsController.overlayOffsets = sensorLocation
+            sideFpsController.updateOverlayParams(windowManager.defaultDisplay, indicatorBounds)
+            overlayController.show(SENSOR_ID, REASON_UNKNOWN)
+            executor.runAllReady()
+
+            verify(windowManager).updateViewLayout(any(), overlayViewParamsCaptor.capture())
+            assertThat(overlayViewParamsCaptor.value.x).isEqualTo(displayWidth - boundsWidth)
+            assertThat(overlayViewParamsCaptor.value.y).isEqualTo(sensorLocation.sensorLocationY)
+        }
+
+    @Test
+    fun hasSideFpsSensor_withSensorProps_returnsTrue() = testWithDisplay {
+        // By default all those tests assume the side fps sensor is available.
+
+        assertThat(fingerprintManager.hasSideFpsSensor()).isTrue()
+    }
+
+    @Test
+    fun hasSideFpsSensor_withoutSensorProps_returnsFalse() {
+        whenEver(fingerprintManager.sensorPropertiesInternal).thenReturn(null)
+
+        assertThat(fingerprintManager.hasSideFpsSensor()).isFalse()
+    }
+
+    @Test
+    fun testLayoutParams_hasNoMoveAnimationWindowFlag() =
+        testWithDisplay(deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED) {
+            sideFpsController.overlayOffsets = sensorLocation
+            sideFpsController.updateOverlayParams(windowManager.defaultDisplay, indicatorBounds)
+            overlayController.show(SENSOR_ID, REASON_UNKNOWN)
+            executor.runAllReady()
+
+            verify(windowManager).updateViewLayout(any(), overlayViewParamsCaptor.capture())
+
+            val lpFlags = overlayViewParamsCaptor.value.privateFlags
+
+            assertThat((lpFlags and PRIVATE_FLAG_NO_MOVE_ANIMATION) != 0).isTrue()
+        }
+
+    @Test
+    fun testLayoutParams_hasTrustedOverlayWindowFlag() =
+        testWithDisplay(deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED) {
+            sideFpsController.overlayOffsets = sensorLocation
+            sideFpsController.updateOverlayParams(windowManager.defaultDisplay, indicatorBounds)
+            overlayController.show(SENSOR_ID, REASON_UNKNOWN)
+            executor.runAllReady()
+
+            verify(windowManager).updateViewLayout(any(), overlayViewParamsCaptor.capture())
+
+            val lpFlags = overlayViewParamsCaptor.value.privateFlags
+
+            assertThat((lpFlags and PRIVATE_FLAG_TRUSTED_OVERLAY) != 0).isTrue()
+        }
+}
+
+private fun insetsForSmallNavbar() = insetsWithBottom(60)
+
+private fun insetsForLargeNavbar() = insetsWithBottom(100)
+
+private fun insetsWithBottom(bottom: Int) =
+    WindowInsets.Builder()
+        .setInsets(WindowInsets.Type.navigationBars(), Insets.of(0, 0, 0, bottom))
+        .build()
+
+private fun fpEnrollTask() = settingsTask(".biometrics.fingerprint.FingerprintEnrollEnrolling")
+
+private fun fpSettingsTask() = settingsTask(".biometrics.fingerprint.FingerprintSettings")
+
+private fun settingsTask(cls: String) =
+    ActivityManager.RunningTaskInfo().apply {
+        topActivity = ComponentName.createRelative("com.android.settings", cls)
+    }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
deleted file mode 100644
index 8d969d0..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics
-
-import android.animation.Animator
-import android.app.ActivityManager
-import android.app.ActivityTaskManager
-import android.content.ComponentName
-import android.graphics.Insets
-import android.graphics.Rect
-import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD
-import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_SETTINGS
-import android.hardware.biometrics.BiometricOverlayConstants.REASON_UNKNOWN
-import android.hardware.biometrics.SensorLocationInternal
-import android.hardware.biometrics.SensorProperties
-import android.hardware.display.DisplayManager
-import android.hardware.display.DisplayManagerGlobal
-import android.hardware.fingerprint.FingerprintManager
-import android.hardware.fingerprint.FingerprintSensorProperties
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
-import android.hardware.fingerprint.ISidefpsController
-import android.os.Handler
-import android.testing.AndroidTestingRunner
-import android.testing.TestableLooper
-import android.view.Display
-import android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS
-import android.view.DisplayInfo
-import android.view.LayoutInflater
-import android.view.Surface
-import android.view.View
-import android.view.ViewPropertyAnimator
-import android.view.WindowInsets
-import android.view.WindowManager
-import android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION
-import android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY
-import android.view.WindowMetrics
-import androidx.test.filters.SmallTest
-import com.airbnb.lottie.LottieAnimationView
-import com.android.systemui.R
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.recents.OverviewProxyService
-import com.android.systemui.util.concurrency.FakeExecutor
-import com.android.systemui.util.time.FakeSystemClock
-import com.google.common.truth.Truth.assertThat
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.ArgumentCaptor
-import org.mockito.ArgumentMatchers.eq
-import org.mockito.Captor
-import org.mockito.Mock
-import org.mockito.Mockito.any
-import org.mockito.Mockito.anyFloat
-import org.mockito.Mockito.anyInt
-import org.mockito.Mockito.anyLong
-import org.mockito.Mockito.mock
-import org.mockito.Mockito.never
-import org.mockito.Mockito.reset
-import org.mockito.Mockito.times
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenEver
-import org.mockito.junit.MockitoJUnit
-
-private const val DISPLAY_ID = 2
-private const val SENSOR_ID = 1
-
-@SmallTest
-@RunWith(AndroidTestingRunner::class)
-@TestableLooper.RunWithLooper
-class SidefpsControllerTest : SysuiTestCase() {
-
-    @JvmField @Rule
-    var rule = MockitoJUnit.rule()
-
-    @Mock
-    lateinit var layoutInflater: LayoutInflater
-    @Mock
-    lateinit var fingerprintManager: FingerprintManager
-    @Mock
-    lateinit var windowManager: WindowManager
-    @Mock
-    lateinit var activityTaskManager: ActivityTaskManager
-    @Mock
-    lateinit var sidefpsView: View
-    @Mock
-    lateinit var displayManager: DisplayManager
-    @Mock
-    lateinit var overviewProxyService: OverviewProxyService
-    @Mock
-    lateinit var handler: Handler
-    @Captor
-    lateinit var overlayCaptor: ArgumentCaptor<View>
-    @Captor
-    lateinit var overlayViewParamsCaptor: ArgumentCaptor<WindowManager.LayoutParams>
-
-    private val executor = FakeExecutor(FakeSystemClock())
-    private lateinit var overlayController: ISidefpsController
-    private lateinit var sideFpsController: SidefpsController
-
-    enum class DeviceConfig { X_ALIGNED, Y_ALIGNED_UNFOLDED, Y_ALIGNED_FOLDED }
-
-    private lateinit var deviceConfig: DeviceConfig
-    private lateinit var indicatorBounds: Rect
-    private lateinit var displayBounds: Rect
-    private lateinit var sensorLocation: SensorLocationInternal
-    private var displayWidth: Int = 0
-    private var displayHeight: Int = 0
-    private var boundsWidth: Int = 0
-    private var boundsHeight: Int = 0
-
-    @Before
-    fun setup() {
-        context.addMockSystemService(DisplayManager::class.java, displayManager)
-        context.addMockSystemService(WindowManager::class.java, windowManager)
-
-        whenEver(layoutInflater.inflate(R.layout.sidefps_view, null, false)).thenReturn(sidefpsView)
-        whenEver(sidefpsView.findViewById<LottieAnimationView>(eq(R.id.sidefps_animation)))
-            .thenReturn(mock(LottieAnimationView::class.java))
-        with(mock(ViewPropertyAnimator::class.java)) {
-            whenEver(sidefpsView.animate()).thenReturn(this)
-            whenEver(alpha(anyFloat())).thenReturn(this)
-            whenEver(setStartDelay(anyLong())).thenReturn(this)
-            whenEver(setDuration(anyLong())).thenReturn(this)
-            whenEver(setListener(any())).thenAnswer {
-                (it.arguments[0] as Animator.AnimatorListener)
-                    .onAnimationEnd(mock(Animator::class.java))
-                this
-            }
-        }
-    }
-
-    private fun testWithDisplay(
-        deviceConfig: DeviceConfig = DeviceConfig.X_ALIGNED,
-        initInfo: DisplayInfo.() -> Unit = {},
-        windowInsets: WindowInsets = insetsForSmallNavbar(),
-        block: () -> Unit
-    ) {
-        this.deviceConfig = deviceConfig
-
-        when (deviceConfig) {
-            DeviceConfig.X_ALIGNED -> {
-                displayWidth = 2560
-                displayHeight = 1600
-                sensorLocation = SensorLocationInternal("", 2325, 0, 0)
-                boundsWidth = 160
-                boundsHeight = 84
-            }
-            DeviceConfig.Y_ALIGNED_UNFOLDED -> {
-                displayWidth = 2208
-                displayHeight = 1840
-                sensorLocation = SensorLocationInternal("", 0, 510, 0)
-                boundsWidth = 110
-                boundsHeight = 210
-            }
-            DeviceConfig.Y_ALIGNED_FOLDED -> {
-                displayWidth = 1080
-                displayHeight = 2100
-                sensorLocation = SensorLocationInternal("", 0, 590, 0)
-                boundsWidth = 110
-                boundsHeight = 210
-            }
-        }
-        indicatorBounds = Rect(0, 0, boundsWidth, boundsHeight)
-        displayBounds = Rect(0, 0, displayWidth, displayHeight)
-        var locations = listOf(sensorLocation)
-
-        whenEver(fingerprintManager.sensorPropertiesInternal).thenReturn(
-            listOf(
-                FingerprintSensorPropertiesInternal(
-                    SENSOR_ID,
-                    SensorProperties.STRENGTH_STRONG,
-                    5 /* maxEnrollmentsPerUser */,
-                    listOf() /* componentInfo */,
-                    FingerprintSensorProperties.TYPE_POWER_BUTTON,
-                    true /* halControlsIllumination */,
-                    true /* resetLockoutRequiresHardwareAuthToken */,
-                    locations
-                )
-            )
-        )
-
-        val displayInfo = DisplayInfo()
-        displayInfo.initInfo()
-        val dmGlobal = mock(DisplayManagerGlobal::class.java)
-        val display = Display(dmGlobal, DISPLAY_ID, displayInfo, DEFAULT_DISPLAY_ADJUSTMENTS)
-        whenEver(dmGlobal.getDisplayInfo(eq(DISPLAY_ID))).thenReturn(displayInfo)
-        whenEver(windowManager.defaultDisplay).thenReturn(display)
-        whenEver(windowManager.maximumWindowMetrics).thenReturn(
-                WindowMetrics(displayBounds, WindowInsets.CONSUMED)
-        )
-        whenEver(windowManager.currentWindowMetrics).thenReturn(
-            WindowMetrics(displayBounds, windowInsets)
-        )
-
-        sideFpsController = SidefpsController(
-            context.createDisplayContext(display), layoutInflater, fingerprintManager,
-            windowManager, activityTaskManager, overviewProxyService, displayManager, executor,
-            handler
-        )
-
-        overlayController = ArgumentCaptor.forClass(ISidefpsController::class.java).apply {
-            verify(fingerprintManager).setSidefpsController(capture())
-        }.value
-
-        block()
-    }
-
-    @Test
-    fun testSubscribesToOrientationChangesWhenShowingOverlay() = testWithDisplay {
-        overlayController.show(SENSOR_ID, REASON_UNKNOWN)
-        executor.runAllReady()
-
-        verify(displayManager).registerDisplayListener(any(), eq(handler), anyLong())
-
-        overlayController.hide(SENSOR_ID)
-        executor.runAllReady()
-        verify(displayManager).unregisterDisplayListener(any())
-    }
-
-    @Test
-    fun testShowsAndHides() = testWithDisplay {
-        overlayController.show(SENSOR_ID, REASON_UNKNOWN)
-        executor.runAllReady()
-
-        verify(windowManager).addView(overlayCaptor.capture(), any())
-
-        reset(windowManager)
-        overlayController.hide(SENSOR_ID)
-        executor.runAllReady()
-
-        verify(windowManager, never()).addView(any(), any())
-        verify(windowManager).removeView(eq(overlayCaptor.value))
-    }
-
-    @Test
-    fun testShowsOnce() = testWithDisplay {
-        repeat(5) {
-            overlayController.show(SENSOR_ID, REASON_UNKNOWN)
-            executor.runAllReady()
-        }
-
-        verify(windowManager).addView(any(), any())
-        verify(windowManager, never()).removeView(any())
-    }
-
-    @Test
-    fun testHidesOnce() = testWithDisplay {
-        overlayController.show(SENSOR_ID, REASON_UNKNOWN)
-        executor.runAllReady()
-
-        repeat(5) {
-            overlayController.hide(SENSOR_ID)
-            executor.runAllReady()
-        }
-
-        verify(windowManager).addView(any(), any())
-        verify(windowManager).removeView(any())
-    }
-
-    @Test
-    fun testIgnoredForKeyguard() = testWithDisplay {
-        testIgnoredFor(REASON_AUTH_KEYGUARD)
-    }
-
-    @Test
-    fun testShowsForMostSettings() = testWithDisplay {
-        whenEver(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpEnrollTask()))
-        testIgnoredFor(REASON_AUTH_SETTINGS, ignored = false)
-    }
-
-    @Test
-    fun testIgnoredForVerySpecificSettings() = testWithDisplay {
-        whenEver(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpSettingsTask()))
-        testIgnoredFor(REASON_AUTH_SETTINGS)
-    }
-
-    private fun testIgnoredFor(reason: Int, ignored: Boolean = true) {
-        overlayController.show(SENSOR_ID, reason)
-        executor.runAllReady()
-
-        verify(windowManager, if (ignored) never() else times(1)).addView(any(), any())
-    }
-
-    @Test
-    fun showsWithTaskbar() = testWithDisplay(
-        deviceConfig = DeviceConfig.X_ALIGNED,
-        { rotation = Surface.ROTATION_0 }
-    ) {
-        hidesWithTaskbar(visible = true)
-    }
-
-    @Test
-    fun showsWithTaskbarOnY() = testWithDisplay(
-        deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED,
-        { rotation = Surface.ROTATION_0 }
-    ) {
-        hidesWithTaskbar(visible = true)
-    }
-
-    @Test
-    fun showsWithTaskbar90() = testWithDisplay(
-        deviceConfig = DeviceConfig.X_ALIGNED,
-        { rotation = Surface.ROTATION_90 }
-    ) {
-        hidesWithTaskbar(visible = true)
-    }
-
-    @Test
-    fun showsWithTaskbar90OnY() = testWithDisplay(
-        deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED,
-        { rotation = Surface.ROTATION_90 }
-    ) {
-        hidesWithTaskbar(visible = true)
-    }
-
-    @Test
-    fun showsWithTaskbar180() = testWithDisplay(
-        deviceConfig = DeviceConfig.X_ALIGNED,
-        { rotation = Surface.ROTATION_180 }
-    ) {
-        hidesWithTaskbar(visible = true)
-    }
-
-    @Test
-    fun showsWithTaskbar270OnY() = testWithDisplay(
-        deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED,
-        { rotation = Surface.ROTATION_270 }
-    ) {
-        hidesWithTaskbar(visible = true)
-    }
-
-    @Test
-    fun showsWithTaskbarCollapsedDown() = testWithDisplay(
-        deviceConfig = DeviceConfig.X_ALIGNED,
-        { rotation = Surface.ROTATION_270 },
-        windowInsets = insetsForSmallNavbar()
-    ) {
-        hidesWithTaskbar(visible = true)
-    }
-
-    @Test
-    fun showsWithTaskbarCollapsedDownOnY() = testWithDisplay(
-        deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED,
-        { rotation = Surface.ROTATION_180 },
-        windowInsets = insetsForSmallNavbar()
-    ) {
-        hidesWithTaskbar(visible = true)
-    }
-
-    @Test
-    fun hidesWithTaskbarDown() = testWithDisplay(
-        deviceConfig = DeviceConfig.X_ALIGNED,
-        { rotation = Surface.ROTATION_180 },
-        windowInsets = insetsForLargeNavbar()
-    ) {
-        hidesWithTaskbar(visible = false)
-    }
-
-    @Test
-    fun hidesWithTaskbarDownOnY() = testWithDisplay(
-        deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED,
-        { rotation = Surface.ROTATION_270 },
-        windowInsets = insetsForLargeNavbar()
-    ) {
-        hidesWithTaskbar(visible = true)
-    }
-
-    private fun hidesWithTaskbar(visible: Boolean) {
-        overlayController.show(SENSOR_ID, REASON_UNKNOWN)
-        executor.runAllReady()
-
-        sideFpsController.overviewProxyListener.onTaskbarStatusUpdated(visible, false)
-        executor.runAllReady()
-
-        verify(windowManager).addView(any(), any())
-        verify(windowManager, never()).removeView(any())
-        verify(sidefpsView).visibility = if (visible) View.VISIBLE else View.GONE
-    }
-
-    @Test
-    fun testIndicatorPlacementForXAlignedSensor() = testWithDisplay(
-        deviceConfig = DeviceConfig.X_ALIGNED
-    ) {
-        overlayController.show(SENSOR_ID, REASON_UNKNOWN)
-        sideFpsController.overlayOffsets = sensorLocation
-        sideFpsController.updateOverlayParams(
-            windowManager.defaultDisplay,
-            indicatorBounds
-        )
-        executor.runAllReady()
-
-        verify(windowManager).updateViewLayout(any(), overlayViewParamsCaptor.capture())
-
-        assertThat(overlayViewParamsCaptor.value.x).isEqualTo(sensorLocation.sensorLocationX)
-        assertThat(overlayViewParamsCaptor.value.y).isEqualTo(0)
-    }
-
-    @Test
-    fun testIndicatorPlacementForYAlignedSensor() = testWithDisplay(
-        deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED
-    ) {
-        sideFpsController.overlayOffsets = sensorLocation
-        sideFpsController.updateOverlayParams(
-            windowManager.defaultDisplay,
-            indicatorBounds
-        )
-        overlayController.show(SENSOR_ID, REASON_UNKNOWN)
-        executor.runAllReady()
-
-        verify(windowManager).updateViewLayout(any(), overlayViewParamsCaptor.capture())
-        assertThat(overlayViewParamsCaptor.value.x).isEqualTo(displayWidth - boundsWidth)
-        assertThat(overlayViewParamsCaptor.value.y).isEqualTo(sensorLocation.sensorLocationY)
-    }
-
-    @Test
-    fun hasSideFpsSensor_withSensorProps_returnsTrue() = testWithDisplay {
-        // By default all those tests assume the side fps sensor is available.
-
-        assertThat(fingerprintManager.hasSideFpsSensor()).isTrue()
-    }
-
-    @Test
-    fun hasSideFpsSensor_withoutSensorProps_returnsFalse() {
-        whenEver(fingerprintManager.sensorPropertiesInternal).thenReturn(null)
-
-        assertThat(fingerprintManager.hasSideFpsSensor()).isFalse()
-    }
-
-    @Test
-    fun testLayoutParams_hasNoMoveAnimationWindowFlag() = testWithDisplay(
-        deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED
-    ) {
-        sideFpsController.overlayOffsets = sensorLocation
-        sideFpsController.updateOverlayParams(
-            windowManager.defaultDisplay,
-            indicatorBounds
-        )
-        overlayController.show(SENSOR_ID, REASON_UNKNOWN)
-        executor.runAllReady()
-
-        verify(windowManager).updateViewLayout(any(), overlayViewParamsCaptor.capture())
-
-        val lpFlags = overlayViewParamsCaptor.value.privateFlags
-
-        assertThat((lpFlags and PRIVATE_FLAG_NO_MOVE_ANIMATION) != 0).isTrue()
-    }
-
-    @Test
-    fun testLayoutParams_hasTrustedOverlayWindowFlag() = testWithDisplay(
-        deviceConfig = DeviceConfig.Y_ALIGNED_UNFOLDED
-    ) {
-        sideFpsController.overlayOffsets = sensorLocation
-        sideFpsController.updateOverlayParams(
-            windowManager.defaultDisplay,
-            indicatorBounds
-        )
-        overlayController.show(SENSOR_ID, REASON_UNKNOWN)
-        executor.runAllReady()
-
-        verify(windowManager).updateViewLayout(any(), overlayViewParamsCaptor.capture())
-
-        val lpFlags = overlayViewParamsCaptor.value.privateFlags
-
-        assertThat((lpFlags and PRIVATE_FLAG_TRUSTED_OVERLAY) != 0).isTrue()
-    }
-}
-
-private fun insetsForSmallNavbar() = insetsWithBottom(60)
-private fun insetsForLargeNavbar() = insetsWithBottom(100)
-private fun insetsWithBottom(bottom: Int) = WindowInsets.Builder()
-    .setInsets(WindowInsets.Type.navigationBars(), Insets.of(0, 0, 0, bottom))
-    .build()
-
-private fun fpEnrollTask() = settingsTask(".biometrics.fingerprint.FingerprintEnrollEnrolling")
-private fun fpSettingsTask() = settingsTask(".biometrics.fingerprint.FingerprintSettings")
-private fun settingsTask(cls: String) = ActivityManager.RunningTaskInfo().apply {
-    topActivity = ComponentName.createRelative("com.android.settings", cls)
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
index 7bc39c7..53d9b87 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
@@ -17,7 +17,6 @@
 package com.android.systemui.keyguard.data.repository
 
 import androidx.test.filters.SmallTest
-import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Position
 import com.android.systemui.doze.DozeHost
@@ -49,7 +48,6 @@
     @Mock private lateinit var dozeHost: DozeHost
     @Mock private lateinit var keyguardStateController: KeyguardStateController
     @Mock private lateinit var wakefulnessLifecycle: WakefulnessLifecycle
-    @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
     @Mock private lateinit var biometricUnlockController: BiometricUnlockController
 
     private lateinit var underTest: KeyguardRepositoryImpl
@@ -60,12 +58,11 @@
 
         underTest =
             KeyguardRepositoryImpl(
-                    statusBarStateController,
-                    dozeHost,
-                    wakefulnessLifecycle,
-                    biometricUnlockController,
-                    keyguardStateController,
-                    keyguardUpdateMonitor,
+                statusBarStateController,
+                keyguardStateController,
+                dozeHost,
+                wakefulnessLifecycle,
+                biometricUnlockController,
             )
     }
 
@@ -226,15 +223,6 @@
     }
 
     @Test
-    fun isUdfpsSupported() = runBlockingTest {
-        whenever(keyguardUpdateMonitor.isUdfpsSupported).thenReturn(true)
-        assertThat(underTest.isUdfpsSupported()).isTrue()
-
-        whenever(keyguardUpdateMonitor.isUdfpsSupported).thenReturn(false)
-        assertThat(underTest.isUdfpsSupported()).isFalse()
-    }
-    
-    @Test    
     fun isBouncerShowing() = runBlockingTest {
         whenever(keyguardStateController.isBouncerShowing).thenReturn(false)
         var latest: Boolean? = null
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
index 8c3ae3d..68a5f47 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
@@ -43,6 +43,7 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.time.FakeSystemClock
 import com.android.systemui.util.view.ViewUtil
+import com.android.systemui.util.wakelock.WakeLockFake
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
@@ -85,6 +86,10 @@
     private lateinit var fakeAppIconDrawable: Drawable
     private lateinit var uiEventLoggerFake: UiEventLoggerFake
     private lateinit var receiverUiEventLogger: MediaTttReceiverUiEventLogger
+    private lateinit var fakeClock: FakeSystemClock
+    private lateinit var fakeExecutor: FakeExecutor
+    private lateinit var fakeWakeLockBuilder: WakeLockFake.Builder
+    private lateinit var fakeWakeLock: WakeLockFake
 
     @Before
     fun setUp() {
@@ -99,15 +104,22 @@
         )).thenReturn(applicationInfo)
         context.setMockPackageManager(packageManager)
 
+        fakeClock = FakeSystemClock()
+        fakeExecutor = FakeExecutor(fakeClock)
+
         uiEventLoggerFake = UiEventLoggerFake()
         receiverUiEventLogger = MediaTttReceiverUiEventLogger(uiEventLoggerFake)
 
+        fakeWakeLock = WakeLockFake()
+        fakeWakeLockBuilder = WakeLockFake.Builder(context)
+        fakeWakeLockBuilder.setWakeLock(fakeWakeLock)
+
         controllerReceiver = MediaTttChipControllerReceiver(
             commandQueue,
             context,
             logger,
             windowManager,
-            FakeExecutor(FakeSystemClock()),
+            fakeExecutor,
             accessibilityManager,
             configurationController,
             powerManager,
@@ -115,6 +127,7 @@
             mediaTttFlags,
             receiverUiEventLogger,
             viewUtil,
+            fakeWakeLockBuilder,
         )
         controllerReceiver.start()
 
@@ -141,6 +154,7 @@
             mediaTttFlags,
             receiverUiEventLogger,
             viewUtil,
+            fakeWakeLockBuilder,
         )
         controllerReceiver.start()
 
@@ -200,6 +214,39 @@
     }
 
     @Test
+    fun commandQueueCallback_closeThenFar_wakeLockAcquiredThenReleased() {
+        commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
+                StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
+                routeInfo,
+                null,
+                null
+        )
+
+        assertThat(fakeWakeLock.isHeld).isTrue()
+
+        commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
+                StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER,
+                routeInfo,
+                null,
+                null
+        )
+
+        assertThat(fakeWakeLock.isHeld).isFalse()
+    }
+
+    @Test
+    fun commandQueueCallback_closeThenFar_wakeLockNeverAcquired() {
+        commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
+                StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER,
+                routeInfo,
+                null,
+                null
+        )
+
+        assertThat(fakeWakeLock.isHeld).isFalse()
+    }
+
+    @Test
     fun receivesNewStateFromCommandQueue_isLogged() {
         commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
             StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
index ad19bc2..4437394 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
@@ -52,6 +52,7 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.time.FakeSystemClock
 import com.android.systemui.util.view.ViewUtil
+import com.android.systemui.util.wakelock.WakeLockFake
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
@@ -89,6 +90,8 @@
     @Mock private lateinit var viewUtil: ViewUtil
     @Mock private lateinit var windowManager: WindowManager
     @Mock private lateinit var vibratorHelper: VibratorHelper
+    private lateinit var fakeWakeLockBuilder: WakeLockFake.Builder
+    private lateinit var fakeWakeLock: WakeLockFake
     private lateinit var chipbarCoordinator: ChipbarCoordinator
     private lateinit var commandQueueCallback: CommandQueue.Callbacks
     private lateinit var fakeAppIconDrawable: Drawable
@@ -118,6 +121,10 @@
         fakeClock = FakeSystemClock()
         fakeExecutor = FakeExecutor(fakeClock)
 
+        fakeWakeLock = WakeLockFake()
+        fakeWakeLockBuilder = WakeLockFake.Builder(context)
+        fakeWakeLockBuilder.setWakeLock(fakeWakeLock)
+
         uiEventLoggerFake = UiEventLoggerFake()
         uiEventLogger = MediaTttSenderUiEventLogger(uiEventLoggerFake)
 
@@ -134,6 +141,7 @@
                 falsingCollector,
                 viewUtil,
                 vibratorHelper,
+                fakeWakeLockBuilder,
             )
         chipbarCoordinator.start()
 
@@ -472,6 +480,36 @@
     }
 
     @Test
+    fun commandQueueCallback_almostCloseThenFarFromReceiver_wakeLockAcquiredThenReleased() {
+        commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST,
+            routeInfo,
+            null
+        )
+
+        assertThat(fakeWakeLock.isHeld).isTrue()
+
+        commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
+            routeInfo,
+            null
+        )
+
+        assertThat(fakeWakeLock.isHeld).isFalse()
+    }
+
+    @Test
+    fun commandQueueCallback_FarFromReceiver_wakeLockNeverReleased() {
+        commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
+            routeInfo,
+            null
+        )
+
+        assertThat(fakeWakeLock.isHeld).isFalse()
+    }
+
+    @Test
     fun commandQueueCallback_invalidStateParam_noChipShown() {
         commandQueueCallback.updateMediaTapToTransferSenderDisplay(100, routeInfo, null)
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
index bd4b94e..52462c7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
@@ -311,6 +311,37 @@
     }
 
     @Test
+    fun testCallbackCalledOnUserInfoChanged() {
+        tracker.initialize(0)
+        val callback = TestCallback()
+        tracker.addCallback(callback, executor)
+        val profileID = tracker.userId + 10
+
+        `when`(userManager.getProfiles(anyInt())).thenAnswer { invocation ->
+            val id = invocation.getArgument<Int>(0)
+            val info = UserInfo(id, "", UserInfo.FLAG_FULL)
+            val infoProfile = UserInfo(
+                id + 10,
+                "",
+                "",
+                UserInfo.FLAG_MANAGED_PROFILE,
+                UserManager.USER_TYPE_PROFILE_MANAGED
+            )
+            infoProfile.profileGroupId = id
+            listOf(info, infoProfile)
+        }
+
+        val intent = Intent(Intent.ACTION_USER_INFO_CHANGED)
+            .putExtra(Intent.EXTRA_USER, UserHandle.of(profileID))
+
+        tracker.onReceive(context, intent)
+
+        assertThat(callback.calledOnUserChanged).isEqualTo(0)
+        assertThat(callback.calledOnProfilesChanged).isEqualTo(1)
+        assertThat(callback.lastUserProfiles.map { it.id }).containsExactly(0, profileID)
+    }
+
+    @Test
     fun testCallbackRemoved() {
         tracker.initialize(0)
         val newID = 5
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
index 52ab6a6..14a3bc1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
@@ -35,8 +35,6 @@
 import com.android.systemui.animation.ShadeInterpolation
 import com.android.systemui.battery.BatteryMeterView
 import com.android.systemui.battery.BatteryMeterViewController
-import com.android.systemui.demomode.DemoMode
-import com.android.systemui.demomode.DemoModeController
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
@@ -52,12 +50,10 @@
 import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
 import com.android.systemui.statusbar.phone.StatusBarIconController
 import com.android.systemui.statusbar.phone.StatusIconContainer
-import com.android.systemui.statusbar.policy.Clock
 import com.android.systemui.statusbar.policy.FakeConfigurationController
 import com.android.systemui.statusbar.policy.VariableDateView
 import com.android.systemui.statusbar.policy.VariableDateViewController
 import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.mock
@@ -108,7 +104,7 @@
     @Mock
     private lateinit var featureFlags: FeatureFlags
     @Mock
-    private lateinit var clock: Clock
+    private lateinit var clock: TextView
     @Mock
     private lateinit var date: VariableDateView
     @Mock
@@ -142,7 +138,6 @@
     private lateinit var qsConstraints: ConstraintSet
     @Mock
     private lateinit var largeScreenConstraints: ConstraintSet
-    @Mock private lateinit var demoModeController: DemoModeController
 
     @JvmField @Rule
     val mockitoRule = MockitoJUnit.rule()
@@ -154,7 +149,7 @@
 
     @Before
     fun setUp() {
-        whenever<Clock>(view.findViewById(R.id.clock)).thenReturn(clock)
+        whenever<TextView>(view.findViewById(R.id.clock)).thenReturn(clock)
         whenever(clock.context).thenReturn(mockedContext)
 
         whenever<TextView>(view.findViewById(R.id.date)).thenReturn(date)
@@ -201,8 +196,7 @@
             dumpManager,
             featureFlags,
             qsCarrierGroupControllerBuilder,
-            combinedShadeHeadersConstraintManager,
-            demoModeController
+            combinedShadeHeadersConstraintManager
         )
         whenever(view.isAttachedToWindow).thenReturn(true)
         controller.init()
@@ -624,23 +618,6 @@
     }
 
     @Test
-    fun demoMode_attachDemoMode() {
-        val cb = argumentCaptor<DemoMode>()
-        verify(demoModeController).addCallback(cb.capture())
-        cb.value.onDemoModeStarted()
-        verify(clock).onDemoModeStarted()
-    }
-
-    @Test
-    fun demoMode_detachDemoMode() {
-        controller.simulateViewDetached()
-        val cb = argumentCaptor<DemoMode>()
-        verify(demoModeController).removeCallback(cb.capture())
-        cb.value.onDemoModeFinished()
-        verify(clock).onDemoModeFinished()
-    }
-
-    @Test
     fun animateOutOnStartCustomizing() {
         val animator = Mockito.mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
         val duration = 1000L
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
index 0b85043..90ae693 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
@@ -13,8 +13,6 @@
 import com.android.systemui.animation.ShadeInterpolation
 import com.android.systemui.battery.BatteryMeterView
 import com.android.systemui.battery.BatteryMeterViewController
-import com.android.systemui.demomode.DemoMode
-import com.android.systemui.demomode.DemoModeController
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
@@ -24,11 +22,9 @@
 import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
 import com.android.systemui.statusbar.phone.StatusBarIconController
 import com.android.systemui.statusbar.phone.StatusIconContainer
-import com.android.systemui.statusbar.policy.Clock
 import com.android.systemui.statusbar.policy.FakeConfigurationController
 import com.android.systemui.statusbar.policy.VariableDateViewController
 import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.argumentCaptor
 import com.google.common.truth.Truth.assertThat
 import org.junit.After
 import org.junit.Before
@@ -56,7 +52,7 @@
     @Mock private lateinit var qsCarrierGroupController: QSCarrierGroupController
     @Mock private lateinit var qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder
     @Mock private lateinit var featureFlags: FeatureFlags
-    @Mock private lateinit var clock: Clock
+    @Mock private lateinit var clock: TextView
     @Mock private lateinit var date: TextView
     @Mock private lateinit var carrierGroup: QSCarrierGroup
     @Mock private lateinit var batteryMeterView: BatteryMeterView
@@ -70,7 +66,6 @@
         CombinedShadeHeadersConstraintManager
 
     @Mock private lateinit var mockedContext: Context
-    @Mock private lateinit var demoModeController: DemoModeController
 
     @JvmField @Rule val mockitoRule = MockitoJUnit.rule()
     var viewVisibility = View.GONE
@@ -81,7 +76,7 @@
 
     @Before
     fun setup() {
-        whenever<Clock>(view.findViewById(R.id.clock)).thenReturn(clock)
+        whenever<TextView>(view.findViewById(R.id.clock)).thenReturn(clock)
         whenever(clock.context).thenReturn(mockedContext)
         whenever<TextView>(view.findViewById(R.id.date)).thenReturn(date)
         whenever(date.context).thenReturn(mockedContext)
@@ -116,9 +111,8 @@
                 dumpManager,
                 featureFlags,
                 qsCarrierGroupControllerBuilder,
-                combinedShadeHeadersConstraintManager,
-                demoModeController
-                )
+                combinedShadeHeadersConstraintManager
+        )
         whenever(view.isAttachedToWindow).thenReturn(true)
         mLargeScreenShadeHeaderController.init()
         carrierIconSlots = listOf(
@@ -236,21 +230,4 @@
         verify(animator).setInterpolator(Interpolators.ALPHA_IN)
         verify(animator).start()
     }
-
-    @Test
-    fun demoMode_attachDemoMode() {
-        val cb = argumentCaptor<DemoMode>()
-        verify(demoModeController).addCallback(cb.capture())
-        cb.value.onDemoModeStarted()
-        verify(clock).onDemoModeStarted()
-    }
-
-    @Test
-    fun demoMode_detachDemoMode() {
-        mLargeScreenShadeHeaderController.simulateViewDetached()
-        val cb = argumentCaptor<DemoMode>()
-        verify(demoModeController).removeCallback(cb.capture())
-        cb.value.onDemoModeFinished()
-        verify(clock).onDemoModeFinished()
-    }
 }
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 9a13e93..9b17cc2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -20,6 +20,7 @@
 import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED;
 import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
 import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT;
 import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_TIMEOUT;
 
 import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
@@ -54,6 +55,7 @@
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.Instrumentation;
@@ -88,6 +90,7 @@
 import com.android.settingslib.fuelgauge.BatteryStatus;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.biometrics.FaceHelpMessageDeferral;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dock.DockManager;
@@ -173,6 +176,8 @@
     private FaceHelpMessageDeferral mFaceHelpMessageDeferral;
     @Mock
     private ScreenLifecycle mScreenLifecycle;
+    @Mock
+    private AuthController mAuthController;
     @Captor
     private ArgumentCaptor<DockManager.AlignmentStateListener> mAlignmentListener;
     @Captor
@@ -263,8 +268,9 @@
                 mWakeLockBuilder,
                 mKeyguardStateController, mStatusBarStateController, mKeyguardUpdateMonitor,
                 mDockManager, mBroadcastDispatcher, mDevicePolicyManager, mIBatteryStats,
-                mUserManager, mExecutor, mExecutor,  mFalsingManager, mLockPatternUtils,
-                mScreenLifecycle, mKeyguardBypassController, mAccessibilityManager,
+                mUserManager, mExecutor, mExecutor, mFalsingManager,
+                mAuthController, mLockPatternUtils, mScreenLifecycle,
+                mKeyguardBypassController, mAccessibilityManager,
                 mFaceHelpMessageDeferral);
         mController.init();
         mController.setIndicationArea(mIndicationArea);
@@ -1371,6 +1377,110 @@
     }
 
 
+    @Test
+    public void onBiometricError_faceLockedOutFirstTime_showsThePassedInMessage() {
+        createController();
+        onFaceLockoutError("first lockout");
+
+        verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE, "first lockout");
+    }
+
+    @Test
+    public void onBiometricError_faceLockedOutFirstTimeAndFpAllowed_showsTheFpFollowupMessage() {
+        createController();
+        fingerprintUnlockIsPossible();
+        onFaceLockoutError("first lockout");
+
+        verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP,
+                mContext.getString(R.string.keyguard_suggest_fingerprint));
+    }
+
+    @Test
+    public void onBiometricError_faceLockedOutFirstTimeAndFpNotAllowed_showsDefaultFollowup() {
+        createController();
+        fingerprintUnlockIsNotPossible();
+        onFaceLockoutError("first lockout");
+
+        verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP,
+                mContext.getString(R.string.keyguard_unlock));
+    }
+
+    @Test
+    public void onBiometricError_faceLockedOutSecondTimeInSession_showsUnavailableMessage() {
+        createController();
+        onFaceLockoutError("first lockout");
+        clearInvocations(mRotateTextViewController);
+
+        onFaceLockoutError("second lockout");
+
+        verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE,
+                mContext.getString(R.string.keyguard_face_unlock_unavailable));
+    }
+
+    @Test
+    public void onBiometricError_faceLockedOutSecondTimeButUdfpsActive_showsNoMessage() {
+        createController();
+        onFaceLockoutError("first lockout");
+        clearInvocations(mRotateTextViewController);
+
+        when(mAuthController.isUdfpsFingerDown()).thenReturn(true);
+        onFaceLockoutError("second lockout");
+
+        verifyNoMoreInteractions(mRotateTextViewController);
+    }
+
+    @Test
+    public void onBiometricError_faceLockedOutAgainAndFpAllowed_showsTheFpFollowupMessage() {
+        createController();
+        fingerprintUnlockIsPossible();
+        onFaceLockoutError("first lockout");
+        clearInvocations(mRotateTextViewController);
+
+        onFaceLockoutError("second lockout");
+
+        verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP,
+                mContext.getString(R.string.keyguard_suggest_fingerprint));
+    }
+
+    @Test
+    public void onBiometricError_faceLockedOutAgainAndFpNotAllowed_showsDefaultFollowup() {
+        createController();
+        fingerprintUnlockIsNotPossible();
+        onFaceLockoutError("first lockout");
+        clearInvocations(mRotateTextViewController);
+
+        onFaceLockoutError("second lockout");
+
+        verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP,
+                mContext.getString(R.string.keyguard_unlock));
+    }
+
+    @Test
+    public void onBiometricError_whenFaceLockoutReset_onLockOutError_showsPassedInMessage() {
+        createController();
+        onFaceLockoutError("first lockout");
+        clearInvocations(mRotateTextViewController);
+        when(mKeyguardUpdateMonitor.isFaceLockedOut()).thenReturn(false);
+        mKeyguardUpdateMonitorCallback.onLockedOutStateChanged(BiometricSourceType.FACE);
+
+        onFaceLockoutError("second lockout");
+
+        verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE, "second lockout");
+    }
+
+    @Test
+    public void onBiometricError_whenFaceIsLocked_onMultipleLockOutErrors_showUnavailableMessage() {
+        createController();
+        onFaceLockoutError("first lockout");
+        clearInvocations(mRotateTextViewController);
+        when(mKeyguardUpdateMonitor.isFaceLockedOut()).thenReturn(true);
+        mKeyguardUpdateMonitorCallback.onLockedOutStateChanged(BiometricSourceType.FACE);
+
+        onFaceLockoutError("second lockout");
+
+        verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE,
+                mContext.getString(R.string.keyguard_face_unlock_unavailable));
+    }
 
     private void sendUpdateDisclosureBroadcast() {
         mBroadcastReceiver.onReceive(mContext, new Intent());
@@ -1419,4 +1529,33 @@
                     anyObject(), anyBoolean());
         }
     }
+
+    private void verifyIndicationShown(int indicationType, String message) {
+        verify(mRotateTextViewController)
+                .updateIndication(eq(indicationType),
+                        mKeyguardIndicationCaptor.capture(),
+                        eq(true));
+        assertThat(mKeyguardIndicationCaptor.getValue().getMessage().toString())
+                .isEqualTo(message);
+    }
+
+    private void fingerprintUnlockIsNotPossible() {
+        setupFingerprintUnlockPossible(false);
+    }
+
+    private void fingerprintUnlockIsPossible() {
+        setupFingerprintUnlockPossible(true);
+    }
+
+    private void setupFingerprintUnlockPossible(boolean possible) {
+        when(mKeyguardUpdateMonitor
+                .getCachedIsUnlockWithFingerprintPossible(KeyguardUpdateMonitor.getCurrentUser()))
+                .thenReturn(possible);
+    }
+
+    private void onFaceLockoutError(String errMsg) {
+        mKeyguardUpdateMonitorCallback.onBiometricError(FACE_ERROR_LOCKOUT_PERMANENT,
+                errMsg,
+                BiometricSourceType.FACE);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt
index 086e5df..b80b825 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt
@@ -92,7 +92,7 @@
 
         iconContainer.calculateIconXTranslations()
         assertEquals(10f, iconState.xTranslation)
-        assertFalse(iconContainer.hasOverflow())
+        assertFalse(iconContainer.areIconsOverflowing())
     }
 
     @Test
@@ -121,7 +121,7 @@
         assertEquals(30f, iconContainer.getIconState(iconThree).xTranslation)
         assertEquals(40f, iconContainer.getIconState(iconFour).xTranslation)
 
-        assertFalse(iconContainer.hasOverflow())
+        assertFalse(iconContainer.areIconsOverflowing())
     }
 
     @Test
@@ -150,7 +150,7 @@
         assertEquals(10f, iconContainer.getIconState(iconOne).xTranslation)
         assertEquals(20f, iconContainer.getIconState(iconTwo).xTranslation)
         assertEquals(30f, iconContainer.getIconState(iconThree).xTranslation)
-        assertTrue(iconContainer.hasOverflow())
+        assertTrue(iconContainer.areIconsOverflowing())
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
index 91b5c35..9dea48e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
@@ -35,6 +35,8 @@
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.time.FakeSystemClock
+import com.android.systemui.util.wakelock.WakeLock
+import com.android.systemui.util.wakelock.WakeLockFake
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
@@ -53,6 +55,9 @@
     private lateinit var fakeClock: FakeSystemClock
     private lateinit var fakeExecutor: FakeExecutor
 
+    private lateinit var fakeWakeLockBuilder: WakeLockFake.Builder
+    private lateinit var fakeWakeLock: WakeLockFake
+
     @Mock
     private lateinit var logger: TemporaryViewLogger
     @Mock
@@ -74,6 +79,10 @@
         fakeClock = FakeSystemClock()
         fakeExecutor = FakeExecutor(fakeClock)
 
+        fakeWakeLock = WakeLockFake()
+        fakeWakeLockBuilder = WakeLockFake.Builder(context)
+        fakeWakeLockBuilder.setWakeLock(fakeWakeLock)
+
         underTest = TestController(
                 context,
                 logger,
@@ -82,7 +91,9 @@
                 accessibilityManager,
                 configurationController,
                 powerManager,
+                fakeWakeLockBuilder,
         )
+        underTest.start()
     }
 
     @Test
@@ -112,25 +123,33 @@
     }
 
     @Test
-    fun displayView_screenOff_screenWakes() {
-        whenever(powerManager.isScreenOn).thenReturn(false)
-
+    fun displayView_screenOff_wakeLockAcquired() {
         underTest.displayView(getState())
 
-        verify(powerManager).wakeUp(any(), any(), any())
+        assertThat(fakeWakeLock.isHeld).isTrue()
     }
 
     @Test
-    fun displayView_screenAlreadyOn_screenNotWoken() {
+    fun displayView_screenAlreadyOn_wakeLockNotAcquired() {
         whenever(powerManager.isScreenOn).thenReturn(true)
 
         underTest.displayView(getState())
 
-        verify(powerManager, never()).wakeUp(any(), any(), any())
+        assertThat(fakeWakeLock.isHeld).isFalse()
     }
 
     @Test
-    fun displayView_twiceWithSameWindowTitle_viewNotAddedTwice() {
+    fun displayView_screenOff_wakeLockCanBeReleasedAfterTimeOut() {
+        underTest.displayView(getState())
+        assertThat(fakeWakeLock.isHeld).isTrue()
+
+        fakeClock.advanceTime(TIMEOUT_MS + 1)
+
+        assertThat(fakeWakeLock.isHeld).isFalse()
+    }
+
+    @Test
+    fun displayView_twice_viewNotAddedTwice() {
         underTest.displayView(getState())
         reset(windowManager)
 
@@ -269,6 +288,7 @@
         accessibilityManager: AccessibilityManager,
         configurationController: ConfigurationController,
         powerManager: PowerManager,
+        wakeLockBuilder: WakeLock.Builder,
     ) : TemporaryViewDisplayController<ViewInfo, TemporaryViewLogger>(
         context,
         logger,
@@ -278,13 +298,12 @@
         configurationController,
         powerManager,
         R.layout.chipbar,
+        wakeLockBuilder,
     ) {
         var mostRecentViewInfo: ViewInfo? = null
 
         override val windowLayoutParams = commonWindowLayoutParams
 
-        override fun start() {}
-
         override fun updateView(newInfo: ViewInfo, currentView: ViewGroup) {
             mostRecentViewInfo = newInfo
         }
@@ -292,6 +311,8 @@
         override fun getTouchableRegion(view: View, outRect: Rect) {
             outRect.setEmpty()
         }
+
+        override fun start() {}
     }
 
     inner class ViewInfo(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
index f643973..8e37aa2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
@@ -43,6 +43,7 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.time.FakeSystemClock
 import com.android.systemui.util.view.ViewUtil
+import com.android.systemui.util.wakelock.WakeLockFake
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
@@ -69,6 +70,8 @@
     @Mock private lateinit var falsingCollector: FalsingCollector
     @Mock private lateinit var viewUtil: ViewUtil
     @Mock private lateinit var vibratorHelper: VibratorHelper
+    private lateinit var fakeWakeLockBuilder: WakeLockFake.Builder
+    private lateinit var fakeWakeLock: WakeLockFake
     private lateinit var fakeClock: FakeSystemClock
     private lateinit var fakeExecutor: FakeExecutor
     private lateinit var uiEventLoggerFake: UiEventLoggerFake
@@ -81,6 +84,10 @@
         fakeClock = FakeSystemClock()
         fakeExecutor = FakeExecutor(fakeClock)
 
+        fakeWakeLock = WakeLockFake()
+        fakeWakeLockBuilder = WakeLockFake.Builder(context)
+        fakeWakeLockBuilder.setWakeLock(fakeWakeLock)
+
         uiEventLoggerFake = UiEventLoggerFake()
 
         underTest =
@@ -96,6 +103,7 @@
                 falsingCollector,
                 viewUtil,
                 vibratorHelper,
+                fakeWakeLockBuilder,
             )
         underTest.start()
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/FakeChipbarCoordinator.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/FakeChipbarCoordinator.kt
index 574f70e..beedf9f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/FakeChipbarCoordinator.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/FakeChipbarCoordinator.kt
@@ -27,6 +27,7 @@
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.util.concurrency.DelayableExecutor
 import com.android.systemui.util.view.ViewUtil
+import com.android.systemui.util.wakelock.WakeLock
 
 /** A fake implementation of [ChipbarCoordinator] for testing. */
 class FakeChipbarCoordinator(
@@ -41,6 +42,7 @@
     falsingCollector: FalsingCollector,
     viewUtil: ViewUtil,
     vibratorHelper: VibratorHelper,
+    wakeLockBuilder: WakeLock.Builder,
 ) :
     ChipbarCoordinator(
         context,
@@ -54,6 +56,7 @@
         falsingCollector,
         viewUtil,
         vibratorHelper,
+        wakeLockBuilder,
     ) {
     override fun animateViewOut(view: ViewGroup, onAnimationEnd: Runnable) {
         // Just bypass the animation in tests
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/CreateUserActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/CreateUserActivityTest.kt
new file mode 100644
index 0000000..51afbcb
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/CreateUserActivityTest.kt
@@ -0,0 +1,55 @@
+package com.android.systemui.user
+
+import android.app.Dialog
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.ext.junit.rules.ActivityScenarioRule
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.nullable
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+@TestableLooper.RunWithLooper
+class CreateUserActivityTest : SysuiTestCase() {
+    open class CreateUserActivityTestable :
+        CreateUserActivity(
+            /* userCreator = */ mock(),
+            /* editUserInfoController = */ mock {
+                val dialog: Dialog = mock()
+                whenever(
+                        createDialog(
+                            /* activity = */ nullable(),
+                            /* activityStarter = */ nullable(),
+                            /* oldUserIcon = */ nullable(),
+                            /* defaultUserName = */ nullable(),
+                            /* title = */ nullable(),
+                            /* successCallback = */ nullable(),
+                            /* cancelCallback = */ nullable()
+                        )
+                    )
+                    .thenReturn(dialog)
+            },
+            /* activityManager = */ mock(),
+            /* activityStarter = */ mock(),
+        )
+
+    @get:Rule val activityRule = ActivityScenarioRule(CreateUserActivityTestable::class.java)
+
+    @Test
+    fun onBackPressed_finishActivity() {
+        activityRule.scenario.onActivity { activity ->
+            assertThat(activity.isFinishing).isFalse()
+
+            activity.onBackPressed()
+
+            assertThat(activity.isFinishing).isTrue()
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/data/repository/UserRepositoryImplRefactoredTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/data/repository/UserRepositoryImplRefactoredTest.kt
index 525d837..7c7f0e1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/data/repository/UserRepositoryImplRefactoredTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/data/repository/UserRepositoryImplRefactoredTest.kt
@@ -145,6 +145,25 @@
         assertThat(userInfos).isEqualTo(expectedUsers)
     }
 
+    @Test
+    fun `userTrackerCallback - updates selectedUserInfo`() = runSelfCancelingTest {
+        underTest = create(this)
+        var selectedUserInfo: UserInfo? = null
+        underTest.selectedUserInfo.onEach { selectedUserInfo = it }.launchIn(this)
+        setUpUsers(
+            count = 2,
+            selectedIndex = 0,
+        )
+        tracker.onProfileChanged()
+        assertThat(selectedUserInfo?.id == 0)
+        setUpUsers(
+            count = 2,
+            selectedIndex = 1,
+        )
+        tracker.onProfileChanged()
+        assertThat(selectedUserInfo?.id == 1)
+    }
+
     private fun setUpUsers(
         count: Int,
         isLastGuestUser: Boolean = false,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java
index fe01f84..6e109ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java
@@ -42,7 +42,9 @@
 
     @Before
     public void setUp() {
-        mInner = WakeLock.createPartialInner(mContext, WakeLockTest.class.getName());
+        mInner = WakeLock.createWakeLockInner(mContext,
+                WakeLockTest.class.getName(),
+                PowerManager.PARTIAL_WAKE_LOCK);
         mWakeLock = WakeLock.wrap(mInner, 20000);
     }
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
index 6f70f0e..627bd09 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
@@ -53,8 +53,6 @@
     private val _wakefulnessState = MutableStateFlow(WakefulnessModel.ASLEEP)
     override val wakefulnessState: Flow<WakefulnessModel> = _wakefulnessState
 
-    private val _isUdfpsSupported = MutableStateFlow(false)
-    
     private val _isBouncerShowing = MutableStateFlow(false)
     override val isBouncerShowing: Flow<Boolean> = _isBouncerShowing
 
@@ -88,8 +86,4 @@
     fun setDozeAmount(dozeAmount: Float) {
         _dozeAmount.value = dozeAmount
     }
-
-    override fun isUdfpsSupported(): Boolean {
-        return _isUdfpsSupported.value
-    }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/settings/FakeUserTracker.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/settings/FakeUserTracker.kt
index 9726bf8..a7eadba 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/settings/FakeUserTracker.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/settings/FakeUserTracker.kt
@@ -68,4 +68,8 @@
 
         callbacks.forEach { it.onUserChanged(_userId, userContext) }
     }
+
+    fun onProfileChanged() {
+        callbacks.forEach { it.onProfilesChanged(_userProfiles) }
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/job/WorkTypeConfigTest.java b/services/tests/servicestests/src/com/android/server/job/WorkTypeConfigTest.java
index a5fedef..21d2784 100644
--- a/services/tests/servicestests/src/com/android/server/job/WorkTypeConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/WorkTypeConfigTest.java
@@ -36,7 +36,6 @@
 
 import com.android.server.job.JobConcurrencyManager.WorkTypeConfig;
 
-import org.junit.After;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -59,30 +58,6 @@
     private static final String KEY_MIN_BGUSER_IMPORTANT = "concurrency_min_bguser_important_test";
     private static final String KEY_MIN_BGUSER = "concurrency_min_bguser_test";
 
-    @After
-    public void tearDown() throws Exception {
-        resetConfig();
-    }
-
-    private void resetConfig() {
-        // DeviceConfig.resetToDefaults() doesn't work here. Need to reset constants manually.
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_JOB_SCHEDULER, KEY_MAX_TOTAL, null, false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_JOB_SCHEDULER, KEY_MAX_TOP, null, false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_JOB_SCHEDULER, KEY_MAX_FGS, null, false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_JOB_SCHEDULER, KEY_MAX_EJ, null, false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_JOB_SCHEDULER, KEY_MAX_BG, null, false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_JOB_SCHEDULER,
-                KEY_MAX_BGUSER_IMPORTANT, null, false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_JOB_SCHEDULER, KEY_MAX_BGUSER, null, false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_JOB_SCHEDULER, KEY_MIN_TOP, null, false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_JOB_SCHEDULER, KEY_MIN_FGS, null, false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_JOB_SCHEDULER, KEY_MIN_EJ, null, false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_JOB_SCHEDULER, KEY_MIN_BG, null, false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_JOB_SCHEDULER,
-                KEY_MIN_BGUSER_IMPORTANT, null, false);
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_JOB_SCHEDULER, KEY_MIN_BGUSER, null, false);
-    }
-
     private void check(@Nullable DeviceConfig.Properties config,
             int defaultTotal,
             @NonNull List<Pair<Integer, Integer>> defaultMin,
@@ -90,10 +65,6 @@
             boolean expectedValid, int expectedTotal,
             @NonNull List<Pair<Integer, Integer>> expectedMinLimits,
             @NonNull List<Pair<Integer, Integer>> expectedMaxLimits) throws Exception {
-        resetConfig();
-        if (config != null) {
-            DeviceConfig.setProperties(config);
-        }
 
         final WorkTypeConfig counts;
         try {
@@ -112,7 +83,9 @@
             }
         }
 
-        counts.update(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_JOB_SCHEDULER));
+        if (config != null) {
+            counts.update(config);
+        }
 
         assertEquals(expectedTotal, counts.getMaxTotal());
         for (Pair<Integer, Integer> min : expectedMinLimits) {