summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java24
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/UserWakeupStore.java10
-rw-r--r--core/api/system-current.txt2
-rw-r--r--core/java/Android.bp6
-rw-r--r--core/java/android/app/ActivityManagerInternal.java23
-rw-r--r--core/java/android/app/ActivityThread.java88
-rw-r--r--core/java/android/app/AppCompatTaskInfo.java338
-rw-r--r--core/java/android/app/OWNERS3
-rw-r--r--core/java/android/app/PropertyInvalidatedCache.java13
-rw-r--r--core/java/android/appwidget/AppWidgetHostView.java61
-rw-r--r--core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl5
-rw-r--r--core/java/android/companion/virtual/VirtualDeviceInternal.java11
-rw-r--r--core/java/android/companion/virtual/VirtualDeviceManager.java22
-rw-r--r--core/java/android/companion/virtual/flags.aconfig25
-rw-r--r--core/java/android/companion/virtual/flags/flags.aconfig29
-rw-r--r--core/java/android/content/BroadcastReceiver.java12
-rw-r--r--core/java/android/content/pm/flags.aconfig2
-rw-r--r--core/java/android/content/pm/multiuser.aconfig7
-rw-r--r--core/java/android/hardware/input/InputSettings.java10
-rw-r--r--core/java/android/os/ConcurrentMessageQueue/MessageQueue.java21
-rw-r--r--core/java/android/os/FileUtils.java6
-rw-r--r--core/java/android/os/LockedMessageQueue/MessageQueue.java1351
-rw-r--r--core/java/android/os/Message.java4
-rw-r--r--core/java/android/os/OWNERS3
-rw-r--r--core/java/android/os/ParcelFileDescriptor.java38
-rw-r--r--core/java/android/os/SemiConcurrentMessageQueue/MessageQueue.java2
-rw-r--r--core/java/android/permission/flags.aconfig2
-rw-r--r--core/java/android/provider/Settings.java8
-rw-r--r--core/java/android/service/notification/ZenModeConfig.java35
-rw-r--r--core/java/android/service/notification/ZenModeDiff.java8
-rw-r--r--core/java/android/service/notification/ZenPolicy.java5
-rw-r--r--core/java/android/view/SurfaceControlRegistry.java2
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java4
-rw-r--r--core/java/android/widget/Editor.java4
-rw-r--r--core/java/android/window/DisplayWindowPolicyController.java13
-rw-r--r--core/java/android/window/ImeOnBackInvokedDispatcher.java16
-rw-r--r--core/java/android/window/flags/lse_desktop_experience.aconfig14
-rw-r--r--core/java/android/window/flags/windowing_frontend.aconfig8
-rw-r--r--core/java/android/window/flags/windowing_sdk.aconfig11
-rw-r--r--core/java/com/android/internal/os/BackgroundThread.java4
-rw-r--r--core/java/com/android/internal/os/DebugStore.java247
-rw-r--r--core/java/com/android/internal/os/flags.aconfig8
-rw-r--r--core/java/com/android/internal/widget/OWNERS4
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java101
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/Operation.java1
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/Operations.java56
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/PaintContext.java67
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java8
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java144
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java17
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentationBuilder.java22
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedCompanionOperation.java22
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/documentation/Operation.java151
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java58
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/documentation/StringPair.java32
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase4.java8
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/Header.java38
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java19
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java473
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java82
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java193
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStartOperation.java21
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/DecoratorComponent.java27
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java220
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java68
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java173
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java311
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java186
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/Particle.java34
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/ParticleAnimation.java64
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java189
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java291
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java136
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java294
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/ComponentMeasure.java91
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java45
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/MeasurePass.java63
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Size.java44
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java146
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java164
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java88
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java109
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DecoratorModifierOperation.java32
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java159
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java55
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ModifierOperation.java26
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java135
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java78
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ShapeType.java25
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java55
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java127
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/StringValueSupplier.java27
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintBundle.java23
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntFloatMap.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntIntMap.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java3
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringSerializer.java52
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/GeneralEasing.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java9
-rw-r--r--core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java28
-rw-r--r--core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java3
-rw-r--r--core/jni/Android.bp2
-rw-r--r--core/jni/AndroidRuntime.cpp2
-rw-r--r--core/jni/com_android_internal_os_DebugStore.cpp105
-rw-r--r--core/proto/android/providers/settings/system.proto1
-rw-r--r--core/res/Android.bp1
-rw-r--r--core/res/AndroidManifest.xml8
-rw-r--r--core/res/TEST_MAPPING19
-rw-r--r--core/res/res/drawable/ic_call_answer_video.xml4
-rw-r--r--core/res/res/values/config.xml16
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--core/tests/coretests/src/android/os/FileUtilsTest.java41
-rw-r--r--core/tests/coretests/src/android/widget/TextViewContextMenuTest.java41
-rw-r--r--core/tests/coretests/src/com/android/internal/os/DebugStoreTest.java311
-rw-r--r--data/keyboards/Vendor_054c_Product_05c4.idc10
-rw-r--r--data/keyboards/Vendor_054c_Product_09cc.idc8
-rw-r--r--data/keyboards/Vendor_054c_Product_0ce6.idc31
-rw-r--r--data/keyboards/Vendor_054c_Product_0df2.idc31
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java26
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java2
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/collections/ListUtil.java41
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/layout/CommonFoldingFeature.java (renamed from libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java)2
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/layout/DisplayFoldFeatureCommon.java171
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java2
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/DisplayFoldFeatureUtil.java42
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java11
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java2
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarHelper.java2
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/collections/ListUtilTest.java51
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/layout/DisplayFoldFeatureCommonTest.java135
-rw-r--r--libs/WindowManager/Shell/res/layout/bubble_bar_menu_view.xml2
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduWindowManager.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/ReachabilityEduWindowManager.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponent.kt43
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponentIdGenerator.kt31
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponentState.kt24
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUISharedState.kt (renamed from packages/SystemUI/shared/src/com/android/systemui/shared/education/GestureType.kt)11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUISpec.kt27
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIState.kt75
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/CompatUIEvents.kt6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandler.kt49
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultComponentIdGenerator.kt32
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java23
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt138
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt79
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ReturnToDragStartAnimator.kt96
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java34
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java44
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java24
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java16
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl43
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java243
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java574
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java25
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java22
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java96
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/OnTaskRepositionAnimationListener.kt32
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.kt2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java26
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt8
-rw-r--r--libs/WindowManager/Shell/tests/OWNERS2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/OWNERS3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/CloseAllAppsWithAppHeaderExitTest.kt34
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/DragAppWindowMultiWindowTest.kt34
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/DragAppWindowSingleWindowTest.kt34
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/EnterDesktopWithAppHandleMenuTest.kt33
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/EnterDesktopWithDragTest.kt35
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/ExitDesktopWithDragToTopDragZoneTest.kt35
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/MaximizeAppWindowTest.kt34
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/MinimizeWindowOnAppOpenTest.kt36
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/ResizeAppWithCornerResizeTest.kt34
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/SwitchToOverviewFromDesktopTest.kt33
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java12
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java8
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUILayoutTest.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java8
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/CompatUIStateUtil.kt51
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandlerTest.kt196
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIRepositoryTest.kt23
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUIComponentIdGenerator.kt43
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUILifecyclePredicates.kt69
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUISpec.kt32
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt142
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java39
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorationTests.kt10
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt229
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt1
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt9
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java3
-rw-r--r--media/java/android/media/tv/flags/media_tv.aconfig8
-rw-r--r--native/graphics/jni/Android.bp27
-rw-r--r--native/graphics/jni/fuzz/fuzz_imagedecoder.cpp65
-rw-r--r--packages/CompanionDeviceManager/res/values/strings.xml53
-rw-r--r--packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionAssociationActivity.java10
-rw-r--r--packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceResources.java69
-rw-r--r--packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionVendorHelperDialogFragment.java46
-rw-r--r--packages/CredentialManager/wear/robotests/src/com/android/credentialmanager/CredentialSelectorUiStateGetMapperTest.kt48
-rw-r--r--packages/CredentialManager/wear/src/com/android/credentialmanager/FlowEngine.kt6
-rw-r--r--packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt9
-rw-r--r--packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFlattenScreen.kt2
-rw-r--r--packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/signInWithProvider/SignInWithProviderScreen.kt6
-rw-r--r--packages/SettingsLib/res/values/strings.xml5
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java1
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java3
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java18
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig11
-rw-r--r--packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java1
-rw-r--r--packages/SystemUI/Android.bp2
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/Android.bp1
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/AndroidManifest.xml1
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig10
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java45
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp1
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/tests/AndroidManifest.xml1
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java100
-rw-r--r--packages/SystemUI/aconfig/systemui.aconfig66
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt6
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Key.kt1
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt11
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt10
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/PredictiveBackHandlerTest.kt35
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt14
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt2
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt14
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt14
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadStatsInteractorTest.kt14
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt24
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt52
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/lifecycle/ActivatableTest.kt76
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/lifecycle/SafeActivatableTest.kt121
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/lifecycle/SysUiViewModelTest.kt113
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorSceneContainerImplTest.kt32
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt2
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/PrivacyDotViewControllerTest.kt30
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/SettingsProxyExtTest.kt165
-rw-r--r--packages/SystemUI/res/drawable/ic_redacted_notification_single_line_icon.xml27
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_fingerprint_to_error_landscape.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_folded_base_bottomright.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_folded_base_default.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_folded_base_topleft.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_landscape_base.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_portrait_base_bottomright.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_portrait_base_topleft.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_rear_landscape_base.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_rear_portrait_base.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_rear_portrait_reverse_base.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_error_to_fingerprint.json1
-rwxr-xr-xpackages/SystemUI/res/raw/biometricprompt_sfps_error_to_fingerprint_180.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_error_to_fingerprint_270.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_error_to_fingerprint_90.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_error_to_success.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_error_to_unlock.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_authenticating.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_error.json1
-rwxr-xr-xpackages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_error_180.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_error_270.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_error_90.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_success.json1
-rwxr-xr-xpackages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_success_180.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_success_270.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_success_90.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_unlock.json1
-rwxr-xr-xpackages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_unlock_180.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_unlock_270.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_unlock_90.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_error_to_fingerprint.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_error_to_fingerprint_180.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_error_to_fingerprint_270.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_error_to_fingerprint_90.json1
-rwxr-xr-xpackages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_authenticating.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_error.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_error_180.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_error_270.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_error_90.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_success.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_success_180.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_success_270.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_success_90.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_unlock.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_unlock_180.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_unlock_270.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_unlock_90.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_sfps_unlock_to_success.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_symbol_error_to_fingerprint_landscape.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_symbol_error_to_fingerprint_portrait_bottomright.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_symbol_error_to_fingerprint_portrait_topleft.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_symbol_error_to_success_landscape.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_symbol_error_to_success_portrait_bottomright.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_symbol_error_to_success_portrait_topleft.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_symbol_fingerprint_to_error_portrait_bottomright.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_symbol_fingerprint_to_error_portrait_topleft.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_symbol_fingerprint_to_success_landscape.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_symbol_fingerprint_to_success_portrait_bottomright.json1
-rw-r--r--packages/SystemUI/res/raw/biometricprompt_symbol_fingerprint_to_success_portrait_topleft.json1
-rw-r--r--packages/SystemUI/res/values/dimens.xml10
-rw-r--r--packages/SystemUI/res/values/ids.xml1
-rw-r--r--packages/SystemUI/res/values/strings.xml17
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/data/repository/BiometricStatusRepository.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/shared/model/AuthenticationState.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt34
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt187
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt557
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/common/ui/binder/IconViewBinder.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractor.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHost.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostView.kt32
-rw-r--r--packages/SystemUI/src/com/android/systemui/education/dagger/ContextualEducationModule.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/education/data/repository/ContextualEducationRepository.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/education/data/repository/UserContextualEducationRepository.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/education/domain/interactor/ContextualEducationInteractor.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduStatsInteractor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/education/shared/model/EducationInfo.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt53
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/InternalKeyguardTransitionInteractor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/lifecycle/Activatable.kt (renamed from packages/SystemUI/src/com/android/systemui/activatable/Activatable.kt)23
-rw-r--r--packages/SystemUI/src/com/android/systemui/lifecycle/SafeActivatable.kt72
-rw-r--r--packages/SystemUI/src/com/android/systemui/lifecycle/SysUiViewModel.kt44
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionUtils.kt39
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java71
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionUtils.kt47
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediaprojection/permission/ShareToAppPermissionDialogDelegate.kt (renamed from packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegate.kt)73
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediaprojection/permission/SystemCastPermissionDialogDelegate.kt112
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/PowerUI.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotController.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractor.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorEmptyImpl.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorLegacyImpl.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorSceneContainerImpl.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt215
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconPack.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt32
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java87
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt79
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt76
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/LockscreenOtpRedaction.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/NotificationContentModel.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineConversationViewBinder.kt40
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineViewBinder.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/GroupHunAnimationFix.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt166
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt296
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt299
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialScreenConfig.kt48
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitor.kt44
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureMonitor.kt39
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/ThreeFingerGestureMonitor.kt59
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/sensors/ProximityCheck.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxyExt.kt33
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt243
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt68
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/ShareToAppPermissionDialogDelegateTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegateTest.kt)31
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/SystemCastPermissionDialogDelegateTest.kt147
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt119
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt28
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt33
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt29
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt58
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt36
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineConversationViewBinderTest.kt117
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt99
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt56
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java21
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt44
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt118
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureMonitorTest.kt87
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/FakeContextualEducationRepository.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/lifecycle/ActivatableExt.kt (renamed from packages/SystemUI/tests/utils/src/com/android/systemui/activatable/ActivatableExt.kt)11
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/lifecycle/FakeActivatable.kt38
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/lifecycle/FakeSysUiViewModel.kt38
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModelBuilder.kt27
-rw-r--r--packages/overlays/HsumConfigOverlay/Android.bp16
-rw-r--r--packages/overlays/HsumConfigOverlay/AndroidManifest.xml22
-rw-r--r--packages/overlays/HsumConfigOverlay/OWNERS2
-rw-r--r--packages/overlays/HsumConfigOverlay/res/values/config.xml38
-rw-r--r--ravenwood/Android.bp8
-rw-r--r--ravenwood/runtime-common-src/com/android/ravenwood/common/JvmWorkaround.java11
-rw-r--r--ravenwood/runtime-common-src/com/android/ravenwood/common/OpenJdkWorkaround.java17
-rw-r--r--ravenwood/runtime-common-src/com/android/ravenwood/common/SneakyThrow.java33
-rw-r--r--ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/nativesubstitution/ParcelFileDescriptor_host.java93
-rw-r--r--ravenwood/runtime-helper-src/libcore-fake/android/system/Os.java13
-rw-r--r--ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/common/RavenwoodRuntimeNative.java15
-rw-r--r--ravenwood/runtime-jni/ravenwood_runtime.cpp52
-rw-r--r--services/Android.bp6
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java26
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java5
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java52
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java33
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/MouseEventHandler.java61
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java4
-rw-r--r--services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java69
-rw-r--r--services/companion/java/com/android/server/companion/virtual/InputController.java8
-rw-r--r--services/companion/java/com/android/server/companion/virtual/SensorController.java8
-rw-r--r--services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java51
-rw-r--r--services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java12
-rw-r--r--services/companion/java/com/android/server/companion/virtual/audio/VirtualAudioController.java8
-rw-r--r--services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraController.java8
-rw-r--r--services/core/Android.bp19
-rw-r--r--services/core/java/com/android/server/BatteryService.java6
-rw-r--r--services/core/java/com/android/server/TelephonyRegistry.java10
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java37
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java3
-rw-r--r--services/core/java/com/android/server/am/CachedAppOptimizer.java169
-rw-r--r--services/core/java/com/android/server/am/ContentProviderHelper.java6
-rw-r--r--services/core/java/com/android/server/am/Freezer.java115
-rw-r--r--services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java30
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java4
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java32
-rw-r--r--services/core/java/com/android/server/content/SyncManager.java8
-rw-r--r--services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionService.java28
-rw-r--r--services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java90
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodBindingController.java3
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java256
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodMenuControllerNew.java4
-rw-r--r--services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java40
-rw-r--r--services/core/java/com/android/server/inputmethod/UserData.java7
-rw-r--r--services/core/java/com/android/server/inputmethod/UserDataRepository.java11
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java31
-rw-r--r--services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java2
-rw-r--r--services/core/java/com/android/server/notification/NotificationAttentionHelper.java24
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java9
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java15
-rw-r--r--services/core/java/com/android/server/power/stats/AggregatedPowerStats.java12
-rw-r--r--services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java1
-rw-r--r--services/core/java/com/android/server/power/stats/PowerStatsAggregator.java15
-rw-r--r--services/core/java/com/android/server/power/stats/PowerStatsExporter.java4
-rw-r--r--services/core/java/com/android/server/stats/pull/StatsPullAtomService.java2
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperCropper.java4
-rw-r--r--services/core/java/com/android/server/wm/ActivityMetricsLogger.java3
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java12
-rw-r--r--services/core/java/com/android/server/wm/ActivitySnapshotController.java9
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java19
-rw-r--r--services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java27
-rw-r--r--services/core/java/com/android/server/wm/AppCompatController.java25
-rw-r--r--services/core/java/com/android/server/wm/AppCompatDeviceStateQuery.java64
-rw-r--r--services/core/java/com/android/server/wm/AppCompatOverrides.java18
-rw-r--r--services/core/java/com/android/server/wm/AppCompatReachabilityOverrides.java343
-rw-r--r--services/core/java/com/android/server/wm/AppCompatReachabilityPolicy.java178
-rw-r--r--services/core/java/com/android/server/wm/AppCompatUtils.java143
-rw-r--r--services/core/java/com/android/server/wm/BackNavigationController.java3
-rw-r--r--services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java13
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java5
-rw-r--r--services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java7
-rw-r--r--services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java16
-rw-r--r--services/core/java/com/android/server/wm/ImeTargetChangeListener.java8
-rw-r--r--services/core/java/com/android/server/wm/Letterbox.java18
-rw-r--r--services/core/java/com/android/server/wm/LetterboxUiController.java467
-rw-r--r--services/core/java/com/android/server/wm/Task.java1
-rw-r--r--services/core/java/com/android/server/wm/WallpaperController.java6
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java21
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerShellCommand.java10
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java15
-rw-r--r--services/core/jni/Android.bp8
-rw-r--r--services/core/jni/com_android_server_am_CachedAppOptimizer.cpp66
-rw-r--r--services/core/jni/com_android_server_am_Freezer.cpp124
-rw-r--r--services/core/jni/onload.cpp2
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java2
-rw-r--r--services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java30
-rw-r--r--services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java49
-rw-r--r--services/tests/mockingservicestests/jni/Android.bp1
-rw-r--r--services/tests/mockingservicestests/jni/onload.cpp3
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java27
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/UserWakeupStoreTest.java10
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java147
-rw-r--r--services/tests/servicestests/jni/Android.bp1
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java40
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java335
-rw-r--r--services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java100
-rw-r--r--services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java84
-rw-r--r--services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java1
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java111
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java59
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java38
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/ModifierShortcutManagerTests.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/StemKeyGestureTests.java28
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppCompatUtilsTest.java144
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java68
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java74
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskTests.java8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java13
-rw-r--r--services/usb/java/com/android/server/usb/UsbDeviceManager.java13
-rw-r--r--telecomm/java/android/telecom/CallerInfoAsyncQuery.java14
-rw-r--r--telephony/common/com/android/internal/telephony/SmsApplication.java8
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java5
-rw-r--r--tools/protologtool/src/com/android/protolog/tool/ViewerConfigProtoBuilder.kt1
-rw-r--r--wifi/java/src/android/net/wifi/WifiBlobStore.java34
562 files changed, 18232 insertions, 5054 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 9a178e573b53..18ee6f2c7992 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -165,6 +165,7 @@ import com.android.server.SystemService;
import com.android.server.SystemServiceManager;
import com.android.server.SystemTimeZone;
import com.android.server.SystemTimeZone.TimeZoneConfidence;
+import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.permission.PermissionManagerService;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.pm.pkg.AndroidPackage;
@@ -3763,8 +3764,10 @@ public class AlarmManagerService extends SystemService {
}
mNextAlarmClockForUser.put(userId, alarmClock);
if (mStartUserBeforeScheduledAlarms) {
- mUserWakeupStore.addUserWakeup(userId, convertToElapsed(
- mNextAlarmClockForUser.get(userId).getTriggerTime(), RTC));
+ if (shouldAddWakeupForUser(userId)) {
+ mUserWakeupStore.addUserWakeup(userId, convertToElapsed(
+ mNextAlarmClockForUser.get(userId).getTriggerTime(), RTC));
+ }
}
} else {
if (DEBUG_ALARM_CLOCK) {
@@ -3784,6 +3787,23 @@ public class AlarmManagerService extends SystemService {
}
/**
+ * Checks whether the user is of type that needs to be started before the alarm.
+ */
+ @VisibleForTesting
+ boolean shouldAddWakeupForUser(@UserIdInt int userId) {
+ final UserManagerInternal umInternal = LocalServices.getService(UserManagerInternal.class);
+ if (umInternal.getUserInfo(userId) == null || umInternal.getUserInfo(userId).isGuest()) {
+ // Guest user should not be started in the background.
+ return false;
+ } else {
+ // SYSTEM user is always running, so no need to schedule wakeup for it.
+ // Profiles are excluded from the wakeup list because users can explicitly stop them and
+ // so starting them in the background would go against the user's intent.
+ return userId != UserHandle.USER_SYSTEM && umInternal.getUserInfo(userId).isFull();
+ }
+ }
+
+ /**
* Updates NEXT_ALARM_FORMATTED and sends NEXT_ALARM_CLOCK_CHANGED_INTENT for all users
* for which alarm clocks have changed since the last call to this.
*
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/UserWakeupStore.java b/apex/jobscheduler/service/java/com/android/server/alarm/UserWakeupStore.java
index 93904a773ed5..9fe197d69ce5 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/UserWakeupStore.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/UserWakeupStore.java
@@ -20,7 +20,6 @@ package com.android.server.alarm;
import android.annotation.Nullable;
import android.os.Environment;
import android.os.SystemClock;
-import android.os.UserHandle;
import android.util.AtomicFile;
import android.util.IndentingPrintWriter;
import android.util.Pair;
@@ -119,13 +118,10 @@ public class UserWakeupStore {
* @param alarmTime time when alarm is expected to trigger.
*/
public void addUserWakeup(int userId, long alarmTime) {
- // SYSTEM user is always running, so no need to schedule wakeup for it.
- if (userId != UserHandle.USER_SYSTEM) {
- synchronized (mUserWakeupLock) {
- mUserStarts.put(userId, alarmTime - BUFFER_TIME_MS + getUserWakeupOffset());
- }
- updateUserListFile();
+ synchronized (mUserWakeupLock) {
+ mUserStarts.put(userId, alarmTime - BUFFER_TIME_MS + getUserWakeupOffset());
}
+ updateUserListFile();
}
/**
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index bed1b43fdbe7..15e5706db9d1 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -3448,7 +3448,7 @@ package android.companion.virtual {
}
public static interface VirtualDeviceManager.ActivityListener {
- method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") public default void onActivityLaunchBlocked(int, @NonNull android.content.ComponentName, int);
+ method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") public default void onActivityLaunchBlocked(int, @NonNull android.content.ComponentName, int, @Nullable android.content.IntentSender);
method public void onDisplayEmpty(int);
method @Deprecated public void onTopActivityChanged(int, @NonNull android.content.ComponentName);
method public default void onTopActivityChanged(int, @NonNull android.content.ComponentName, int);
diff --git a/core/java/Android.bp b/core/java/Android.bp
index 128fb62e21c9..92bca3cfbef2 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -22,11 +22,9 @@ filegroup {
":framework-nfc-non-updatable-sources",
":messagequeue-gen",
],
- // Exactly one of the below will be added to srcs by messagequeue-gen
+ // Exactly one MessageQueue.java will be added to srcs by messagequeue-gen
exclude_srcs: [
- "android/os/LegacyMessageQueue/MessageQueue.java",
- "android/os/ConcurrentMessageQueue/MessageQueue.java",
- "android/os/SemiConcurrentMessageQueue/MessageQueue.java",
+ "android/os/*MessageQueue/**/*.java",
],
visibility: ["//frameworks/base"],
}
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 83c3bf6eda76..89efa9b77a60 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -55,6 +55,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.Executor;
import java.util.function.BiFunction;
/**
@@ -1268,6 +1269,28 @@ public abstract class ActivityManagerInternal {
public abstract boolean shouldDelayHomeLaunch(int userId);
/**
+ * Used to track when a process is frozen or unfrozen.
+ */
+ public interface FrozenProcessListener {
+ /**
+ * Called when a process is frozen.
+ */
+ void onProcessFrozen(int pid);
+
+ /**
+ * Called when a process is unfrozen.
+ */
+ void onProcessUnfrozen(int pid);
+ }
+
+ /**
+ * Register the frozen process event listener callback. The same listener may be reused for
+ * multiple pids. Listeners are dropped when the process dies.
+ */
+ public abstract void addFrozenProcessListener(int pid, @NonNull Executor executor,
+ @NonNull FrozenProcessListener listener);
+
+ /**
* Add a startup timestamp to the most recent start of the specified process.
*
* @param key The {@link ApplicationStartInfo} start timestamp key of the timestamp to add.
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 2f80b30aed8b..d4558533291f 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -232,6 +232,7 @@ import com.android.internal.app.IVoiceInteractor;
import com.android.internal.content.ReferrerIntent;
import com.android.internal.os.BinderCallsStats;
import com.android.internal.os.BinderInternal;
+import com.android.internal.os.DebugStore;
import com.android.internal.os.RuntimeInit;
import com.android.internal.os.SafeZipPathValidatorCallback;
import com.android.internal.os.SomeArgs;
@@ -358,6 +359,15 @@ public final class ActivityThread extends ClientTransactionHandler
private static final long BINDER_CALLBACK_THROTTLE = 10_100L;
private long mBinderCallbackLast = -1;
+ private static final boolean DEBUG_STORE_ENABLED =
+ com.android.internal.os.Flags.debugStoreEnabled();
+
+ /**
+ * Threshold for identifying long-running looper messages (in milliseconds).
+ * Calculated as 2 seconds multiplied by the hardware timeout multiplier.
+ */
+ private static final long LONG_MESSAGE_THRESHOLD_MS = 2000 * Build.HW_TIMEOUT_MULTIPLIER;
+
/**
* Denotes the sequence number of the process state change for which the main thread needs
* to block until the network rules are updated for it.
@@ -2395,6 +2405,12 @@ public final class ActivityThread extends ClientTransactionHandler
}
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
+ long debugStoreId = -1;
+ // By default, log all long messages when the debug store is enabled,
+ // unless this is overridden for certain message types, for which we have
+ // more granular debug store logging.
+ boolean shouldLogLongMessage = DEBUG_STORE_ENABLED;
+ final long messageStartUptimeMs = SystemClock.uptimeMillis();
switch (msg.what) {
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
@@ -2419,24 +2435,61 @@ public final class ActivityThread extends ClientTransactionHandler
"broadcastReceiveComp");
}
}
- handleReceiver((ReceiverData)msg.obj);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ ReceiverData receiverData = (ReceiverData) msg.obj;
+ if (DEBUG_STORE_ENABLED) {
+ debugStoreId =
+ DebugStore.recordBroadcastHandleReceiver(receiverData.intent);
+ }
+
+ try {
+ handleReceiver(receiverData);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ if (DEBUG_STORE_ENABLED) {
+ DebugStore.recordEventEnd(debugStoreId);
+ shouldLogLongMessage = false;
+ }
+ }
break;
case CREATE_SERVICE:
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
("serviceCreate: " + String.valueOf(msg.obj)));
}
- handleCreateService((CreateServiceData)msg.obj);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ CreateServiceData createServiceData = (CreateServiceData) msg.obj;
+ if (DEBUG_STORE_ENABLED) {
+ debugStoreId = DebugStore.recordServiceCreate(createServiceData.info);
+ }
+
+ try {
+ handleCreateService(createServiceData);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ if (DEBUG_STORE_ENABLED) {
+ DebugStore.recordEventEnd(debugStoreId);
+ shouldLogLongMessage = false;
+ }
+ }
break;
case BIND_SERVICE:
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind: "
+ String.valueOf(msg.obj));
}
- handleBindService((BindServiceData)msg.obj);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ BindServiceData bindData = (BindServiceData) msg.obj;
+ if (DEBUG_STORE_ENABLED) {
+ debugStoreId =
+ DebugStore.recordServiceBind(bindData.rebind, bindData.intent);
+ }
+ try {
+ handleBindService(bindData);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ if (DEBUG_STORE_ENABLED) {
+ DebugStore.recordEventEnd(debugStoreId);
+ shouldLogLongMessage = false;
+ }
+ }
break;
case UNBIND_SERVICE:
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
@@ -2452,8 +2505,21 @@ public final class ActivityThread extends ClientTransactionHandler
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
("serviceStart: " + String.valueOf(msg.obj)));
}
- handleServiceArgs((ServiceArgsData)msg.obj);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ ServiceArgsData serviceData = (ServiceArgsData) msg.obj;
+ if (DEBUG_STORE_ENABLED) {
+ debugStoreId = DebugStore.recordServiceOnStart(serviceData.startId,
+ serviceData.flags, serviceData.args);
+ }
+
+ try {
+ handleServiceArgs(serviceData);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ if (DEBUG_STORE_ENABLED) {
+ DebugStore.recordEventEnd(debugStoreId);
+ shouldLogLongMessage = false;
+ }
+ }
break;
case STOP_SERVICE:
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
@@ -2649,11 +2715,17 @@ public final class ActivityThread extends ClientTransactionHandler
handleFinishInstrumentationWithoutRestart();
break;
}
+ long messageElapsedTimeMs = SystemClock.uptimeMillis() - messageStartUptimeMs;
Object obj = msg.obj;
if (obj instanceof SomeArgs) {
((SomeArgs) obj).recycle();
}
if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
+ if (shouldLogLongMessage
+ && messageElapsedTimeMs > LONG_MESSAGE_THRESHOLD_MS) {
+ DebugStore.recordLongLooperMessage(msg.what, msg.getTarget().getClass().getName(),
+ messageElapsedTimeMs);
+ }
}
}
diff --git a/core/java/android/app/AppCompatTaskInfo.java b/core/java/android/app/AppCompatTaskInfo.java
index a07f620d944c..81e9df66e18a 100644
--- a/core/java/android/app/AppCompatTaskInfo.java
+++ b/core/java/android/app/AppCompatTaskInfo.java
@@ -16,90 +16,113 @@
package android.app;
+import static android.app.TaskInfo.PROPERTY_VALUE_UNSET;
+
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* Stores App Compat information about a particular Task.
* @hide
*/
public class AppCompatTaskInfo implements Parcelable {
/**
- * Whether the direct top activity is eligible for letterbox education.
- */
- public boolean topActivityEligibleForLetterboxEducation;
-
- /**
- * Whether the letterbox education is enabled.
- */
- public boolean isLetterboxEducationEnabled;
-
- /**
- * Whether the direct top activity is in size compat mode on foreground.
+ * If {@link #isLetterboxDoubleTapEnabled} it contains the current letterbox vertical position
+ * or {@link TaskInfo#PROPERTY_VALUE_UNSET} otherwise.
*/
- public boolean topActivityInSizeCompat;
+ public int topActivityLetterboxVerticalPosition = PROPERTY_VALUE_UNSET;
/**
- * Whether the double tap is enabled.
+ * If {@link #isLetterboxDoubleTapEnabled} it contains the current letterbox vertical position
+ * or {@link TaskInfo#PROPERTY_VALUE_UNSET} otherwise.
*/
- public boolean isLetterboxDoubleTapEnabled;
+ public int topActivityLetterboxHorizontalPosition = PROPERTY_VALUE_UNSET;
/**
- * Whether the user aspect ratio settings button is enabled.
+ * If {@link #isLetterboxDoubleTapEnabled} it contains the current width of the letterboxed
+ * activity or {@link TaskInfo#PROPERTY_VALUE_UNSET} otherwise.
*/
- public boolean topActivityEligibleForUserAspectRatioButton;
+ public int topActivityLetterboxWidth = PROPERTY_VALUE_UNSET;
/**
- * Whether the user has forced the activity to be fullscreen through the user aspect ratio
- * settings.
+ * If {@link #isLetterboxDoubleTapEnabled} it contains the current height of the letterboxed
+ * activity or {@link TaskInfo#PROPERTY_VALUE_UNSET} otherwise.
*/
- public boolean isUserFullscreenOverrideEnabled;
+ public int topActivityLetterboxHeight = PROPERTY_VALUE_UNSET;
/**
- * Whether the system has forced the activity to be fullscreen
+ * Contains the current app height of the letterboxed activity if available or
+ * {@link TaskInfo#PROPERTY_VALUE_UNSET} otherwise.
*/
- public boolean isSystemFullscreenOverrideEnabled;
+ public int topActivityLetterboxAppHeight = PROPERTY_VALUE_UNSET;
/**
- * Hint about the letterbox state of the top activity.
+ * Contains the current app width of the letterboxed activity if available or
+ * {@link TaskInfo#PROPERTY_VALUE_UNSET} otherwise.
*/
- public boolean topActivityBoundsLetterboxed;
+ public int topActivityLetterboxAppWidth = PROPERTY_VALUE_UNSET;
/**
- * Whether the update comes from a letterbox double-tap action from the user or not.
+ * Stores camera-related app compat information about a particular Task.
*/
- public boolean isFromLetterboxDoubleTap;
+ public CameraCompatTaskInfo cameraCompatTaskInfo = CameraCompatTaskInfo.create();
- /**
- * If {@link #isLetterboxDoubleTapEnabled} it contains the current letterbox vertical position
- * or {@link TaskInfo#PROPERTY_VALUE_UNSET} otherwise.
- */
- public int topActivityLetterboxVerticalPosition;
+ /** Constant indicating no top activity flag has been set. */
+ private static final int FLAG_UNDEFINED = 0x0;
+ /** Constant base value for top activity flag. */
+ private static final int FLAG_BASE = 0x1;
+ /** Top activity flag for whether letterbox education is enabled. */
+ private static final int FLAG_LETTERBOX_EDU_ENABLED = FLAG_BASE;
+ /** Top activity flag for whether activity is eligible for letterbox education. */
+ private static final int FLAG_ELIGIBLE_FOR_LETTERBOX_EDU = FLAG_BASE << 1;
+ /** Top activity flag for whether activity bounds are letterboxed. */
+ private static final int FLAG_LETTERBOXED = FLAG_BASE << 2;
+ /** Top activity flag for whether activity is in size compat mode. */
+ private static final int FLAG_IN_SIZE_COMPAT = FLAG_BASE << 3;
+ /** Top activity flag for whether letterbox double tap is enabled. */
+ private static final int FLAG_LETTERBOX_DOUBLE_TAP_ENABLED = FLAG_BASE << 4;
+ /** Top activity flag for whether the update comes from a letterbox double tap action. */
+ private static final int FLAG_IS_FROM_LETTERBOX_DOUBLE_TAP = FLAG_BASE << 5;
+ /** Top activity flag for whether activity is eligible for user aspect ratio button. */
+ private static final int FLAG_ELIGIBLE_FOR_USER_ASPECT_RATIO_BUTTON = FLAG_BASE << 6;
+ /** Top activity flag for whether has activity has been overridden to fullscreen by system. */
+ private static final int FLAG_FULLSCREEN_OVERRIDE_SYSTEM = FLAG_BASE << 7;
+ /** Top activity flag for whether has activity has been overridden to fullscreen by user. */
+ private static final int FLAG_FULLSCREEN_OVERRIDE_USER = FLAG_BASE << 8;
- /**
- * If {@link #isLetterboxDoubleTapEnabled} it contains the current letterbox vertical position
- * or {@link TaskInfo#PROPERTY_VALUE_UNSET} otherwise.
- */
- public int topActivityLetterboxHorizontalPosition;
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, value = {
+ FLAG_UNDEFINED,
+ FLAG_BASE,
+ FLAG_LETTERBOX_EDU_ENABLED,
+ FLAG_ELIGIBLE_FOR_LETTERBOX_EDU,
+ FLAG_LETTERBOXED,
+ FLAG_IN_SIZE_COMPAT,
+ FLAG_LETTERBOX_DOUBLE_TAP_ENABLED,
+ FLAG_IS_FROM_LETTERBOX_DOUBLE_TAP,
+ FLAG_ELIGIBLE_FOR_USER_ASPECT_RATIO_BUTTON,
+ FLAG_FULLSCREEN_OVERRIDE_SYSTEM,
+ FLAG_FULLSCREEN_OVERRIDE_USER
+ })
+ public @interface TopActivityFlag {}
- /**
- * If {@link #isLetterboxDoubleTapEnabled} it contains the current width of the letterboxed
- * activity or {@link TaskInfo#PROPERTY_VALUE_UNSET} otherwise.
- */
- public int topActivityLetterboxWidth;
+ @TopActivityFlag
+ private int mTopActivityFlags;
- /**
- * If {@link #isLetterboxDoubleTapEnabled} it contains the current height of the letterboxed
- * activity or {@link TaskInfo#PROPERTY_VALUE_UNSET} otherwise.
- */
- public int topActivityLetterboxHeight;
+ @TopActivityFlag
+ private static final int FLAGS_ORGANIZER_INTERESTED = FLAG_IS_FROM_LETTERBOX_DOUBLE_TAP
+ | FLAG_ELIGIBLE_FOR_USER_ASPECT_RATIO_BUTTON | FLAG_FULLSCREEN_OVERRIDE_SYSTEM
+ | FLAG_FULLSCREEN_OVERRIDE_USER;
- /**
- * Stores camera-related app compat information about a particular Task.
- */
- public CameraCompatTaskInfo cameraCompatTaskInfo = CameraCompatTaskInfo.create();
+ @TopActivityFlag
+ private static final int FLAGS_COMPAT_UI_INTERESTED = FLAGS_ORGANIZER_INTERESTED
+ | FLAG_IN_SIZE_COMPAT | FLAG_ELIGIBLE_FOR_LETTERBOX_EDU | FLAG_LETTERBOX_EDU_ENABLED;
private AppCompatTaskInfo() {
// Do nothing
@@ -136,9 +159,8 @@ public class AppCompatTaskInfo implements Parcelable {
* @return {@code true} if the task has some compat ui.
*/
public boolean hasCompatUI() {
- return topActivityInSizeCompat || topActivityEligibleForLetterboxEducation
- || isLetterboxDoubleTapEnabled
- || topActivityEligibleForUserAspectRatioButton;
+ return isTopActivityInSizeCompat() || eligibleForLetterboxEducation()
+ || isLetterboxDoubleTapEnabled() || eligibleForUserAspectRatioButton();
}
/**
@@ -149,6 +171,142 @@ public class AppCompatTaskInfo implements Parcelable {
}
/**
+ * @return {@code true} if the letterbox education is enabled.
+ */
+ public boolean isLetterboxEducationEnabled() {
+ return isTopActivityFlagEnabled(FLAG_LETTERBOX_EDU_ENABLED);
+ }
+
+ /**
+ * Sets the top activity flag for whether letterbox education is enabled.
+ */
+ public void setLetterboxEducationEnabled(boolean enable) {
+ setTopActivityFlag(FLAG_LETTERBOX_EDU_ENABLED, enable);
+ }
+
+ /**
+ * @return {@code true} if the direct top activity is eligible for letterbox education.
+ */
+ public boolean eligibleForLetterboxEducation() {
+ return isTopActivityFlagEnabled(FLAG_ELIGIBLE_FOR_LETTERBOX_EDU);
+ }
+
+ /**
+ * Sets the top activity flag to be eligible for letterbox education.
+ */
+ public void setEligibleForLetterboxEducation(boolean enable) {
+ setTopActivityFlag(FLAG_ELIGIBLE_FOR_LETTERBOX_EDU, enable);
+ }
+
+ /**
+ * @return {@code true} if the direct top activity is eligible for the user aspect ratio
+ * settings button.
+ */
+ public boolean eligibleForUserAspectRatioButton() {
+ return isTopActivityFlagEnabled(FLAG_ELIGIBLE_FOR_USER_ASPECT_RATIO_BUTTON);
+ }
+
+ /**
+ * Sets the top activity flag to be eligible for the user aspect ratio settings button.
+ */
+ public void setEligibleForUserAspectRatioButton(boolean enable) {
+ setTopActivityFlag(FLAG_ELIGIBLE_FOR_USER_ASPECT_RATIO_BUTTON, enable);
+ }
+
+ /**
+ * @return {@code true} if double tap to reposition letterboxed app is enabled.
+ */
+ public boolean isLetterboxDoubleTapEnabled() {
+ return isTopActivityFlagEnabled(FLAG_LETTERBOX_DOUBLE_TAP_ENABLED);
+ }
+
+ /**
+ * Sets the top activity flag to enable double tap to reposition letterboxed app.
+ */
+ public void setLetterboxDoubleTapEnabled(boolean enable) {
+ setTopActivityFlag(FLAG_LETTERBOX_DOUBLE_TAP_ENABLED, enable);
+ }
+
+ /**
+ * @return {@code true} if the update comes from a letterbox double-tap action from the user.
+ */
+ public boolean isFromLetterboxDoubleTap() {
+ return isTopActivityFlagEnabled(FLAG_IS_FROM_LETTERBOX_DOUBLE_TAP);
+ }
+
+ /**
+ * Sets the top activity flag for whether the update comes from a letterbox double-tap action
+ * from the user.
+ */
+ public void setIsFromLetterboxDoubleTap(boolean enable) {
+ setTopActivityFlag(FLAG_IS_FROM_LETTERBOX_DOUBLE_TAP, enable);
+ }
+
+ /**
+ * @return {@code true} if the user has forced the activity to be fullscreen through the
+ * user aspect ratio settings.
+ */
+ public boolean isUserFullscreenOverrideEnabled() {
+ return isTopActivityFlagEnabled(FLAG_FULLSCREEN_OVERRIDE_USER);
+ }
+
+ /**
+ * Sets the top activity flag for whether the user has forced the activity to be fullscreen
+ * through the user aspect ratio settings.
+ */
+ public void setUserFullscreenOverrideEnabled(boolean enable) {
+ setTopActivityFlag(FLAG_FULLSCREEN_OVERRIDE_USER, enable);
+ }
+
+ /**
+ * @return {@code true} if the system has forced the activity to be fullscreen.
+ */
+ public boolean isSystemFullscreenOverrideEnabled() {
+ return isTopActivityFlagEnabled(FLAG_FULLSCREEN_OVERRIDE_SYSTEM);
+ }
+
+ /**
+ * Sets the top activity flag for whether the system has forced the activity to be fullscreen.
+ */
+ public void setSystemFullscreenOverrideEnabled(boolean enable) {
+ setTopActivityFlag(FLAG_FULLSCREEN_OVERRIDE_SYSTEM, enable);
+ }
+
+ /**
+ * @return {@code true} if the direct top activity is in size compat mode on foreground.
+ */
+ public boolean isTopActivityInSizeCompat() {
+ return isTopActivityFlagEnabled(FLAG_IN_SIZE_COMPAT);
+ }
+
+ /**
+ * Sets the top activity flag for whether the direct top activity is in size compat mode
+ * on foreground.
+ */
+ public void setTopActivityInSizeCompat(boolean enable) {
+ setTopActivityFlag(FLAG_IN_SIZE_COMPAT, enable);
+ }
+
+ /**
+ * @return {@code true} if the top activity bounds are letterboxed.
+ */
+ public boolean isTopActivityLetterboxed() {
+ return isTopActivityFlagEnabled(FLAG_LETTERBOXED);
+ }
+
+ /**
+ * Sets the top activity flag for whether the top activity bounds are letterboxed.
+ */
+ public void setTopActivityLetterboxed(boolean enable) {
+ setTopActivityFlag(FLAG_LETTERBOXED, enable);
+ }
+
+ /** Clear all top activity flags and set to false. */
+ public void clearTopActivityFlags() {
+ mTopActivityFlags = FLAG_UNDEFINED;
+ }
+
+ /**
* @return {@code true} if the app compat parameters that are important for task organizers
* are equal.
*/
@@ -156,16 +314,15 @@ public class AppCompatTaskInfo implements Parcelable {
if (that == null) {
return false;
}
- return isFromLetterboxDoubleTap == that.isFromLetterboxDoubleTap
- && topActivityEligibleForUserAspectRatioButton
- == that.topActivityEligibleForUserAspectRatioButton
+ return (mTopActivityFlags & FLAGS_ORGANIZER_INTERESTED)
+ == (that.mTopActivityFlags & FLAGS_ORGANIZER_INTERESTED)
&& topActivityLetterboxVerticalPosition == that.topActivityLetterboxVerticalPosition
&& topActivityLetterboxWidth == that.topActivityLetterboxWidth
&& topActivityLetterboxHeight == that.topActivityLetterboxHeight
+ && topActivityLetterboxAppWidth == that.topActivityLetterboxAppWidth
+ && topActivityLetterboxAppHeight == that.topActivityLetterboxAppHeight
&& topActivityLetterboxHorizontalPosition
== that.topActivityLetterboxHorizontalPosition
- && isUserFullscreenOverrideEnabled == that.isUserFullscreenOverrideEnabled
- && isSystemFullscreenOverrideEnabled == that.isSystemFullscreenOverrideEnabled
&& cameraCompatTaskInfo.equalsForTaskOrganizer(that.cameraCompatTaskInfo);
}
@@ -176,20 +333,15 @@ public class AppCompatTaskInfo implements Parcelable {
if (that == null) {
return false;
}
- return topActivityInSizeCompat == that.topActivityInSizeCompat
- && isFromLetterboxDoubleTap == that.isFromLetterboxDoubleTap
- && topActivityEligibleForUserAspectRatioButton
- == that.topActivityEligibleForUserAspectRatioButton
- && topActivityEligibleForLetterboxEducation
- == that.topActivityEligibleForLetterboxEducation
- && isLetterboxEducationEnabled == that.isLetterboxEducationEnabled
+ return (mTopActivityFlags & FLAGS_COMPAT_UI_INTERESTED)
+ == (that.mTopActivityFlags & FLAGS_COMPAT_UI_INTERESTED)
&& topActivityLetterboxVerticalPosition == that.topActivityLetterboxVerticalPosition
&& topActivityLetterboxHorizontalPosition
== that.topActivityLetterboxHorizontalPosition
&& topActivityLetterboxWidth == that.topActivityLetterboxWidth
&& topActivityLetterboxHeight == that.topActivityLetterboxHeight
- && isUserFullscreenOverrideEnabled == that.isUserFullscreenOverrideEnabled
- && isSystemFullscreenOverrideEnabled == that.isSystemFullscreenOverrideEnabled
+ && topActivityLetterboxAppWidth == that.topActivityLetterboxAppWidth
+ && topActivityLetterboxAppHeight == that.topActivityLetterboxAppHeight
&& cameraCompatTaskInfo.equalsForCompatUi(that.cameraCompatTaskInfo);
}
@@ -197,19 +349,13 @@ public class AppCompatTaskInfo implements Parcelable {
* Reads the AppCompatTaskInfo from a parcel.
*/
void readFromParcel(Parcel source) {
- isLetterboxEducationEnabled = source.readBoolean();
- topActivityInSizeCompat = source.readBoolean();
- topActivityEligibleForLetterboxEducation = source.readBoolean();
- isLetterboxDoubleTapEnabled = source.readBoolean();
- topActivityEligibleForUserAspectRatioButton = source.readBoolean();
- topActivityBoundsLetterboxed = source.readBoolean();
- isFromLetterboxDoubleTap = source.readBoolean();
+ mTopActivityFlags = source.readInt();
topActivityLetterboxVerticalPosition = source.readInt();
topActivityLetterboxHorizontalPosition = source.readInt();
topActivityLetterboxWidth = source.readInt();
topActivityLetterboxHeight = source.readInt();
- isUserFullscreenOverrideEnabled = source.readBoolean();
- isSystemFullscreenOverrideEnabled = source.readBoolean();
+ topActivityLetterboxAppWidth = source.readInt();
+ topActivityLetterboxAppHeight = source.readInt();
cameraCompatTaskInfo = source.readTypedObject(CameraCompatTaskInfo.CREATOR);
}
@@ -218,41 +364,43 @@ public class AppCompatTaskInfo implements Parcelable {
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeBoolean(isLetterboxEducationEnabled);
- dest.writeBoolean(topActivityInSizeCompat);
- dest.writeBoolean(topActivityEligibleForLetterboxEducation);
- dest.writeBoolean(isLetterboxDoubleTapEnabled);
- dest.writeBoolean(topActivityEligibleForUserAspectRatioButton);
- dest.writeBoolean(topActivityBoundsLetterboxed);
- dest.writeBoolean(isFromLetterboxDoubleTap);
+ dest.writeInt(mTopActivityFlags);
dest.writeInt(topActivityLetterboxVerticalPosition);
dest.writeInt(topActivityLetterboxHorizontalPosition);
dest.writeInt(topActivityLetterboxWidth);
dest.writeInt(topActivityLetterboxHeight);
- dest.writeBoolean(isUserFullscreenOverrideEnabled);
- dest.writeBoolean(isSystemFullscreenOverrideEnabled);
+ dest.writeInt(topActivityLetterboxAppWidth);
+ dest.writeInt(topActivityLetterboxAppHeight);
dest.writeTypedObject(cameraCompatTaskInfo, flags);
}
@Override
public String toString() {
- return "AppCompatTaskInfo { topActivityInSizeCompat=" + topActivityInSizeCompat
- + " topActivityEligibleForLetterboxEducation= "
- + topActivityEligibleForLetterboxEducation
- + "isLetterboxEducationEnabled= " + isLetterboxEducationEnabled
- + " isLetterboxDoubleTapEnabled= " + isLetterboxDoubleTapEnabled
- + " topActivityEligibleForUserAspectRatioButton= "
- + topActivityEligibleForUserAspectRatioButton
- + " topActivityBoundsLetterboxed= " + topActivityBoundsLetterboxed
- + " isFromLetterboxDoubleTap= " + isFromLetterboxDoubleTap
+ return "AppCompatTaskInfo { topActivityInSizeCompat=" + isTopActivityInSizeCompat()
+ + " eligibleForLetterboxEducation= " + eligibleForLetterboxEducation()
+ + " isLetterboxEducationEnabled= " + isLetterboxEducationEnabled()
+ + " isLetterboxDoubleTapEnabled= " + isLetterboxDoubleTapEnabled()
+ + " eligibleForUserAspectRatioButton= " + eligibleForUserAspectRatioButton()
+ + " topActivityBoundsLetterboxed= " + isTopActivityLetterboxed()
+ + " isFromLetterboxDoubleTap= " + isFromLetterboxDoubleTap()
+ " topActivityLetterboxVerticalPosition= " + topActivityLetterboxVerticalPosition
+ " topActivityLetterboxHorizontalPosition= "
+ topActivityLetterboxHorizontalPosition
+ " topActivityLetterboxWidth=" + topActivityLetterboxWidth
+ " topActivityLetterboxHeight=" + topActivityLetterboxHeight
- + " isUserFullscreenOverrideEnabled=" + isUserFullscreenOverrideEnabled
- + " isSystemFullscreenOverrideEnabled=" + isSystemFullscreenOverrideEnabled
+ + " topActivityLetterboxAppWidth=" + topActivityLetterboxAppWidth
+ + " topActivityLetterboxAppHeight=" + topActivityLetterboxAppHeight
+ + " isUserFullscreenOverrideEnabled=" + isUserFullscreenOverrideEnabled()
+ + " isSystemFullscreenOverrideEnabled=" + isSystemFullscreenOverrideEnabled()
+ " cameraCompatTaskInfo=" + cameraCompatTaskInfo.toString()
+ "}";
}
+
+ private void setTopActivityFlag(@TopActivityFlag int flag, boolean enable) {
+ mTopActivityFlags = enable ? (mTopActivityFlags | flag) : (mTopActivityFlags & ~flag);
+ }
+
+ private boolean isTopActivityFlagEnabled(@TopActivityFlag int flag) {
+ return (mTopActivityFlags & flag) == flag;
+ }
}
diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS
index 1200b4b45712..adeb0451cd43 100644
--- a/core/java/android/app/OWNERS
+++ b/core/java/android/app/OWNERS
@@ -94,6 +94,9 @@ per-file IEphemeralResolver.aidl = file:/services/core/java/com/android/server/p
per-file IInstantAppResolver.aidl = file:/services/core/java/com/android/server/pm/OWNERS
per-file InstantAppResolveInfo.aidl = file:/services/core/java/com/android/server/pm/OWNERS
+# Performance
+per-file PropertyInvalidatedCache.java = file:/PERFORMANCE_OWNERS
+
# Pinner
per-file pinner-client.aconfig = file:/core/java/android/app/pinner/OWNERS
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java
index 22804a2039d1..0c786cb20fdc 100644
--- a/core/java/android/app/PropertyInvalidatedCache.java
+++ b/core/java/android/app/PropertyInvalidatedCache.java
@@ -29,6 +29,7 @@ import android.text.TextUtils;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.BackgroundThread;
import com.android.internal.util.FastPrintWriter;
import java.lang.annotation.Retention;
@@ -1260,7 +1261,7 @@ public class PropertyInvalidatedCache<Query, Result> {
}
public void autoCork() {
- if (Looper.getMainLooper() == null) {
+ if (getLooper() == null) {
// We're not ready to auto-cork yet, so just invalidate the cache immediately.
if (DEBUG) {
Log.w(TAG, "invalidating instead of autocorking early in init: "
@@ -1322,7 +1323,7 @@ public class PropertyInvalidatedCache<Query, Result> {
@GuardedBy("mLock")
private Handler getHandlerLocked() {
if (mHandler == null) {
- mHandler = new Handler(Looper.getMainLooper()) {
+ mHandler = new Handler(getLooper()) {
@Override
public void handleMessage(Message msg) {
AutoCorker.this.handleMessage(msg);
@@ -1331,6 +1332,14 @@ public class PropertyInvalidatedCache<Query, Result> {
}
return mHandler;
}
+
+ /**
+ * Return a looper for auto-uncork messages. Messages should be processed on the
+ * background thread, not on the main thread.
+ */
+ private static Looper getLooper() {
+ return BackgroundThread.getHandler().getLooper();
+ }
}
/**
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index 1f19f817a0b3..933c336c1359 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -132,7 +132,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
* Create a host view. Uses specified animations when pushing
* {@link #updateAppWidget(RemoteViews)}.
*
- * @param animationIn Resource ID of in animation to use
+ * @param animationIn Resource ID of in animation to use
* @param animationOut Resource ID of out animation to use
*/
@SuppressWarnings({"UnusedDeclaration"})
@@ -148,7 +148,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
* Pass the given handler to RemoteViews when updating this widget. Unless this
* is done immediatly after construction, a call to {@link #updateAppWidget(RemoteViews)}
* should be made.
- * @param handler
+ *
* @hide
*/
public void setInteractionHandler(InteractionHandler handler) {
@@ -206,10 +206,10 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
* order for the AppWidgetHost to account for the automatic padding when computing the number
* of cells to allocate to a particular widget.
*
- * @param context the current context
+ * @param context the current context
* @param component the component name of the widget
- * @param padding Rect in which to place the output, if null, a new Rect will be allocated and
- * returned
+ * @param padding Rect in which to place the output, if null, a new Rect will be allocated and
+ * returned
* @return default padding for this widget, in pixels
*/
public static Rect getDefaultPaddingForWidget(Context context, ComponentName component,
@@ -291,7 +291,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
}
mDelayedRestoredInflationId = -1;
mDelayedRestoredState = null;
- try {
+ try {
super.dispatchRestoreInstanceState(state);
} catch (Exception e) {
Log.e(TAG, "failed to restoreInstanceState for widget id: " + mAppWidgetId + ", "
@@ -354,14 +354,14 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
* the framework will be accounted for automatically. This information gets embedded into the
* AppWidget options and causes a callback to the AppWidgetProvider. In addition, the list of
* sizes is explicitly set to an empty list.
- * @see AppWidgetProvider#onAppWidgetOptionsChanged(Context, AppWidgetManager, int, Bundle)
*
* @param newOptions The bundle of options, in addition to the size information,
- * can be null.
- * @param minWidth The minimum width in dips that the widget will be displayed at.
- * @param minHeight The maximum height in dips that the widget will be displayed at.
- * @param maxWidth The maximum width in dips that the widget will be displayed at.
- * @param maxHeight The maximum height in dips that the widget will be displayed at.
+ * can be null.
+ * @param minWidth The minimum width in dips that the widget will be displayed at.
+ * @param minHeight The maximum height in dips that the widget will be displayed at.
+ * @param maxWidth The maximum width in dips that the widget will be displayed at.
+ * @param maxHeight The maximum height in dips that the widget will be displayed at.
+ * @see AppWidgetProvider#onAppWidgetOptionsChanged(Context, AppWidgetManager, int, Bundle)
* @deprecated use {@link AppWidgetHostView#updateAppWidgetSize(Bundle, List)} instead.
*/
@Deprecated
@@ -378,12 +378,14 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
* This method will update the option bundle with the list of sizes and the min/max bounds for
* width and height.
*
- * @see AppWidgetProvider#onAppWidgetOptionsChanged(Context, AppWidgetManager, int, Bundle)
- *
* @param newOptions The bundle of options, in addition to the size information.
- * @param sizes Sizes, in dips, the widget may be displayed at without calling the provider
- * again. Typically, this will be size of the widget in landscape and portrait.
- * On some foldables, this might include the size on the outer and inner screens.
+ * @param sizes Sizes, in dips, the widget may be displayed at without calling the
+ * provider
+ * again. Typically, this will be size of the widget in landscape and
+ * portrait.
+ * On some foldables, this might include the size on the outer and inner
+ * screens.
+ * @see AppWidgetProvider#onAppWidgetOptionsChanged(Context, AppWidgetManager, int, Bundle)
*/
public void updateAppWidgetSize(@NonNull Bundle newOptions, @NonNull List<SizeF> sizes) {
AppWidgetManager widgetManager = AppWidgetManager.getInstance(mContext);
@@ -470,9 +472,9 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
/**
* Specify some extra information for the widget provider. Causes a callback to the
* AppWidgetProvider.
- * @see AppWidgetProvider#onAppWidgetOptionsChanged(Context, AppWidgetManager, int, Bundle)
*
* @param options The bundle of options information.
+ * @see AppWidgetProvider#onAppWidgetOptionsChanged(Context, AppWidgetManager, int, Bundle)
*/
public void updateAppWidgetOptions(Bundle options) {
AppWidgetManager.getInstance(mContext).updateAppWidgetOptions(mAppWidgetId, options);
@@ -507,6 +509,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
/**
* Sets whether the widget is being displayed on a light/white background and use an
* alternate UI if available.
+ *
* @see RemoteViews#setLightBackgroundLayoutId(int)
*/
public void setOnLightBackground(boolean onLightBackground) {
@@ -620,7 +623,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
if (content == null) {
if (mViewMode == VIEW_MODE_ERROR) {
// We've already done this -- nothing to do.
- return ;
+ return;
}
if (exception != null) {
Log.w(TAG, "Error inflating RemoteViews", exception);
@@ -733,7 +736,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
if (adapter instanceof BaseAdapter) {
BaseAdapter baseAdapter = (BaseAdapter) adapter;
baseAdapter.notifyDataSetChanged();
- } else if (adapter == null && adapterView instanceof RemoteAdapterConnectionCallback) {
+ } else if (adapter == null && adapterView instanceof RemoteAdapterConnectionCallback) {
// If the adapter is null, it may mean that the RemoteViewsAapter has not yet
// connected to its associated service, and hence the adapter hasn't been set.
// In this case, we need to defer the notify call until it has been set.
@@ -745,6 +748,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
/**
* Build a {@link Context} cloned into another package name, usually for the
* purposes of reading remote resources.
+ *
* @hide
*/
protected Context getRemoteContextEnsuringCorrectCachedApkPath() {
@@ -760,7 +764,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
}
return newContext;
} catch (NameNotFoundException e) {
- Log.e(TAG, "Package name " + mInfo.providerInfo.packageName + " not found");
+ Log.e(TAG, "Package name " + mInfo.providerInfo.packageName + " not found");
return mContext;
} catch (NullPointerException e) {
Log.e(TAG, "Error trying to create the remote context.", e);
@@ -774,7 +778,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
*/
protected void prepareView(View view) {
// Take requested dimensions from child, but apply default gravity.
- FrameLayout.LayoutParams requested = (FrameLayout.LayoutParams)view.getLayoutParams();
+ FrameLayout.LayoutParams requested = (FrameLayout.LayoutParams) view.getLayoutParams();
if (requested == null) {
requested = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
@@ -839,7 +843,18 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
return defaultView;
}
- private void onDefaultViewClicked(View view) {
+ /**
+ * Handles interactions on the default view of the widget. By default does not use the
+ * {@link InteractionHandler} used by other interactions. However, this can be overridden
+ * in order to customize the click behavior.
+ *
+ * @hide
+ */
+ protected void onDefaultViewClicked(@NonNull View view) {
+ final AppWidgetManager manager = AppWidgetManager.getInstance(mContext);
+ if (manager != null) {
+ manager.noteAppWidgetTapped(mAppWidgetId);
+ }
if (mInfo != null) {
LauncherApps launcherApps = getContext().getSystemService(LauncherApps.class);
List<LauncherActivityInfo> activities = launcherApps.getActivityList(
diff --git a/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl b/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl
index 39371a3dbd3f..564fb023dc7b 100644
--- a/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl
+++ b/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl
@@ -17,6 +17,7 @@
package android.companion.virtual;
import android.content.ComponentName;
+import android.content.IntentSender;
/**
* Interface to listen for activity changes in a virtual device.
@@ -48,6 +49,8 @@ oneway interface IVirtualDeviceActivityListener {
* @param displayId The display ID on which the activity tried to launch.
* @param componentName The component name of the blocked activity.
* @param userId The user ID associated with the blocked activity.
+ * @param intentSender The original sender of the intent.
*/
- void onActivityLaunchBlocked(int displayId, in ComponentName componentName, int userId);
+ void onActivityLaunchBlocked(int displayId, in ComponentName componentName, int userId,
+ in IntentSender intentSender);
}
diff --git a/core/java/android/companion/virtual/VirtualDeviceInternal.java b/core/java/android/companion/virtual/VirtualDeviceInternal.java
index d8899b24eda3..19eb497dbd7a 100644
--- a/core/java/android/companion/virtual/VirtualDeviceInternal.java
+++ b/core/java/android/companion/virtual/VirtualDeviceInternal.java
@@ -38,6 +38,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.IntentSender;
import android.hardware.display.DisplayManagerGlobal;
import android.hardware.display.IVirtualDisplayCallback;
import android.hardware.display.VirtualDisplay;
@@ -135,13 +136,14 @@ public class VirtualDeviceInternal {
@Override
public void onActivityLaunchBlocked(int displayId, ComponentName componentName,
- @UserIdInt int userId) {
+ @UserIdInt int userId, IntentSender intentSender) {
final long token = Binder.clearCallingIdentity();
try {
synchronized (mActivityListenersLock) {
for (int i = 0; i < mActivityListeners.size(); i++) {
mActivityListeners.valueAt(i)
- .onActivityLaunchBlocked(displayId, componentName, userId);
+ .onActivityLaunchBlocked(
+ displayId, componentName, userId, intentSender);
}
}
} finally {
@@ -593,9 +595,10 @@ public class VirtualDeviceInternal {
}
public void onActivityLaunchBlocked(int displayId, ComponentName componentName,
- @UserIdInt int userId) {
+ @UserIdInt int userId, IntentSender intentSender) {
mExecutor.execute(() ->
- mActivityListener.onActivityLaunchBlocked(displayId, componentName, userId));
+ mActivityListener.onActivityLaunchBlocked(
+ displayId, componentName, userId, intentSender));
}
}
diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index 42da7e9e1815..8b60580ec114 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -43,6 +43,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.IntentSender;
import android.graphics.Point;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.VirtualDisplayFlag;
@@ -837,8 +838,15 @@ public final class VirtualDeviceManager {
* components.</p>
* <p>Any change to the exemptions will only be applied for new activity launches.</p>
*
+ * @param componentName the component name to be exempt from the activity launch policy.
+ * @param displayId the ID of the display, for which to apply the exemption. The display
+ * must belong to the virtual device.
+ * @throws IllegalArgumentException if the specified display does not belong to the virtual
+ * device.
+ *
* @see #removeActivityPolicyExemption
* @see #setDevicePolicy
+ * @see Display#getDisplayId
*/
@FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
@RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
@@ -861,8 +869,15 @@ public final class VirtualDeviceManager {
* <p>Note that changing the activity launch policy will clear current set of exempt
* components.</p>
*
+ * @param componentName the component name to be removed from the exemption list.
+ * @param displayId the ID of the display, for which to apply the exemption. The display
+ * must belong to the virtual device.
+ * @throws IllegalArgumentException if the specified display does not belong to the virtual
+ * device.
+ *
* @see #addActivityPolicyExemption
* @see #setDevicePolicy
+ * @see Display#getDisplayId
*/
@FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
@RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
@@ -1250,13 +1265,18 @@ public final class VirtualDeviceManager {
* @param displayId The display ID on which the activity tried to launch.
* @param componentName The component name of the blocked activity.
* @param userId The user ID associated with the blocked activity.
+ * @param intentSender The original sender of the intent. May be {@code null} if the sender
+ * expects an activity result to be reported. In that case
+ * {@link android.app.Activity#RESULT_CANCELED} was already reported back because the
+ * launch was blocked. This {@link IntentSender} can be used to relaunch the blocked
+ * activity to a different display.
*
* @see VirtualDeviceParams#POLICY_TYPE_ACTIVITY
* @see VirtualDevice#addActivityPolicyExemption(ComponentName)
*/
@FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
default void onActivityLaunchBlocked(int displayId, @NonNull ComponentName componentName,
- @UserIdInt int userId) {}
+ @UserIdInt int userId, @Nullable IntentSender intentSender) {}
}
/**
diff --git a/core/java/android/companion/virtual/flags.aconfig b/core/java/android/companion/virtual/flags.aconfig
index b29b52d67310..91586b6bfae2 100644
--- a/core/java/android/companion/virtual/flags.aconfig
+++ b/core/java/android/companion/virtual/flags.aconfig
@@ -81,13 +81,6 @@ flag {
}
flag {
- name: "stream_permissions"
- namespace: "virtual_devices"
- description: "Enable streaming permission dialogs to Virtual Devices"
- bug: "291737919"
-}
-
-flag {
name: "persistent_device_id_api"
is_exported: true
namespace: "virtual_devices"
@@ -96,13 +89,6 @@ flag {
}
flag {
- name: "express_metrics"
- namespace: "virtual_devices"
- description: "Enable express metrics in VDM"
- bug: "307297730"
-}
-
-flag {
name: "interactive_screen_mirror"
is_exported: true
namespace: "virtual_devices"
@@ -119,17 +105,6 @@ flag {
}
flag {
- name: "intercept_intents_before_applying_policy"
- is_exported: true
- namespace: "virtual_devices"
- description: "Apply intent interception before applying activity policy"
- bug: "333444131"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
name: "impulse_velocity_strategy_for_touch_navigation"
is_exported: true
namespace: "virtual_devices"
diff --git a/core/java/android/companion/virtual/flags/flags.aconfig b/core/java/android/companion/virtual/flags/flags.aconfig
index a1ae9da636d5..c3c3f0ef32e1 100644
--- a/core/java/android/companion/virtual/flags/flags.aconfig
+++ b/core/java/android/companion/virtual/flags/flags.aconfig
@@ -47,14 +47,6 @@ flag {
flag {
namespace: "virtual_devices"
- name: "metrics_collection"
- description: "Enable collection of VDM-related metrics"
- bug: "324842215"
- is_fixed_read_only: true
-}
-
-flag {
- namespace: "virtual_devices"
name: "activity_control_api"
description: "Enable APIs for fine grained activity policy, fallback and callbacks"
bug: "333443509"
@@ -92,27 +84,6 @@ flag {
flag {
namespace: "virtual_devices"
- name: "virtual_display_multi_window_mode_support"
- description: "Add support for WINDOWING_MODE_MULTI_WINDOW to virtual displays by default"
- is_fixed_read_only: true
- bug: "341151395"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
- namespace: "virtual_devices"
- name: "intent_interception_action_matching_fix"
- description: "Do not match intents without actions if the filter has actions"
- bug: "343805037"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
- namespace: "virtual_devices"
name: "virtual_display_rotation_api"
description: "API for on-demand rotation of virtual displays"
bug: "291748430"
diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java
index d7195a76d873..964a8be0f153 100644
--- a/core/java/android/content/BroadcastReceiver.java
+++ b/core/java/android/content/BroadcastReceiver.java
@@ -34,6 +34,8 @@ import android.os.UserHandle;
import android.util.Log;
import android.util.Slog;
+import com.android.internal.os.DebugStore;
+
/**
* Base class for code that receives and handles broadcast intents sent by
* {@link android.content.Context#sendBroadcast(Intent)}.
@@ -55,6 +57,9 @@ public abstract class BroadcastReceiver {
private PendingResult mPendingResult;
private boolean mDebugUnregister;
+ private static final boolean DEBUG_STORE_ENABLED =
+ com.android.internal.os.Flags.debugStoreEnabled();
+
/**
* State for a result that is pending for a broadcast receiver. Returned
* by {@link BroadcastReceiver#goAsync() goAsync()}
@@ -255,6 +260,9 @@ public abstract class BroadcastReceiver {
"PendingResult#finish#ClassName:" + mReceiverClassName,
1);
}
+ if (DEBUG_STORE_ENABLED) {
+ DebugStore.recordFinish(mReceiverClassName);
+ }
if (mType == TYPE_COMPONENT) {
final IActivityManager mgr = ActivityManager.getService();
@@ -433,7 +441,9 @@ public abstract class BroadcastReceiver {
public final PendingResult goAsync() {
PendingResult res = mPendingResult;
mPendingResult = null;
-
+ if (DEBUG_STORE_ENABLED) {
+ DebugStore.recordGoAsync(getClass().getName());
+ }
if (res != null && Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
res.mReceiverClassName = getClass().getName();
Trace.traceCounter(Trace.TRACE_TAG_ACTIVITY_MANAGER,
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
index d9b0e6dd2681..7c2edd7bbc17 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -237,6 +237,8 @@ flag {
bug: "307327678"
}
+# This flag is enabled since V but not a MUST requirement in CDD yet, so it needs to stay around
+# for now and any code working with it should keep checking the flag.
flag {
name: "restrict_nonpreloads_system_shareduids"
namespace: "package_manager_service"
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig
index 77f2323884ca..835459e09ca2 100644
--- a/core/java/android/content/pm/multiuser.aconfig
+++ b/core/java/android/content/pm/multiuser.aconfig
@@ -379,3 +379,10 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "unicorn_mode_refactoring_for_hsum"
+ namespace: "multiuser"
+ description: "Refactorings related to unicorn mode to work on HSUM mode"
+ bug: "339201286"
+}
diff --git a/core/java/android/hardware/input/InputSettings.java b/core/java/android/hardware/input/InputSettings.java
index bec1c9ef8059..d85e41d19c68 100644
--- a/core/java/android/hardware/input/InputSettings.java
+++ b/core/java/android/hardware/input/InputSettings.java
@@ -25,6 +25,7 @@ import static com.android.hardware.input.Flags.keyboardA11ySlowKeysFlag;
import static com.android.hardware.input.Flags.keyboardA11yStickyKeysFlag;
import static com.android.hardware.input.Flags.keyboardA11yMouseKeys;
import static com.android.hardware.input.Flags.touchpadTapDragging;
+import static com.android.hardware.input.Flags.touchpadVisualizer;
import static com.android.input.flags.Flags.enableInputFilterRustImpl;
import android.Manifest;
@@ -326,6 +327,15 @@ public class InputSettings {
}
/**
+ * Returns true if the feature flag for touchpad visualizer is enabled.
+ *
+ * @hide
+ */
+ public static boolean isTouchpadVisualizerFeatureFlagEnabled() {
+ return touchpadVisualizer();
+ }
+
+ /**
* Returns true if the touchpad should allow tap dragging.
*
* The returned value only applies to gesture-compatible touchpads.
diff --git a/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java b/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
index 72b5cf79133d..da2eec9cbb28 100644
--- a/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
+++ b/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
@@ -20,6 +20,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.TestApi;
import android.os.Handler;
+import android.os.Looper;
import android.os.Trace;
import android.util.Log;
import android.util.Printer;
@@ -214,7 +215,7 @@ public final class MessageQueue {
private volatile long mNextInsertSeqValue = 0;
/*
* The exception to the FIFO order rule is sendMessageAtFrontOfQueue().
- * Those messages must be in LIFO order - SIGH.
+ * Those messages must be in LIFO order.
* Decrements on each front of queue insert.
*/
private static final VarHandle sNextFrontInsertSeq;
@@ -535,6 +536,7 @@ public final class MessageQueue {
/* This is only read/written from the Looper thread */
private int mNextPollTimeoutMillis;
private static final AtomicLong mMessagesDelivered = new AtomicLong();
+ private boolean mMessageDirectlyQueued;
private Message nextMessage() {
int i = 0;
@@ -729,6 +731,7 @@ public final class MessageQueue {
Binder.flushPendingCommands();
}
+ mMessageDirectlyQueued = false;
nativePollOnce(ptr, mNextPollTimeoutMillis);
Message msg = nextMessage();
@@ -841,6 +844,22 @@ public final class MessageQueue {
+ node.isAsync() + " now: " + SystemClock.uptimeMillis());
}
+ final Looper myLooper = Looper.myLooper();
+ /* If we are running on the looper thread we can add directly to the priority queue */
+ if (myLooper != null && myLooper.getQueue() == this) {
+ node.removeFromStack();
+ insertIntoPriorityQueue(node);
+ /*
+ * We still need to do this even though we are the current thread,
+ * otherwise next() may sleep indefinitely.
+ */
+ if (!mMessageDirectlyQueued) {
+ mMessageDirectlyQueued = true;
+ nativeWake(mPtr);
+ }
+ return true;
+ }
+
while (true) {
StackNode old = (StackNode) sState.getVolatile(this);
boolean wakeNeeded;
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index e6b1c07846f9..14005b31903a 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -54,7 +54,6 @@ import android.provider.DocumentsContract.Document;
import android.provider.MediaStore;
import android.system.ErrnoException;
import android.system.Os;
-import android.system.OsConstants;
import android.system.StructStat;
import android.text.TextUtils;
import android.util.DataUnit;
@@ -1535,7 +1534,6 @@ public final class FileUtils {
}
/** {@hide} */
- @android.ravenwood.annotation.RavenwoodThrow(blockedBy = OsConstants.class)
public static int translateModeStringToPosix(String mode) {
// Quick check for invalid chars
for (int i = 0; i < mode.length(); i++) {
@@ -1570,7 +1568,6 @@ public final class FileUtils {
}
/** {@hide} */
- @android.ravenwood.annotation.RavenwoodThrow(blockedBy = OsConstants.class)
public static String translateModePosixToString(int mode) {
String res = "";
if ((mode & O_ACCMODE) == O_RDWR) {
@@ -1592,7 +1589,6 @@ public final class FileUtils {
}
/** {@hide} */
- @android.ravenwood.annotation.RavenwoodThrow(blockedBy = OsConstants.class)
public static int translateModePosixToPfd(int mode) {
int res = 0;
if ((mode & O_ACCMODE) == O_RDWR) {
@@ -1617,7 +1613,6 @@ public final class FileUtils {
}
/** {@hide} */
- @android.ravenwood.annotation.RavenwoodThrow(blockedBy = OsConstants.class)
public static int translateModePfdToPosix(int mode) {
int res = 0;
if ((mode & MODE_READ_WRITE) == MODE_READ_WRITE) {
@@ -1642,7 +1637,6 @@ public final class FileUtils {
}
/** {@hide} */
- @android.ravenwood.annotation.RavenwoodThrow(blockedBy = OsConstants.class)
public static int translateModeAccessToPosix(int mode) {
if (mode == F_OK) {
// There's not an exact mapping, so we attempt a read-only open to
diff --git a/core/java/android/os/LockedMessageQueue/MessageQueue.java b/core/java/android/os/LockedMessageQueue/MessageQueue.java
new file mode 100644
index 000000000000..b24e14b0419e
--- /dev/null
+++ b/core/java/android/os/LockedMessageQueue/MessageQueue.java
@@ -0,0 +1,1351 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Handler;
+import android.os.Trace;
+import android.util.Log;
+import android.util.Printer;
+import android.util.SparseArray;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.io.FileDescriptor;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Low-level class holding the list of messages to be dispatched by a
+ * {@link Looper}. Messages are not added directly to a MessageQueue,
+ * but rather through {@link Handler} objects associated with the Looper.
+ *
+ * <p>You can retrieve the MessageQueue for the current thread with
+ * {@link Looper#myQueue() Looper.myQueue()}.
+ */
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
+@android.ravenwood.annotation.RavenwoodNativeSubstitutionClass(
+ "com.android.platform.test.ravenwood.nativesubstitution.MessageQueue_host")
+public final class MessageQueue {
+ private static final String TAG = "LockedMessageQueue";
+ private static final boolean DEBUG = false;
+ private static final boolean TRACE = false;
+
+ static final class MessageHeap {
+ static final int MESSAGE_HEAP_INITIAL_SIZE = 16;
+
+ Message[] mHeap = new Message[MESSAGE_HEAP_INITIAL_SIZE];
+ int mNumElements = 0;
+
+ static int parentNodeIdx(int i) {
+ return (i - 1) >>> 1;
+ }
+
+ Message getParentNode(int i) {
+ return mHeap[(i - 1) >>> 1];
+ }
+
+ static int rightNodeIdx(int i) {
+ return 2 * i + 2;
+ }
+
+ Message getRightNode(int i) {
+ return mHeap[2 * i + 2];
+ }
+
+ static int leftNodeIdx(int i) {
+ return 2 * i + 1;
+ }
+
+ Message getLeftNode(int i) {
+ return mHeap[2 * i + 1];
+ }
+
+ int size() {
+ return mHeap.length;
+ }
+
+ int numElements() {
+ return mNumElements;
+ }
+
+ boolean isEmpty() {
+ return mNumElements == 0;
+ }
+
+ Message getMessageAt(int index) {
+ return mHeap[index];
+ }
+
+ /*
+ * Returns:
+ * 0 if x==y.
+ * A value less than 0 if x<y.
+ * A value greater than 0 if x>y.
+ */
+ int compareMessage(Message x, Message y) {
+ int compared = Long.compare(x.when, y.when);
+ if (compared == 0) {
+ compared = Long.compare(x.mInsertSeq, y.mInsertSeq);
+ }
+ return compared;
+ }
+
+ int compareMessageByIdx(int x, int y) {
+ return compareMessage(mHeap[x], mHeap[y]);
+ }
+
+ void swap(int x, int y) {
+ Message tmp = mHeap[x];
+ mHeap[x] = mHeap[y];
+ mHeap[y] = tmp;
+ }
+
+ void siftDown(int i) {
+ int smallest = i;
+ int r, l;
+
+ while (true) {
+ r = rightNodeIdx(i);
+ l = leftNodeIdx(i);
+
+ if (r < mNumElements && compareMessageByIdx(r, smallest) < 0) {
+ smallest = r;
+ }
+
+ if (l < mNumElements && compareMessageByIdx(l, smallest) < 0) {
+ smallest = l;
+ }
+
+ if (smallest != i) {
+ swap(i, smallest);
+ i = smallest;
+ continue;
+ }
+ break;
+ }
+ }
+
+ boolean siftUp(int i) {
+ boolean swapped = false;
+ while (i != 0 && compareMessage(mHeap[i], getParentNode(i)) < 0) {
+ int p = parentNodeIdx(i);
+
+ swap(i, p);
+ swapped = true;
+ i = p;
+ }
+
+ return swapped;
+ }
+
+ void maybeGrowHeap() {
+ if (mNumElements == mHeap.length) {
+ /* Grow by 1.5x */
+ int newSize = mHeap.length + (mHeap.length >>> 1);
+ Message[] newHeap;
+ if (DEBUG) {
+ Log.v(TAG, "maybeGrowHeap mNumElements " + mNumElements + " mHeap.length "
+ + mHeap.length + " newSize " + newSize);
+ }
+
+ newHeap = Arrays.copyOf(mHeap, newSize);
+ mHeap = newHeap;
+ }
+ }
+
+ void add(Message m) {
+ int i;
+
+ maybeGrowHeap();
+
+ i = mNumElements;
+ mNumElements++;
+ mHeap[i] = m;
+
+ siftUp(i);
+ }
+
+ void maybeShrinkHeap() {
+ /* Shrink by 2x */
+ int newSize = mHeap.length >>> 1;
+
+ if (newSize >= MESSAGE_HEAP_INITIAL_SIZE
+ && mNumElements <= newSize) {
+ Message[] newHeap;
+
+ if (DEBUG) {
+ Log.v(TAG, "maybeShrinkHeap mNumElements " + mNumElements + " mHeap.length "
+ + mHeap.length + " newSize " + newSize);
+ }
+
+ newHeap = Arrays.copyOf(mHeap, newSize);
+ mHeap = newHeap;
+ }
+ }
+
+ Message poll() {
+ if (mNumElements > 0) {
+ Message ret = mHeap[0];
+ mNumElements--;
+ mHeap[0] = mHeap[mNumElements];
+ mHeap[mNumElements] = null;
+
+ siftDown(0);
+
+ maybeShrinkHeap();
+ return ret;
+ }
+ return null;
+ }
+
+ Message peek() {
+ if (mNumElements > 0) {
+ return mHeap[0];
+ }
+ return null;
+ }
+
+ private void remove(int i) throws IllegalArgumentException {
+ if (i > mNumElements || mNumElements == 0) {
+ throw new IllegalArgumentException("Index " + i + " out of bounds: "
+ + mNumElements);
+ } else if (i == (mNumElements - 1)) {
+ mHeap[i] = null;
+ mNumElements--;
+ } else {
+ mNumElements--;
+ mHeap[i] = mHeap[mNumElements];
+ mHeap[mNumElements] = null;
+ if (!siftUp(i)) {
+ siftDown(i);
+ }
+ }
+ /* Don't shink here, let the caller do this once it has removed all matching items. */
+ }
+
+ void removeAll() {
+ Message m;
+ for (int i = 0; i < mNumElements; i++) {
+ m = mHeap[i];
+ mHeap[i] = null;
+ m.recycleUnchecked();
+ }
+ mNumElements = 0;
+ maybeShrinkHeap();
+ }
+
+ abstract static class MessageHeapCompare {
+ public abstract boolean compareMessage(Message m, Handler h, int what, Object object,
+ Runnable r, long when);
+ }
+
+ boolean findOrRemoveMessages(Handler h, int what, Object object, Runnable r, long when,
+ MessageHeapCompare compare, boolean removeMatches) {
+ boolean found = false;
+ /*
+ * Walk the heap backwards so we don't have to re-visit an array element due to
+ * sifting
+ */
+ for (int i = mNumElements - 1; i >= 0; i--) {
+ if (compare.compareMessage(mHeap[i], h, what, object, r, when)) {
+ found = true;
+ if (removeMatches) {
+ Message m = mHeap[i];
+ try {
+ remove(i);
+ } catch (IllegalArgumentException e) {
+ Log.wtf(TAG, "Index out of bounds during remove " + e);
+ }
+ m.recycleUnchecked();
+ continue;
+ }
+ break;
+ }
+ }
+ if (found && removeMatches) {
+ maybeShrinkHeap();
+ }
+ return found;
+ }
+
+ /*
+ * Keep this for manual debugging. It's easier to pepper the code with this function
+ * than MessageQueue.dump()
+ */
+ void print() {
+ Log.v(TAG, "heap num elem: " + mNumElements + " mHeap.length " + mHeap.length);
+ for (int i = 0; i < mNumElements; i++) {
+ Log.v(TAG, "[" + i + "]\t" + mHeap[i] + " seq: " + mHeap[i].mInsertSeq + " async: "
+ + mHeap[i].isAsynchronous());
+ }
+ }
+
+ boolean verify(int root) {
+ int r = rightNodeIdx(root);
+ int l = leftNodeIdx(root);
+
+ if (l >= mNumElements && r >= mNumElements) {
+ return true;
+ }
+
+ if (l < mNumElements && compareMessageByIdx(l, root) < 0) {
+ Log.wtf(TAG, "Verify failure: root idx/when: " + root + "/" + mHeap[root].when
+ + " left node idx/when: " + l + "/" + mHeap[l].when);
+ return false;
+ }
+
+ if (r < mNumElements && compareMessageByIdx(r, root) < 0) {
+ Log.wtf(TAG, "Verify failure: root idx/when: " + root + "/" + mHeap[root].when
+ + " right node idx/when: " + r + "/" + mHeap[r].when);
+ return false;
+ }
+
+ if (!verify(r) || !verify(l)) {
+ return false;
+ }
+ return true;
+ }
+
+ boolean checkDanglingReferences(String where) {
+ /* First, let's make sure we didn't leave any dangling references */
+ for (int i = mNumElements; i < mHeap.length; i++) {
+ if (mHeap[i] != null) {
+ Log.wtf(TAG, "[" + where
+ + "] Verify failure: dangling reference found at index "
+ + i + ": " + mHeap[i] + " Async " + mHeap[i].isAsynchronous()
+ + " mNumElements " + mNumElements + " mHeap.length " + mHeap.length);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ boolean verify() {
+ if (!checkDanglingReferences(TAG)) {
+ return false;
+ }
+ return verify(0);
+ }
+ }
+
+ // True if the message queue can be quit.
+ @UnsupportedAppUsage
+ private final boolean mQuitAllowed;
+
+ @UnsupportedAppUsage
+ @SuppressWarnings("unused")
+ private long mPtr; // used by native code
+
+ private final MessageHeap mPriorityQueue = new MessageHeap();
+ private final MessageHeap mAsyncPriorityQueue = new MessageHeap();
+
+ /*
+ * This helps us ensure that messages with the same timestamp are inserted in FIFO order.
+ * Increments on each insert, starting at 0. MessaeHeap.compareMessage() will compare sequences
+ * when delivery timestamps are identical.
+ */
+ private long mNextInsertSeq;
+
+ /*
+ * The exception to the FIFO order rule is sendMessageAtFrontOfQueue().
+ * Those messages must be in LIFO order.
+ * Decrements on each front of queue insert.
+ */
+ private long mNextFrontInsertSeq = -1;
+
+ @UnsupportedAppUsage
+ private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>();
+ private SparseArray<FileDescriptorRecord> mFileDescriptorRecords;
+ private IdleHandler[] mPendingIdleHandlers;
+ private boolean mQuitting;
+
+ // Indicates whether next() is blocked waiting in pollOnce() with a non-zero timeout.
+ private boolean mBlocked;
+
+ // The next barrier token.
+ // Barriers are indicated by messages with a null target whose arg1 field carries the token.
+ @UnsupportedAppUsage
+ private int mNextBarrierToken;
+
+ private native static long nativeInit();
+ private native static void nativeDestroy(long ptr);
+ @UnsupportedAppUsage
+ private native void nativePollOnce(long ptr, int timeoutMillis); /*non-static for callbacks*/
+ private native static void nativeWake(long ptr);
+ private native static boolean nativeIsPolling(long ptr);
+ private native static void nativeSetFileDescriptorEvents(long ptr, int fd, int events);
+
+ MessageQueue(boolean quitAllowed) {
+ mQuitAllowed = quitAllowed;
+ mPtr = nativeInit();
+ }
+
+ @GuardedBy("this")
+ private void removeRootFromPriorityQueue(Message msg) {
+ Message tmp;
+ if (msg.isAsynchronous()) {
+ tmp = mAsyncPriorityQueue.poll();
+ } else {
+ tmp = mPriorityQueue.poll();
+ }
+ if (DEBUG && tmp != msg) {
+ Log.wtf(TAG, "Unexpected message at head of heap. Wanted: " + msg + " msg.isAsync "
+ + msg.isAsynchronous() + " Found: " + tmp);
+
+ mPriorityQueue.print();
+ mAsyncPriorityQueue.print();
+ }
+ }
+
+ @GuardedBy("this")
+ private Message pickEarliestMessage(Message x, Message y) {
+ if (x != null && y != null) {
+ if (mPriorityQueue.compareMessage(x, y) < 0) {
+ return x;
+ }
+ return y;
+ }
+
+ return x != null ? x : y;
+ }
+
+ @GuardedBy("this")
+ private Message peekEarliestMessage() {
+ Message x = mPriorityQueue.peek();
+ Message y = mAsyncPriorityQueue.peek();
+
+ return pickEarliestMessage(x, y);
+ }
+
+ @GuardedBy("this")
+ private boolean priorityQueuesAreEmpty() {
+ return mPriorityQueue.isEmpty() && mAsyncPriorityQueue.isEmpty();
+ }
+
+ @GuardedBy("this")
+ private boolean priorityQueueHasBarrier() {
+ Message m = mPriorityQueue.peek();
+
+ if (m != null && m.target == null) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ dispose();
+ } finally {
+ super.finalize();
+ }
+ }
+
+ // Disposes of the underlying message queue.
+ // Must only be called on the looper thread or the finalizer.
+ private void dispose() {
+ if (mPtr != 0) {
+ nativeDestroy(mPtr);
+ mPtr = 0;
+ }
+ }
+
+ /**
+ * Returns true if the looper has no pending messages which are due to be processed.
+ *
+ * <p>This method is safe to call from any thread.
+ *
+ * @return True if the looper is idle.
+ */
+ public boolean isIdle() {
+ synchronized (this) {
+ Message m = peekEarliestMessage();
+ final long now = SystemClock.uptimeMillis();
+
+ return (priorityQueuesAreEmpty() || now < m.when);
+ }
+ }
+
+ /**
+ * Add a new {@link IdleHandler} to this message queue. This may be
+ * removed automatically for you by returning false from
+ * {@link IdleHandler#queueIdle IdleHandler.queueIdle()} when it is
+ * invoked, or explicitly removing it with {@link #removeIdleHandler}.
+ *
+ * <p>This method is safe to call from any thread.
+ *
+ * @param handler The IdleHandler to be added.
+ */
+ public void addIdleHandler(@NonNull IdleHandler handler) {
+ if (handler == null) {
+ throw new NullPointerException("Can't add a null IdleHandler");
+ }
+ synchronized (this) {
+ mIdleHandlers.add(handler);
+ }
+ }
+
+ /**
+ * Remove an {@link IdleHandler} from the queue that was previously added
+ * with {@link #addIdleHandler}. If the given object is not currently
+ * in the idle list, nothing is done.
+ *
+ * <p>This method is safe to call from any thread.
+ *
+ * @param handler The IdleHandler to be removed.
+ */
+ public void removeIdleHandler(@NonNull IdleHandler handler) {
+ synchronized (this) {
+ mIdleHandlers.remove(handler);
+ }
+ }
+
+ /**
+ * Returns whether this looper's thread is currently polling for more work to do.
+ * This is a good signal that the loop is still alive rather than being stuck
+ * handling a callback. Note that this method is intrinsically racy, since the
+ * state of the loop can change before you get the result back.
+ *
+ * <p>This method is safe to call from any thread.
+ *
+ * @return True if the looper is currently polling for events.
+ * @hide
+ */
+ public boolean isPolling() {
+ synchronized (this) {
+ return isPollingLocked();
+ }
+ }
+
+ private boolean isPollingLocked() {
+ // If the loop is quitting then it must not be idling.
+ // We can assume mPtr != 0 when mQuitting is false.
+ return !mQuitting && nativeIsPolling(mPtr);
+ }
+
+ /**
+ * Adds a file descriptor listener to receive notification when file descriptor
+ * related events occur.
+ * <p>
+ * If the file descriptor has already been registered, the specified events
+ * and listener will replace any that were previously associated with it.
+ * It is not possible to set more than one listener per file descriptor.
+ * </p><p>
+ * It is important to always unregister the listener when the file descriptor
+ * is no longer of use.
+ * </p>
+ *
+ * @param fd The file descriptor for which a listener will be registered.
+ * @param events The set of events to receive: a combination of the
+ * {@link OnFileDescriptorEventListener#EVENT_INPUT},
+ * {@link OnFileDescriptorEventListener#EVENT_OUTPUT}, and
+ * {@link OnFileDescriptorEventListener#EVENT_ERROR} event masks. If the requested
+ * set of events is zero, then the listener is unregistered.
+ * @param listener The listener to invoke when file descriptor events occur.
+ *
+ * @see OnFileDescriptorEventListener
+ * @see #removeOnFileDescriptorEventListener
+ */
+ @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+ public void addOnFileDescriptorEventListener(@NonNull FileDescriptor fd,
+ @OnFileDescriptorEventListener.Events int events,
+ @NonNull OnFileDescriptorEventListener listener) {
+ if (fd == null) {
+ throw new IllegalArgumentException("fd must not be null");
+ }
+ if (listener == null) {
+ throw new IllegalArgumentException("listener must not be null");
+ }
+
+ synchronized (this) {
+ updateOnFileDescriptorEventListenerLocked(fd, events, listener);
+ }
+ }
+
+ /**
+ * Removes a file descriptor listener.
+ * <p>
+ * This method does nothing if no listener has been registered for the
+ * specified file descriptor.
+ * </p>
+ *
+ * @param fd The file descriptor whose listener will be unregistered.
+ *
+ * @see OnFileDescriptorEventListener
+ * @see #addOnFileDescriptorEventListener
+ */
+ @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+ public void removeOnFileDescriptorEventListener(@NonNull FileDescriptor fd) {
+ if (fd == null) {
+ throw new IllegalArgumentException("fd must not be null");
+ }
+
+ synchronized (this) {
+ updateOnFileDescriptorEventListenerLocked(fd, 0, null);
+ }
+ }
+
+ @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+ private void updateOnFileDescriptorEventListenerLocked(FileDescriptor fd, int events,
+ OnFileDescriptorEventListener listener) {
+ final int fdNum = fd.getInt$();
+
+ int index = -1;
+ FileDescriptorRecord record = null;
+ if (mFileDescriptorRecords != null) {
+ index = mFileDescriptorRecords.indexOfKey(fdNum);
+ if (index >= 0) {
+ record = mFileDescriptorRecords.valueAt(index);
+ if (record != null && record.mEvents == events) {
+ return;
+ }
+ }
+ }
+
+ if (events != 0) {
+ events |= OnFileDescriptorEventListener.EVENT_ERROR;
+ if (record == null) {
+ if (mFileDescriptorRecords == null) {
+ mFileDescriptorRecords = new SparseArray<FileDescriptorRecord>();
+ }
+ record = new FileDescriptorRecord(fd, events, listener);
+ mFileDescriptorRecords.put(fdNum, record);
+ } else {
+ record.mListener = listener;
+ record.mEvents = events;
+ record.mSeq += 1;
+ }
+ nativeSetFileDescriptorEvents(mPtr, fdNum, events);
+ } else if (record != null) {
+ record.mEvents = 0;
+ mFileDescriptorRecords.removeAt(index);
+ nativeSetFileDescriptorEvents(mPtr, fdNum, 0);
+ }
+ }
+
+ // Called from native code.
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ private int dispatchEvents(int fd, int events) {
+ // Get the file descriptor record and any state that might change.
+ final FileDescriptorRecord record;
+ final int oldWatchedEvents;
+ final OnFileDescriptorEventListener listener;
+ final int seq;
+ synchronized (this) {
+ record = mFileDescriptorRecords.get(fd);
+ if (record == null) {
+ return 0; // spurious, no listener registered
+ }
+
+ oldWatchedEvents = record.mEvents;
+ events &= oldWatchedEvents; // filter events based on current watched set
+ if (events == 0) {
+ return oldWatchedEvents; // spurious, watched events changed
+ }
+
+ listener = record.mListener;
+ seq = record.mSeq;
+ }
+
+ // Invoke the listener outside of the lock.
+ int newWatchedEvents = listener.onFileDescriptorEvents(
+ record.mDescriptor, events);
+ if (newWatchedEvents != 0) {
+ newWatchedEvents |= OnFileDescriptorEventListener.EVENT_ERROR;
+ }
+
+ // Update the file descriptor record if the listener changed the set of
+ // events to watch and the listener itself hasn't been updated since.
+ if (newWatchedEvents != oldWatchedEvents) {
+ synchronized (this) {
+ int index = mFileDescriptorRecords.indexOfKey(fd);
+ if (index >= 0 && mFileDescriptorRecords.valueAt(index) == record
+ && record.mSeq == seq) {
+ record.mEvents = newWatchedEvents;
+ if (newWatchedEvents == 0) {
+ mFileDescriptorRecords.removeAt(index);
+ }
+ }
+ }
+ }
+
+ // Return the new set of events to watch for native code to take care of.
+ return newWatchedEvents;
+ }
+
+ private static final AtomicLong mMessagesDelivered = new AtomicLong();
+
+ @UnsupportedAppUsage
+ Message next() {
+ // Return here if the message loop has already quit and been disposed.
+ // This can happen if the application tries to restart a looper after quit
+ // which is not supported.
+ final long ptr = mPtr;
+ if (ptr == 0) {
+ return null;
+ }
+
+ int pendingIdleHandlerCount = -1; // -1 only during first iteration
+ int nextPollTimeoutMillis = 0;
+ for (;;) {
+ if (nextPollTimeoutMillis != 0) {
+ Binder.flushPendingCommands();
+ }
+
+ nativePollOnce(ptr, nextPollTimeoutMillis);
+
+ synchronized (this) {
+ // Try to retrieve the next message. Return if found.
+ final long now = SystemClock.uptimeMillis();
+ Message prevMsg = null;
+ Message msg = peekEarliestMessage();
+
+ if (DEBUG && msg != null) {
+ Log.v(TAG, "Next found message " + msg + " isAsynchronous: "
+ + msg.isAsynchronous() + " target " + msg.target);
+ }
+
+ if (msg != null && !msg.isAsynchronous() && msg.target == null) {
+ // Stalled by a barrier. Find the next asynchronous message in the queue.
+ msg = mAsyncPriorityQueue.peek();
+ if (DEBUG) {
+ Log.v(TAG, "Next message was barrier async msg: " + msg);
+ }
+ }
+
+ if (msg != null) {
+ if (now < msg.when) {
+ // Next message is not ready. Set a timeout to wake up when it is ready.
+ nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
+ } else {
+ mBlocked = false;
+ removeRootFromPriorityQueue(msg);
+ if (DEBUG) Log.v(TAG, "Returning message: " + msg);
+ msg.markInUse();
+ if (TRACE) {
+ Trace.setCounter("MQ.Delivered", mMessagesDelivered.incrementAndGet());
+ }
+ return msg;
+ }
+ } else {
+ // No more messages.
+ nextPollTimeoutMillis = -1;
+ }
+
+ // Process the quit message now that all pending messages have been handled.
+ if (mQuitting) {
+ dispose();
+ return null;
+ }
+
+ // If first time idle, then get the number of idlers to run.
+ // Idle handles only run if the queue is empty or if the first message
+ // in the queue (possibly a barrier) is due to be handled in the future.
+ Message next = peekEarliestMessage();
+ if (pendingIdleHandlerCount < 0
+ && (next == null || now < next.when)) {
+ pendingIdleHandlerCount = mIdleHandlers.size();
+ }
+ if (pendingIdleHandlerCount <= 0) {
+ // No idle handlers to run. Loop and wait some more.
+ mBlocked = true;
+ continue;
+ }
+
+ if (mPendingIdleHandlers == null) {
+ mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
+ }
+ mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
+ }
+
+ // Run the idle handlers.
+ // We only ever reach this code block during the first iteration.
+ for (int i = 0; i < pendingIdleHandlerCount; i++) {
+ final IdleHandler idler = mPendingIdleHandlers[i];
+ mPendingIdleHandlers[i] = null; // release the reference to the handler
+
+ boolean keep = false;
+ try {
+ keep = idler.queueIdle();
+ } catch (Throwable t) {
+ Log.wtf(TAG, "IdleHandler threw exception", t);
+ }
+
+ if (!keep) {
+ synchronized (this) {
+ mIdleHandlers.remove(idler);
+ }
+ }
+ }
+
+ // Reset the idle handler count to 0 so we do not run them again.
+ pendingIdleHandlerCount = 0;
+
+ // While calling an idle handler, a new message could have been delivered
+ // so go back and look again for a pending message without waiting.
+ nextPollTimeoutMillis = 0;
+ }
+ }
+
+ void quit(boolean safe) {
+ if (!mQuitAllowed) {
+ throw new IllegalStateException("Main thread not allowed to quit.");
+ }
+
+ synchronized (this) {
+ if (mQuitting) {
+ return;
+ }
+ mQuitting = true;
+
+ if (safe) {
+ removeAllFutureMessagesLocked();
+ } else {
+ removeAllMessagesLocked();
+ }
+
+ // We can assume mPtr != 0 because mQuitting was previously false.
+ nativeWake(mPtr);
+ }
+ }
+
+ /**
+ * Posts a synchronization barrier to the Looper's message queue.
+ *
+ * Message processing occurs as usual until the message queue encounters the
+ * synchronization barrier that has been posted. When the barrier is encountered,
+ * later synchronous messages in the queue are stalled (prevented from being executed)
+ * until the barrier is released by calling {@link #removeSyncBarrier} and specifying
+ * the token that identifies the synchronization barrier.
+ *
+ * This method is used to immediately postpone execution of all subsequently posted
+ * synchronous messages until a condition is met that releases the barrier.
+ * Asynchronous messages (see {@link Message#isAsynchronous} are exempt from the barrier
+ * and continue to be processed as usual.
+ *
+ * This call must be always matched by a call to {@link #removeSyncBarrier} with
+ * the same token to ensure that the message queue resumes normal operation.
+ * Otherwise the application will probably hang!
+ *
+ * @return A token that uniquely identifies the barrier. This token must be
+ * passed to {@link #removeSyncBarrier} to release the barrier.
+ *
+ * @hide
+ */
+ @UnsupportedAppUsage
+ @TestApi
+ public int postSyncBarrier() {
+ return postSyncBarrier(SystemClock.uptimeMillis());
+ }
+
+ private int postSyncBarrier(long when) {
+ // Enqueue a new sync barrier token.
+ // We don't need to wake the queue because the purpose of a barrier is to stall it.
+ synchronized (this) {
+ final int token = mNextBarrierToken++;
+ final Message msg = Message.obtain();
+ msg.arg1 = token;
+
+ enqueueMessageUnchecked(msg, when);
+ return token;
+ }
+ }
+
+ private class MatchBarrierToken extends MessageHeap.MessageHeapCompare {
+ int mBarrierToken;
+
+ MatchBarrierToken(int token) {
+ super();
+ mBarrierToken = token;
+ }
+
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == null && m.arg1 == mBarrierToken) {
+ return true;
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Removes a synchronization barrier.
+ *
+ * @param token The synchronization barrier token that was returned by
+ * {@link #postSyncBarrier}.
+ *
+ * @throws IllegalStateException if the barrier was not found.
+ *
+ * @hide
+ */
+ @UnsupportedAppUsage
+ @TestApi
+ public void removeSyncBarrier(int token) {
+ final MatchBarrierToken matchBarrierToken = new MatchBarrierToken(token);
+
+ // Remove a sync barrier token from the queue.
+ // If the queue is no longer stalled by a barrier then wake it.
+ synchronized (this) {
+ boolean removed;
+ Message first = mPriorityQueue.peek();
+
+ removed = mPriorityQueue.findOrRemoveMessages(null, 0, null, null, 0,
+ matchBarrierToken, true);
+ if (removed && first != null) {
+ // If the loop is quitting then it is already awake.
+ // We can assume mPtr != 0 when mQuitting is false.
+ if (first.target == null && first.arg1 == token && !mQuitting) {
+ nativeWake(mPtr);
+ }
+ } else if (!removed) {
+ throw new IllegalStateException("The specified message queue synchronization "
+ + " barrier token has not been posted or has already been removed.");
+ }
+ }
+ }
+
+ boolean enqueueMessage(Message msg, long when) {
+ if (msg.target == null) {
+ throw new IllegalArgumentException("Message must have a target.");
+ }
+
+ return enqueueMessageUnchecked(msg, when);
+ }
+
+ boolean enqueueMessageUnchecked(Message msg, long when) {
+ synchronized (this) {
+ if (mQuitting) {
+ IllegalStateException e = new IllegalStateException(
+ msg.target + " sending message to a Handler on a dead thread");
+ Log.w(TAG, e.getMessage(), e);
+ msg.recycle();
+ return false;
+ }
+
+ if (msg.isInUse()) {
+ throw new IllegalStateException(msg + " This message is already in use.");
+ }
+
+ msg.markInUse();
+ msg.when = when;
+ msg.mInsertSeq = when != 0 ? mNextInsertSeq++ : mNextFrontInsertSeq--;
+ if (DEBUG) Log.v(TAG, "Enqueue message: " + msg);
+ boolean needWake;
+ boolean isBarrier = msg.target == null;
+ Message first = peekEarliestMessage();
+
+ if (priorityQueuesAreEmpty() || when == 0 || when < first.when) {
+ needWake = mBlocked && !isBarrier;
+ } else {
+ Message firstNonAsyncMessage =
+ first.isAsynchronous() ? mPriorityQueue.peek() : first;
+
+ needWake = mBlocked && firstNonAsyncMessage != null
+ && firstNonAsyncMessage.target == null && msg.isAsynchronous();
+ }
+
+ if (msg.isAsynchronous()) {
+ mAsyncPriorityQueue.add(msg);
+ } else {
+ mPriorityQueue.add(msg);
+ }
+
+ // We can assume mPtr != 0 because mQuitting is false.
+ if (needWake) {
+ nativeWake(mPtr);
+ }
+ }
+ return true;
+ }
+
+ @GuardedBy("this")
+ boolean findOrRemoveMessages(Handler h, int what, Object object, Runnable r, long when,
+ MessageHeap.MessageHeapCompare compare, boolean removeMatches) {
+ boolean found = mPriorityQueue.findOrRemoveMessages(h, what, object, r, when, compare,
+ removeMatches);
+ boolean foundAsync = mAsyncPriorityQueue.findOrRemoveMessages(h, what, object, r, when,
+ compare, removeMatches);
+ return found || foundAsync;
+ }
+
+ private static class MatchHandlerWhatAndObject extends MessageHeap.MessageHeapCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h && m.what == what && (object == null || m.obj == object)) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private static final MatchHandlerWhatAndObject sMatchHandlerWhatAndObject =
+ new MatchHandlerWhatAndObject();
+
+ boolean hasMessages(Handler h, int what, Object object) {
+ if (h == null) {
+ return false;
+ }
+
+ synchronized (this) {
+ return findOrRemoveMessages(h, what, object, null, 0, sMatchHandlerWhatAndObject,
+ false);
+ }
+ }
+
+ private static class MatchHandlerWhatAndObjectEquals extends MessageHeap.MessageHeapCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h && m.what == what && (object == null || object.equals(m.obj))) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private static final MatchHandlerWhatAndObjectEquals sMatchHandlerWhatAndObjectEquals =
+ new MatchHandlerWhatAndObjectEquals();
+ boolean hasEqualMessages(Handler h, int what, Object object) {
+ if (h == null) {
+ return false;
+ }
+
+ synchronized (this) {
+ return findOrRemoveMessages(h, what, object, null, 0,
+ sMatchHandlerWhatAndObjectEquals, false);
+ }
+ }
+
+ private static class MatchHandlerRunnableAndObject extends MessageHeap.MessageHeapCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h && m.callback == r && (object == null || m.obj == object)) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private static final MatchHandlerRunnableAndObject sMatchHandlerRunnableAndObject =
+ new MatchHandlerRunnableAndObject();
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ boolean hasMessages(Handler h, Runnable r, Object object) {
+ if (h == null) {
+ return false;
+ }
+
+ synchronized (this) {
+ return findOrRemoveMessages(h, -1, object, r, 0, sMatchHandlerRunnableAndObject,
+ false);
+ }
+ }
+
+ private static class MatchHandler extends MessageHeap.MessageHeapCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private static final MatchHandler sMatchHandler = new MatchHandler();
+ boolean hasMessages(Handler h) {
+ if (h == null) {
+ return false;
+ }
+
+ synchronized (this) {
+ return findOrRemoveMessages(h, -1, null, null, 0, sMatchHandler, false);
+ }
+ }
+
+ void removeMessages(Handler h, int what, Object object) {
+ if (h == null) {
+ return;
+ }
+
+ synchronized (this) {
+ findOrRemoveMessages(h, what, object, null, 0, sMatchHandlerWhatAndObject, true);
+ }
+ }
+
+ void removeEqualMessages(Handler h, int what, Object object) {
+ if (h == null) {
+ return;
+ }
+
+ synchronized (this) {
+ findOrRemoveMessages(h, what, object, null, 0, sMatchHandlerWhatAndObjectEquals, true);
+ }
+ }
+
+ void removeMessages(Handler h, Runnable r, Object object) {
+ if (h == null || r == null) {
+ return;
+ }
+
+ synchronized (this) {
+ findOrRemoveMessages(h, -1, object, r, 0, sMatchHandlerRunnableAndObject, true);
+ }
+ }
+
+ private static class MatchHandlerRunnableAndObjectEquals
+ extends MessageHeap.MessageHeapCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h && m.callback == r && (object == null || object.equals(m.obj))) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private static final MatchHandlerRunnableAndObjectEquals sMatchHandlerRunnableAndObjectEquals =
+ new MatchHandlerRunnableAndObjectEquals();
+ void removeEqualMessages(Handler h, Runnable r, Object object) {
+ if (h == null || r == null) {
+ return;
+ }
+
+ synchronized (this) {
+ findOrRemoveMessages(h, -1, object, r, 0, sMatchHandlerRunnableAndObjectEquals, true);
+ }
+ }
+
+ private static class MatchHandlerAndObject extends MessageHeap.MessageHeapCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h && (object == null || m.obj == object)) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private static final MatchHandlerAndObject sMatchHandlerAndObject = new MatchHandlerAndObject();
+ void removeCallbacksAndMessages(Handler h, Object object) {
+ if (h == null) {
+ return;
+ }
+
+ synchronized (this) {
+ findOrRemoveMessages(h, -1, object, null, 0, sMatchHandlerAndObject, true);
+ }
+ }
+
+ private static class MatchHandlerAndObjectEquals extends MessageHeap.MessageHeapCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.target == h && (object == null || object.equals(m.obj))) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private static final MatchHandlerAndObjectEquals sMatchHandlerAndObjectEquals =
+ new MatchHandlerAndObjectEquals();
+ void removeCallbacksAndEqualMessages(Handler h, Object object) {
+ if (h == null) {
+ return;
+ }
+
+ synchronized (this) {
+ findOrRemoveMessages(h, -1, object, null, 0, sMatchHandlerAndObjectEquals, true);
+ }
+ }
+
+ @GuardedBy("this")
+ private void removeAllMessagesLocked() {
+ mPriorityQueue.removeAll();
+ mAsyncPriorityQueue.removeAll();
+ }
+
+ private static class MatchAllFutureMessages extends MessageHeap.MessageHeapCompare {
+ @Override
+ public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ long when) {
+ if (m.when > when) {
+ return true;
+ }
+ return false;
+ }
+ }
+ private static final MatchAllFutureMessages sMatchAllFutureMessages =
+ new MatchAllFutureMessages();
+ @GuardedBy("this")
+ private void removeAllFutureMessagesLocked() {
+ findOrRemoveMessages(null, -1, null, null, SystemClock.uptimeMillis(),
+ sMatchAllFutureMessages, true);
+ }
+
+ int dumpPriorityQueue(Printer pw, String prefix, Handler h, MessageHeap priorityQueue) {
+ int n = 0;
+ long now = SystemClock.uptimeMillis();
+ for (int i = 0; i < priorityQueue.numElements(); i++) {
+ Message m = priorityQueue.getMessageAt(i);
+ if (h == null && h == m.target) {
+ pw.println(prefix + "Message " + n + ": " + m.toString(now));
+ n++;
+ }
+ }
+ return n;
+ }
+
+ void dumpPriorityQueue(ProtoOutputStream proto, MessageHeap priorityQueue) {
+ for (int i = 0; i < priorityQueue.numElements(); i++) {
+ Message m = priorityQueue.getMessageAt(i);
+ m.dumpDebug(proto, MessageQueueProto.MESSAGES);
+ }
+ }
+
+ void dump(Printer pw, String prefix, Handler h) {
+ synchronized (this) {
+ pw.println(prefix + "(MessageQueue is using Locked implementation)");
+ long now = SystemClock.uptimeMillis();
+ int n = dumpPriorityQueue(pw, prefix, h, mPriorityQueue);
+ n += dumpPriorityQueue(pw, prefix, h, mAsyncPriorityQueue);
+ pw.println(prefix + "(Total messages: " + n + ", polling=" + isPollingLocked()
+ + ", quitting=" + mQuitting + ")");
+ }
+ }
+
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
+ final long messageQueueToken = proto.start(fieldId);
+ synchronized (this) {
+ dumpPriorityQueue(proto, mPriorityQueue);
+ dumpPriorityQueue(proto, mAsyncPriorityQueue);
+ proto.write(MessageQueueProto.IS_POLLING_LOCKED, isPollingLocked());
+ proto.write(MessageQueueProto.IS_QUITTING, mQuitting);
+ }
+ proto.end(messageQueueToken);
+ }
+
+ /**
+ * Callback interface for discovering when a thread is going to block
+ * waiting for more messages.
+ */
+ public static interface IdleHandler {
+ /**
+ * Called when the message queue has run out of messages and will now
+ * wait for more. Return true to keep your idle handler active, false
+ * to have it removed. This may be called if there are still messages
+ * pending in the queue, but they are all scheduled to be dispatched
+ * after the current time.
+ */
+ boolean queueIdle();
+ }
+
+ /**
+ * A listener which is invoked when file descriptor related events occur.
+ */
+ public interface OnFileDescriptorEventListener {
+ /**
+ * File descriptor event: Indicates that the file descriptor is ready for input
+ * operations, such as reading.
+ * <p>
+ * The listener should read all available data from the file descriptor
+ * then return <code>true</code> to keep the listener active or <code>false</code>
+ * to remove the listener.
+ * </p><p>
+ * In the case of a socket, this event may be generated to indicate
+ * that there is at least one incoming connection that the listener
+ * should accept.
+ * </p><p>
+ * This event will only be generated if the {@link #EVENT_INPUT} event mask was
+ * specified when the listener was added.
+ * </p>
+ */
+ public static final int EVENT_INPUT = 1 << 0;
+
+ /**
+ * File descriptor event: Indicates that the file descriptor is ready for output
+ * operations, such as writing.
+ * <p>
+ * The listener should write as much data as it needs. If it could not
+ * write everything at once, then it should return <code>true</code> to
+ * keep the listener active. Otherwise, it should return <code>false</code>
+ * to remove the listener then re-register it later when it needs to write
+ * something else.
+ * </p><p>
+ * This event will only be generated if the {@link #EVENT_OUTPUT} event mask was
+ * specified when the listener was added.
+ * </p>
+ */
+ public static final int EVENT_OUTPUT = 1 << 1;
+
+ /**
+ * File descriptor event: Indicates that the file descriptor encountered a
+ * fatal error.
+ * <p>
+ * File descriptor errors can occur for various reasons. One common error
+ * is when the remote peer of a socket or pipe closes its end of the connection.
+ * </p><p>
+ * This event may be generated at any time regardless of whether the
+ * {@link #EVENT_ERROR} event mask was specified when the listener was added.
+ * </p>
+ */
+ public static final int EVENT_ERROR = 1 << 2;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, prefix = { "EVENT_" }, value = {
+ EVENT_INPUT,
+ EVENT_OUTPUT,
+ EVENT_ERROR
+ })
+ public @interface Events {}
+
+ /**
+ * Called when a file descriptor receives events.
+ *
+ * @param fd The file descriptor.
+ * @param events The set of events that occurred: a combination of the
+ * {@link #EVENT_INPUT}, {@link #EVENT_OUTPUT}, and {@link #EVENT_ERROR} event masks.
+ * @return The new set of events to watch, or 0 to unregister the listener.
+ *
+ * @see #EVENT_INPUT
+ * @see #EVENT_OUTPUT
+ * @see #EVENT_ERROR
+ */
+ @Events int onFileDescriptorEvents(@NonNull FileDescriptor fd, @Events int events);
+ }
+
+ private static final class FileDescriptorRecord {
+ public final FileDescriptor mDescriptor;
+ public int mEvents;
+ public OnFileDescriptorEventListener mListener;
+ public int mSeq;
+
+ public FileDescriptorRecord(FileDescriptor descriptor,
+ int events, OnFileDescriptorEventListener listener) {
+ mDescriptor = descriptor;
+ mEvents = events;
+ mListener = listener;
+ }
+ }
+}
diff --git a/core/java/android/os/Message.java b/core/java/android/os/Message.java
index 161951ead77f..a1db9be0b693 100644
--- a/core/java/android/os/Message.java
+++ b/core/java/android/os/Message.java
@@ -126,6 +126,10 @@ public final class Message implements Parcelable {
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public long when;
+ /** @hide */
+ @SuppressWarnings("unused")
+ public long mInsertSeq;
+
/*package*/ Bundle data;
@UnsupportedAppUsage
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index 6d6757d5afd1..7d3076d6611f 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -106,6 +106,9 @@ per-file SystemConfigManager.java = file:/PACKAGE_MANAGER_OWNERS
# ProfilingService
per-file ProfilingServiceManager.java = file:/PERFORMANCE_OWNERS
+# Performance
+per-file IpcDataCache.java = file:/PERFORMANCE_OWNERS
+
# Memory
per-file OomKillRecord.java = file:/MEMORY_OWNERS
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 464df239b8fd..4cc057a8e0ed 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -340,7 +340,6 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
return pfd;
}
- @RavenwoodReplace
private static FileDescriptor openInternal(File file, int mode) throws FileNotFoundException {
if ((mode & MODE_WRITE_ONLY) != 0 && (mode & MODE_APPEND) == 0
&& (mode & MODE_TRUNCATE) == 0 && ((mode & MODE_READ_ONLY) == 0)
@@ -364,26 +363,16 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
}
}
- private static FileDescriptor openInternal$ravenwood(File file, int mode)
- throws FileNotFoundException {
- try {
- return native_open$ravenwood(file, mode);
- } catch (FileNotFoundException e) {
- throw e;
- } catch (IOException e) {
- throw new FileNotFoundException(e.getMessage());
- }
- }
-
@RavenwoodReplace
private static void closeInternal(FileDescriptor fd) {
IoUtils.closeQuietly(fd);
}
private static void closeInternal$ravenwood(FileDescriptor fd) {
- // Desktop JVM doesn't have FileDescriptor.close(), so we'll need to go to the ravenwood
- // side to close it.
- native_close$ravenwood(fd);
+ try {
+ Os.close(fd);
+ } catch (ErrnoException ignored) {
+ }
}
/**
@@ -743,7 +732,6 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
* Return the total size of the file representing this fd, as determined by
* {@code stat()}. Returns -1 if the fd is not a file.
*/
- @RavenwoodThrow(reason = "Os.readlink() and Os.stat()")
public long getStatSize() {
if (mWrapped != null) {
return mWrapped.getStatSize();
@@ -1277,32 +1265,19 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
}
}
- // These native methods are currently only implemented by Ravenwood, as it's the only
- // mechanism we have to jump to our RavenwoodNativeSubstitutionClass
- private static native void native_setFdInt$ravenwood(FileDescriptor fd, int fdInt);
- private static native int native_getFdInt$ravenwood(FileDescriptor fd);
- private static native FileDescriptor native_open$ravenwood(File file, int pfdMode)
- throws IOException;
- private static native void native_close$ravenwood(FileDescriptor fd);
+ private static native void setFdInt$ravenwood(FileDescriptor fd, int fdInt);
+ private static native int getFdInt$ravenwood(FileDescriptor fd);
@RavenwoodReplace
private static void setFdInt(FileDescriptor fd, int fdInt) {
fd.setInt$(fdInt);
}
- private static void setFdInt$ravenwood(FileDescriptor fd, int fdInt) {
- native_setFdInt$ravenwood(fd, fdInt);
- }
-
@RavenwoodReplace
private static int getFdInt(FileDescriptor fd) {
return fd.getInt$();
}
- private static int getFdInt$ravenwood(FileDescriptor fd) {
- return native_getFdInt$ravenwood(fd);
- }
-
@RavenwoodReplace
private void setFdOwner(FileDescriptor fd) {
IoUtils.setFdOwner(fd, this);
@@ -1320,7 +1295,6 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
private int acquireRawFd$ravenwood(FileDescriptor fd) {
// FD owners currently unsupported under Ravenwood; return FD directly
return getFdInt(fd);
-
}
@RavenwoodReplace
diff --git a/core/java/android/os/SemiConcurrentMessageQueue/MessageQueue.java b/core/java/android/os/SemiConcurrentMessageQueue/MessageQueue.java
index 967332fcf80c..79f229acbccb 100644
--- a/core/java/android/os/SemiConcurrentMessageQueue/MessageQueue.java
+++ b/core/java/android/os/SemiConcurrentMessageQueue/MessageQueue.java
@@ -209,7 +209,7 @@ public final class MessageQueue {
private volatile long mNextInsertSeqValue = 0;
/*
* The exception to the FIFO order rule is sendMessageAtFrontOfQueue().
- * Those messages must be in LIFO order - SIGH.
+ * Those messages must be in LIFO order.
* Decrements on each front of queue insert.
*/
private static final VarHandle sNextFrontInsertSeq;
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index 5ef597d7104a..3fe063df0e1b 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -91,6 +91,8 @@ flag {
bug: "283989236"
}
+# This flag is enabled since V but not a MUST requirement in CDD yet, so it needs to stay around
+# for now and any code working with it should keep checking the flag.
flag {
name: "signature_permission_allowlist_enabled"
is_fixed_read_only: true
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 0ee6f43e1329..5703f693792c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5912,6 +5912,14 @@ public final class Settings {
public static final String SHOW_KEY_PRESSES = "show_key_presses";
/**
+ * Show touchpad input visualization on screen.
+ * 0 = no
+ * 1 = yes
+ * @hide
+ */
+ public static final String TOUCHPAD_VISUALIZER = "touchpad_visualizer";
+
+ /**
* Show rotary input dispatched to focused windows on the screen.
* 0 = no
* 1 = yes
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index e16a6a1197ae..7ca248da3dd8 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -211,6 +211,9 @@ public class ZenModeConfig implements Parcelable {
SUPPRESSED_EFFECT_SCREEN_OFF | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
| SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_PEEK | SUPPRESSED_EFFECT_AMBIENT;
+ private static final int LEGACY_SUPPRESSED_EFFECTS =
+ Policy.SUPPRESSED_EFFECT_SCREEN_ON | Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
+
// ZenModeConfig XML versions distinguishing key changes.
public static final int XML_VERSION_ZEN_UPGRADE = 8;
public static final int XML_VERSION_MODES_API = 11;
@@ -284,6 +287,7 @@ public class ZenModeConfig implements Parcelable {
private static final String RULE_ATT_TRIGGER_DESC = "triggerDesc";
private static final String RULE_ATT_DELETION_INSTANT = "deletionInstant";
private static final String RULE_ATT_DISABLED_ORIGIN = "disabledOrigin";
+ private static final String RULE_ATT_LEGACY_SUPPRESSED_EFFECTS = "legacySuppressedEffects";
private static final String DEVICE_EFFECT_DISPLAY_GRAYSCALE = "zdeDisplayGrayscale";
private static final String DEVICE_EFFECT_SUPPRESS_AMBIENT_DISPLAY =
@@ -1171,6 +1175,8 @@ public class ZenModeConfig implements Parcelable {
if (Flags.modesUi()) {
rt.disabledOrigin = safeInt(parser, RULE_ATT_DISABLED_ORIGIN,
UPDATE_ORIGIN_UNKNOWN);
+ rt.legacySuppressedEffects = safeInt(parser,
+ RULE_ATT_LEGACY_SUPPRESSED_EFFECTS, 0);
}
}
return rt;
@@ -1228,6 +1234,8 @@ public class ZenModeConfig implements Parcelable {
}
if (Flags.modesUi()) {
out.attributeInt(null, RULE_ATT_DISABLED_ORIGIN, rule.disabledOrigin);
+ out.attributeInt(null, RULE_ATT_LEGACY_SUPPRESSED_EFFECTS,
+ rule.legacySuppressedEffects);
}
}
}
@@ -1903,6 +1911,13 @@ public class ZenModeConfig implements Parcelable {
ZenPolicy.VISUAL_EFFECT_NOTIFICATION_LIST))) {
suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST;
}
+
+ // Restore legacy suppressed effects (obsolete fields which are not in ZenPolicy).
+ // These are deprecated and have no effect on behavior, however apps should get them
+ // back if provided to setNotificationPolicy() earlier.
+ suppressedVisualEffects &= ~LEGACY_SUPPRESSED_EFFECTS;
+ suppressedVisualEffects |=
+ (LEGACY_SUPPRESSED_EFFECTS & manualRule.legacySuppressedEffects);
} else {
if (isAllowConversations()) {
priorityCategories |= Policy.PRIORITY_CATEGORY_CONVERSATIONS;
@@ -1996,6 +2011,8 @@ public class ZenModeConfig implements Parcelable {
if (policy == null) return;
if (Flags.modesUi()) {
manualRule.zenPolicy = ZenAdapters.notificationPolicyToZenPolicy(policy);
+ manualRule.legacySuppressedEffects =
+ LEGACY_SUPPRESSED_EFFECTS & policy.suppressedVisualEffects;
} else {
setAllowAlarms((policy.priorityCategories & Policy.PRIORITY_CATEGORY_ALARMS) != 0);
allowMedia = (policy.priorityCategories & Policy.PRIORITY_CATEGORY_MEDIA) != 0;
@@ -2521,6 +2538,10 @@ public class ZenModeConfig implements Parcelable {
@Nullable public Instant deletionInstant; // Only set on deleted rules.
@FlaggedApi(Flags.FLAG_MODES_UI)
@ConfigChangeOrigin public int disabledOrigin = UPDATE_ORIGIN_UNKNOWN;
+ // The obsolete suppressed effects in NM.Policy (SCREEN_ON, SCREEN_OFF) cannot be put in a
+ // ZenPolicy, so we store them here, only for the manual rule.
+ @FlaggedApi(Flags.FLAG_MODES_UI)
+ int legacySuppressedEffects;
public ZenRule() { }
@@ -2561,6 +2582,7 @@ public class ZenModeConfig implements Parcelable {
}
if (Flags.modesUi()) {
disabledOrigin = source.readInt();
+ legacySuppressedEffects = source.readInt();
}
}
}
@@ -2638,6 +2660,7 @@ public class ZenModeConfig implements Parcelable {
}
if (Flags.modesUi()) {
dest.writeInt(disabledOrigin);
+ dest.writeInt(legacySuppressedEffects);
}
}
}
@@ -2686,6 +2709,7 @@ public class ZenModeConfig implements Parcelable {
}
if (Flags.modesUi()) {
sb.append(",disabledOrigin=").append(disabledOrigin);
+ sb.append(",legacySuppressedEffects=").append(legacySuppressedEffects);
}
}
@@ -2754,7 +2778,8 @@ public class ZenModeConfig implements Parcelable {
if (Flags.modesUi()) {
finalEquals = finalEquals
- && other.disabledOrigin == disabledOrigin;
+ && other.disabledOrigin == disabledOrigin
+ && other.legacySuppressedEffects == legacySuppressedEffects;
}
}
@@ -2769,15 +2794,15 @@ public class ZenModeConfig implements Parcelable {
component, configurationActivity, pkg, id, enabler, zenPolicy,
zenDeviceEffects, modified, allowManualInvocation, iconResName,
triggerDescription, type, userModifiedFields,
- zenPolicyUserModifiedFields,
- zenDeviceEffectsUserModifiedFields, deletionInstant, disabledOrigin);
+ zenPolicyUserModifiedFields, zenDeviceEffectsUserModifiedFields,
+ deletionInstant, disabledOrigin, legacySuppressedEffects);
} else {
return Objects.hash(enabled, snoozing, name, zenMode, conditionId, condition,
component, configurationActivity, pkg, id, enabler, zenPolicy,
zenDeviceEffects, modified, allowManualInvocation, iconResName,
triggerDescription, type, userModifiedFields,
- zenPolicyUserModifiedFields,
- zenDeviceEffectsUserModifiedFields, deletionInstant);
+ zenPolicyUserModifiedFields, zenDeviceEffectsUserModifiedFields,
+ deletionInstant);
}
}
return Objects.hash(enabled, snoozing, name, zenMode, conditionId, condition,
diff --git a/core/java/android/service/notification/ZenModeDiff.java b/core/java/android/service/notification/ZenModeDiff.java
index 91ef11cf1d2d..a37e2277f0d1 100644
--- a/core/java/android/service/notification/ZenModeDiff.java
+++ b/core/java/android/service/notification/ZenModeDiff.java
@@ -472,6 +472,7 @@ public class ZenModeDiff {
public static final String FIELD_ICON_RES = "iconResName";
public static final String FIELD_TRIGGER_DESCRIPTION = "triggerDescription";
public static final String FIELD_TYPE = "type";
+ public static final String FIELD_LEGACY_SUPPRESSED_EFFECTS = "legacySuppressedEffects";
// NOTE: new field strings must match the variable names in ZenModeConfig.ZenRule
// Special field to track whether this rule became active or inactive
@@ -567,6 +568,13 @@ public class ZenModeDiff {
if (!Objects.equals(from.iconResName, to.iconResName)) {
addField(FIELD_ICON_RES, new FieldDiff<>(from.iconResName, to.iconResName));
}
+ if (android.app.Flags.modesUi()) {
+ if (from.legacySuppressedEffects != to.legacySuppressedEffects) {
+ addField(FIELD_LEGACY_SUPPRESSED_EFFECTS,
+ new FieldDiff<>(from.legacySuppressedEffects,
+ to.legacySuppressedEffects));
+ }
+ }
}
}
diff --git a/core/java/android/service/notification/ZenPolicy.java b/core/java/android/service/notification/ZenPolicy.java
index 910c4626ea96..2669391b4d45 100644
--- a/core/java/android/service/notification/ZenPolicy.java
+++ b/core/java/android/service/notification/ZenPolicy.java
@@ -1240,7 +1240,10 @@ public final class ZenPolicy implements Parcelable {
return "invalidState{" + state + "}";
}
- private String peopleTypeToString(@PeopleType int peopleType) {
+ /**
+ * @hide
+ */
+ public static String peopleTypeToString(@PeopleType int peopleType) {
switch (peopleType) {
case PEOPLE_TYPE_ANYONE:
return "anyone";
diff --git a/core/java/android/view/SurfaceControlRegistry.java b/core/java/android/view/SurfaceControlRegistry.java
index a806bd226c36..121c01be7294 100644
--- a/core/java/android/view/SurfaceControlRegistry.java
+++ b/core/java/android/view/SurfaceControlRegistry.java
@@ -73,7 +73,7 @@ public class SurfaceControlRegistry {
}
// Sort entries by time registered when dumping
// TODO: Or should it sort by name?
- entries.sort((o1, o2) -> (int) (o1.getValue() - o2.getValue()));
+ entries.sort((o1, o2) -> Long.compare(o1.getValue(), o2.getValue()));
final int size = Math.min(entries.size(), limit);
pw.println("SurfaceControlRegistry");
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 2ac5873cf736..4ab67581a44e 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -973,8 +973,12 @@ public final class InputMethodManager {
@GuardedBy("mH")
private void setCurrentRootViewLocked(ViewRootImpl rootView) {
+ final boolean wasEmpty = mCurRootView == null;
mImeDispatcher.switchRootView(mCurRootView, rootView);
mCurRootView = rootView;
+ if (wasEmpty && mCurRootView != null) {
+ mImeDispatcher.updateReceivingDispatcher(mCurRootView.getOnBackInvokedDispatcher());
+ }
}
}
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 8b6ead7d37c5..d28c953fe0bd 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -3285,9 +3285,11 @@ public class Editor {
.setEnabled(mTextView.canShare())
.setIcon(a.getDrawable(6))
.setOnMenuItemClickListener(mOnContextMenuItemClickListener);
+ final String selected = mTextView.getSelectedText();
menu.add(CONTEXT_MENU_GROUP_MISC, TextView.ID_AUTOFILL, menuItemOrderAutofill,
android.R.string.autofill)
- .setEnabled(mTextView.canRequestAutofill())
+ .setEnabled(mTextView.canRequestAutofill()
+ && (selected == null || selected.isEmpty()))
.setOnMenuItemClickListener(mOnContextMenuItemClickListener);
mPreserveSelection = true;
diff --git a/core/java/android/window/DisplayWindowPolicyController.java b/core/java/android/window/DisplayWindowPolicyController.java
index 9cd2a716e498..a16d53768ca1 100644
--- a/core/java/android/window/DisplayWindowPolicyController.java
+++ b/core/java/android/window/DisplayWindowPolicyController.java
@@ -23,15 +23,16 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.WindowConfiguration;
-import android.companion.virtualdevice.flags.Flags;
import android.content.ComponentName;
import android.content.Intent;
+import android.content.IntentSender;
import android.content.pm.ActivityInfo;
import android.util.ArraySet;
import java.io.PrintWriter;
import java.util.List;
import java.util.Set;
+import java.util.function.Supplier;
/**
* Abstract class to control the policies of the windows that can be displayed on the virtual
@@ -67,9 +68,7 @@ public abstract class DisplayWindowPolicyController {
public DisplayWindowPolicyController() {
synchronized (mSupportedWindowingModes) {
mSupportedWindowingModes.add(WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
- if (Flags.virtualDisplayMultiWindowModeSupport()) {
- mSupportedWindowingModes.add(WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW);
- }
+ mSupportedWindowingModes.add(WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW);
}
}
@@ -139,10 +138,14 @@ public abstract class DisplayWindowPolicyController {
* Returns {@code true} if the given activity can be launched on this virtual display in the
* configuration defined by the rest of the arguments. If the given intent would be intercepted
* by the display owner then this means that the activity cannot be launched.
+ *
+ * The intentSender argument can provide an IntentSender for the original intent to be passed
+ * to any activity listeners, in case the activity cannot be launched.
*/
public abstract boolean canActivityBeLaunched(@NonNull ActivityInfo activityInfo,
@Nullable Intent intent, @WindowConfiguration.WindowingMode int windowingMode,
- int launchingFromDisplayId, boolean isNewTask);
+ int launchingFromDisplayId, boolean isNewTask, boolean isResultExpected,
+ @Nullable Supplier<IntentSender> intentSender);
/**
* Returns {@code true} if the given activity can be launched on this virtual display in the
diff --git a/core/java/android/window/ImeOnBackInvokedDispatcher.java b/core/java/android/window/ImeOnBackInvokedDispatcher.java
index ce1f9869b690..771dc7a99c0e 100644
--- a/core/java/android/window/ImeOnBackInvokedDispatcher.java
+++ b/core/java/android/window/ImeOnBackInvokedDispatcher.java
@@ -27,10 +27,12 @@ import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.util.Log;
+import android.util.Pair;
import android.view.ViewRootImpl;
import com.android.internal.annotations.VisibleForTesting;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.function.Consumer;
@@ -58,7 +60,7 @@ public class ImeOnBackInvokedDispatcher implements OnBackInvokedDispatcher, Parc
// The handler to run callbacks on. This should be on the same thread
// the ViewRootImpl holding IME's WindowOnBackInvokedDispatcher is created on.
private Handler mHandler;
-
+ private final ArrayDeque<Pair<Integer, Bundle>> mQueuedReceive = new ArrayDeque<>();
public ImeOnBackInvokedDispatcher(Handler handler) {
mResultReceiver = new ResultReceiver(handler) {
@Override
@@ -66,11 +68,22 @@ public class ImeOnBackInvokedDispatcher implements OnBackInvokedDispatcher, Parc
WindowOnBackInvokedDispatcher dispatcher = getReceivingDispatcher();
if (dispatcher != null) {
receive(resultCode, resultData, dispatcher);
+ } else {
+ mQueuedReceive.add(new Pair<>(resultCode, resultData));
}
}
};
}
+ /** Set receiving dispatcher to consume queued receiving events. */
+ public void updateReceivingDispatcher(@NonNull WindowOnBackInvokedDispatcher dispatcher) {
+ while (!mQueuedReceive.isEmpty()) {
+ final Pair<Integer, Bundle> queuedMessage = mQueuedReceive.poll();
+ receive(queuedMessage.first, queuedMessage.second, dispatcher);
+ }
+ }
+
+
void setHandler(@NonNull Handler handler) {
mHandler = handler;
}
@@ -198,6 +211,7 @@ public class ImeOnBackInvokedDispatcher implements OnBackInvokedDispatcher, Parc
}
}
mImeCallbacks.clear();
+ mQueuedReceive.clear();
}
@VisibleForTesting(visibility = PACKAGE)
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index 2d5b02ad9b3b..125a0b242df9 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -31,6 +31,13 @@ flag {
}
flag {
+ name: "disable_non_resizable_app_snap_resizing"
+ namespace: "lse_desktop_experience"
+ description: "Stops non-resizable app desktop windows from being snap resized"
+ bug: "325240072"
+}
+
+flag {
name: "enable_desktop_windowing_task_limit"
namespace: "lse_desktop_experience"
description: "Enables a limit on the number of Tasks shown in Desktop Mode"
@@ -204,3 +211,10 @@ flag {
description: "Enables the tracking of the status for compat ui elements."
bug: "350953004"
}
+
+flag {
+ name: "enable_desktop_windowing_app_to_web_education"
+ namespace: "lse_desktop_experience"
+ description: "Enables desktop windowing app-to-web education"
+ bug: "348205896"
+}
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 80a0102341c0..d5746e58ffe6 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -94,14 +94,6 @@ flag {
}
flag {
- name: "activity_snapshot_by_default"
- namespace: "systemui"
- description: "Enable record activity snapshot by default"
- bug: "259497289"
- is_fixed_read_only: true
-}
-
-flag {
name: "supports_multi_instance_system_ui"
is_exported: true
namespace: "multitasking"
diff --git a/core/java/android/window/flags/windowing_sdk.aconfig b/core/java/android/window/flags/windowing_sdk.aconfig
index 4c18bbfbeebf..b8c2a5f8eb6b 100644
--- a/core/java/android/window/flags/windowing_sdk.aconfig
+++ b/core/java/android/window/flags/windowing_sdk.aconfig
@@ -135,14 +135,3 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
-
-flag {
- namespace: "windowing_sdk"
- name: "per_user_display_window_settings"
- description: "Whether to store display window settings per user to avoid conflicts"
- bug: "346668297"
- is_fixed_read_only: true
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
diff --git a/core/java/com/android/internal/os/BackgroundThread.java b/core/java/com/android/internal/os/BackgroundThread.java
index b75daeda480c..79996e56b689 100644
--- a/core/java/com/android/internal/os/BackgroundThread.java
+++ b/core/java/com/android/internal/os/BackgroundThread.java
@@ -16,6 +16,7 @@
package com.android.internal.os;
+import android.annotation.NonNull;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.HandlerThread;
@@ -53,6 +54,7 @@ public final class BackgroundThread extends HandlerThread {
}
}
+ @NonNull
public static BackgroundThread get() {
synchronized (BackgroundThread.class) {
ensureThreadLocked();
@@ -60,6 +62,7 @@ public final class BackgroundThread extends HandlerThread {
}
}
+ @NonNull
public static Handler getHandler() {
synchronized (BackgroundThread.class) {
ensureThreadLocked();
@@ -67,6 +70,7 @@ public final class BackgroundThread extends HandlerThread {
}
}
+ @NonNull
public static Executor getExecutor() {
synchronized (BackgroundThread.class) {
ensureThreadLocked();
diff --git a/core/java/com/android/internal/os/DebugStore.java b/core/java/com/android/internal/os/DebugStore.java
new file mode 100644
index 000000000000..4c45feed8511
--- /dev/null
+++ b/core/java/com/android/internal/os/DebugStore.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+import android.annotation.Nullable;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Intent;
+import android.content.pm.ServiceInfo;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+
+/**
+ * The DebugStore class provides methods for recording various debug events related to service
+ * lifecycle, broadcast receivers and others.
+ * The DebugStore class facilitates debugging ANR issues by recording time-stamped events
+ * related to service lifecycles, broadcast receivers, and other framework operations. It logs
+ * the start and end times of operations within the ANR timer scope called by framework,
+ * enabling pinpointing of methods and events contributing to ANRs.
+ *
+ * Usage currently includes recording service starts, binds, and asynchronous operations initiated
+ * by broadcast receivers, providing a granular view of system behavior that facilitates
+ * identifying performance bottlenecks and optimizing issue resolution.
+ *
+ * @hide
+ */
+public class DebugStore {
+ private static DebugStoreNative sDebugStoreNative = new DebugStoreNativeImpl();
+
+ @UnsupportedAppUsage
+ @VisibleForTesting
+ public static void setDebugStoreNative(DebugStoreNative nativeImpl) {
+ sDebugStoreNative = nativeImpl;
+ }
+ /**
+ * Records the start of a service.
+ *
+ * @param startId The start ID of the service.
+ * @param flags Additional flags for the service start.
+ * @param intent The Intent associated with the service start.
+ * @return A unique ID for the recorded event.
+ */
+ @UnsupportedAppUsage
+ public static long recordServiceOnStart(int startId, int flags, @Nullable Intent intent) {
+ return sDebugStoreNative.beginEvent(
+ "SvcStart",
+ List.of(
+ "stId",
+ String.valueOf(startId),
+ "flg",
+ Integer.toHexString(flags),
+ "act",
+ Objects.toString(intent != null ? intent.getAction() : null),
+ "comp",
+ Objects.toString(intent != null ? intent.getComponent() : null),
+ "pkg",
+ Objects.toString(intent != null ? intent.getPackage() : null)));
+ }
+
+ /**
+ * Records the creation of a service.
+ *
+ * @param serviceInfo Information about the service being created.
+ * @return A unique ID for the recorded event.
+ */
+ @UnsupportedAppUsage
+ public static long recordServiceCreate(@Nullable ServiceInfo serviceInfo) {
+ return sDebugStoreNative.beginEvent(
+ "SvcCreate",
+ List.of(
+ "name",
+ Objects.toString(serviceInfo != null ? serviceInfo.name : null),
+ "pkg",
+ Objects.toString(serviceInfo != null ? serviceInfo.packageName : null)));
+ }
+
+ /**
+ * Records the binding of a service.
+ *
+ * @param isRebind Indicates whether the service is being rebound.
+ * @param intent The Intent associated with the service binding.
+ * @return A unique identifier for the recorded event.
+ */
+ @UnsupportedAppUsage
+ public static long recordServiceBind(boolean isRebind, @Nullable Intent intent) {
+ return sDebugStoreNative.beginEvent(
+ "SvcBind",
+ List.of(
+ "rebind",
+ String.valueOf(isRebind),
+ "act",
+ Objects.toString(intent != null ? intent.getAction() : null),
+ "cmp",
+ Objects.toString(intent != null ? intent.getComponent() : null),
+ "pkg",
+ Objects.toString(intent != null ? intent.getPackage() : null)));
+ }
+
+ /**
+ * Records an asynchronous operation initiated by a broadcast receiver through calling GoAsync.
+ *
+ * @param receiverClassName The class name of the broadcast receiver.
+ */
+ @UnsupportedAppUsage
+ public static void recordGoAsync(String receiverClassName) {
+ sDebugStoreNative.recordEvent(
+ "GoAsync",
+ List.of(
+ "tname",
+ Thread.currentThread().getName(),
+ "tid",
+ String.valueOf(Thread.currentThread().getId()),
+ "rcv",
+ Objects.toString(receiverClassName)));
+ }
+
+ /**
+ * Records the completion of a broadcast operation through calling Finish.
+ *
+ * @param receiverClassName The class of the broadcast receiver that completed the operation.
+ */
+ @UnsupportedAppUsage
+ public static void recordFinish(String receiverClassName) {
+ sDebugStoreNative.recordEvent(
+ "Finish",
+ List.of(
+ "tname",
+ Thread.currentThread().getName(),
+ "tid",
+ String.valueOf(Thread.currentThread().getId()),
+ "rcv",
+ Objects.toString(receiverClassName)));
+ }
+ /**
+ * Records the completion of a long-running looper message.
+ *
+ * @param messageCode The code representing the type of the message.
+ * @param targetClass The FQN of the class that handled the message.
+ * @param elapsedTimeMs The time that was taken to process the message, in milliseconds.
+ */
+ @UnsupportedAppUsage
+ public static void recordLongLooperMessage(int messageCode, String targetClass,
+ long elapsedTimeMs) {
+ sDebugStoreNative.recordEvent(
+ "LooperMsg",
+ List.of(
+ "code",
+ String.valueOf(messageCode),
+ "trgt",
+ Objects.toString(targetClass),
+ "elapsed",
+ String.valueOf(elapsedTimeMs)));
+ }
+
+
+ /**
+ * Records the reception of a broadcast.
+ *
+ * @param intent The Intent associated with the broadcast.
+ * @return A unique ID for the recorded event.
+ */
+ @UnsupportedAppUsage
+ public static long recordBroadcastHandleReceiver(@Nullable Intent intent) {
+ return sDebugStoreNative.beginEvent(
+ "HandleReceiver",
+ List.of(
+ "tname", Thread.currentThread().getName(),
+ "tid", String.valueOf(Thread.currentThread().getId()),
+ "act", Objects.toString(intent != null ? intent.getAction() : null),
+ "cmp", Objects.toString(intent != null ? intent.getComponent() : null),
+ "pkg", Objects.toString(intent != null ? intent.getPackage() : null)));
+ }
+
+ /**
+ * Ends a previously recorded event.
+ *
+ * @param id The unique ID of the event to be ended.
+ */
+ @UnsupportedAppUsage
+ public static void recordEventEnd(long id) {
+ sDebugStoreNative.endEvent(id, Collections.emptyList());
+ }
+
+ /**
+ * An interface for a class that acts as a wrapper for the static native methods
+ * of the Debug Store.
+ *
+ * It allows us to mock static native methods in our tests and should be removed
+ * once mocking static methods becomes easier.
+ */
+ @VisibleForTesting
+ public interface DebugStoreNative {
+ /**
+ * Begins an event with the given name and attributes.
+ */
+ long beginEvent(String eventName, List<String> attributes);
+ /**
+ * Ends an event with the given ID and attributes.
+ */
+ void endEvent(long id, List<String> attributes);
+ /**
+ * Records an event with the given name and attributes.
+ */
+ void recordEvent(String eventName, List<String> attributes);
+ }
+
+ private static class DebugStoreNativeImpl implements DebugStoreNative {
+ @Override
+ public long beginEvent(String eventName, List<String> attributes) {
+ return DebugStore.beginEventNative(eventName, attributes);
+ }
+
+ @Override
+ public void endEvent(long id, List<String> attributes) {
+ DebugStore.endEventNative(id, attributes);
+ }
+
+ @Override
+ public void recordEvent(String eventName, List<String> attributes) {
+ DebugStore.recordEventNative(eventName, attributes);
+ }
+ }
+
+ private static native long beginEventNative(String eventName, List<String> attributes);
+
+ private static native void endEventNative(long id, List<String> attributes);
+
+ private static native void recordEventNative(String eventName, List<String> attributes);
+}
diff --git a/core/java/com/android/internal/os/flags.aconfig b/core/java/com/android/internal/os/flags.aconfig
index 2ad665181e70..c7117e977ee2 100644
--- a/core/java/com/android/internal/os/flags.aconfig
+++ b/core/java/com/android/internal/os/flags.aconfig
@@ -19,4 +19,12 @@ flag {
metadata {
purpose: PURPOSE_BUGFIX
}
+}
+
+flag {
+ name: "debug_store_enabled"
+ namespace: "stability"
+ description: "If the debug store is enabled."
+ bug: "314735374"
+ is_fixed_read_only: true
} \ No newline at end of file
diff --git a/core/java/com/android/internal/widget/OWNERS b/core/java/com/android/internal/widget/OWNERS
index cf2f202a03ac..2d1c2f032d16 100644
--- a/core/java/com/android/internal/widget/OWNERS
+++ b/core/java/com/android/internal/widget/OWNERS
@@ -3,7 +3,9 @@ per-file RecyclerView.java = mount@google.com
per-file ViewPager.java = mount@google.com
# LockSettings related
-per-file *LockPattern* = file:/services/core/java/com/android/server/locksettings/OWNERS
+per-file LockPatternChecker.java = file:/services/core/java/com/android/server/locksettings/OWNERS
+per-file LockPatternUtils.java = file:/services/core/java/com/android/server/locksettings/OWNERS
+per-file LockPatternView.java = file:/packages/SystemUI/OWNERS
per-file *LockScreen* = file:/services/core/java/com/android/server/locksettings/OWNERS
per-file *Lockscreen* = file:/services/core/java/com/android/server/locksettings/OWNERS
per-file *LockSettings* = file:/services/core/java/com/android/server/locksettings/OWNERS
diff --git a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
index 5c2a1678a556..effbbe2f0c1d 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
@@ -18,6 +18,11 @@ package com.android.internal.widget.remotecompose.core;
import com.android.internal.widget.remotecompose.core.operations.NamedVariable;
import com.android.internal.widget.remotecompose.core.operations.RootContentBehavior;
import com.android.internal.widget.remotecompose.core.operations.Theme;
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+import com.android.internal.widget.remotecompose.core.operations.layout.ComponentEnd;
+import com.android.internal.widget.remotecompose.core.operations.layout.ComponentStartOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponent;
+import com.android.internal.widget.remotecompose.core.operations.layout.RootLayoutComponent;
import java.util.ArrayList;
import java.util.HashSet;
@@ -30,6 +35,9 @@ import java.util.Set;
public class CoreDocument {
ArrayList<Operation> mOperations;
+
+ RootLayoutComponent mRootLayoutComponent = null;
+
RemoteComposeState mRemoteComposeState = new RemoteComposeState();
TimeVariables mTimeVariables = new TimeVariables();
// Semantic version of the document
@@ -81,7 +89,6 @@ public class CoreDocument {
public void setHeight(int height) {
this.mHeight = height;
mRemoteComposeState.setWindowHeight(height);
-
}
public RemoteComposeBuffer getBuffer() {
@@ -259,10 +266,43 @@ public class CoreDocument {
translateOutput[1] = translateY;
}
+ /**
+ * Returns the list of click areas
+ * @return list of click areas in document coordinates
+ */
public Set<ClickAreaRepresentation> getClickAreas() {
return mClickAreas;
}
+ /**
+ * Returns the root layout component
+ * @return returns the root component if it exists, null otherwise
+ */
+ public RootLayoutComponent getRootLayoutComponent() {
+ return mRootLayoutComponent;
+ }
+
+ /**
+ * Invalidate the document for layout measures. This will trigger a layout remeasure pass.
+ */
+ public void invalidateMeasure() {
+ if (mRootLayoutComponent != null) {
+ mRootLayoutComponent.invalidateMeasure();
+ }
+ }
+
+ /**
+ * Returns the component with the given id
+ * @param id component id
+ * @return the component if it exists, null otherwise
+ */
+ public Component getComponent(int id) {
+ if (mRootLayoutComponent != null) {
+ return mRootLayoutComponent.getComponent(id);
+ }
+ return null;
+ }
+
public interface ClickCallbacks {
void click(int id, String metadata);
}
@@ -354,7 +394,54 @@ public class CoreDocument {
public void initFromBuffer(RemoteComposeBuffer buffer) {
mOperations = new ArrayList<Operation>();
buffer.inflateFromBuffer(mOperations);
+ mOperations = inflateComponents(mOperations);
mBuffer = buffer;
+ for (Operation op : mOperations) {
+ if (op instanceof RootLayoutComponent) {
+ mRootLayoutComponent = (RootLayoutComponent) op;
+ break;
+ }
+ }
+ if (mRootLayoutComponent != null) {
+ mRootLayoutComponent.assignIds();
+ }
+ }
+
+ /**
+ * Inflate a component tree
+ * @param operations flat list of operations
+ * @return nested list of operations / components
+ */
+ private ArrayList<Operation> inflateComponents(ArrayList<Operation> operations) {
+ Component currentComponent = null;
+ ArrayList<Component> components = new ArrayList<>();
+ ArrayList<Operation> finalOperationsList = new ArrayList<>();
+ ArrayList<Operation> ops = finalOperationsList;
+
+ for (Operation o : operations) {
+ if (o instanceof ComponentStartOperation) {
+ Component component = (Component) o;
+ component.setParent(currentComponent);
+ components.add(component);
+ currentComponent = component;
+ ops.add(currentComponent);
+ ops = currentComponent.getList();
+ } else if (o instanceof ComponentEnd) {
+ if (currentComponent instanceof LayoutComponent) {
+ ((LayoutComponent) currentComponent).inflate();
+ }
+ components.remove(components.size() - 1);
+ if (!components.isEmpty()) {
+ currentComponent = components.get(components.size() - 1);
+ ops = currentComponent.getList();
+ } else {
+ ops = finalOperationsList;
+ }
+ } else {
+ ops.add(o);
+ }
+ }
+ return ops;
}
/**
@@ -559,6 +646,18 @@ public class CoreDocument {
context.loadFloat(RemoteContext.ID_WINDOW_WIDTH, getWidth());
context.loadFloat(RemoteContext.ID_WINDOW_HEIGHT, getHeight());
mRepaintNext = context.updateOps();
+ if (mRootLayoutComponent != null) {
+ if (context.mWidth != mRootLayoutComponent.getWidth()
+ || context.mHeight != mRootLayoutComponent.getHeight()) {
+ mRootLayoutComponent.invalidateMeasure();
+ }
+ if (mRootLayoutComponent.needsMeasure()) {
+ mRootLayoutComponent.layout(context);
+ }
+ if (mRootLayoutComponent.doesNeedsRepaint()) {
+ mRepaintNext = 1;
+ }
+ }
for (Operation op : mOperations) {
// operations will only be executed if no theme is set (ie UNSPECIFIED)
// or the theme is equal as the one passed in argument to paint.
diff --git a/core/java/com/android/internal/widget/remotecompose/core/Operation.java b/core/java/com/android/internal/widget/remotecompose/core/Operation.java
index 7cb9a4272704..4a8b3d7a76d4 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/Operation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/Operation.java
@@ -37,4 +37,3 @@ public interface Operation {
*/
String deepToString(String indent);
}
-
diff --git a/core/java/com/android/internal/widget/remotecompose/core/Operations.java b/core/java/com/android/internal/widget/remotecompose/core/Operations.java
index 4b8dbf6365f9..9cb024bd234e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/Operations.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/Operations.java
@@ -54,6 +54,21 @@ import com.android.internal.widget.remotecompose.core.operations.TextData;
import com.android.internal.widget.remotecompose.core.operations.TextFromFloat;
import com.android.internal.widget.remotecompose.core.operations.TextMerge;
import com.android.internal.widget.remotecompose.core.operations.Theme;
+import com.android.internal.widget.remotecompose.core.operations.layout.ComponentEnd;
+import com.android.internal.widget.remotecompose.core.operations.layout.ComponentStart;
+import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponentContent;
+import com.android.internal.widget.remotecompose.core.operations.layout.RootLayoutComponent;
+import com.android.internal.widget.remotecompose.core.operations.layout.animation.AnimationSpec;
+import com.android.internal.widget.remotecompose.core.operations.layout.managers.BoxLayout;
+import com.android.internal.widget.remotecompose.core.operations.layout.managers.ColumnLayout;
+import com.android.internal.widget.remotecompose.core.operations.layout.managers.RowLayout;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.BackgroundModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.BorderModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ClipRectModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.HeightModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.PaddingModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.RoundedClipRectModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.WidthModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.utilities.IntMap;
import com.android.internal.widget.remotecompose.core.types.BooleanConstant;
import com.android.internal.widget.remotecompose.core.types.IntegerConstant;
@@ -117,6 +132,27 @@ public class Operations {
public static final int INTEGER_EXPRESSION = 144;
/////////////////////////////////////////======================
+
+ ////////////////////////////////////////
+ // Layout commands
+ ////////////////////////////////////////
+
+ public static final int LAYOUT_ROOT = 200;
+ public static final int LAYOUT_CONTENT = 201;
+ public static final int LAYOUT_BOX = 202;
+ public static final int LAYOUT_ROW = 203;
+ public static final int LAYOUT_COLUMN = 204;
+ public static final int COMPONENT_START = 2;
+ public static final int COMPONENT_END = 3;
+ public static final int MODIFIER_WIDTH = 16;
+ public static final int MODIFIER_HEIGHT = 67;
+ public static final int MODIFIER_BACKGROUND = 55;
+ public static final int MODIFIER_BORDER = 107;
+ public static final int MODIFIER_PADDING = 58;
+ public static final int MODIFIER_CLIP_RECT = 108;
+ public static final int MODIFIER_ROUNDED_CLIP_RECT = 54;
+ public static final int ANIMATION_SPEC = 14;
+
public static IntMap<CompanionOperation> map = new IntMap<>();
static {
@@ -162,6 +198,26 @@ public class Operations {
map.put(DATA_INT, IntegerConstant.COMPANION);
map.put(INTEGER_EXPRESSION, IntegerExpression.COMPANION);
map.put(DATA_BOOLEAN, BooleanConstant.COMPANION);
+
+ // Layout
+
+ map.put(COMPONENT_START, ComponentStart.COMPANION);
+ map.put(COMPONENT_END, ComponentEnd.COMPANION);
+ map.put(ANIMATION_SPEC, AnimationSpec.COMPANION);
+
+ map.put(MODIFIER_WIDTH, WidthModifierOperation.COMPANION);
+ map.put(MODIFIER_HEIGHT, HeightModifierOperation.COMPANION);
+ map.put(MODIFIER_PADDING, PaddingModifierOperation.COMPANION);
+ map.put(MODIFIER_BACKGROUND, BackgroundModifierOperation.COMPANION);
+ map.put(MODIFIER_BORDER, BorderModifierOperation.COMPANION);
+ map.put(MODIFIER_ROUNDED_CLIP_RECT, RoundedClipRectModifierOperation.COMPANION);
+ map.put(MODIFIER_CLIP_RECT, ClipRectModifierOperation.COMPANION);
+
+ map.put(LAYOUT_ROOT, RootLayoutComponent.COMPANION);
+ map.put(LAYOUT_CONTENT, LayoutComponentContent.COMPANION);
+ map.put(LAYOUT_BOX, BoxLayout.COMPANION);
+ map.put(LAYOUT_COLUMN, ColumnLayout.COMPANION);
+ map.put(LAYOUT_ROW, RowLayout.COMPANION);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java b/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java
index 6d8a44297538..665fcb749db8 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java
@@ -23,6 +23,10 @@ import com.android.internal.widget.remotecompose.core.operations.paint.PaintBund
public abstract class PaintContext {
protected RemoteContext mContext;
+ public RemoteContext getContext() {
+ return mContext;
+ }
+
public PaintContext(RemoteContext context) {
this.mContext = context;
}
@@ -31,6 +35,28 @@ public abstract class PaintContext {
this.mContext = context;
}
+ /**
+ * convenience function to call matrixSave()
+ */
+ public void save() {
+ matrixSave();
+ }
+
+ /**
+ * convenience function to call matrixRestore()
+ */
+ public void restore() {
+ matrixRestore();
+ }
+
+ /**
+ * convenience function to call matrixSave()
+ */
+ public void saveLayer(float x, float y, float width, float height) {
+ // TODO
+ matrixSave();
+ }
+
public abstract void drawBitmap(int imageId,
int srcLeft, int srcTop, int srcRight, int srcBottom,
int dstLeft, int dstTop, int dstRight, int dstBottom,
@@ -197,8 +223,49 @@ public abstract class PaintContext {
public abstract void clipPath(int pathId, int regionOp);
/**
+ * Clip based ona round rect
+ * @param width
+ * @param height
+ * @param topStart
+ * @param topEnd
+ * @param bottomStart
+ * @param bottomEnd
+ */
+ public abstract void roundedClipRect(float width, float height,
+ float topStart, float topEnd,
+ float bottomStart, float bottomEnd);
+
+ /**
* Reset the paint
*/
public abstract void reset();
+
+ /**
+ * Returns true if the context is in debug mode
+ *
+ * @return true if in debug mode, false otherwise
+ */
+ public boolean isDebug() {
+ return mContext.isDebug();
+ }
+
+ /**
+ * Returns true if layout animations are enabled
+ *
+ * @return true if animations are enabled, false otherwise
+ */
+ public boolean isAnimationEnabled() {
+ return mContext.isAnimationEnabled();
+ }
+
+ /**
+ * Utility function to log comments
+ *
+ * @param content the content to log
+ */
+ public void log(String content) {
+ System.out.println("[LOG] " + content);
+ }
+
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java b/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java
index 2f3fe5739b58..4a1ccc9d3156 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java
@@ -23,9 +23,11 @@ public abstract class PaintOperation implements Operation {
@Override
public void apply(RemoteContext context) {
- if (context.getMode() == RemoteContext.ContextMode.PAINT
- && context.getPaintContext() != null) {
- paint((PaintContext) context.getPaintContext());
+ if (context.getMode() == RemoteContext.ContextMode.PAINT) {
+ PaintContext paintContext = context.getPaintContext();
+ if (paintContext != null) {
+ paint(paintContext);
+ }
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
index f5f155e3ab0b..333951ba2386 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
@@ -54,6 +54,18 @@ import com.android.internal.widget.remotecompose.core.operations.TextFromFloat;
import com.android.internal.widget.remotecompose.core.operations.TextMerge;
import com.android.internal.widget.remotecompose.core.operations.Theme;
import com.android.internal.widget.remotecompose.core.operations.Utils;
+import com.android.internal.widget.remotecompose.core.operations.layout.ComponentEnd;
+import com.android.internal.widget.remotecompose.core.operations.layout.ComponentStart;
+import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponentContent;
+import com.android.internal.widget.remotecompose.core.operations.layout.RootLayoutComponent;
+import com.android.internal.widget.remotecompose.core.operations.layout.managers.BoxLayout;
+import com.android.internal.widget.remotecompose.core.operations.layout.managers.ColumnLayout;
+import com.android.internal.widget.remotecompose.core.operations.layout.managers.RowLayout;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.BackgroundModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.BorderModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ClipRectModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.PaddingModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.RoundedClipRectModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.paint.PaintBundle;
import com.android.internal.widget.remotecompose.core.operations.utilities.easing.FloatAnimation;
import com.android.internal.widget.remotecompose.core.types.IntegerConstant;
@@ -132,8 +144,9 @@ public class RemoteComposeBuffer {
* @param contentDescription content description of the document
* @param capabilities bitmask indicating needed capabilities (unused for now)
*/
- public void header(int width, int height, String contentDescription, long capabilities) {
- Header.COMPANION.apply(mBuffer, width, height, capabilities);
+ public void header(int width, int height, String contentDescription,
+ float density, long capabilities) {
+ Header.COMPANION.apply(mBuffer, width, height, density, capabilities);
int contentDescriptionId = 0;
if (contentDescription != null) {
contentDescriptionId = addText(contentDescription);
@@ -149,7 +162,7 @@ public class RemoteComposeBuffer {
* @param contentDescription content description of the document
*/
public void header(int width, int height, String contentDescription) {
- header(width, height, contentDescription, 0);
+ header(width, height, contentDescription, 1f, 0);
}
/**
@@ -857,7 +870,7 @@ public class RemoteComposeBuffer {
}
/**
- * Sets the clip based on clip rec
+ * Sets the clip based on clip rect
* @param left
* @param top
* @param right
@@ -1074,5 +1087,128 @@ public class RemoteComposeBuffer {
NamedVariable.COLOR_TYPE, name);
}
+ /**
+ * Add a component start tag
+ * @param type type of component
+ * @param id component id
+ */
+ public void addComponentStart(int type, int id) {
+ switch (type) {
+ case ComponentStart.ROOT_LAYOUT: {
+ RootLayoutComponent.COMPANION.apply(mBuffer);
+ } break;
+ case ComponentStart.LAYOUT_CONTENT: {
+ LayoutComponentContent.COMPANION.apply(mBuffer);
+ } break;
+ case ComponentStart.LAYOUT_BOX: {
+ BoxLayout.COMPANION.apply(mBuffer, id, -1,
+ BoxLayout.CENTER, BoxLayout.CENTER);
+ } break;
+ case ComponentStart.LAYOUT_ROW: {
+ RowLayout.COMPANION.apply(mBuffer, id, -1,
+ RowLayout.START, RowLayout.TOP, 0f);
+ } break;
+ case ComponentStart.LAYOUT_COLUMN: {
+ ColumnLayout.COMPANION.apply(mBuffer, id, -1,
+ ColumnLayout.START, ColumnLayout.TOP, 0f);
+ } break;
+ default:
+ ComponentStart.Companion.apply(mBuffer,
+ type, id, 0f, 0f);
+ }
+ }
+
+ /**
+ * Add a component start tag
+ * @param type type of component
+ */
+ public void addComponentStart(int type) {
+ addComponentStart(type, -1);
+ }
+
+ /**
+ * Add a component end tag
+ */
+ public void addComponentEnd() {
+ ComponentEnd.Companion.apply(mBuffer);
+ }
+
+ /**
+ * Add a background modifier of provided color
+ * @param color the color of the background
+ * @param shape the background shape -- SHAPE_RECTANGLE, SHAPE_CIRCLE
+ */
+ public void addModifierBackground(int color, int shape) {
+ float r = ((color >> 16) & 0xff) / 255.0f;
+ float g = ((color >> 8) & 0xff) / 255.0f;
+ float b = ((color) & 0xff) / 255.0f;
+ float a = ((color >> 24) & 0xff) / 255.0f;
+ BackgroundModifierOperation.COMPANION.apply(mBuffer, 0f, 0f, 0f, 0f,
+ r, g, b, a, shape);
+ }
+
+ /**
+ * Add a border modifier
+ * @param borderWidth the border width
+ * @param borderRoundedCorner the rounded corner radius if the shape is ROUNDED_RECT
+ * @param color the color of the border
+ * @param shape the shape of the border
+ */
+ public void addModifierBorder(float borderWidth, float borderRoundedCorner,
+ int color, int shape) {
+ float r = ((color >> 16) & 0xff) / 255.0f;
+ float g = ((color >> 8) & 0xff) / 255.0f;
+ float b = ((color) & 0xff) / 255.0f;
+ float a = ((color >> 24) & 0xff) / 255.0f;
+ BorderModifierOperation.COMPANION.apply(mBuffer, 0f, 0f, 0f, 0f,
+ borderWidth, borderRoundedCorner, r, g, b, a, shape);
+ }
+
+ /**
+ * Add a padding modifier
+ * @param left left padding
+ * @param top top padding
+ * @param right right padding
+ * @param bottom bottom padding
+ */
+ public void addModifierPadding(float left, float top, float right, float bottom) {
+ PaddingModifierOperation.COMPANION.apply(mBuffer, left, top, right, bottom);
+ }
+
+
+ /**
+ * Sets the clip based on rounded clip rect
+ * @param topStart
+ * @param topEnd
+ * @param bottomStart
+ * @param bottomEnd
+ */
+ public void addRoundClipRectModifier(float topStart, float topEnd,
+ float bottomStart, float bottomEnd) {
+ RoundedClipRectModifierOperation.COMPANION.apply(mBuffer,
+ topStart, topEnd, bottomStart, bottomEnd);
+ }
+
+ public void addClipRectModifier() {
+ ClipRectModifierOperation.COMPANION.apply(mBuffer);
+ }
+
+ public void addBoxStart(int componentId, int animationId,
+ int horizontal, int vertical) {
+ BoxLayout.COMPANION.apply(mBuffer, componentId, animationId,
+ horizontal, vertical);
+ }
+
+ public void addRowStart(int componentId, int animationId,
+ int horizontal, int vertical, float spacedBy) {
+ RowLayout.COMPANION.apply(mBuffer, componentId, animationId,
+ horizontal, vertical, spacedBy);
+ }
+
+ public void addColumnStart(int componentId, int animationId,
+ int horizontal, int vertical, float spacedBy) {
+ ColumnLayout.COMPANION.apply(mBuffer, componentId, animationId,
+ horizontal, vertical, spacedBy);
+ }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
index 41eeb5bdd476..893dcce30842 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
@@ -19,6 +19,7 @@ import com.android.internal.widget.remotecompose.core.operations.FloatExpression
import com.android.internal.widget.remotecompose.core.operations.ShaderData;
import com.android.internal.widget.remotecompose.core.operations.Theme;
import com.android.internal.widget.remotecompose.core.operations.Utils;
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
/**
* Specify an abstract context used to playback RemoteCompose documents
@@ -35,12 +36,26 @@ public abstract class RemoteContext {
ContextMode mMode = ContextMode.UNSET;
boolean mDebug = false;
+
private int mTheme = Theme.UNSPECIFIED;
public float mWidth = 0f;
public float mHeight = 0f;
private float mAnimationTime;
+ private boolean mAnimate = true;
+
+ public Component lastComponent;
+ public long currentTime = 0L;
+
+ public boolean isAnimationEnabled() {
+ return mAnimate;
+ }
+
+ public void setAnimationEnabled(boolean value) {
+ mAnimate = value;
+ }
+
/**
* Load a path under an id.
* Paths can be use in clip drawPath and drawTweenPath
@@ -333,9 +348,11 @@ public abstract class RemoteContext {
public static final float FLOAT_COMPONENT_HEIGHT = Utils.asNan(ID_COMPONENT_HEIGHT);
// ID_OFFSET_TO_UTC is the offset from UTC in sec (typically / 3600f)
public static final float FLOAT_OFFSET_TO_UTC = Utils.asNan(ID_OFFSET_TO_UTC);
+
///////////////////////////////////////////////////////////////////////////////////////////////
// Click handling
///////////////////////////////////////////////////////////////////////////////////////////////
+
public abstract void addClickArea(
int id,
int contentDescription,
diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentationBuilder.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentationBuilder.java
new file mode 100644
index 000000000000..ccbcdf6e615d
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentationBuilder.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.documentation;
+
+public interface DocumentationBuilder {
+ void add(String value);
+ Operation operation(String category, int id, String name);
+ Operation wipOperation(String category, int id, String name);
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedCompanionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedCompanionOperation.java
new file mode 100644
index 000000000000..6a98b78f569d
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedCompanionOperation.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.documentation;
+
+import com.android.internal.widget.remotecompose.core.CompanionOperation;
+
+public interface DocumentedCompanionOperation extends CompanionOperation {
+ void documentation(DocumentationBuilder doc);
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/Operation.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/Operation.java
new file mode 100644
index 000000000000..643b925ae637
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/Operation.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.documentation;
+
+import java.util.ArrayList;
+
+public class Operation {
+ public static final int LAYOUT = 0;
+ public static final int INT = 0;
+ public static final int FLOAT = 1;
+ public static final int BOOLEAN = 2;
+ public static final int BUFFER = 4;
+ public static final int UTF8 = 5;
+ public static final int BYTE = 6;
+ public static final int VALUE = 7;
+ public static final int LONG = 8;
+
+ String mCategory;
+ int mId;
+ String mName;
+ String mDescription;
+
+ boolean mWIP;
+ String mTextExamples;
+
+ ArrayList<StringPair> mExamples = new ArrayList<>();
+ ArrayList<OperationField> mFields = new ArrayList<>();
+
+ int mExamplesWidth = 100;
+ int mExamplesHeight = 100;
+
+
+ public static String getType(int type) {
+ switch (type) {
+ case (INT): return "INT";
+ case (FLOAT): return "FLOAT";
+ case (BOOLEAN): return "BOOLEAN";
+ case (BUFFER): return "BUFFER";
+ case (UTF8): return "UTF8";
+ case (BYTE): return "BYTE";
+ case (VALUE): return "VALUE";
+ case (LONG): return "LONG";
+ }
+ return "UNKNOWN";
+ }
+
+ public Operation(String category, int id, String name, boolean wip) {
+ mCategory = category;
+ mId = id;
+ mName = name;
+ mWIP = wip;
+ }
+
+ public Operation(String category, int id, String name) {
+ this(category, id, name, false);
+ }
+
+ public ArrayList<OperationField> getFields() {
+ return mFields;
+ }
+
+ public String getCategory() {
+ return mCategory;
+ }
+
+ public int getId() {
+ return mId;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public boolean isWIP() {
+ return mWIP;
+ }
+
+ public int getSizeFields() {
+ int size = 0;
+ for (OperationField field : mFields) {
+ size += field.getSize();
+ }
+ return size;
+ }
+
+ public String getDescription() {
+ return mDescription;
+ }
+
+ public String getTextExamples() {
+ return mTextExamples;
+ }
+
+ public ArrayList<StringPair> getExamples() {
+ return mExamples;
+ }
+
+ public int getExamplesWidth() {
+ return mExamplesWidth;
+ }
+
+ public int getExamplesHeight() {
+ return mExamplesHeight;
+ }
+
+ public Operation field(int type, String name, String description) {
+ mFields.add(new OperationField(type, name, description));
+ return this;
+ }
+
+ public Operation possibleValues(String name, int value) {
+ if (!mFields.isEmpty()) {
+ mFields.get(mFields.size() - 1).possibleValue(name, "" + value);
+ }
+ return this;
+ }
+
+ public Operation description(String description) {
+ mDescription = description;
+ return this;
+ }
+
+ public Operation examples(String examples) {
+ mTextExamples = examples;
+ return this;
+ }
+
+ public Operation exampleImage(String name, String imagePath) {
+ mExamples.add(new StringPair(name, imagePath));
+ return this;
+ }
+
+ public Operation examplesDimension(int width, int height) {
+ mExamplesWidth = width;
+ mExamplesHeight = height;
+ return this;
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java
new file mode 100644
index 000000000000..fc73f4ed63f8
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.documentation;
+
+import java.util.ArrayList;
+
+public class OperationField {
+ int mType;
+ String mName;
+ String mDescription;
+ ArrayList<StringPair> mPossibleValues = new ArrayList<>();
+
+ public OperationField(int type, String name, String description) {
+ mType = type;
+ mName = name;
+ mDescription = description;
+ }
+ public int getType() {
+ return mType;
+ }
+ public String getName() {
+ return mName;
+ }
+ public String getDescription() {
+ return mDescription;
+ }
+ public ArrayList<StringPair> getPossibleValues() {
+ return mPossibleValues;
+ }
+ public void possibleValue(String name, String value) {
+ mPossibleValues.add(new StringPair(name, value));
+ }
+ public boolean hasEnumeratedValues() {
+ return !mPossibleValues.isEmpty();
+ }
+ public int getSize() {
+ switch (mType) {
+ case (Operation.BYTE) : return 1;
+ case (Operation.INT) : return 4;
+ case (Operation.FLOAT) : return 4;
+ case (Operation.LONG) : return 8;
+ default : return 0;
+ }
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/StringPair.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/StringPair.java
new file mode 100644
index 000000000000..787bb54a5f0a
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/StringPair.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.documentation;
+public class StringPair {
+ String mName;
+ String mValue;
+
+ StringPair(String name, String value) {
+ mName = name;
+ mValue = value;
+ }
+
+ public String getName() {
+ return mName;
+ }
+ public String getValue() {
+ return mValue;
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase4.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase4.java
index ec35a160079c..53a3aa917d0f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase4.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase4.java
@@ -41,10 +41,10 @@ public abstract class DrawBase4 extends PaintOperation
}
};
protected String mName = "DrawRectBase";
- float mX1;
- float mY1;
- float mX2;
- float mY2;
+ protected float mX1;
+ protected float mY1;
+ protected float mX2;
+ protected float mY2;
float mX1Value;
float mY1Value;
float mX2Value;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java b/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java
index aabed15e833d..9a1f37b22de5 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java
@@ -15,12 +15,16 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
-import com.android.internal.widget.remotecompose.core.CompanionOperation;
+import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT;
+import static com.android.internal.widget.remotecompose.core.documentation.Operation.LONG;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteComposeOperation;
import com.android.internal.widget.remotecompose.core.RemoteContext;
import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentedCompanionOperation;
import java.util.List;
@@ -41,6 +45,8 @@ public class Header implements RemoteComposeOperation {
int mWidth;
int mHeight;
+
+ float mDensity;
long mCapabilities;
public static final Companion COMPANION = new Companion();
@@ -54,21 +60,23 @@ public class Header implements RemoteComposeOperation {
* @param patchVersion the patch version of the RemoteCompose document API
* @param width the width of the RemoteCompose document
* @param height the height of the RemoteCompose document
+ * @param density the density at which the document was originally created
* @param capabilities bitmask field storing needed capabilities (unused for now)
*/
public Header(int majorVersion, int minorVersion, int patchVersion,
- int width, int height, long capabilities) {
+ int width, int height, float density, long capabilities) {
this.mMajorVersion = majorVersion;
this.mMinorVersion = minorVersion;
this.mPatchVersion = patchVersion;
this.mWidth = width;
this.mHeight = height;
+ this.mDensity = density;
this.mCapabilities = capabilities;
}
@Override
public void write(WireBuffer buffer) {
- COMPANION.apply(buffer, mWidth, mHeight, mCapabilities);
+ COMPANION.apply(buffer, mWidth, mHeight, mDensity, mCapabilities);
}
@Override
@@ -88,7 +96,7 @@ public class Header implements RemoteComposeOperation {
return toString();
}
- public static class Companion implements CompanionOperation {
+ public static class Companion implements DocumentedCompanionOperation {
private Companion() {
}
@@ -102,13 +110,15 @@ public class Header implements RemoteComposeOperation {
return Operations.HEADER;
}
- public void apply(WireBuffer buffer, int width, int height, long capabilities) {
+ public void apply(WireBuffer buffer, int width, int height,
+ float density, long capabilities) {
buffer.start(Operations.HEADER);
buffer.writeInt(MAJOR_VERSION); // major version number of the protocol
buffer.writeInt(MINOR_VERSION); // minor version number of the protocol
buffer.writeInt(PATCH_VERSION); // patch version number of the protocol
buffer.writeInt(width);
buffer.writeInt(height);
+ // buffer.writeFloat(density);
buffer.writeLong(capabilities);
}
@@ -119,10 +129,26 @@ public class Header implements RemoteComposeOperation {
int patchVersion = buffer.readInt();
int width = buffer.readInt();
int height = buffer.readInt();
+ // float density = buffer.readFloat();
+ float density = 1f;
long capabilities = buffer.readLong();
Header header = new Header(majorVersion, minorVersion, patchVersion,
- width, height, capabilities);
+ width, height, density, capabilities);
operations.add(header);
}
+
+ @Override
+ public void documentation(DocumentationBuilder doc) {
+ doc.operation("Protocol Operations", id(), name())
+ .description("Document metadata, containing the version,"
+ + " original size & density, capabilities mask")
+ .field(INT, "MAJOR_VERSION", "Major version")
+ .field(INT, "MINOR_VERSION", "Minor version")
+ .field(INT, "PATCH_VERSION", "Patch version")
+ .field(INT, "WIDTH", "Major version")
+ .field(INT, "HEIGHT", "Major version")
+ // .field(FLOAT, "DENSITY", "Major version")
+ .field(LONG, "CAPABILITIES", "Major version");
+ }
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java b/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java
index cbe9c12e666c..f98299770570 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java
@@ -15,12 +15,15 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
-import com.android.internal.widget.remotecompose.core.CompanionOperation;
+import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteComposeOperation;
import com.android.internal.widget.remotecompose.core.RemoteContext;
import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentedCompanionOperation;
import java.util.List;
@@ -70,12 +73,12 @@ public class Theme implements RemoteComposeOperation {
return indent + toString();
}
- public static class Companion implements CompanionOperation {
+ public static class Companion implements DocumentedCompanionOperation {
private Companion() {}
@Override
public String name() {
- return "SetTheme";
+ return "Theme";
}
@Override
@@ -93,5 +96,15 @@ public class Theme implements RemoteComposeOperation {
int theme = buffer.readInt();
operations.add(new Theme(theme));
}
+
+ @Override
+ public void documentation(DocumentationBuilder doc) {
+ doc.operation("Protocol Operations", id(), name())
+ .description("Set a theme")
+ .field(INT, "THEME", "theme id")
+ .possibleValues("UNSPECIFIED", Theme.UNSPECIFIED)
+ .possibleValues("DARK", Theme.DARK)
+ .possibleValues("LIGHT", Theme.LIGHT);
+ }
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
new file mode 100644
index 000000000000..ee2e11be6c1e
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
@@ -0,0 +1,473 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.PaintOperation;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.operations.layout.animation.AnimateMeasure;
+import com.android.internal.widget.remotecompose.core.operations.layout.animation.AnimationSpec;
+import com.android.internal.widget.remotecompose.core.operations.layout.measure.ComponentMeasure;
+import com.android.internal.widget.remotecompose.core.operations.layout.measure.Measurable;
+import com.android.internal.widget.remotecompose.core.operations.layout.measure.MeasurePass;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ComponentModifiers;
+import com.android.internal.widget.remotecompose.core.operations.paint.PaintBundle;
+import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
+
+import java.util.ArrayList;
+
+/**
+ * Generic Component class
+ */
+public class Component extends PaintOperation implements Measurable {
+
+ protected int mComponentId = -1;
+ protected float mX;
+ protected float mY;
+ protected float mWidth;
+ protected float mHeight;
+ protected Component mParent;
+ protected int mAnimationId = -1;
+ public Visibility mVisibility = Visibility.VISIBLE;
+ public ArrayList<Operation> mList = new ArrayList<>();
+ public PaintOperation mPreTranslate;
+ public boolean mNeedsMeasure = true;
+ public boolean mNeedsRepaint = false;
+ public AnimateMeasure mAnimateMeasure;
+ public AnimationSpec mAnimationSpec = new AnimationSpec();
+ public boolean mFirstLayout = true;
+ PaintBundle mPaint = new PaintBundle();
+
+ public ArrayList<Operation> getList() {
+ return mList;
+ }
+ public float getX() {
+ return mX;
+ }
+ public float getY() {
+ return mY;
+ }
+ public float getWidth() {
+ return mWidth;
+ }
+ public float getHeight() {
+ return mHeight;
+ }
+ public int getComponentId() {
+ return mComponentId;
+ }
+
+ public int getAnimationId() {
+ return mAnimationId;
+ }
+
+ public Component getParent() {
+ return mParent;
+ }
+ public void setX(float value) {
+ mX = value;
+ }
+ public void setY(float value) {
+ mY = value;
+ }
+ public void setWidth(float value) {
+ mWidth = value;
+ }
+ public void setHeight(float value) {
+ mHeight = value;
+ }
+
+ public void setComponentId(int id) {
+ mComponentId = id;
+ }
+
+ public void setAnimationId(int id) {
+ mAnimationId = id;
+ }
+
+ public Component(Component parent, int componentId, int animationId,
+ float x, float y, float width, float height) {
+ this.mComponentId = componentId;
+ this.mX = x;
+ this.mY = y;
+ this.mWidth = width;
+ this.mHeight = height;
+ this.mParent = parent;
+ this.mAnimationId = animationId;
+ }
+
+ public Component(int componentId, float x, float y, float width, float height,
+ Component parent) {
+ this(parent, componentId, -1, x, y, width, height);
+ }
+
+ public Component(Component component) {
+ this(component.mParent, component.mComponentId, component.mAnimationId,
+ component.mX, component.mY, component.mWidth, component.mHeight
+ );
+ mList.addAll(component.mList);
+ finalizeCreation();
+ }
+
+ public void finalizeCreation() {
+ for (Operation op : mList) {
+ if (op instanceof Component) {
+ ((Component) op).mParent = this;
+ }
+ if (op instanceof AnimationSpec) {
+ mAnimationSpec = (AnimationSpec) op;
+ mAnimationId = mAnimationSpec.getAnimationId();
+ }
+ }
+ }
+
+ @Override
+ public boolean needsMeasure() {
+ return mNeedsMeasure;
+ }
+
+ public void setParent(Component parent) {
+ mParent = parent;
+ }
+
+ public enum Visibility {
+ VISIBLE,
+ INVISIBLE,
+ GONE
+ }
+
+ public boolean isVisible() {
+ if (mVisibility != Visibility.VISIBLE || mParent == null) {
+ return mVisibility == Visibility.VISIBLE;
+ }
+ if (mParent != null) {
+ return mParent.isVisible();
+ }
+ return true;
+ }
+
+ @Override
+ public void measure(PaintContext context, float minWidth, float maxWidth,
+ float minHeight, float maxHeight, MeasurePass measure) {
+ ComponentMeasure m = measure.get(this);
+ m.setW(mWidth);
+ m.setH(mHeight);
+ }
+
+ @Override
+ public void layout(RemoteContext context, MeasurePass measure) {
+ ComponentMeasure m = measure.get(this);
+ if (!mFirstLayout && context.isAnimationEnabled()) {
+ if (mAnimateMeasure == null) {
+ ComponentMeasure origin = new ComponentMeasure(mComponentId,
+ mX, mY, mWidth, mHeight, mVisibility);
+ ComponentMeasure target = new ComponentMeasure(mComponentId,
+ m.getX(), m.getY(), m.getW(), m.getH(), m.getVisibility());
+ mAnimateMeasure = new AnimateMeasure(context.currentTime, this,
+ origin, target,
+ mAnimationSpec.getMotionDuration(), mAnimationSpec.getVisibilityDuration(),
+ mAnimationSpec.getEnterAnimation(), mAnimationSpec.getExitAnimation(),
+ mAnimationSpec.getMotionEasingType(),
+ mAnimationSpec.getVisibilityEasingType());
+ } else {
+ mAnimateMeasure.updateTarget(m, context.currentTime);
+ }
+ } else {
+ mVisibility = m.getVisibility();
+ }
+ mWidth = m.getW();
+ mHeight = m.getH();
+ setLayoutPosition(m.getX(), m.getY());
+ mFirstLayout = false;
+ }
+
+ public float[] locationInWindow = new float[2];
+
+ public boolean contains(float x, float y) {
+ locationInWindow[0] = 0f;
+ locationInWindow[1] = 0f;
+ getLocationInWindow(locationInWindow);
+ float lx1 = locationInWindow[0];
+ float lx2 = lx1 + mWidth;
+ float ly1 = locationInWindow[1];
+ float ly2 = ly1 + mHeight;
+ return x >= lx1 && x < lx2 && y >= ly1 && y < ly2;
+ }
+
+ public void onClick(float x, float y) {
+ if (!contains(x, y)) {
+ return;
+ }
+ for (Operation op : mList) {
+ if (op instanceof Component) {
+ ((Component) op).onClick(x, y);
+ }
+ if (op instanceof ComponentModifiers) {
+ ((ComponentModifiers) op).onClick(x, y);
+ }
+ }
+ }
+
+ public void getLocationInWindow(float[] value) {
+ value[0] += mX;
+ value[1] += mY;
+ if (mParent != null && mParent instanceof Component) {
+ if (mParent instanceof LayoutComponent) {
+ value[0] += ((LayoutComponent) mParent).getMarginLeft();
+ value[1] += ((LayoutComponent) mParent).getMarginTop();
+ }
+ mParent.getLocationInWindow(value);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "COMPONENT(<" + mComponentId + "> " + getClass().getSimpleName()
+ + ") [" + mX + "," + mY + " - " + mWidth + " x " + mHeight + "] " + textContent()
+ + " Visibility (" + mVisibility + ") ";
+ }
+
+ protected String getSerializedName() {
+ return "COMPONENT";
+ }
+
+ public void serializeToString(int indent, StringSerializer serializer) {
+ serializer.append(indent, getSerializedName() + " [" + mComponentId
+ + ":" + mAnimationId + "] = "
+ + "[" + mX + ", " + mY + ", " + mWidth + ", " + mHeight + "] "
+ + mVisibility
+ // + " [" + mNeedsMeasure + ", " + mNeedsRepaint + "]"
+ );
+ }
+
+ @Override
+ public void write(WireBuffer buffer) {
+ // nothing
+ }
+
+ /**
+ * Returns the top-level RootLayoutComponent
+ */
+ public RootLayoutComponent getRoot() throws Exception {
+ if (this instanceof RootLayoutComponent) {
+ return (RootLayoutComponent) this;
+ }
+ Component p = mParent;
+ while (!(p instanceof RootLayoutComponent)) {
+ if (p == null) {
+ throw new Exception("No RootLayoutComponent found");
+ }
+ p = p.mParent;
+ }
+ return (RootLayoutComponent) p;
+ }
+
+ @Override
+ public String deepToString(String indent) {
+ StringBuilder builder = new StringBuilder();
+ builder.append(indent);
+ builder.append(toString());
+ builder.append("\n");
+ String indent2 = " " + indent;
+ for (Operation op : mList) {
+ builder.append(op.deepToString(indent2));
+ builder.append("\n");
+ }
+ return builder.toString();
+ }
+
+ /**
+ * Mark itself as needing to be remeasured, and walk back up the tree
+ * to mark each parents as well.
+ */
+ public void invalidateMeasure() {
+ needsRepaint();
+ mNeedsMeasure = true;
+ Component p = mParent;
+ while (p != null) {
+ p.mNeedsMeasure = true;
+ p = p.mParent;
+ }
+ }
+
+ public void needsRepaint() {
+ try {
+ getRoot().mNeedsRepaint = true;
+ } catch (Exception e) {
+ // nothing
+ }
+ }
+
+ public String content() {
+ StringBuilder builder = new StringBuilder();
+ for (Operation op : mList) {
+ builder.append("- ");
+ builder.append(op);
+ builder.append("\n");
+ }
+ return builder.toString();
+ }
+
+ public String textContent() {
+ StringBuilder builder = new StringBuilder();
+ for (Operation op : mList) {
+ String letter = "";
+ // if (op instanceof DrawTextRun) {
+ // letter = "[" + ((DrawTextRun) op).text + "]";
+ // }
+ builder.append(letter);
+ }
+ return builder.toString();
+ }
+
+ public void debugBox(Component component, PaintContext context) {
+ float width = component.mWidth;
+ float height = component.mHeight;
+
+ context.savePaint();
+ mPaint.reset();
+ mPaint.setColor(0, 0, 255, 255); // Blue color
+ context.applyPaint(mPaint);
+ context.drawLine(0f, 0f, width, 0f);
+ context.drawLine(width, 0f, width, height);
+ context.drawLine(width, height, 0f, height);
+ context.drawLine(0f, height, 0f, 0f);
+ // context.setColor(255, 0, 0, 255)
+ // context.drawLine(0f, 0f, width, height)
+ // context.drawLine(0f, height, width, 0f)
+ context.restorePaint();
+ }
+
+ public void setLayoutPosition(float x, float y) {
+ this.mX = x;
+ this.mY = y;
+ }
+
+ public float getTranslateX() {
+ if (mParent != null) {
+ return mX - mParent.mX;
+ }
+ return 0f;
+ }
+
+ public float getTranslateY() {
+ if (mParent != null) {
+ return mY - mParent.mY;
+ }
+ return 0f;
+ }
+
+ public void paintingComponent(PaintContext context) {
+ if (mPreTranslate != null) {
+ mPreTranslate.paint(context);
+ }
+ context.save();
+ context.translate(mX, mY);
+ if (context.isDebug()) {
+ debugBox(this, context);
+ }
+ for (Operation op : mList) {
+ if (op instanceof PaintOperation) {
+ ((PaintOperation) op).paint(context);
+ }
+ }
+ context.restore();
+ }
+
+ public boolean applyAnimationAsNeeded(PaintContext context) {
+ if (context.isAnimationEnabled() && mAnimateMeasure != null) {
+ mAnimateMeasure.apply(context);
+ needsRepaint();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void paint(PaintContext context) {
+ if (context.isDebug()) {
+ context.save();
+ context.translate(mX, mY);
+ context.savePaint();
+ mPaint.reset();
+ mPaint.setColor(0, 255, 0, 255); // Green
+ context.applyPaint(mPaint);
+ context.drawLine(0f, 0f, mWidth, 0f);
+ context.drawLine(mWidth, 0f, mWidth, mHeight);
+ context.drawLine(mWidth, mHeight, 0f, mHeight);
+ context.drawLine(0f, mHeight, 0f, 0f);
+ mPaint.setColor(255, 0, 0, 255); // Red
+ context.applyPaint(mPaint);
+ context.drawLine(0f, 0f, mWidth, mHeight);
+ context.drawLine(0f, mHeight, mWidth, 0f);
+ context.restorePaint();
+ context.restore();
+ }
+ if (applyAnimationAsNeeded(context)) {
+ return;
+ }
+ if (mVisibility == Visibility.GONE) {
+ return;
+ }
+ paintingComponent(context);
+ }
+
+ public void getComponents(ArrayList<Component> components) {
+ for (Operation op : mList) {
+ if (op instanceof Component) {
+ components.add((Component) op);
+ }
+ }
+ }
+
+ public int getComponentCount() {
+ int count = 0;
+ for (Operation op : mList) {
+ if (op instanceof Component) {
+ count += 1 + ((Component) op).getComponentCount();
+ }
+ }
+ return count;
+ }
+
+ public int getPaintId() {
+ if (mAnimationId != -1) {
+ return mAnimationId;
+ }
+ return mComponentId;
+ }
+
+ public boolean doesNeedsRepaint() {
+ return mNeedsRepaint;
+ }
+
+ public Component getComponent(int cid) {
+ if (mComponentId == cid || mAnimationId == cid) {
+ return this;
+ }
+ for (Operation c : mList) {
+ if (c instanceof Component) {
+ Component search = ((Component) c).getComponent(cid);
+ if (search != null) {
+ return search;
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java
new file mode 100644
index 000000000000..8a523a20cab1
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentedCompanionOperation;
+
+import java.util.List;
+
+public class ComponentEnd implements Operation {
+
+ public static final ComponentEnd.Companion COMPANION = new ComponentEnd.Companion();
+
+ @Override
+ public void write(WireBuffer buffer) {
+ Companion.apply(buffer);
+ }
+
+ @Override
+ public String toString() {
+ return "COMPONENT_END";
+ }
+
+ @Override
+ public void apply(RemoteContext context) {
+ // nothing
+ }
+
+ @Override
+ public String deepToString(String indent) {
+ return (indent != null ? indent : "") + toString();
+ }
+
+ public static class Companion implements DocumentedCompanionOperation {
+ @Override
+ public String name() {
+ return "ComponentEnd";
+ }
+
+ @Override
+ public int id() {
+ return Operations.COMPONENT_END;
+ }
+
+ public static void apply(WireBuffer buffer) {
+ buffer.start(Operations.COMPONENT_END);
+ }
+
+ public static int size() {
+ return 1 + 4 + 4 + 4;
+ }
+
+ @Override
+ public void read(WireBuffer buffer, List<Operation> operations) {
+ operations.add(new ComponentEnd());
+ }
+
+ @Override
+ public void documentation(DocumentationBuilder doc) {
+ doc.operation("Layout Operations", id(), name())
+ .description("End tag for components / layouts. This operation marks the end"
+ + "of a component");
+ }
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java
new file mode 100644
index 000000000000..5cfad2521403
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout;
+
+import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT;
+import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentedCompanionOperation;
+
+import java.util.List;
+
+public class ComponentStart implements ComponentStartOperation {
+
+ public static final ComponentStart.Companion COMPANION = new ComponentStart.Companion();
+
+ int mType = DEFAULT;
+ float mX;
+ float mY;
+ float mWidth;
+ float mHeight;
+ int mComponentId;
+
+ public int getType() {
+ return mType;
+ }
+
+ public float getX() {
+ return mX;
+ }
+
+ public float getY() {
+ return mY;
+ }
+
+ public float getWidth() {
+ return mWidth;
+ }
+
+ public float getHeight() {
+ return mHeight;
+ }
+
+ public int getComponentId() {
+ return mComponentId;
+ }
+
+ public ComponentStart(int type, int componentId, float width, float height) {
+ this.mType = type;
+ this.mComponentId = componentId;
+ this.mX = 0f;
+ this.mY = 0f;
+ this.mWidth = width;
+ this.mHeight = height;
+ }
+
+ @Override
+ public void write(WireBuffer buffer) {
+ Companion.apply(buffer, mType, mComponentId, mWidth, mHeight);
+ }
+
+ @Override
+ public String toString() {
+ return "COMPONENT_START (type " + mType + " " + Companion.typeDescription(mType)
+ + ") - (" + mX + ", " + mY + " - " + mWidth + " x " + mHeight + ")";
+ }
+
+ @Override
+ public String deepToString(String indent) {
+ return (indent != null ? indent : "") + toString();
+ }
+
+ @Override
+ public void apply(RemoteContext context) {
+ // nothing
+ }
+
+ public static final int UNKNOWN = -1;
+ public static final int DEFAULT = 0;
+ public static final int ROOT_LAYOUT = 1;
+ public static final int LAYOUT = 2;
+ public static final int LAYOUT_CONTENT = 3;
+ public static final int SCROLL_CONTENT = 4;
+ public static final int BUTTON = 5;
+ public static final int CHECKBOX = 6;
+ public static final int TEXT = 7;
+ public static final int CURVED_TEXT = 8;
+ public static final int STATE_HOST = 9;
+ public static final int CUSTOM = 10;
+ public static final int LOTTIE = 11;
+ public static final int IMAGE = 12;
+ public static final int STATE_BOX_CONTENT = 13;
+ public static final int LAYOUT_BOX = 14;
+ public static final int LAYOUT_ROW = 15;
+ public static final int LAYOUT_COLUMN = 16;
+
+ public static class Companion implements DocumentedCompanionOperation {
+
+
+ public static String typeDescription(int type) {
+ switch (type) {
+ case DEFAULT:
+ return "DEFAULT";
+ case ROOT_LAYOUT:
+ return "ROOT_LAYOUT";
+ case LAYOUT:
+ return "LAYOUT";
+ case LAYOUT_CONTENT:
+ return "CONTENT";
+ case SCROLL_CONTENT:
+ return "SCROLL_CONTENT";
+ case BUTTON:
+ return "BUTTON";
+ case CHECKBOX:
+ return "CHECKBOX";
+ case TEXT:
+ return "TEXT";
+ case CURVED_TEXT:
+ return "CURVED_TEXT";
+ case STATE_HOST:
+ return "STATE_HOST";
+ case LOTTIE:
+ return "LOTTIE";
+ case CUSTOM:
+ return "CUSTOM";
+ case IMAGE:
+ return "IMAGE";
+ default:
+ return "UNKNOWN";
+ }
+ }
+
+ @Override
+ public String name() {
+ return "ComponentStart";
+ }
+
+ @Override
+ public int id() {
+ return Operations.COMPONENT_START;
+ }
+
+ public static void apply(WireBuffer buffer, int type, int componentId,
+ float width, float height) {
+ buffer.start(Operations.COMPONENT_START);
+ buffer.writeInt(type);
+ buffer.writeInt(componentId);
+ buffer.writeFloat(width);
+ buffer.writeFloat(height);
+ }
+
+ public static int size() {
+ return 1 + 4 + 4 + 4;
+ }
+
+ @Override
+ public void read(WireBuffer buffer, List<Operation> operations) {
+ int type = buffer.readInt();
+ int componentId = buffer.readInt();
+ float width = buffer.readFloat();
+ float height = buffer.readFloat();
+ operations.add(new ComponentStart(type, componentId, width, height));
+ }
+
+ @Override
+ public void documentation(DocumentationBuilder doc) {
+ doc.operation("Layout Operations", id(), name())
+ .description("Basic component encapsulating draw commands."
+ + "This is not resizable.")
+ .field(INT, "TYPE", "Type of components")
+ .field(INT, "COMPONENT_ID", "unique id for this component")
+ .field(FLOAT, "WIDTH", "width of the component")
+ .field(FLOAT, "HEIGHT", "height of the component");
+ }
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStartOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStartOperation.java
new file mode 100644
index 000000000000..67964efe816f
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStartOperation.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+
+public interface ComponentStartOperation extends Operation {
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/DecoratorComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/DecoratorComponent.java
new file mode 100644
index 000000000000..941666aa90d7
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/DecoratorComponent.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout;
+
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+
+/**
+ * Indicates a lightweight component (without children) that is only laid out and not able to be
+ * measured. Eg borders, background, clips, etc.
+ */
+public interface DecoratorComponent {
+ void layout(RemoteContext context, float width, float height);
+ void onClick(float x, float y);
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
new file mode 100644
index 000000000000..f198c4a9337b
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ComponentModifiers;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.DimensionModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.HeightModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.PaddingModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.WidthModifierOperation;
+
+import java.util.ArrayList;
+
+/**
+ * Component with modifiers and children
+ */
+public class LayoutComponent extends Component {
+
+ protected WidthModifierOperation mWidthModifier = null;
+ protected HeightModifierOperation mHeightModifier = null;
+
+ // Margins
+ protected float mMarginLeft = 0f;
+ protected float mMarginRight = 0f;
+ protected float mMarginTop = 0f;
+ protected float mMarginBottom = 0f;
+
+ protected float mPaddingLeft = 0f;
+ protected float mPaddingRight = 0f;
+ protected float mPaddingTop = 0f;
+ protected float mPaddingBottom = 0f;
+
+ protected ComponentModifiers mComponentModifiers = new ComponentModifiers();
+ protected ArrayList<Component> mChildrenComponents = new ArrayList<>();
+
+ public LayoutComponent(Component parent, int componentId, int animationId,
+ float x, float y, float width, float height) {
+ super(parent, componentId, animationId, x, y, width, height);
+ }
+
+ public float getMarginLeft() {
+ return mMarginLeft;
+ }
+ public float getMarginRight() {
+ return mMarginRight;
+ }
+ public float getMarginTop() {
+ return mMarginTop;
+ }
+ public float getMarginBottom() {
+ return mMarginBottom;
+ }
+
+ public WidthModifierOperation getWidthModifier() {
+ return mWidthModifier;
+ }
+ public HeightModifierOperation getHeightModifier() {
+ return mHeightModifier;
+ }
+
+ public void inflate() {
+ for (Operation op : mList) {
+ if (op instanceof LayoutComponentContent) {
+ ((LayoutComponentContent) op).mParent = this;
+ mChildrenComponents.clear();
+ ((LayoutComponentContent) op).getComponents(mChildrenComponents);
+ if (mChildrenComponents.isEmpty()) {
+ mChildrenComponents.add((Component) op);
+ }
+ } else if (op instanceof ModifierOperation) {
+ mComponentModifiers.add((ModifierOperation) op);
+ } else {
+ // nothing
+ }
+ }
+
+ mList.clear();
+ mList.add(mComponentModifiers);
+ for (Component c : mChildrenComponents) {
+ c.mParent = this;
+ mList.add(c);
+ }
+
+ mX = 0f;
+ mY = 0f;
+ mMarginLeft = 0f;
+ mMarginTop = 0f;
+ mMarginRight = 0f;
+ mMarginBottom = 0f;
+ mPaddingLeft = 0f;
+ mPaddingTop = 0f;
+ mPaddingRight = 0f;
+ mPaddingBottom = 0f;
+
+ boolean applyHorizontalMargin = true;
+ boolean applyVerticalMargin = true;
+ for (Operation op : mComponentModifiers.getList()) {
+ if (op instanceof PaddingModifierOperation) {
+ // We are accumulating padding modifiers to compute the margin
+ // until we hit a dimension; the computed padding for the
+ // content simply accumulate all the padding modifiers.
+ float left = ((PaddingModifierOperation) op).getLeft();
+ float right = ((PaddingModifierOperation) op).getRight();
+ float top = ((PaddingModifierOperation) op).getTop();
+ float bottom = ((PaddingModifierOperation) op).getBottom();
+ if (applyHorizontalMargin) {
+ mMarginLeft += left;
+ mMarginRight += right;
+ }
+ if (applyVerticalMargin) {
+ mMarginTop += top;
+ mMarginBottom += bottom;
+ }
+ mPaddingLeft += left;
+ mPaddingTop += top;
+ mPaddingRight += right;
+ mPaddingBottom += bottom;
+ }
+ if (op instanceof WidthModifierOperation && mWidthModifier == null) {
+ mWidthModifier = (WidthModifierOperation) op;
+ applyHorizontalMargin = false;
+ }
+ if (op instanceof HeightModifierOperation && mHeightModifier == null) {
+ mHeightModifier = (HeightModifierOperation) op;
+ applyVerticalMargin = false;
+ }
+ }
+ if (mWidthModifier == null) {
+ mWidthModifier = new WidthModifierOperation(DimensionModifierOperation.Type.WRAP);
+ }
+ if (mHeightModifier == null) {
+ mHeightModifier = new HeightModifierOperation(DimensionModifierOperation.Type.WRAP);
+ }
+ mWidth = computeModifierDefinedWidth();
+ mHeight = computeModifierDefinedHeight();
+ }
+
+ @Override
+ public String toString() {
+ return "UNKNOWN LAYOUT_COMPONENT";
+ }
+
+ @Override
+ public void paintingComponent(PaintContext context) {
+ context.save();
+ context.translate(mX, mY);
+ mComponentModifiers.paint(context);
+ float tx = mPaddingLeft;
+ float ty = mPaddingTop;
+ context.translate(tx, ty);
+ for (Component child : mChildrenComponents) {
+ child.paint(context);
+ }
+ context.translate(-tx, -ty);
+ context.restore();
+ }
+
+ /**
+ * Traverse the modifiers to compute indicated dimension
+ */
+ public float computeModifierDefinedWidth() {
+ float s = 0f;
+ float e = 0f;
+ float w = 0f;
+ for (Operation c : mComponentModifiers.getList()) {
+ if (c instanceof WidthModifierOperation) {
+ WidthModifierOperation o = (WidthModifierOperation) c;
+ if (o.getType() == DimensionModifierOperation.Type.EXACT) {
+ w = o.getValue();
+ }
+ break;
+ }
+ if (c instanceof PaddingModifierOperation) {
+ PaddingModifierOperation pop = (PaddingModifierOperation) c;
+ s += pop.getLeft();
+ e += pop.getRight();
+ }
+ }
+ return s + w + e;
+ }
+
+ /**
+ * Traverse the modifiers to compute indicated dimension
+ */
+ public float computeModifierDefinedHeight() {
+ float t = 0f;
+ float b = 0f;
+ float h = 0f;
+ for (Operation c : mComponentModifiers.getList()) {
+ if (c instanceof HeightModifierOperation) {
+ HeightModifierOperation o = (HeightModifierOperation) c;
+ if (o.getType() == DimensionModifierOperation.Type.EXACT) {
+ h = o.getValue();
+ }
+ break;
+ }
+ if (c instanceof PaddingModifierOperation) {
+ PaddingModifierOperation pop = (PaddingModifierOperation) c;
+ t += pop.getTop();
+ b += pop.getBottom();
+ }
+ }
+ return t + h + b;
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java
new file mode 100644
index 000000000000..769ff6ac3e7d
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentedCompanionOperation;
+
+import java.util.List;
+
+/**
+ * Represents the content of a LayoutComponent (i.e. the children components)
+ */
+public class LayoutComponentContent extends Component implements ComponentStartOperation {
+
+ public static final LayoutComponentContent.Companion COMPANION =
+ new LayoutComponentContent.Companion();
+
+ public LayoutComponentContent(int componentId, float x, float y,
+ float width, float height, Component parent, int animationId) {
+ super(parent, componentId, animationId, x, y, width, height);
+ }
+
+ public static class Companion implements DocumentedCompanionOperation {
+ @Override
+ public String name() {
+ return "LayoutContent";
+ }
+
+ @Override
+ public int id() {
+ return Operations.LAYOUT_CONTENT;
+ }
+
+ public void apply(WireBuffer buffer) {
+ buffer.start(Operations.LAYOUT_CONTENT);
+ }
+
+ @Override
+ public void read(WireBuffer buffer, List<Operation> operations) {
+ operations.add(new LayoutComponentContent(
+ -1, 0, 0, 0, 0, null, -1));
+ }
+
+ @Override
+ public void documentation(DocumentationBuilder doc) {
+ doc.operation("Layout Operations", id(), name())
+ .description("Container for components. BoxLayout, RowLayout and ColumnLayout "
+ + "expects a LayoutComponentContent as a child, encapsulating the "
+ + "components that needs to be laid out.");
+ }
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java
new file mode 100644
index 000000000000..dc13768992ce
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.PaintOperation;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentedCompanionOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.measure.Measurable;
+import com.android.internal.widget.remotecompose.core.operations.layout.measure.MeasurePass;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ComponentModifiers;
+import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
+
+import java.util.List;
+
+/**
+ * Represents the root layout component. Entry point to the component tree layout/paint.
+ */
+public class RootLayoutComponent extends Component implements ComponentStartOperation {
+
+ public static final RootLayoutComponent.Companion COMPANION =
+ new RootLayoutComponent.Companion();
+
+ int mCurrentId = -1;
+
+ public RootLayoutComponent(int componentId, float x, float y,
+ float width, float height, Component parent, int animationId) {
+ super(parent, componentId, animationId, x, y, width, height);
+ }
+
+ public RootLayoutComponent(int componentId, float x, float y,
+ float width, float height, Component parent) {
+ super(parent, componentId, -1, x, y, width, height);
+ }
+
+ @Override
+ public String toString() {
+ return "ROOT (" + mX + ", " + mY + " - " + mWidth + " x " + mHeight + ") " + mVisibility;
+ }
+
+ @Override
+ public void serializeToString(int indent, StringSerializer serializer) {
+ serializer.append(indent, "ROOT [" + mComponentId + ":" + mAnimationId
+ + "] = [" + mX + ", " + mY + ", " + mWidth + ", " + mHeight + "] " + mVisibility);
+ }
+
+ public int getNextId() {
+ mCurrentId--;
+ return mCurrentId;
+ }
+
+ public void assignIds() {
+ assignId(this);
+ }
+
+ void assignId(Component component) {
+ if (component.mComponentId == -1) {
+ component.mComponentId = getNextId();
+ }
+ for (Operation op : component.mList) {
+ if (op instanceof Component) {
+ assignId((Component) op);
+ }
+ }
+ }
+
+ /**
+ * This will measure then layout the tree of components
+ */
+ public void layout(RemoteContext context) {
+ if (!mNeedsMeasure) {
+ return;
+ }
+ context.lastComponent = this;
+ mWidth = context.mWidth;
+ mHeight = context.mHeight;
+
+ // TODO: reuse MeasurePass
+ MeasurePass measurePass = new MeasurePass();
+ for (Operation op : mList) {
+ if (op instanceof Measurable) {
+ Measurable m = (Measurable) op;
+ m.measure(context.getPaintContext(),
+ 0f, mWidth, 0f, mHeight, measurePass);
+ m.layout(context, measurePass);
+ }
+ }
+ mNeedsMeasure = false;
+ }
+
+ @Override
+ public void paint(PaintContext context) {
+ mNeedsRepaint = false;
+ context.getContext().lastComponent = this;
+ context.save();
+
+ if (mParent == null) { // root layout
+ context.clipRect(0f, 0f, mWidth, mHeight);
+ }
+
+ for (Operation op : mList) {
+ if (op instanceof PaintOperation) {
+ ((PaintOperation) op).paint(context);
+ }
+ }
+
+ context.restore();
+ }
+
+ public String displayHierarchy() {
+ StringSerializer serializer = new StringSerializer();
+ displayHierarchy(this, 0, serializer);
+ return serializer.toString();
+ }
+
+ public void displayHierarchy(Component component, int indent, StringSerializer serializer) {
+ component.serializeToString(indent, serializer);
+ for (Operation c : component.mList) {
+ if (c instanceof ComponentModifiers) {
+ ((ComponentModifiers) c).serializeToString(indent + 1, serializer);
+ }
+ if (c instanceof Component) {
+ displayHierarchy((Component) c, indent + 1, serializer);
+ }
+ }
+ }
+
+ public static class Companion implements DocumentedCompanionOperation {
+ @Override
+ public String name() {
+ return "RootLayout";
+ }
+
+ @Override
+ public int id() {
+ return Operations.LAYOUT_ROOT;
+ }
+
+ public void apply(WireBuffer buffer) {
+ buffer.start(Operations.LAYOUT_ROOT);
+ }
+
+ @Override
+ public void read(WireBuffer buffer, List<Operation> operations) {
+ operations.add(new RootLayoutComponent(
+ -1, 0, 0, 0, 0, null, -1));
+ }
+
+ @Override
+ public void documentation(DocumentationBuilder doc) {
+ doc.operation("Layout Operations", id(), name())
+ .description("Root element for a document. Other components / layout managers "
+ + "are children in the component tree starting from this Root component.");
+ }
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java
new file mode 100644
index 000000000000..7c6bef425eef
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.animation;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+import com.android.internal.widget.remotecompose.core.operations.layout.DecoratorComponent;
+import com.android.internal.widget.remotecompose.core.operations.layout.measure.ComponentMeasure;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.PaddingModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.paint.PaintBundle;
+import com.android.internal.widget.remotecompose.core.operations.utilities.easing.FloatAnimation;
+import com.android.internal.widget.remotecompose.core.operations.utilities.easing.GeneralEasing;
+
+/**
+ * Basic interpolation manager between two ComponentMeasures
+ *
+ * Handles position, size and visibility
+ */
+public class AnimateMeasure {
+ long mStartTime = System.currentTimeMillis();
+ Component mComponent;
+ ComponentMeasure mOriginal;
+ ComponentMeasure mTarget;
+ int mDuration;
+ int mDurationVisibilityChange = mDuration;
+ AnimationSpec.ANIMATION mEnterAnimation = AnimationSpec.ANIMATION.FADE_IN;
+ AnimationSpec.ANIMATION mExitAnimation = AnimationSpec.ANIMATION.FADE_OUT;
+ int mMotionEasingType = GeneralEasing.CUBIC_STANDARD;
+ int mVisibilityEasingType = GeneralEasing.CUBIC_ACCELERATE;
+
+ float mP = 0f;
+ float mVp = 0f;
+ FloatAnimation mMotionEasing = new FloatAnimation(mMotionEasingType,
+ mDuration / 1000f, null, 0f, Float.NaN);
+ FloatAnimation mVisibilityEasing = new FloatAnimation(mVisibilityEasingType,
+ mDurationVisibilityChange / 1000f,
+ null, 0f, Float.NaN);
+ ParticleAnimation mParticleAnimation;
+
+ public AnimateMeasure(long startTime, Component component, ComponentMeasure original,
+ ComponentMeasure target, int duration, int durationVisibilityChange,
+ AnimationSpec.ANIMATION enterAnimation,
+ AnimationSpec.ANIMATION exitAnimation,
+ int motionEasingType, int visibilityEasingType) {
+ this.mStartTime = startTime;
+ this.mComponent = component;
+ this.mOriginal = original;
+ this.mTarget = target;
+ this.mDuration = duration;
+ this.mDurationVisibilityChange = durationVisibilityChange;
+ this.mEnterAnimation = enterAnimation;
+ this.mExitAnimation = exitAnimation;
+
+ mMotionEasing.setTargetValue(1f);
+ mVisibilityEasing.setTargetValue(1f);
+ component.mVisibility = target.getVisibility();
+ }
+
+ public void update(long currentTime) {
+ long elapsed = currentTime - mStartTime;
+ mP = Math.min(elapsed / (float) mDuration, 1f);
+ //mP = motionEasing.get(mP);
+ mVp = Math.min(elapsed / (float) mDurationVisibilityChange, 1f);
+ mVp = mVisibilityEasing.get(mVp);
+ }
+
+ public PaintBundle paint = new PaintBundle();
+
+ public void apply(PaintContext context) {
+ update(context.getContext().currentTime);
+
+ mComponent.setX(getX());
+ mComponent.setY(getY());
+ mComponent.setWidth(getWidth());
+ mComponent.setHeight(getHeight());
+
+ float w = mComponent.getWidth();
+ float h = mComponent.getHeight();
+ for (Operation op : mComponent.mList) {
+ if (op instanceof PaddingModifierOperation) {
+ PaddingModifierOperation pop = (PaddingModifierOperation) op;
+ w -= pop.getLeft() + pop.getRight();
+ h -= pop.getTop() + pop.getBottom();
+ }
+ if (op instanceof DecoratorComponent) {
+ ((DecoratorComponent) op).layout(context.getContext(), w, h);
+ }
+ }
+
+ mComponent.mVisibility = mTarget.getVisibility();
+ if (mOriginal.getVisibility() != mTarget.getVisibility()) {
+ if (mTarget.getVisibility() == Component.Visibility.GONE) {
+ switch (mExitAnimation) {
+ case PARTICLE:
+ // particleAnimation(context, component, original, target, vp)
+ if (mParticleAnimation == null) {
+ mParticleAnimation = new ParticleAnimation();
+ }
+ mParticleAnimation.animate(context, mComponent, mOriginal, mTarget, mVp);
+ break;
+ case FADE_OUT:
+ context.save();
+ context.savePaint();
+ paint.reset();
+ paint.setColor(0f, 0f, 0f, 1f - mVp);
+ context.applyPaint(paint);
+ context.saveLayer(mComponent.getX(), mComponent.getY(),
+ mComponent.getWidth(), mComponent.getHeight());
+ mComponent.paintingComponent(context);
+ context.restore();
+ context.restorePaint();
+ context.restore();
+ break;
+ case SLIDE_LEFT:
+ context.save();
+ context.translate(-mVp * mComponent.getParent().getWidth(), 0f);
+ context.saveLayer(mComponent.getX(), mComponent.getY(),
+ mComponent.getWidth(), mComponent.getHeight());
+ mComponent.paintingComponent(context);
+ context.restore();
+ context.restore();
+ break;
+ case SLIDE_RIGHT:
+ context.save();
+ context.savePaint();
+ paint.reset();
+ paint.setColor(0f, 0f, 0f, 1f);
+ context.applyPaint(paint);
+ context.translate(mVp * mComponent.getParent().getWidth(), 0f);
+ context.saveLayer(mComponent.getX(), mComponent.getY(),
+ mComponent.getWidth(), mComponent.getHeight());
+ mComponent.paintingComponent(context);
+ context.restore();
+ context.restorePaint();
+ context.restore();
+ break;
+ case SLIDE_TOP:
+ context.save();
+ context.translate(0f,
+ -mVp * mComponent.getParent().getHeight());
+ context.saveLayer(mComponent.getX(), mComponent.getY(),
+ mComponent.getWidth(), mComponent.getHeight());
+ mComponent.paintingComponent(context);
+ context.restore();
+ context.restore();
+ break;
+ case SLIDE_BOTTOM:
+ context.save();
+ context.translate(0f,
+ mVp * mComponent.getParent().getHeight());
+ context.saveLayer(mComponent.getX(), mComponent.getY(),
+ mComponent.getWidth(), mComponent.getHeight());
+ mComponent.paintingComponent(context);
+ context.restore();
+ context.restore();
+ break;
+ default:
+ // particleAnimation(context, component, original, target, vp)
+ if (mParticleAnimation == null) {
+ mParticleAnimation = new ParticleAnimation();
+ }
+ mParticleAnimation.animate(context, mComponent, mOriginal, mTarget, mVp);
+ break;
+ }
+ } else if (mOriginal.getVisibility() == Component.Visibility.GONE
+ && mTarget.getVisibility() == Component.Visibility.VISIBLE) {
+ switch (mEnterAnimation) {
+ case ROTATE:
+ float px = mTarget.getX() + mTarget.getW() / 2f;
+ float py = mTarget.getY() + mTarget.getH() / 2f;
+
+ context.save();
+ context.savePaint();
+ context.matrixRotate(mVp * 360f, px, py);
+ context.matrixScale(1f * mVp, 1f * mVp, px, py);
+ paint.reset();
+ paint.setColor(0f, 0f, 0f, mVp);
+ context.applyPaint(paint);
+ context.saveLayer(mComponent.getX(), mComponent.getY(),
+ mComponent.getWidth(), mComponent.getHeight());
+ mComponent.paintingComponent(context);
+ context.restore();
+ context.restorePaint();
+ context.restore();
+ break;
+ case FADE_IN:
+ context.save();
+ context.savePaint();
+ paint.reset();
+ paint.setColor(0f, 0f, 0f, mVp);
+ context.applyPaint(paint);
+ context.saveLayer(mComponent.getX(), mComponent.getY(),
+ mComponent.getWidth(), mComponent.getHeight());
+ mComponent.paintingComponent(context);
+ context.restore();
+ context.restorePaint();
+ context.restore();
+ break;
+ case SLIDE_LEFT:
+ context.save();
+ context.translate(
+ (1f - mVp) * mComponent.getParent().getWidth(), 0f);
+ context.saveLayer(mComponent.getX(), mComponent.getY(),
+ mComponent.getWidth(), mComponent.getHeight());
+ mComponent.paintingComponent(context);
+ context.restore();
+ context.restore();
+ break;
+ case SLIDE_RIGHT:
+ context.save();
+ context.translate(
+ -(1f - mVp) * mComponent.getParent().getWidth(), 0f);
+ context.saveLayer(mComponent.getX(), mComponent.getY(),
+ mComponent.getWidth(), mComponent.getHeight());
+ mComponent.paintingComponent(context);
+ context.restore();
+ context.restore();
+ break;
+ case SLIDE_TOP:
+ context.save();
+ context.translate(0f,
+ (1f - mVp) * mComponent.getParent().getHeight());
+ context.saveLayer(mComponent.getX(), mComponent.getY(),
+ mComponent.getWidth(), mComponent.getHeight());
+ mComponent.paintingComponent(context);
+ context.restore();
+ context.restore();
+ break;
+ case SLIDE_BOTTOM:
+ context.save();
+ context.translate(0f,
+ -(1f - mVp) * mComponent.getParent().getHeight());
+ context.saveLayer(mComponent.getX(), mComponent.getY(),
+ mComponent.getWidth(), mComponent.getHeight());
+ mComponent.paintingComponent(context);
+ context.restore();
+ context.restore();
+ break;
+ default:
+ break;
+ }
+ } else {
+ mComponent.paintingComponent(context);
+ }
+ } else {
+ mComponent.paintingComponent(context);
+ }
+
+ if (mP >= 1f && mVp >= 1f) {
+ mComponent.mAnimateMeasure = null;
+ mComponent.mVisibility = mTarget.getVisibility();
+ }
+ }
+
+ public boolean isDone() {
+ return mP >= 1f && mVp >= 1f;
+ }
+
+ public float getX() {
+ return mOriginal.getX() * (1 - mP) + mTarget.getX() * mP;
+ }
+
+ public float getY() {
+ return mOriginal.getY() * (1 - mP) + mTarget.getY() * mP;
+ }
+
+ public float getWidth() {
+ return mOriginal.getW() * (1 - mP) + mTarget.getW() * mP;
+ }
+
+ public float getHeight() {
+ return mOriginal.getH() * (1 - mP) + mTarget.getH() * mP;
+ }
+
+ public float getVisibility() {
+ if (mOriginal.getVisibility() == mTarget.getVisibility()) {
+ return 1f;
+ } else if (mTarget.getVisibility() == Component.Visibility.VISIBLE) {
+ return mVp;
+ } else {
+ return 1 - mVp;
+ }
+ }
+
+ public void updateTarget(ComponentMeasure measure, long currentTime) {
+ mOriginal.setX(getX());
+ mOriginal.setY(getY());
+ mOriginal.setW(getWidth());
+ mOriginal.setH(getHeight());
+ mTarget.setX(measure.getX());
+ mTarget.setY(measure.getY());
+ mTarget.setW(measure.getW());
+ mTarget.setH(measure.getH());
+ mTarget.setVisibility(measure.getVisibility());
+ mStartTime = currentTime;
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java
new file mode 100644
index 000000000000..386d365ec033
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.animation;
+
+import com.android.internal.widget.remotecompose.core.CompanionOperation;
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.operations.utilities.easing.GeneralEasing;
+
+import java.util.List;
+
+/**
+ * Basic component animation spec
+ */
+public class AnimationSpec implements Operation {
+
+ public static final AnimationSpec.Companion COMPANION = new AnimationSpec.Companion();
+
+ int mAnimationId = -1;
+ int mMotionDuration = 300;
+ int mMotionEasingType = GeneralEasing.CUBIC_STANDARD;
+ int mVisibilityDuration = 300;
+ int mVisibilityEasingType = GeneralEasing.CUBIC_STANDARD;
+ ANIMATION mEnterAnimation = ANIMATION.FADE_IN;
+ ANIMATION mExitAnimation = ANIMATION.FADE_OUT;
+
+ public AnimationSpec(int animationId, int motionDuration, int motionEasingType,
+ int visibilityDuration, int visibilityEasingType,
+ ANIMATION enterAnimation, ANIMATION exitAnimation) {
+ this.mAnimationId = animationId;
+ this.mMotionDuration = motionDuration;
+ this.mMotionEasingType = motionEasingType;
+ this.mVisibilityDuration = visibilityDuration;
+ this.mVisibilityEasingType = visibilityEasingType;
+ this.mEnterAnimation = enterAnimation;
+ this.mExitAnimation = exitAnimation;
+ }
+
+ public AnimationSpec() {
+ this(-1, 300, GeneralEasing.CUBIC_STANDARD,
+ 300, GeneralEasing.CUBIC_STANDARD,
+ ANIMATION.FADE_IN, ANIMATION.FADE_OUT);
+ }
+
+ public int getAnimationId() {
+ return mAnimationId;
+ }
+
+ public int getMotionDuration() {
+ return mMotionDuration;
+ }
+
+ public int getMotionEasingType() {
+ return mMotionEasingType;
+ }
+
+ public int getVisibilityDuration() {
+ return mVisibilityDuration;
+ }
+
+ public int getVisibilityEasingType() {
+ return mVisibilityEasingType;
+ }
+
+ public ANIMATION getEnterAnimation() {
+ return mEnterAnimation;
+ }
+
+ public ANIMATION getExitAnimation() {
+ return mExitAnimation;
+ }
+
+ @Override
+ public String toString() {
+ return "ANIMATION_SPEC (" + mMotionDuration + " ms)";
+ }
+
+ public enum ANIMATION {
+ FADE_IN,
+ FADE_OUT,
+ SLIDE_LEFT,
+ SLIDE_RIGHT,
+ SLIDE_TOP,
+ SLIDE_BOTTOM,
+ ROTATE,
+ PARTICLE
+ }
+
+ @Override
+ public void write(WireBuffer buffer) {
+ Companion.apply(buffer, mAnimationId, mMotionDuration, mMotionEasingType,
+ mVisibilityDuration, mVisibilityEasingType, mEnterAnimation, mExitAnimation);
+ }
+
+ @Override
+ public void apply(RemoteContext context) {
+ // nothing here
+ }
+
+ @Override
+ public String deepToString(String indent) {
+ return (indent != null ? indent : "") + toString();
+ }
+
+ public static class Companion implements CompanionOperation {
+ @Override
+ public String name() {
+ return "AnimationSpec";
+ }
+
+ @Override
+ public int id() {
+ return Operations.ANIMATION_SPEC;
+ }
+
+ public static int animationToInt(ANIMATION animation) {
+ return animation.ordinal();
+ }
+
+ public static ANIMATION intToAnimation(int value) {
+ switch (value) {
+ case 0:
+ return ANIMATION.FADE_IN;
+ case 1:
+ return ANIMATION.FADE_OUT;
+ case 2:
+ return ANIMATION.SLIDE_LEFT;
+ case 3:
+ return ANIMATION.SLIDE_RIGHT;
+ case 4:
+ return ANIMATION.SLIDE_TOP;
+ case 5:
+ return ANIMATION.SLIDE_BOTTOM;
+ case 6:
+ return ANIMATION.ROTATE;
+ case 7:
+ return ANIMATION.PARTICLE;
+ default:
+ return ANIMATION.FADE_IN;
+ }
+ }
+
+ public static void apply(WireBuffer buffer, int animationId, int motionDuration,
+ int motionEasingType, int visibilityDuration,
+ int visibilityEasingType, ANIMATION enterAnimation,
+ ANIMATION exitAnimation) {
+ buffer.start(Operations.ANIMATION_SPEC);
+ buffer.writeInt(animationId);
+ buffer.writeInt(motionDuration);
+ buffer.writeInt(motionEasingType);
+ buffer.writeInt(visibilityDuration);
+ buffer.writeInt(visibilityEasingType);
+ buffer.writeInt(animationToInt(enterAnimation));
+ buffer.writeInt(animationToInt(exitAnimation));
+ }
+
+ @Override
+ public void read(WireBuffer buffer, List<Operation> operations) {
+ int animationId = buffer.readInt();
+ int motionDuration = buffer.readInt();
+ int motionEasingType = buffer.readInt();
+ int visibilityDuration = buffer.readInt();
+ int visibilityEasingType = buffer.readInt();
+ ANIMATION enterAnimation = intToAnimation(buffer.readInt());
+ ANIMATION exitAnimation = intToAnimation(buffer.readInt());
+ AnimationSpec op = new AnimationSpec(animationId, motionDuration, motionEasingType,
+ visibilityDuration, visibilityEasingType, enterAnimation, exitAnimation);
+ operations.add(op);
+ }
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/Particle.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/Particle.java
new file mode 100644
index 000000000000..45626921a4f6
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/Particle.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.animation;
+
+public class Particle {
+ public final float x;
+ public final float y;
+ public float radius;
+ public float r;
+ public float g;
+ public float b;
+
+ public Particle(float x, float y, float radius, float r, float g, float b) {
+ this.x = x;
+ this.y = y;
+ this.radius = radius;
+ this.r = r;
+ this.g = g;
+ this.b = b;
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/ParticleAnimation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/ParticleAnimation.java
new file mode 100644
index 000000000000..5c5d05658f65
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/ParticleAnimation.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.animation;
+
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+import com.android.internal.widget.remotecompose.core.operations.layout.measure.ComponentMeasure;
+import com.android.internal.widget.remotecompose.core.operations.paint.PaintBundle;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class ParticleAnimation {
+ HashMap<Integer, ArrayList<Particle>> mAllParticles = new HashMap<>();
+
+ PaintBundle mPaint = new PaintBundle();
+ public void animate(PaintContext context, Component component,
+ ComponentMeasure start, ComponentMeasure end,
+ float progress) {
+ ArrayList<Particle> particles = mAllParticles.get(component.getComponentId());
+ if (particles == null) {
+ particles = new ArrayList<Particle>();
+ for (int i = 0; i < 20; i++) {
+ float x = (float) Math.random();
+ float y = (float) Math.random();
+ float radius = (float) Math.random();
+ float r = 250f;
+ float g = 250f;
+ float b = 250f;
+ particles.add(new Particle(x, y, radius, r, g, b));
+ }
+ mAllParticles.put(component.getComponentId(), particles);
+ }
+ context.save();
+ context.savePaint();
+ for (int i = 0; i < particles.size(); i++) {
+ Particle particle = particles.get(i);
+ mPaint.reset();
+ mPaint.setColor(particle.r, particle.g, particle.b,
+ 200 * (1 - progress));
+ context.applyPaint(mPaint);
+ float dx = start.getX() + component.getWidth() * particle.x;
+ float dy = start.getY() + component.getHeight() * particle.y
+ + progress * 0.01f * component.getHeight();
+ float dr = (component.getHeight() + 60) * 0.15f * particle.radius + (30 * progress);
+ context.drawCircle(dx, dy, dr);
+ }
+ context.restorePaint();
+ context.restore();
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java
new file mode 100644
index 000000000000..fea8dd2de209
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.managers;
+
+import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentedCompanionOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+import com.android.internal.widget.remotecompose.core.operations.layout.ComponentStartOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.measure.ComponentMeasure;
+import com.android.internal.widget.remotecompose.core.operations.layout.measure.MeasurePass;
+import com.android.internal.widget.remotecompose.core.operations.layout.measure.Size;
+
+import java.util.List;
+
+/**
+ * Simple Box layout implementation
+ */
+public class BoxLayout extends LayoutManager implements ComponentStartOperation {
+
+ public static final int START = 1;
+ public static final int CENTER = 2;
+ public static final int END = 3;
+ public static final int TOP = 4;
+ public static final int BOTTOM = 5;
+
+ public static final BoxLayout.Companion COMPANION = new BoxLayout.Companion();
+
+ int mHorizontalPositioning;
+ int mVerticalPositioning;
+
+ public BoxLayout(Component parent, int componentId, int animationId,
+ float x, float y, float width, float height,
+ int horizontalPositioning, int verticalPositioning) {
+ super(parent, componentId, animationId, x, y, width, height);
+ mHorizontalPositioning = horizontalPositioning;
+ mVerticalPositioning = verticalPositioning;
+ }
+
+ public BoxLayout(Component parent, int componentId, int animationId,
+ int horizontalPositioning, int verticalPositioning) {
+ this(parent, componentId, animationId, 0, 0, 0, 0,
+ horizontalPositioning, verticalPositioning);
+ }
+
+ @Override
+ public String toString() {
+ return "BOX [" + mComponentId + ":" + mAnimationId + "] (" + mX + ", "
+ + mY + " - " + mWidth + " x " + mHeight + ") " + mVisibility;
+ }
+
+ protected String getSerializedName() {
+ return "BOX";
+ }
+
+ @Override
+ public void computeWrapSize(PaintContext context, float maxWidth, float maxHeight,
+ MeasurePass measure, Size size) {
+ for (Component c : mChildrenComponents) {
+ c.measure(context, 0f, maxWidth, 0f, maxHeight, measure);
+ ComponentMeasure m = measure.get(c);
+ size.setWidth(Math.max(size.getWidth(), m.getW()));
+ size.setHeight(Math.max(size.getHeight(), m.getH()));
+ }
+ // add padding
+ size.setWidth(Math.max(size.getWidth(), computeModifierDefinedWidth()));
+ size.setHeight(Math.max(size.getHeight(), computeModifierDefinedHeight()));
+ }
+
+ @Override
+ public void computeSize(PaintContext context, float minWidth, float maxWidth,
+ float minHeight, float maxHeight, MeasurePass measure) {
+ for (Component child : mChildrenComponents) {
+ child.measure(context, minWidth, maxWidth, minHeight, maxHeight, measure);
+ }
+ }
+
+ @Override
+ public void internalLayoutMeasure(PaintContext context,
+ MeasurePass measure) {
+ ComponentMeasure selfMeasure = measure.get(this);
+ float selfWidth = selfMeasure.getW() - mPaddingLeft - mPaddingRight;
+ float selfHeight = selfMeasure.getH() - mPaddingTop - mPaddingBottom;
+ for (Component child : mChildrenComponents) {
+ ComponentMeasure m = measure.get(child);
+ float tx = 0f;
+ float ty = 0f;
+ switch (mVerticalPositioning) {
+ case TOP:
+ ty = 0f;
+ break;
+ case CENTER:
+ ty = (selfHeight - m.getH()) / 2f;
+ break;
+ case BOTTOM:
+ ty = selfHeight - m.getH();
+ break;
+ }
+ switch (mHorizontalPositioning) {
+ case START:
+ tx = 0f;
+ break;
+ case CENTER:
+ tx = (selfWidth - m.getW()) / 2f;
+ break;
+ case END:
+ tx = selfWidth - m.getW();
+ break;
+ }
+ m.setX(tx);
+ m.setY(ty);
+ m.setVisibility(child.mVisibility);
+ }
+ }
+
+ public static class Companion implements DocumentedCompanionOperation {
+ @Override
+ public String name() {
+ return "BoxLayout";
+ }
+
+ @Override
+ public int id() {
+ return Operations.LAYOUT_BOX;
+ }
+
+ public void apply(WireBuffer buffer, int componentId, int animationId,
+ int horizontalPositioning, int verticalPositioning) {
+ buffer.start(Operations.LAYOUT_BOX);
+ buffer.writeInt(componentId);
+ buffer.writeInt(animationId);
+ buffer.writeInt(horizontalPositioning);
+ buffer.writeInt(verticalPositioning);
+ }
+
+ @Override
+ public void read(WireBuffer buffer, List<Operation> operations) {
+ int componentId = buffer.readInt();
+ int animationId = buffer.readInt();
+ int horizontalPositioning = buffer.readInt();
+ int verticalPositioning = buffer.readInt();
+ operations.add(new BoxLayout(null, componentId, animationId,
+ horizontalPositioning, verticalPositioning));
+ }
+
+ @Override
+ public void documentation(DocumentationBuilder doc) {
+ doc.operation("Layout Operations", id(), name())
+ .description("Box layout implementation.\n\n"
+ + "Child components are laid out independently from one another,\n"
+ + " and painted in their hierarchy order (first children drawn"
+ + "before the latter). Horizontal and Vertical positioning"
+ + "are supported.")
+ .examplesDimension(150, 100)
+ .exampleImage("Top", "layout-BoxLayout-start-top.png")
+ .exampleImage("Center", "layout-BoxLayout-center-center.png")
+ .exampleImage("Bottom", "layout-BoxLayout-end-bottom.png")
+ .field(INT, "COMPONENT_ID", "unique id for this component")
+ .field(INT, "ANIMATION_ID", "id used to match components,"
+ + " for animation purposes")
+ .field(INT, "HORIZONTAL_POSITIONING", "horizontal positioning value")
+ .possibleValues("START", BoxLayout.START)
+ .possibleValues("CENTER", BoxLayout.CENTER)
+ .possibleValues("END", BoxLayout.END)
+ .field(INT, "VERTICAL_POSITIONING", "vertical positioning value")
+ .possibleValues("TOP", BoxLayout.TOP)
+ .possibleValues("CENTER", BoxLayout.CENTER)
+ .possibleValues("BOTTOM", BoxLayout.BOTTOM);
+ }
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java
new file mode 100644
index 000000000000..a1a2de5302b8
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.managers;
+
+import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT;
+import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentedCompanionOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+import com.android.internal.widget.remotecompose.core.operations.layout.ComponentStartOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponent;
+import com.android.internal.widget.remotecompose.core.operations.layout.measure.ComponentMeasure;
+import com.android.internal.widget.remotecompose.core.operations.layout.measure.MeasurePass;
+import com.android.internal.widget.remotecompose.core.operations.layout.measure.Size;
+import com.android.internal.widget.remotecompose.core.operations.layout.utils.DebugLog;
+
+import java.util.List;
+
+/**
+ * Simple Column layout implementation
+ * - also supports weight and horizontal/vertical positioning
+ */
+public class ColumnLayout extends LayoutManager implements ComponentStartOperation {
+ public static final int START = 1;
+ public static final int CENTER = 2;
+ public static final int END = 3;
+ public static final int TOP = 4;
+ public static final int BOTTOM = 5;
+ public static final int SPACE_BETWEEN = 6;
+ public static final int SPACE_EVENLY = 7;
+ public static final int SPACE_AROUND = 8;
+
+ public static final ColumnLayout.Companion COMPANION = new ColumnLayout.Companion();
+
+ int mHorizontalPositioning;
+ int mVerticalPositioning;
+ float mSpacedBy = 0f;
+
+ public ColumnLayout(Component parent, int componentId, int animationId,
+ float x, float y, float width, float height,
+ int horizontalPositioning, int verticalPositioning, float spacedBy) {
+ super(parent, componentId, animationId, x, y, width, height);
+ mHorizontalPositioning = horizontalPositioning;
+ mVerticalPositioning = verticalPositioning;
+ mSpacedBy = spacedBy;
+ }
+
+ public ColumnLayout(Component parent, int componentId, int animationId,
+ int horizontalPositioning, int verticalPositioning, float spacedBy) {
+ this(parent, componentId, animationId, 0, 0, 0, 0,
+ horizontalPositioning, verticalPositioning, spacedBy);
+ }
+
+ @Override
+ public String toString() {
+ return "COLUMN [" + mComponentId + ":" + mAnimationId + "] (" + mX + ", "
+ + mY + " - " + mWidth + " x " + mHeight + ") " + mVisibility;
+ }
+
+ protected String getSerializedName() {
+ return "COLUMN";
+ }
+
+ @Override
+ public void computeWrapSize(PaintContext context, float maxWidth, float maxHeight,
+ MeasurePass measure, Size size) {
+ DebugLog.s(() -> "COMPUTE WRAP SIZE in " + this + " (" + mComponentId + ")");
+ for (Component c : mChildrenComponents) {
+ c.measure(context, 0f, maxWidth,
+ 0f, maxHeight, measure);
+ ComponentMeasure m = measure.get(c);
+ size.setWidth(Math.max(size.getWidth(), m.getW()));
+ size.setHeight(size.getHeight() + m.getH());
+ }
+ if (!mChildrenComponents.isEmpty()) {
+ size.setHeight(size.getHeight()
+ + (mSpacedBy * (mChildrenComponents.size() - 1)));
+ }
+ DebugLog.e();
+ }
+
+ @Override
+ public void computeSize(PaintContext context, float minWidth, float maxWidth,
+ float minHeight, float maxHeight, MeasurePass measure) {
+ DebugLog.s(() -> "COMPUTE SIZE in " + this + " (" + mComponentId + ")");
+ float mh = maxHeight;
+ for (Component child : mChildrenComponents) {
+ child.measure(context, minWidth, maxWidth, minHeight, mh, measure);
+ ComponentMeasure m = measure.get(child);
+ mh -= m.getH();
+ }
+ DebugLog.e();
+ }
+
+ @Override
+ public void internalLayoutMeasure(PaintContext context,
+ MeasurePass measure) {
+ ComponentMeasure selfMeasure = measure.get(this);
+ DebugLog.s(() -> "INTERNAL LAYOUT " + this + " (" + mComponentId + ") children: "
+ + mChildrenComponents.size() + " size (" + selfMeasure.getW()
+ + " x " + selfMeasure.getH() + ")");
+ if (mChildrenComponents.isEmpty()) {
+ DebugLog.e();
+ return;
+ }
+ float selfWidth = selfMeasure.getW() - mPaddingLeft - mPaddingRight;
+ float selfHeight = selfMeasure.getH() - mPaddingTop - mPaddingBottom;
+ float childrenWidth = 0f;
+ float childrenHeight = 0f;
+
+ boolean hasWeights = false;
+ float totalWeights = 0f;
+ for (Component child : mChildrenComponents) {
+ ComponentMeasure childMeasure = measure.get(child);
+ if (child instanceof LayoutComponent
+ && ((LayoutComponent) child).getHeightModifier().hasWeight()) {
+ hasWeights = true;
+ totalWeights += ((LayoutComponent) child).getHeightModifier().getValue();
+ } else {
+ childrenHeight += childMeasure.getH();
+ }
+ }
+ if (hasWeights) {
+ float availableSpace = selfHeight - childrenHeight;
+ for (Component child : mChildrenComponents) {
+ if (child instanceof LayoutComponent
+ && ((LayoutComponent) child).getHeightModifier().hasWeight()) {
+ ComponentMeasure childMeasure = measure.get(child);
+ float weight = ((LayoutComponent) child).getHeightModifier().getValue();
+ childMeasure.setH((weight * availableSpace) / totalWeights);
+ child.measure(context, childMeasure.getW(),
+ childMeasure.getW(), childMeasure.getH(), childMeasure.getH(), measure);
+ }
+ }
+ }
+
+ childrenHeight = 0f;
+ for (Component child : mChildrenComponents) {
+ ComponentMeasure childMeasure = measure.get(child);
+ childrenWidth = Math.max(childrenWidth, childMeasure.getW());
+ childrenHeight += childMeasure.getH();
+ }
+ childrenHeight += mSpacedBy * (mChildrenComponents.size() - 1);
+
+ float tx = 0f;
+ float ty = 0f;
+
+ float verticalGap = 0f;
+ float total = 0f;
+ switch (mVerticalPositioning) {
+ case TOP:
+ ty = 0f;
+ break;
+ case CENTER:
+ ty = (selfHeight - childrenHeight) / 2f;
+ break;
+ case BOTTOM:
+ ty = selfHeight - childrenHeight;
+ break;
+ case SPACE_BETWEEN:
+ for (Component child : mChildrenComponents) {
+ ComponentMeasure childMeasure = measure.get(child);
+ total += childMeasure.getH();
+ }
+ verticalGap = (selfHeight - total) / (mChildrenComponents.size() - 1);
+ break;
+ case SPACE_EVENLY:
+ for (Component child : mChildrenComponents) {
+ ComponentMeasure childMeasure = measure.get(child);
+ total += childMeasure.getH();
+ }
+ verticalGap = (selfHeight - total) / (mChildrenComponents.size() + 1);
+ ty = verticalGap;
+ break;
+ case SPACE_AROUND:
+ for (Component child : mChildrenComponents) {
+ ComponentMeasure childMeasure = measure.get(child);
+ total += childMeasure.getH();
+ }
+ verticalGap = (selfHeight - total) / (mChildrenComponents.size());
+ ty = verticalGap / 2f;
+ break;
+ }
+ for (Component child : mChildrenComponents) {
+ ComponentMeasure childMeasure = measure.get(child);
+ switch (mHorizontalPositioning) {
+ case START:
+ tx = 0f;
+ break;
+ case CENTER:
+ tx = (selfWidth - childMeasure.getW()) / 2f;
+ break;
+ case END:
+ tx = selfWidth - childMeasure.getW();
+ break;
+ }
+ childMeasure.setX(tx);
+ childMeasure.setY(ty);
+ childMeasure.setVisibility(child.mVisibility);
+ ty += childMeasure.getH();
+ if (mVerticalPositioning == SPACE_BETWEEN
+ || mVerticalPositioning == SPACE_AROUND
+ || mVerticalPositioning == SPACE_EVENLY) {
+ ty += verticalGap;
+ }
+ ty += mSpacedBy;
+ }
+ DebugLog.e();
+ }
+
+ public static class Companion implements DocumentedCompanionOperation {
+ @Override
+ public String name() {
+ return "ColumnLayout";
+ }
+
+ @Override
+ public int id() {
+ return Operations.LAYOUT_COLUMN;
+ }
+
+ public void apply(WireBuffer buffer, int componentId, int animationId,
+ int horizontalPositioning, int verticalPositioning, float spacedBy) {
+ buffer.start(Operations.LAYOUT_COLUMN);
+ buffer.writeInt(componentId);
+ buffer.writeInt(animationId);
+ buffer.writeInt(horizontalPositioning);
+ buffer.writeInt(verticalPositioning);
+ buffer.writeFloat(spacedBy);
+ }
+
+ @Override
+ public void read(WireBuffer buffer, List<Operation> operations) {
+ int componentId = buffer.readInt();
+ int animationId = buffer.readInt();
+ int horizontalPositioning = buffer.readInt();
+ int verticalPositioning = buffer.readInt();
+ float spacedBy = buffer.readFloat();
+ operations.add(new ColumnLayout(null, componentId, animationId,
+ horizontalPositioning, verticalPositioning, spacedBy));
+ }
+
+ @Override
+ public void documentation(DocumentationBuilder doc) {
+ doc.operation("Layout Operations", id(), name())
+ .description("Column layout implementation, positioning components one"
+ + " after the other vertically.\n\n"
+ + "It supports weight and horizontal/vertical positioning.")
+ .examplesDimension(100, 400)
+ .exampleImage("Top", "layout-ColumnLayout-start-top.png")
+ .exampleImage("Center", "layout-ColumnLayout-start-center.png")
+ .exampleImage("Bottom", "layout-ColumnLayout-start-bottom.png")
+ .exampleImage("SpaceEvenly", "layout-ColumnLayout-start-space-evenly.png")
+ .exampleImage("SpaceAround", "layout-ColumnLayout-start-space-around.png")
+ .exampleImage("SpaceBetween", "layout-ColumnLayout-start-space-between.png")
+ .field(INT, "COMPONENT_ID", "unique id for this component")
+ .field(INT, "ANIMATION_ID", "id used to match components,"
+ + " for animation purposes")
+ .field(INT, "HORIZONTAL_POSITIONING", "horizontal positioning value")
+ .possibleValues("START", ColumnLayout.START)
+ .possibleValues("CENTER", ColumnLayout.CENTER)
+ .possibleValues("END", ColumnLayout.END)
+ .field(INT, "VERTICAL_POSITIONING", "vertical positioning value")
+ .possibleValues("TOP", ColumnLayout.TOP)
+ .possibleValues("CENTER", ColumnLayout.CENTER)
+ .possibleValues("BOTTOM", ColumnLayout.BOTTOM)
+ .possibleValues("SPACE_BETWEEN", ColumnLayout.SPACE_BETWEEN)
+ .possibleValues("SPACE_EVENLY", ColumnLayout.SPACE_EVENLY)
+ .possibleValues("SPACE_AROUND", ColumnLayout.SPACE_AROUND)
+ .field(FLOAT, "SPACED_BY", "Horizontal spacing between components");
+ }
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java
new file mode 100644
index 000000000000..48906837ef94
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.managers;
+
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponent;
+import com.android.internal.widget.remotecompose.core.operations.layout.measure.ComponentMeasure;
+import com.android.internal.widget.remotecompose.core.operations.layout.measure.Measurable;
+import com.android.internal.widget.remotecompose.core.operations.layout.measure.MeasurePass;
+import com.android.internal.widget.remotecompose.core.operations.layout.measure.Size;
+
+/**
+ * Base class for layout managers -- resizable components.
+ */
+public abstract class LayoutManager extends LayoutComponent implements Measurable {
+
+ Size mCachedWrapSize = new Size(0f, 0f);
+
+ public LayoutManager(Component parent, int componentId, int animationId,
+ float x, float y, float width, float height) {
+ super(parent, componentId, animationId, x, y, width, height);
+ }
+
+ /**
+ * Implemented by subclasses to provide a layout/measure pass
+ */
+ public void internalLayoutMeasure(PaintContext context,
+ MeasurePass measure) {
+ // nothing here
+ }
+
+ /**
+ * Subclasses can implement this to provide wrap sizing
+ */
+ public void computeWrapSize(PaintContext context, float maxWidth, float maxHeight,
+ MeasurePass measure, Size size) {
+ // nothing here
+ }
+
+ /**
+ * Subclasses can implement this when not in wrap sizing
+ */
+ public void computeSize(PaintContext context, float minWidth, float maxWidth,
+ float minHeight, float maxHeight, MeasurePass measure) {
+ // nothing here
+ }
+
+ /**
+ * Base implementation of the measure resolution
+ */
+ @Override
+ public void measure(PaintContext context, float minWidth, float maxWidth,
+ float minHeight, float maxHeight, MeasurePass measure) {
+ boolean hasWrap = true;
+ float measuredWidth = Math.min(maxWidth,
+ computeModifierDefinedWidth() - mMarginLeft - mMarginRight);
+ float measuredHeight = Math.min(maxHeight,
+ computeModifierDefinedHeight() - mMarginTop - mMarginBottom);
+ float insetMaxWidth = maxWidth - mMarginLeft - mMarginRight;
+ float insetMaxHeight = maxHeight - mMarginTop - mMarginBottom;
+ if (mWidthModifier.isWrap() || mHeightModifier.isWrap()) {
+ mCachedWrapSize.setWidth(0f);
+ mCachedWrapSize.setHeight(0f);
+ computeWrapSize(context, maxWidth, maxHeight, measure, mCachedWrapSize);
+ measuredWidth = mCachedWrapSize.getWidth();
+ measuredHeight = mCachedWrapSize.getHeight();
+ } else {
+ hasWrap = false;
+ }
+ if (mWidthModifier.isFill()) {
+ measuredWidth = insetMaxWidth;
+ } else if (mWidthModifier.hasWeight()) {
+ measuredWidth = Math.max(measuredWidth, computeModifierDefinedWidth());
+ } else {
+ measuredWidth = Math.max(measuredWidth, minWidth);
+ measuredWidth = Math.min(measuredWidth, insetMaxWidth);
+ }
+ if (mHeightModifier.isFill()) {
+ measuredHeight = insetMaxHeight;
+ } else if (mHeightModifier.hasWeight()) {
+ measuredHeight = Math.max(measuredHeight, computeModifierDefinedHeight());
+ } else {
+ measuredHeight = Math.max(measuredHeight, minHeight);
+ measuredHeight = Math.min(measuredHeight, insetMaxHeight);
+ }
+ if (minWidth == maxWidth) {
+ measuredWidth = maxWidth;
+ }
+ if (minHeight == maxHeight) {
+ measuredHeight = maxHeight;
+ }
+ measuredWidth = Math.min(measuredWidth, insetMaxWidth);
+ measuredHeight = Math.min(measuredHeight, insetMaxHeight);
+ if (!hasWrap) {
+ computeSize(context, 0f, measuredWidth, 0f, measuredHeight, measure);
+ }
+ measuredWidth += mMarginLeft + mMarginRight;
+ measuredHeight += mMarginTop + mMarginBottom;
+
+ ComponentMeasure m = measure.get(this);
+ m.setW(measuredWidth);
+ m.setH(measuredHeight);
+
+ internalLayoutMeasure(context, measure);
+ }
+
+ /**
+ * basic layout of internal components
+ */
+ @Override
+ public void layout(RemoteContext context, MeasurePass measure) {
+ super.layout(context, measure);
+ ComponentMeasure self = measure.get(this);
+
+ mComponentModifiers.layout(context, self.getW(), self.getH());
+ for (Component c : mChildrenComponents) {
+ c.layout(context, measure);
+ }
+ this.mNeedsMeasure = false;
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java
new file mode 100644
index 000000000000..07e2ea186ca5
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.managers;
+
+import static com.android.internal.widget.remotecompose.core.documentation.Operation.FLOAT;
+import static com.android.internal.widget.remotecompose.core.documentation.Operation.INT;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentedCompanionOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+import com.android.internal.widget.remotecompose.core.operations.layout.ComponentStartOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponent;
+import com.android.internal.widget.remotecompose.core.operations.layout.measure.ComponentMeasure;
+import com.android.internal.widget.remotecompose.core.operations.layout.measure.MeasurePass;
+import com.android.internal.widget.remotecompose.core.operations.layout.measure.Size;
+import com.android.internal.widget.remotecompose.core.operations.layout.utils.DebugLog;
+
+import java.util.List;
+
+/**
+ * Simple Row layout implementation
+ * - also supports weight and horizontal/vertical positioning
+ */
+public class RowLayout extends LayoutManager implements ComponentStartOperation {
+ public static final int START = 1;
+ public static final int CENTER = 2;
+ public static final int END = 3;
+ public static final int TOP = 4;
+ public static final int BOTTOM = 5;
+ public static final int SPACE_BETWEEN = 6;
+ public static final int SPACE_EVENLY = 7;
+ public static final int SPACE_AROUND = 8;
+
+ public static final RowLayout.Companion COMPANION = new RowLayout.Companion();
+
+ int mHorizontalPositioning;
+ int mVerticalPositioning;
+ float mSpacedBy = 0f;
+
+ public RowLayout(Component parent, int componentId, int animationId,
+ float x, float y, float width, float height,
+ int horizontalPositioning, int verticalPositioning, float spacedBy) {
+ super(parent, componentId, animationId, x, y, width, height);
+ mHorizontalPositioning = horizontalPositioning;
+ mVerticalPositioning = verticalPositioning;
+ mSpacedBy = spacedBy;
+ }
+
+ public RowLayout(Component parent, int componentId, int animationId,
+ int horizontalPositioning, int verticalPositioning, float spacedBy) {
+ this(parent, componentId, animationId, 0, 0, 0, 0,
+ horizontalPositioning, verticalPositioning, spacedBy);
+ }
+ @Override
+ public String toString() {
+ return "ROW [" + mComponentId + ":" + mAnimationId + "] (" + mX + ", "
+ + mY + " - " + mWidth + " x " + mHeight + ") " + mVisibility;
+ }
+
+ protected String getSerializedName() {
+ return "ROW";
+ }
+
+ @Override
+ public void computeWrapSize(PaintContext context, float maxWidth, float maxHeight,
+ MeasurePass measure, Size size) {
+ DebugLog.s(() -> "COMPUTE WRAP SIZE in " + this + " (" + mComponentId + ")");
+ for (Component c : mChildrenComponents) {
+ c.measure(context, 0f, maxWidth, 0f, maxHeight, measure);
+ ComponentMeasure m = measure.get(c);
+ size.setWidth(size.getWidth() + m.getW());
+ size.setHeight(Math.max(size.getHeight(), m.getH()));
+ }
+ if (!mChildrenComponents.isEmpty()) {
+ size.setWidth(size.getWidth()
+ + (mSpacedBy * (mChildrenComponents.size() - 1)));
+ }
+ DebugLog.e();
+ }
+
+ @Override
+ public void computeSize(PaintContext context, float minWidth, float maxWidth,
+ float minHeight, float maxHeight, MeasurePass measure) {
+ DebugLog.s(() -> "COMPUTE SIZE in " + this + " (" + mComponentId + ")");
+ float mw = maxWidth;
+ for (Component child : mChildrenComponents) {
+ child.measure(context, minWidth, mw, minHeight, maxHeight, measure);
+ ComponentMeasure m = measure.get(child);
+ mw -= m.getW();
+ }
+ DebugLog.e();
+ }
+
+ @Override
+ public void internalLayoutMeasure(PaintContext context,
+ MeasurePass measure) {
+ ComponentMeasure selfMeasure = measure.get(this);
+ DebugLog.s(() -> "INTERNAL LAYOUT " + this + " (" + mComponentId + ") children: "
+ + mChildrenComponents.size() + " size (" + selfMeasure.getW()
+ + " x " + selfMeasure.getH() + ")");
+ if (mChildrenComponents.isEmpty()) {
+ DebugLog.e();
+ return;
+ }
+ float selfWidth = selfMeasure.getW() - mPaddingLeft - mPaddingRight;
+ float selfHeight = selfMeasure.getH() - mPaddingTop - mPaddingBottom;
+ float childrenWidth = 0f;
+ float childrenHeight = 0f;
+
+ boolean hasWeights = false;
+ float totalWeights = 0f;
+ for (Component child : mChildrenComponents) {
+ ComponentMeasure childMeasure = measure.get(child);
+ if (child instanceof LayoutComponent
+ && ((LayoutComponent) child).getWidthModifier().hasWeight()) {
+ hasWeights = true;
+ totalWeights += ((LayoutComponent) child).getWidthModifier().getValue();
+ } else {
+ childrenWidth += childMeasure.getW();
+ }
+ }
+
+ // TODO: need to move the weight measuring in the measure function,
+ // currently we'll measure unnecessarily
+ if (hasWeights) {
+ float availableSpace = selfWidth - childrenWidth;
+ for (Component child : mChildrenComponents) {
+ if (child instanceof LayoutComponent
+ && ((LayoutComponent) child).getWidthModifier().hasWeight()) {
+ ComponentMeasure childMeasure = measure.get(child);
+ float weight = ((LayoutComponent) child).getWidthModifier().getValue();
+ childMeasure.setW((weight * availableSpace) / totalWeights);
+ child.measure(context, childMeasure.getW(),
+ childMeasure.getW(), childMeasure.getH(), childMeasure.getH(), measure);
+ }
+ }
+ }
+
+ childrenWidth = 0f;
+ for (Component child : mChildrenComponents) {
+ ComponentMeasure childMeasure = measure.get(child);
+ childrenWidth += childMeasure.getW();
+ childrenHeight = Math.max(childrenHeight, childMeasure.getH());
+ }
+ childrenWidth += mSpacedBy * (mChildrenComponents.size() - 1);
+
+ float tx = 0f;
+ float ty = 0f;
+
+ float horizontalGap = 0f;
+ float total = 0f;
+
+ switch (mHorizontalPositioning) {
+ case START:
+ tx = 0f;
+ break;
+ case END:
+ tx = selfWidth - childrenWidth;
+ break;
+ case CENTER:
+ tx = (selfWidth - childrenWidth) / 2f;
+ break;
+ case SPACE_BETWEEN:
+ for (Component child : mChildrenComponents) {
+ ComponentMeasure childMeasure = measure.get(child);
+ total += childMeasure.getW();
+ }
+ horizontalGap = (selfWidth - total) / (mChildrenComponents.size() - 1);
+ break;
+ case SPACE_EVENLY:
+ for (Component child : mChildrenComponents) {
+ ComponentMeasure childMeasure = measure.get(child);
+ total += childMeasure.getW();
+ }
+ horizontalGap = (selfWidth - total) / (mChildrenComponents.size() + 1);
+ tx = horizontalGap;
+ break;
+ case SPACE_AROUND:
+ for (Component child : mChildrenComponents) {
+ ComponentMeasure childMeasure = measure.get(child);
+ total += childMeasure.getW();
+ }
+ horizontalGap = (selfWidth - total) / (mChildrenComponents.size());
+ tx = horizontalGap / 2f;
+ break;
+ }
+
+ for (Component child : mChildrenComponents) {
+ ComponentMeasure childMeasure = measure.get(child);
+ switch (mVerticalPositioning) {
+ case TOP:
+ ty = 0f;
+ break;
+ case CENTER:
+ ty = (selfHeight - childMeasure.getH()) / 2f;
+ break;
+ case BOTTOM:
+ ty = selfHeight - childMeasure.getH();
+ break;
+ }
+ childMeasure.setX(tx);
+ childMeasure.setY(ty);
+ childMeasure.setVisibility(child.mVisibility);
+ tx += childMeasure.getW();
+ if (mHorizontalPositioning == SPACE_BETWEEN
+ || mHorizontalPositioning == SPACE_AROUND
+ || mHorizontalPositioning == SPACE_EVENLY) {
+ tx += horizontalGap;
+ }
+ tx += mSpacedBy;
+ }
+ DebugLog.e();
+ }
+
+ public static class Companion implements DocumentedCompanionOperation {
+ @Override
+ public String name() {
+ return "RowLayout";
+ }
+
+ @Override
+ public int id() {
+ return Operations.LAYOUT_ROW;
+ }
+
+ public void apply(WireBuffer buffer, int componentId, int animationId,
+ int horizontalPositioning, int verticalPositioning, float spacedBy) {
+ buffer.start(Operations.LAYOUT_ROW);
+ buffer.writeInt(componentId);
+ buffer.writeInt(animationId);
+ buffer.writeInt(horizontalPositioning);
+ buffer.writeInt(verticalPositioning);
+ buffer.writeFloat(spacedBy);
+ }
+
+ @Override
+ public void read(WireBuffer buffer, List<Operation> operations) {
+ int componentId = buffer.readInt();
+ int animationId = buffer.readInt();
+ int horizontalPositioning = buffer.readInt();
+ int verticalPositioning = buffer.readInt();
+ float spacedBy = buffer.readFloat();
+ operations.add(new RowLayout(null, componentId, animationId,
+ horizontalPositioning, verticalPositioning, spacedBy));
+ }
+
+ @Override
+ public void documentation(DocumentationBuilder doc) {
+ doc.operation("Layout Operations", id(), name())
+ .description("Row layout implementation, positioning components one"
+ + " after the other horizontally.\n\n"
+ + "It supports weight and horizontal/vertical positioning.")
+ .examplesDimension(400, 100)
+ .exampleImage("Start", "layout-RowLayout-start-top.png")
+ .exampleImage("Center", "layout-RowLayout-center-top.png")
+ .exampleImage("End", "layout-RowLayout-end-top.png")
+ .exampleImage("SpaceEvenly", "layout-RowLayout-space-evenly-top.png")
+ .exampleImage("SpaceAround", "layout-RowLayout-space-around-top.png")
+ .exampleImage("SpaceBetween", "layout-RowLayout-space-between-top.png")
+ .field(INT, "COMPONENT_ID", "unique id for this component")
+ .field(INT, "ANIMATION_ID", "id used to match components,"
+ + " for animation purposes")
+ .field(INT, "HORIZONTAL_POSITIONING", "horizontal positioning value")
+ .possibleValues("START", RowLayout.START)
+ .possibleValues("CENTER", RowLayout.CENTER)
+ .possibleValues("END", RowLayout.END)
+ .possibleValues("SPACE_BETWEEN", RowLayout.SPACE_BETWEEN)
+ .possibleValues("SPACE_EVENLY", RowLayout.SPACE_EVENLY)
+ .possibleValues("SPACE_AROUND", RowLayout.SPACE_AROUND)
+ .field(INT, "VERTICAL_POSITIONING", "vertical positioning value")
+ .possibleValues("TOP", RowLayout.TOP)
+ .possibleValues("CENTER", RowLayout.CENTER)
+ .possibleValues("BOTTOM", RowLayout.BOTTOM)
+ .field(FLOAT, "SPACED_BY", "Horizontal spacing between components");
+ }
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/ComponentMeasure.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/ComponentMeasure.java
new file mode 100644
index 000000000000..8dc10d5b0159
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/ComponentMeasure.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget.remotecompose.core.operations.layout.measure;
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+
+/**
+ * Encapsulate the result of a measure pass for a component
+ */
+public class ComponentMeasure {
+ int mId = -1;
+ float mX;
+ float mY;
+ float mW;
+ float mH;
+ Component.Visibility mVisibility = Component.Visibility.VISIBLE;
+
+ public void setX(float value) {
+ mX = value;
+ }
+ public void setY(float value) {
+ mY = value;
+ }
+ public void setW(float value) {
+ mW = value;
+ }
+ public void setH(float value) {
+ mH = value;
+ }
+ public float getX() {
+ return mX;
+ }
+ public float getY() {
+ return mY;
+ }
+ public float getW() {
+ return mW;
+ }
+ public float getH() {
+ return mH;
+ }
+
+ public Component.Visibility getVisibility() {
+ return mVisibility;
+ }
+
+ public void setVisibility(Component.Visibility visibility) {
+ mVisibility = visibility;
+ }
+
+ public ComponentMeasure(int id, float x, float y, float w, float h,
+ Component.Visibility visibility) {
+ this.mId = id;
+ this.mX = x;
+ this.mY = y;
+ this.mW = w;
+ this.mH = h;
+ this.mVisibility = visibility;
+ }
+
+ public ComponentMeasure(int id, float x, float y, float w, float h) {
+ this(id, x, y, w, h, Component.Visibility.VISIBLE);
+ }
+
+ public ComponentMeasure(Component component) {
+ this(component.getComponentId(), component.getX(), component.getY(),
+ component.getWidth(), component.getHeight(),
+ component.mVisibility);
+ }
+
+ public void copyFrom(ComponentMeasure m) {
+ mX = m.mX;
+ mY = m.mY;
+ mW = m.mW;
+ mH = m.mH;
+ mVisibility = m.mVisibility;
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java
new file mode 100644
index 000000000000..d167d9bf45cb
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget.remotecompose.core.operations.layout.measure;
+
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+
+/**
+ * Interface describing the measure/layout contract for components
+ */
+public interface Measurable {
+
+ /**
+ * Measure a component and store the result of the measure in the provided MeasurePass.
+ * This does not apply the measure to the component.
+ */
+ void measure(PaintContext context, float minWidth, float maxWidth,
+ float minHeight, float maxHeight, MeasurePass measure);
+
+ /**
+ * Apply a given measure to the component
+ */
+ void layout(RemoteContext context, MeasurePass measure);
+
+ /**
+ * Return true if the component needs to be remeasured
+ * @return true if need to remeasured, false otherwise
+ */
+ boolean needsMeasure();
+
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/MeasurePass.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/MeasurePass.java
new file mode 100644
index 000000000000..6801debb9c28
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/MeasurePass.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.measure;
+
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+
+import java.util.HashMap;
+
+/**
+ * Represents the result of a measure pass on the entire hierarchy
+ * TODO: optimize to use a flat array vs the current hashmap
+ */
+public class MeasurePass {
+ HashMap<Integer, ComponentMeasure> mList = new HashMap<>();
+
+ public void clear() {
+ mList.clear();
+ }
+
+ public void add(ComponentMeasure measure) throws Exception {
+ if (measure.mId == -1) {
+ throw new Exception("Component has no id!");
+ }
+ mList.put(measure.mId, measure);
+ }
+
+ public boolean contains(int id) {
+ return mList.containsKey(id);
+ }
+
+ public ComponentMeasure get(Component c) {
+ if (!mList.containsKey(c.getComponentId())) {
+ ComponentMeasure measure = new ComponentMeasure(c.getComponentId(),
+ c.getX(), c.getY(), c.getWidth(), c.getHeight());
+ mList.put(c.getComponentId(), measure);
+ return measure;
+ }
+ return mList.get(c.getComponentId());
+ }
+
+ public ComponentMeasure get(int id) {
+ if (!mList.containsKey(id)) {
+ ComponentMeasure measure = new ComponentMeasure(id,
+ 0f, 0f, 0f, 0f, Component.Visibility.GONE);
+ mList.put(id, measure);
+ return measure;
+ }
+ return mList.get(id);
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Size.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Size.java
new file mode 100644
index 000000000000..b11d8e82e7d1
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Size.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.measure;
+
+/**
+ * Basic data class representing a component size, used during layout computations.
+ */
+public class Size {
+ float mWidth;
+ float mHeight;
+ public Size(float width, float height) {
+ this.mWidth = width;
+ this.mHeight = height;
+ }
+
+ public void setWidth(float value) {
+ mWidth = value;
+ }
+
+ public void setHeight(float value) {
+ mHeight = value;
+ }
+
+ public float getWidth() {
+ return mWidth;
+ }
+
+ public float getHeight() {
+ return mHeight;
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java
new file mode 100644
index 000000000000..6f48aee845c6
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+
+import com.android.internal.widget.remotecompose.core.CompanionOperation;
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.operations.paint.PaintBundle;
+import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
+
+import java.util.List;
+
+/**
+ * Component size-aware background draw
+ */
+public class BackgroundModifierOperation extends DecoratorModifierOperation {
+
+ public static final BackgroundModifierOperation.Companion COMPANION =
+ new BackgroundModifierOperation.Companion();
+
+ float mX;
+ float mY;
+ float mWidth;
+ float mHeight;
+ float mR;
+ float mG;
+ float mB;
+ float mA;
+ int mShapeType = ShapeType.RECTANGLE;
+
+ public PaintBundle mPaint = new PaintBundle();
+
+ public BackgroundModifierOperation(float x, float y, float width, float height,
+ float r, float g, float b, float a,
+ int shapeType) {
+ this.mX = x;
+ this.mY = y;
+ this.mWidth = width;
+ this.mHeight = height;
+ this.mR = r;
+ this.mG = g;
+ this.mB = b;
+ this.mA = a;
+ this.mShapeType = shapeType;
+ }
+
+ @Override
+ public void write(WireBuffer buffer) {
+ COMPANION.apply(buffer, mX, mY, mWidth, mHeight, mR, mG, mB, mA, mShapeType);
+ }
+
+ @Override
+ public void serializeToString(int indent, StringSerializer serializer) {
+ serializer.append(indent, "BACKGROUND = [" + mX + ", "
+ + mY + ", " + mWidth + ", " + mHeight
+ + "] color [" + mR + ", " + mG + ", " + mB + ", " + mA
+ + "] shape [" + mShapeType + "]");
+ }
+
+ @Override
+ public void layout(RemoteContext context, float width, float height) {
+ this.mWidth = width;
+ this.mHeight = height;
+ }
+
+ @Override
+ public String toString() {
+ return "BackgroundModifierOperation(" + mWidth + " x " + mHeight + ")";
+ }
+
+ public static class Companion implements CompanionOperation {
+
+
+ @Override
+ public String name() {
+ return "OrigamiBackground";
+ }
+
+ @Override
+ public int id() {
+ return Operations.MODIFIER_BACKGROUND;
+ }
+
+ public void apply(WireBuffer buffer, float x, float y, float width, float height,
+ float r, float g, float b, float a, int shapeType) {
+ buffer.start(Operations.MODIFIER_BACKGROUND);
+ buffer.writeFloat(x);
+ buffer.writeFloat(y);
+ buffer.writeFloat(width);
+ buffer.writeFloat(height);
+ buffer.writeFloat(r);
+ buffer.writeFloat(g);
+ buffer.writeFloat(b);
+ buffer.writeFloat(a);
+ // shape type
+ buffer.writeInt(shapeType);
+ }
+
+ @Override
+ public void read(WireBuffer buffer, List<Operation> operations) {
+ float x = buffer.readFloat();
+ float y = buffer.readFloat();
+ float width = buffer.readFloat();
+ float height = buffer.readFloat();
+ float r = buffer.readFloat();
+ float g = buffer.readFloat();
+ float b = buffer.readFloat();
+ float a = buffer.readFloat();
+ // shape type
+ int shapeType = buffer.readInt();
+ operations.add(new BackgroundModifierOperation(x, y, width, height,
+ r, g, b, a, shapeType));
+ }
+ }
+
+ @Override
+ public void paint(PaintContext context) {
+ context.savePaint();
+ mPaint.reset();
+ mPaint.setColor(mR, mG, mB, mA);
+ context.applyPaint(mPaint);
+ if (mShapeType == ShapeType.RECTANGLE) {
+ context.drawRect(0f, 0f, mWidth, mHeight);
+ } else if (mShapeType == ShapeType.CIRCLE) {
+ context.drawCircle(mWidth / 2f, mHeight / 2f,
+ Math.min(mWidth, mHeight) / 2f);
+ }
+ context.restorePaint();
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java
new file mode 100644
index 000000000000..0b9c01b93896
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+
+import com.android.internal.widget.remotecompose.core.CompanionOperation;
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.operations.paint.PaintBundle;
+import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
+
+import java.util.List;
+
+/**
+ * Component size-aware border draw
+ */
+public class BorderModifierOperation extends DecoratorModifierOperation {
+
+ public static final BorderModifierOperation.Companion COMPANION =
+ new BorderModifierOperation.Companion();
+
+ float mX;
+ float mY;
+ float mWidth;
+ float mHeight;
+ float mBorderWidth;
+ float mRoundedCorner;
+ float mR;
+ float mG;
+ float mB;
+ float mA;
+ int mShapeType = ShapeType.RECTANGLE;
+
+ public PaintBundle paint = new PaintBundle();
+
+ public BorderModifierOperation(float x, float y, float width, float height,
+ float borderWidth, float roundedCorner,
+ float r, float g, float b, float a, int shapeType) {
+ this.mX = x;
+ this.mY = y;
+ this.mWidth = width;
+ this.mHeight = height;
+ this.mBorderWidth = borderWidth;
+ this.mRoundedCorner = roundedCorner;
+ this.mR = r;
+ this.mG = g;
+ this.mB = b;
+ this.mA = a;
+ this.mShapeType = shapeType;
+ }
+
+ @Override
+ public void serializeToString(int indent, StringSerializer serializer) {
+ serializer.append(indent, "BORDER = [" + mX + ", " + mY + ", "
+ + mWidth + ", " + mHeight + "] "
+ + "color [" + mR + ", " + mG + ", " + mB + ", " + mA + "] "
+ + "border [" + mBorderWidth + ", " + mRoundedCorner + "] "
+ + "shape [" + mShapeType + "]");
+ }
+
+ @Override
+ public void write(WireBuffer buffer) {
+ COMPANION.apply(buffer, mX, mY, mWidth, mHeight, mBorderWidth, mRoundedCorner,
+ mR, mG, mB, mA, mShapeType);
+ }
+
+ @Override
+ public void layout(RemoteContext context, float width, float height) {
+ this.mWidth = width;
+ this.mHeight = height;
+ }
+
+ @Override
+ public String toString() {
+ return "BorderModifierOperation(" + mX + "," + mY + " - " + mWidth + " x " + mHeight + ") "
+ + "borderWidth(" + mBorderWidth + ") "
+ + "color(" + mR + "," + mG + "," + mB + "," + mA + ")";
+ }
+
+ public static class Companion implements CompanionOperation {
+
+ @Override
+ public String name() {
+ return "BorderModifier";
+ }
+
+ @Override
+ public int id() {
+ return Operations.MODIFIER_BORDER;
+ }
+
+ public void apply(WireBuffer buffer, float x, float y, float width, float height,
+ float borderWidth, float roundedCorner,
+ float r, float g, float b, float a,
+ int shapeType) {
+ buffer.start(Operations.MODIFIER_BORDER);
+ buffer.writeFloat(x);
+ buffer.writeFloat(y);
+ buffer.writeFloat(width);
+ buffer.writeFloat(height);
+ buffer.writeFloat(borderWidth);
+ buffer.writeFloat(roundedCorner);
+ buffer.writeFloat(r);
+ buffer.writeFloat(g);
+ buffer.writeFloat(b);
+ buffer.writeFloat(a);
+ // shape type
+ buffer.writeInt(shapeType);
+ }
+
+ @Override
+ public void read(WireBuffer buffer, List<Operation> operations) {
+ float x = buffer.readFloat();
+ float y = buffer.readFloat();
+ float width = buffer.readFloat();
+ float height = buffer.readFloat();
+ float bw = buffer.readFloat();
+ float rc = buffer.readFloat();
+ float r = buffer.readFloat();
+ float g = buffer.readFloat();
+ float b = buffer.readFloat();
+ float a = buffer.readFloat();
+ // shape type
+ int shapeType = buffer.readInt();
+ operations.add(new BorderModifierOperation(x, y, width, height, bw,
+ rc, r, g, b, a, shapeType));
+ }
+ }
+
+ @Override
+ public void paint(PaintContext context) {
+ context.savePaint();
+ paint.reset();
+ paint.setColor(mR, mG, mB, mA);
+ paint.setStrokeWidth(mBorderWidth);
+ paint.setStyle(PaintBundle.STYLE_STROKE);
+ context.applyPaint(paint);
+ if (mShapeType == ShapeType.RECTANGLE) {
+ context.drawRect(0f, 0f, mWidth, mHeight);
+ } else {
+ float size = mRoundedCorner;
+ if (mShapeType == ShapeType.CIRCLE) {
+ size = Math.min(mWidth, mHeight) / 2f;
+ }
+ context.drawRoundRect(0f, 0f, mWidth, mHeight, size, size);
+ }
+ context.restorePaint();
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java
new file mode 100644
index 000000000000..30357af6275e
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+
+import com.android.internal.widget.remotecompose.core.CompanionOperation;
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
+
+import java.util.List;
+
+/**
+ * Support modifier clip with a rectangle
+ */
+public class ClipRectModifierOperation extends DecoratorModifierOperation {
+
+ public static final ClipRectModifierOperation.Companion COMPANION =
+ new ClipRectModifierOperation.Companion();
+
+ float mWidth;
+ float mHeight;
+
+
+ @Override
+ public void paint(PaintContext context) {
+ context.clipRect(0f, 0f, mWidth, mHeight);
+ }
+
+ @Override
+ public void layout(RemoteContext context, float width, float height) {
+ this.mWidth = width;
+ this.mHeight = height;
+ }
+
+ @Override
+ public void onClick(float x, float y) {
+ // nothing
+ }
+
+ @Override
+ public void serializeToString(int indent, StringSerializer serializer) {
+ serializer.append(
+ indent, "CLIP_RECT = [" + mWidth + ", " + mHeight + "]");
+ }
+
+ @Override
+ public void write(WireBuffer buffer) {
+ COMPANION.apply(buffer);
+ }
+
+ public static class Companion implements CompanionOperation {
+
+ @Override
+ public String name() {
+ return "ClipRectModifier";
+ }
+
+ @Override
+ public int id() {
+ return Operations.MODIFIER_CLIP_RECT;
+ }
+
+ public void apply(WireBuffer buffer) {
+ buffer.start(Operations.MODIFIER_CLIP_RECT);
+ }
+
+ @Override
+ public void read(WireBuffer buffer, List<Operation> operations) {
+ operations.add(new ClipRectModifierOperation());
+ }
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java
new file mode 100644
index 000000000000..2ef0b9d7a56f
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.PaintOperation;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.operations.MatrixRestore;
+import com.android.internal.widget.remotecompose.core.operations.MatrixSave;
+import com.android.internal.widget.remotecompose.core.operations.layout.DecoratorComponent;
+import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
+
+import java.util.ArrayList;
+
+/**
+ * Maintain a list of modifiers
+ */
+public class ComponentModifiers extends PaintOperation implements DecoratorComponent {
+ ArrayList<ModifierOperation> mList = new ArrayList<>();
+
+ public ArrayList<ModifierOperation> getList() {
+ return mList;
+ }
+
+ @Override
+ public void write(WireBuffer buffer) {
+ // nothing
+ }
+
+ public void serializeToString(int indent, StringSerializer serializer) {
+ serializer.append(indent, "MODIFIERS");
+ for (ModifierOperation m : mList) {
+ m.serializeToString(indent + 1, serializer);
+ }
+ }
+
+ public void add(ModifierOperation operation) {
+ mList.add(operation);
+ }
+
+ public int size() {
+ return mList.size();
+ }
+
+ @Override
+ public void paint(PaintContext context) {
+ float tx = 0f;
+ float ty = 0f;
+ for (ModifierOperation op : mList) {
+ if (op instanceof PaddingModifierOperation) {
+ PaddingModifierOperation pop = (PaddingModifierOperation) op;
+ context.translate(pop.getLeft(), pop.getTop());
+ tx += pop.getLeft();
+ ty += pop.getTop();
+ }
+ if (op instanceof MatrixSave || op instanceof MatrixRestore) {
+ continue;
+ }
+ if (op instanceof PaintOperation) {
+ ((PaintOperation) op).paint(context);
+ }
+ }
+ // Back out the translates created by paddings
+ // TODO: we should be able to get rid of this when drawing the content of a component
+ context.translate(-tx, -ty);
+ }
+
+ @Override
+ public void layout(RemoteContext context, float width, float height) {
+ float w = width;
+ float h = height;
+ for (ModifierOperation op : mList) {
+ if (op instanceof PaddingModifierOperation) {
+ PaddingModifierOperation pop = (PaddingModifierOperation) op;
+ w -= pop.getLeft() + pop.getRight();
+ h -= pop.getTop() + pop.getBottom();
+ }
+ if (op instanceof DecoratorComponent) {
+ ((DecoratorComponent) op).layout(context, w, h);
+ }
+ }
+ }
+
+ public void addAll(ArrayList<ModifierOperation> operations) {
+ mList.addAll(operations);
+ }
+
+ public void onClick(float x, float y) {
+ for (ModifierOperation op : mList) {
+ if (op instanceof DecoratorComponent) {
+ ((DecoratorComponent) op).onClick(x, y);
+ }
+ }
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DecoratorModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DecoratorModifierOperation.java
new file mode 100644
index 000000000000..bf9b27b647db
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DecoratorModifierOperation.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+
+import com.android.internal.widget.remotecompose.core.PaintOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.DecoratorComponent;
+
+/**
+ * Represents a decorator modifier (lightweight component), ie a modifier
+ * that impacts the visual output (background, border...)
+ */
+public abstract class DecoratorModifierOperation extends PaintOperation
+ implements ModifierOperation, DecoratorComponent {
+
+ @Override
+ public void onClick(float x, float y) {
+ // nothing
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java
new file mode 100644
index 000000000000..04e943105ef0
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+
+import com.android.internal.widget.remotecompose.core.CompanionOperation;
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
+
+import java.util.List;
+
+/**
+ * Base class for dimension modifiers
+ */
+public class DimensionModifierOperation implements ModifierOperation {
+
+ public static final DimensionModifierOperation.Companion COMPANION =
+ new DimensionModifierOperation.Companion(0, "DIMENSION");
+
+ public enum Type {
+ EXACT, FILL, WRAP, WEIGHT, INTRINSIC_MIN, INTRINSIC_MAX;
+
+ static Type fromInt(int value) {
+ switch (value) {
+ case 0: return EXACT;
+ case 1: return FILL;
+ case 2: return WRAP;
+ case 3: return WEIGHT;
+ case 4: return INTRINSIC_MIN;
+ case 5: return INTRINSIC_MAX;
+ }
+ return EXACT;
+ }
+ }
+
+ Type mType = Type.EXACT;
+ float mValue = Float.NaN;
+
+ public DimensionModifierOperation(Type type, float value) {
+ mType = type;
+ mValue = value;
+ }
+
+ public DimensionModifierOperation(Type type) {
+ this(type, Float.NaN);
+ }
+
+ public DimensionModifierOperation(float value) {
+ this(Type.EXACT, value);
+ }
+
+
+ public boolean hasWeight() {
+ return mType == Type.WEIGHT;
+ }
+
+ public boolean isWrap() {
+ return mType == Type.WRAP;
+ }
+
+ public boolean isFill() {
+ return mType == Type.FILL;
+ }
+
+ public Type getType() {
+ return mType;
+ }
+
+ public float getValue() {
+ return mValue;
+ }
+
+ public void setValue(float value) {
+ this.mValue = value;
+ }
+
+ @Override
+ public void write(WireBuffer buffer) {
+ COMPANION.apply(buffer, mType.ordinal(), mValue);
+ }
+
+ public String serializedName() {
+ return "DIMENSION";
+ }
+
+ @Override
+ public void serializeToString(int indent, StringSerializer serializer) {
+ if (mType == Type.EXACT) {
+ serializer.append(indent, serializedName() + " = " + mValue);
+ }
+ }
+
+ @Override
+ public void apply(RemoteContext context) {
+ }
+
+ @Override
+ public String deepToString(String indent) {
+ return (indent != null ? indent : "") + toString();
+ }
+
+ @Override
+ public String toString() {
+ return "DimensionModifierOperation(" + mValue + ")";
+ }
+
+ public static class Companion implements CompanionOperation {
+
+ int mOperation;
+ String mName;
+
+ public Companion(int operation, String name) {
+ mOperation = operation;
+ mName = name;
+ }
+
+ @Override
+ public String name() {
+ return mName;
+ }
+
+ @Override
+ public int id() {
+ return mOperation;
+ }
+
+ public void apply(WireBuffer buffer, int type, float value) {
+ buffer.start(mOperation);
+ buffer.writeInt(type);
+ buffer.writeFloat(value);
+ }
+
+ public Operation construct(Type type, float value) {
+ return null;
+ }
+
+ @Override
+ public void read(WireBuffer buffer, List<Operation> operations) {
+ Type type = Type.fromInt(buffer.readInt());
+ float value = buffer.readFloat();
+ Operation op = construct(type, value);
+ operations.add(op);
+ }
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java
new file mode 100644
index 000000000000..81173c3e4343
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+
+/**
+ * Set the height dimension on a component
+ */
+public class HeightModifierOperation extends DimensionModifierOperation {
+
+ public static final DimensionModifierOperation.Companion COMPANION =
+ new DimensionModifierOperation.Companion(Operations.MODIFIER_HEIGHT, "WIDTH") {
+ @Override
+ public Operation construct(DimensionModifierOperation.Type type, float value) {
+ return new HeightModifierOperation(type, value);
+ }
+ };
+
+ public HeightModifierOperation(Type type, float value) {
+ super(type, value);
+ }
+
+ public HeightModifierOperation(Type type) {
+ super(type);
+ }
+
+ public HeightModifierOperation(float value) {
+ super(value);
+ }
+
+ @Override
+ public String toString() {
+ return "Height(" + mValue + ")";
+ }
+
+ @Override
+ public String serializedName() {
+ return "HEIGHT";
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ModifierOperation.java
new file mode 100644
index 000000000000..5299719f674f
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ModifierOperation.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
+
+/**
+ * Represents a modifier
+ */
+public interface ModifierOperation extends Operation {
+ void serializeToString(int indent, StringSerializer serializer);
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java
new file mode 100644
index 000000000000..5ea6a97dd127
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+
+import com.android.internal.widget.remotecompose.core.CompanionOperation;
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
+
+import java.util.List;
+
+/**
+ * Represents a padding modifier.
+ * Padding modifiers can be chained and will impact following modifiers.
+ */
+public class PaddingModifierOperation implements ModifierOperation {
+
+ public static final PaddingModifierOperation.Companion COMPANION =
+ new PaddingModifierOperation.Companion();
+
+ float mLeft;
+ float mTop;
+ float mRight;
+ float mBottom;
+
+ public PaddingModifierOperation(float left, float top, float right, float bottom) {
+ this.mLeft = left;
+ this.mTop = top;
+ this.mRight = right;
+ this.mBottom = bottom;
+ }
+
+ public float getLeft() {
+ return mLeft;
+ }
+
+ public float getTop() {
+ return mTop;
+ }
+
+ public float getRight() {
+ return mRight;
+ }
+
+ public float getBottom() {
+ return mBottom;
+ }
+
+ public void setLeft(float left) {
+ this.mLeft = left;
+ }
+
+ public void setTop(float top) {
+ this.mTop = top;
+ }
+
+ public void setRight(float right) {
+ this.mRight = right;
+ }
+
+ public void setBottom(float bottom) {
+ this.mBottom = bottom;
+ }
+
+ @Override
+ public void write(WireBuffer buffer) {
+ COMPANION.apply(buffer, mLeft, mTop, mRight, mBottom);
+ }
+
+ @Override
+ public void serializeToString(int indent, StringSerializer serializer) {
+ serializer.append(indent, "PADDING = [" + mLeft + ", " + mTop + ", "
+ + mRight + ", " + mBottom + "]");
+ }
+
+ @Override
+ public void apply(RemoteContext context) {
+ }
+
+ @Override
+ public String deepToString(String indent) {
+ return (indent != null ? indent : "") + toString();
+ }
+
+ @Override
+ public String toString() {
+ return "PaddingModifierOperation(" + mLeft + ", " + mTop
+ + ", " + mRight + ", " + mBottom + ")";
+ }
+
+ public static class Companion implements CompanionOperation {
+ @Override
+ public String name() {
+ return "PaddingModifierOperation";
+ }
+
+ @Override
+ public int id() {
+ return Operations.MODIFIER_PADDING;
+ }
+
+ public void apply(WireBuffer buffer,
+ float left, float top, float right, float bottom) {
+ buffer.start(Operations.MODIFIER_PADDING);
+ buffer.writeFloat(left);
+ buffer.writeFloat(top);
+ buffer.writeFloat(right);
+ buffer.writeFloat(bottom);
+ }
+
+ @Override
+ public void read(WireBuffer buffer, List<Operation> operations) {
+ float left = buffer.readFloat();
+ float top = buffer.readFloat();
+ float right = buffer.readFloat();
+ float bottom = buffer.readFloat();
+ operations.add(new PaddingModifierOperation(left, top, right, bottom));
+ }
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java
new file mode 100644
index 000000000000..9c57c6ab4e89
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.operations.DrawBase4;
+import com.android.internal.widget.remotecompose.core.operations.layout.DecoratorComponent;
+import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
+
+/**
+ * Support clip with a rectangle
+ */
+public class RoundedClipRectModifierOperation extends DrawBase4
+ implements ModifierOperation, DecoratorComponent {
+
+ public static final Companion COMPANION =
+ new Companion(Operations.MODIFIER_ROUNDED_CLIP_RECT) {
+ @Override
+ public Operation construct(float x1,
+ float y1,
+ float x2,
+ float y2) {
+ return new RoundedClipRectModifierOperation(x1, y1, x2, y2);
+ }
+ };
+ float mWidth;
+ float mHeight;
+
+
+ public RoundedClipRectModifierOperation(
+ float topStart,
+ float topEnd,
+ float bottomStart,
+ float bottomEnd) {
+ super(topStart, topEnd, bottomStart, bottomEnd);
+ mName = "ModifierRoundedClipRect";
+ }
+
+ @Override
+ public void paint(PaintContext context) {
+ context.roundedClipRect(mWidth, mHeight, mX1, mY1, mX2, mY2);
+ }
+
+ @Override
+ public void layout(RemoteContext context, float width, float height) {
+ this.mWidth = width;
+ this.mHeight = height;
+ }
+
+ @Override
+ public void onClick(float x, float y) {
+ // nothing
+ }
+
+ @Override
+ public void serializeToString(int indent, StringSerializer serializer) {
+ serializer.append(
+ indent, "ROUND_CLIP = [" + mWidth + ", " + mHeight
+ + ", " + mX1 + ", " + mY1
+ + ", " + mX2 + ", " + mY2 + "]");
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ShapeType.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ShapeType.java
new file mode 100644
index 000000000000..e425b4e0cc0a
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ShapeType.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+
+/**
+ * Known shapes, used for modifiers (clip/background/border)
+ */
+public class ShapeType {
+ public static int RECTANGLE = 0;
+ public static int CIRCLE = 1;
+ public static int ROUNDED_RECTANGLE = 2;
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java
new file mode 100644
index 000000000000..c46c8d70c0b1
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+
+/**
+ * Set the width dimension on a component
+ */
+public class WidthModifierOperation extends DimensionModifierOperation {
+
+ public static final DimensionModifierOperation.Companion COMPANION =
+ new DimensionModifierOperation.Companion(Operations.MODIFIER_WIDTH, "WIDTH") {
+ @Override
+ public Operation construct(DimensionModifierOperation.Type type, float value) {
+ return new WidthModifierOperation(type, value);
+ }
+ };
+
+ public WidthModifierOperation(Type type, float value) {
+ super(type, value);
+ }
+
+ public WidthModifierOperation(Type type) {
+ super(type);
+ }
+
+ public WidthModifierOperation(float value) {
+ super(value);
+ }
+
+ @Override
+ public String toString() {
+ return "Width(" + mValue + ")";
+ }
+
+ @Override
+ public String serializedName() {
+ return "WIDTH";
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java
new file mode 100644
index 000000000000..7ccf7f48af24
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.utils;
+
+import java.util.ArrayList;
+
+/**
+ * Internal utility debug class
+ */
+public class DebugLog {
+
+ public static final boolean DEBUG_LAYOUT_ON = false;
+
+ public static class Node {
+ public Node parent;
+ public String name;
+ public String endString;
+ public ArrayList<Node> list = new ArrayList<>();
+
+ public Node(Node parent, String name) {
+ this.parent = parent;
+ this.name = name;
+ this.endString = name + " DONE";
+ if (parent != null) {
+ parent.add(this);
+ }
+ }
+
+ public void add(Node node) {
+ list.add(node);
+ }
+ }
+
+ public static class LogNode extends Node {
+ public LogNode(Node parent, String name) {
+ super(parent, name);
+ }
+ }
+
+ public static Node node = new Node(null, "Root");
+ public static Node currentNode = node;
+
+ public static void clear() {
+ node = new Node(null, "Root");
+ currentNode = node;
+ }
+
+ public static void s(StringValueSupplier valueSupplier) {
+ if (DEBUG_LAYOUT_ON) {
+ currentNode = new Node(currentNode, valueSupplier.getString());
+ }
+ }
+
+ public static void log(StringValueSupplier valueSupplier) {
+ if (DEBUG_LAYOUT_ON) {
+ new LogNode(currentNode, valueSupplier.getString());
+ }
+ }
+
+ public static void e() {
+ if (DEBUG_LAYOUT_ON) {
+ if (currentNode.parent != null) {
+ currentNode = currentNode.parent;
+ } else {
+ currentNode = node;
+ }
+ }
+ }
+
+ public static void e(StringValueSupplier valueSupplier) {
+ if (DEBUG_LAYOUT_ON) {
+ currentNode.endString = valueSupplier.getString();
+ if (currentNode.parent != null) {
+ currentNode = currentNode.parent;
+ } else {
+ currentNode = node;
+ }
+ }
+ }
+
+ public static void printNode(int indent, Node node, StringBuilder builder) {
+ if (DEBUG_LAYOUT_ON) {
+ StringBuilder indentationBuilder = new StringBuilder();
+ for (int i = 0; i < indent; i++) {
+ indentationBuilder.append("| ");
+ }
+ String indentation = indentationBuilder.toString();
+
+ if (node.list.size() > 0) {
+ builder.append(indentation).append(node.name).append("\n");
+ for (Node c : node.list) {
+ printNode(indent + 1, c, builder);
+ }
+ builder.append(indentation).append(node.endString).append("\n");
+ } else {
+ if (node instanceof LogNode) {
+ builder.append(indentation).append(" ").append(node.name).append("\n");
+ } else {
+ builder.append(indentation).append("-- ").append(node.name)
+ .append(" : ").append(node.endString).append("\n");
+ }
+ }
+ }
+ }
+
+ public static void display() {
+ if (DEBUG_LAYOUT_ON) {
+ StringBuilder builder = new StringBuilder();
+ printNode(0, node, builder);
+ System.out.println("\n" + builder.toString());
+ }
+ }
+}
+
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/StringValueSupplier.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/StringValueSupplier.java
new file mode 100644
index 000000000000..79ef16bf25da
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/StringValueSupplier.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.utils;
+
+/**
+ * Basic interface for a lambda (used for logging)
+ */
+public interface StringValueSupplier {
+ /**
+ * returns a string value
+ * @return a string
+ */
+ String getString();
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintBundle.java b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintBundle.java
index a7d0ac6330f7..818619223fb3 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintBundle.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintBundle.java
@@ -695,6 +695,29 @@ public class PaintBundle {
}
/**
+ * Set the color based the R,G,B,A values
+ * @param r red (0 to 255)
+ * @param g green (0 to 255)
+ * @param b blue (0 to 255)
+ * @param a alpha (0 to 255)
+ */
+ public void setColor(int r, int g, int b, int a) {
+ int color = (a << 24) | (r << 16) | (g << 8) | b;
+ setColor(color);
+ }
+
+ /**
+ * Set the color based the R,G,B,A values
+ * @param r red (0.0 to 1.0)
+ * @param g green (0.0 to 1.0)
+ * @param b blue (0.0 to 1.0)
+ * @param a alpha (0.0 to 1.0)
+ */
+ public void setColor(float r, float g, float b, float a) {
+ setColor((int) r * 255, (int) g * 255, (int) b * 255, (int) a * 255);
+ }
+
+ /**
* Set the Color based on ID
* @param color
*/
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntFloatMap.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntFloatMap.java
index 23c3ec593b3c..b2d714e08a0e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntFloatMap.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntFloatMap.java
@@ -54,7 +54,7 @@ public class IntFloatMap {
/**
* Put a item in the map
*
- * @param key item'values key
+ * @param key item's key
* @param value item's value
* @return old value if exist
*/
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntIntMap.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntIntMap.java
index 221014c9049e..606dc785eb20 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntIntMap.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntIntMap.java
@@ -53,7 +53,7 @@ public class IntIntMap {
/**
* Put a item in the map
*
- * @param key item'values key
+ * @param key item's key
* @param value item's value
* @return old value if exist
*/
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java
index 4c1389c5a7df..a4fce80cf843 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java
@@ -400,8 +400,7 @@ public class IntegerExpressionEvaluator {
-1, // no op
2, 2, 2, 2, 2, // + - * / %
2, 2, 2, 2, 2, 2, 2, 2, 2, //<<, >> , >>> , | , &, ^, min max
- 1, 1, 1, 1, 1, 1, // neg, abs, ++, -- , not , sign
-
+ 1, 1, 1, 1, 1, 1, // neg, abs, ++, -- , not , sign
3, 3, 3, // clamp, ifElse, mad,
0, 0, 0 // mad, ?:,
// a[0],a[1],a[2]
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringSerializer.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringSerializer.java
new file mode 100644
index 000000000000..fb9078104089
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringSerializer.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.utilities;
+
+/**
+ * Utility serializer maintaining an indent buffer
+ */
+public class StringSerializer {
+ StringBuffer mBuffer = new StringBuffer();
+ String mIndentBuffer = " ";
+
+ /**
+ * Append some content to the current buffer
+ * @param indent the indentation level to use
+ * @param content content to append
+ */
+ public void append(int indent, String content) {
+ String indentation = mIndentBuffer.substring(0, indent);
+ mBuffer.append(indentation);
+ mBuffer.append(indentation);
+ mBuffer.append(content);
+ mBuffer.append("\n");
+ }
+
+ /**
+ * Reset the buffer
+ */
+ public void reset() {
+ mBuffer = new StringBuffer();
+ }
+
+ /**
+ * Return a string representation of the buffer
+ * @return string representation
+ */
+ public String toString() {
+ return mBuffer.toString();
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/GeneralEasing.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/GeneralEasing.java
index 693deafc5b00..50a7d59ed8e0 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/GeneralEasing.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/GeneralEasing.java
@@ -18,7 +18,7 @@ package com.android.internal.widget.remotecompose.core.operations.utilities.easi
/**
* Provides and interface to create easing functions
*/
-public class GeneralEasing extends Easing{
+public class GeneralEasing extends Easing{
float[] mEasingData = new float[0];
Easing mEasingCurve = new CubicEasing(CUBIC_STANDARD);
diff --git a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java
index a42c58472164..65a337e672b8 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java
@@ -18,6 +18,7 @@ package com.android.internal.widget.remotecompose.player;
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.RemoteComposeBuffer;
import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
import java.io.InputStream;
@@ -113,5 +114,13 @@ public class RemoteComposeDocument {
return mDocument.getNamedColors();
}
+ /**
+ * Return a component associated with id
+ * @param id the component id
+ * @return the corresponding component or null if not found
+ */
+ public Component getComponent(int id) {
+ return mDocument.getComponent(id);
+ }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java
index 39a770acbf97..e01dd17ae0ea 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java
@@ -65,6 +65,21 @@ public class AndroidPaintContext extends PaintContext {
this.mCanvas = canvas;
}
+ @Override
+ public void save() {
+ mCanvas.save();
+ }
+
+ @Override
+ public void saveLayer(float x, float y, float width, float height) {
+ mCanvas.saveLayer(x, y, x + width, y + height, mPaint);
+ }
+
+ @Override
+ public void restore() {
+ mCanvas.restore();
+ }
+
/**
* Draw an image onto the canvas
*
@@ -613,6 +628,19 @@ public class AndroidPaintContext extends PaintContext {
}
@Override
+ public void roundedClipRect(float width, float height,
+ float topStart, float topEnd,
+ float bottomStart, float bottomEnd) {
+ Path roundedPath = new Path();
+ float[] radii = new float[] { topStart, topStart,
+ topEnd, topEnd, bottomEnd, bottomEnd, bottomStart, bottomStart};
+
+ roundedPath.addRoundRect(0f, 0f, width, height,
+ radii, android.graphics.Path.Direction.CW);
+ mCanvas.clipPath(roundedPath);
+ }
+
+ @Override
public void clipPath(int pathId, int regionOp) {
Path path = getPath(pathId, 0, 1);
if (regionOp == ClipPath.DIFFERENCE) {
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
index a2f79cc49f2a..0d7f97ac37c9 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
@@ -215,6 +215,7 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta
}
int w = measureDimension(widthMeasureSpec, mDocument.getWidth());
int h = measureDimension(heightMeasureSpec, mDocument.getHeight());
+ mDocument.getDocument().invalidateMeasure();
if (!USE_VIEW_AREA_CLICK) {
if (mDocument.getDocument().getContentSizing() == RootContentBehavior.SIZING_SCALE) {
@@ -235,6 +236,8 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta
if (mDocument == null) {
return;
}
+ mARContext.setAnimationEnabled(true);
+ mARContext.currentTime = System.currentTimeMillis();
mARContext.setDebug(mDebug);
mARContext.useCanvas(canvas);
mARContext.mWidth = getWidth();
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index ca984c03b174..2abdd57662eb 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -258,6 +258,7 @@ cc_library_shared_for_libandroid_runtime {
"com_android_internal_content_om_OverlayManagerImpl.cpp",
"com_android_internal_net_NetworkUtilsInternal.cpp",
"com_android_internal_os_ClassLoaderFactory.cpp",
+ "com_android_internal_os_DebugStore.cpp",
"com_android_internal_os_FuseAppLoop.cpp",
"com_android_internal_os_KernelAllocationStats.cpp",
"com_android_internal_os_KernelCpuBpfTracking.cpp",
@@ -315,6 +316,7 @@ cc_library_shared_for_libandroid_runtime {
"libcrypto",
"libcutils",
"libdebuggerd_client",
+ "libdebugstore_cxx",
"libutils",
"libbinder",
"libbinderdebug",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index ed59327ff8e9..03b5143ac1f7 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -202,6 +202,7 @@ extern int register_com_android_internal_content_om_OverlayConfig(JNIEnv *env);
extern int register_com_android_internal_content_om_OverlayManagerImpl(JNIEnv* env);
extern int register_com_android_internal_net_NetworkUtilsInternal(JNIEnv* env);
extern int register_com_android_internal_os_ClassLoaderFactory(JNIEnv* env);
+extern int register_com_android_internal_os_DebugStore(JNIEnv* env);
extern int register_com_android_internal_os_FuseAppLoop(JNIEnv* env);
extern int register_com_android_internal_os_KernelAllocationStats(JNIEnv* env);
extern int register_com_android_internal_os_KernelCpuBpfTracking(JNIEnv* env);
@@ -1599,6 +1600,7 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_com_android_internal_content_om_OverlayManagerImpl),
REG_JNI(register_com_android_internal_net_NetworkUtilsInternal),
REG_JNI(register_com_android_internal_os_ClassLoaderFactory),
+ REG_JNI(register_com_android_internal_os_DebugStore),
REG_JNI(register_com_android_internal_os_LongArrayMultiStateCounter),
REG_JNI(register_com_android_internal_os_LongMultiStateCounter),
REG_JNI(register_com_android_internal_os_Zygote),
diff --git a/core/jni/com_android_internal_os_DebugStore.cpp b/core/jni/com_android_internal_os_DebugStore.cpp
new file mode 100644
index 000000000000..874d6ea18917
--- /dev/null
+++ b/core/jni/com_android_internal_os_DebugStore.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+#include <debugstore/debugstore_cxx_bridge.rs.h>
+#include <log/log.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedLocalRef.h>
+#include <nativehelper/ScopedUtfChars.h>
+
+#include <iterator>
+#include <sstream>
+#include <vector>
+
+#include "core_jni_helpers.h"
+
+namespace android {
+
+static struct {
+ jmethodID mGet;
+ jmethodID mSize;
+} gListClassInfo;
+
+static std::vector<std::string> list_to_vector(JNIEnv* env, jobject jList) {
+ std::vector<std::string> vec;
+ jint size = env->CallIntMethod(jList, gListClassInfo.mSize);
+ if (size % 2 != 0) {
+ std::ostringstream oss;
+
+ std::copy(vec.begin(), vec.end(), std::ostream_iterator<std::string>(oss, ", "));
+ ALOGW("DebugStore list size is odd: %d, elements: %s", size, oss.str().c_str());
+
+ return vec;
+ }
+
+ vec.reserve(size);
+
+ for (jint i = 0; i < size; i++) {
+ ScopedLocalRef<jstring> jEntry(env,
+ reinterpret_cast<jstring>(
+ env->CallObjectMethod(jList, gListClassInfo.mGet,
+ i)));
+ ScopedUtfChars cEntry(env, jEntry.get());
+ vec.emplace_back(cEntry.c_str());
+ }
+ return vec;
+}
+
+static void com_android_internal_os_DebugStore_endEvent(JNIEnv* env, jclass clazz, jlong eventId,
+ jobject jAttributeList) {
+ auto attributes = list_to_vector(env, jAttributeList);
+ debugstore::debug_store_end(static_cast<uint64_t>(eventId), attributes);
+}
+
+static jlong com_android_internal_os_DebugStore_beginEvent(JNIEnv* env, jclass clazz,
+ jstring jeventName,
+ jobject jAttributeList) {
+ ScopedUtfChars eventName(env, jeventName);
+ auto attributes = list_to_vector(env, jAttributeList);
+ jlong eventId =
+ static_cast<jlong>(debugstore::debug_store_begin(eventName.c_str(), attributes));
+ return eventId;
+}
+
+static void com_android_internal_os_DebugStore_recordEvent(JNIEnv* env, jclass clazz,
+ jstring jeventName,
+ jobject jAttributeList) {
+ ScopedUtfChars eventName(env, jeventName);
+ auto attributes = list_to_vector(env, jAttributeList);
+ debugstore::debug_store_record(eventName.c_str(), attributes);
+}
+
+static const JNINativeMethod gDebugStoreMethods[] = {
+ /* name, signature, funcPtr */
+ {"beginEventNative", "(Ljava/lang/String;Ljava/util/List;)J",
+ (void*)com_android_internal_os_DebugStore_beginEvent},
+ {"endEventNative", "(JLjava/util/List;)V",
+ (void*)com_android_internal_os_DebugStore_endEvent},
+ {"recordEventNative", "(Ljava/lang/String;Ljava/util/List;)V",
+ (void*)com_android_internal_os_DebugStore_recordEvent},
+};
+
+int register_com_android_internal_os_DebugStore(JNIEnv* env) {
+ int res = RegisterMethodsOrDie(env, "com/android/internal/os/DebugStore", gDebugStoreMethods,
+ NELEM(gDebugStoreMethods));
+ jclass listClass = FindClassOrDie(env, "java/util/List");
+ gListClassInfo.mGet = GetMethodIDOrDie(env, listClass, "get", "(I)Ljava/lang/Object;");
+ gListClassInfo.mSize = GetMethodIDOrDie(env, listClass, "size", "()I");
+
+ return res;
+}
+
+} // namespace android \ No newline at end of file
diff --git a/core/proto/android/providers/settings/system.proto b/core/proto/android/providers/settings/system.proto
index e5ced2521134..e795e8096641 100644
--- a/core/proto/android/providers/settings/system.proto
+++ b/core/proto/android/providers/settings/system.proto
@@ -69,6 +69,7 @@ message SystemSettingsProto {
// 0 = no, 1 = yes
optional SettingProto window_orientation_listener_log = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto show_key_presses = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto touchpad_visualizer = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
}
optional DevOptions developer_options = 7;
diff --git a/core/res/Android.bp b/core/res/Android.bp
index 9207aa8e9c24..e900eb2f01ab 100644
--- a/core/res/Android.bp
+++ b/core/res/Android.bp
@@ -164,6 +164,7 @@ android_app {
"com.android.window.flags.window-aconfig",
"android.permission.flags-aconfig",
"android.os.flags-aconfig",
+ "android.media.tv.flags-aconfig",
],
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f3dac2313c91..50727a2415c6 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -5609,7 +5609,8 @@
@hide
-->
<permission android:name="android.permission.ALWAYS_BOUND_TV_INPUT"
- android:protectionLevel="signature|privileged|vendorPrivileged" />
+ android:protectionLevel="signature|privileged|vendorPrivileged"
+ android:featureFlag="android.media.tv.flags.tis_always_bound_permission"/>
<!-- Must be required by a {@link android.media.tv.interactive.TvInteractiveAppService}
to ensure that only the system can bind to it.
@@ -6107,9 +6108,8 @@
android:description="@string/permdesc_deliverCompanionMessages"
android:protectionLevel="normal" />
- <!-- @hide @FlaggedApi("android.companion.flags.companion_transport_apis")
- Allows an application to send and receive messages via CDM transports.
- -->
+ <!-- Allows an application to send and receive messages via CDM transports.
+ @hide -->
<permission android:name="android.permission.USE_COMPANION_TRANSPORTS"
android:protectionLevel="signature" />
diff --git a/core/res/TEST_MAPPING b/core/res/TEST_MAPPING
index 4d09076779a3..0e01a2ad9b29 100644
--- a/core/res/TEST_MAPPING
+++ b/core/res/TEST_MAPPING
@@ -11,5 +11,22 @@
}
]
}
+ ],
+ // v2/sysui/suite/test-mapping-sysui-screenshot-test
+ "sysui-screenshot-test": [
+ {
+ "name": "SystemUIGoogleScreenshotTests",
+ "options": [
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.Postsubmit"
+ }
+ ]
+ }
]
-} \ No newline at end of file
+}
diff --git a/core/res/res/drawable/ic_call_answer_video.xml b/core/res/res/drawable/ic_call_answer_video.xml
index 77c889234dd0..79af247c98da 100644
--- a/core/res/res/drawable/ic_call_answer_video.xml
+++ b/core/res/res/drawable/ic_call_answer_video.xml
@@ -16,8 +16,8 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
- android:viewportWidth="20"
- android:viewportHeight="20"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal"
android:autoMirrored="true">
<path
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 495af5b35f5f..df288f9eecf0 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3065,10 +3065,13 @@
frameworks/base/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java -->
<integer name="config_userTypePackageWhitelistMode">13</integer> <!-- 1+4+8 -->
- <!-- Whether the main user is a permanent admin user. If the main user is a permanent admin user
- it can't be deleted or downgraded to non-admin status.
- This is generally only relevant on headless system user mode devices; on other devices, the
- main user is the system user which is always a permanent admin anyway. -->
+ <!-- Whether the device will automatically (at first boot) have a designated main user and treat
+ it as a permanent admin.
+ Since the main user is a permanent admin user it can't be deleted or downgraded to
+ non-admin status.
+ This is generally only relevant on headless system user mode (HSUM) devices; on other
+ devices, the main user is the system user which is always a permanent admin anyway.
+ Note that HSUM devices without this enabled will not automatically have a main user. -->
<bool name="config_isMainUserPermanentAdmin">true</bool>
<!-- Whether switch to headless system user is allowed. If allowed,
@@ -3079,7 +3082,7 @@
<bool name="config_enableMultiUserUI">false</bool>
<!-- Whether multiple admins are allowed on the device. If set to true, new users can be created
- with admin privileges and admin privileges can be granted/revoked from existing users. -->
+ with admin privileges and admin privileges can be granted/revoked from existing users. -->
<bool name="config_enableMultipleAdmins">false</bool>
<!-- Whether there is a communal profile which should always be running.
@@ -3961,6 +3964,9 @@
flag does not exist -->
<bool name="config_magnification_always_on_enabled">true</bool>
+ <!-- Whether to keep fullscreen magnification zoom level when context changes. -->
+ <bool name="config_magnification_keep_zoom_level_when_context_changed">false</bool>
+
<!-- If true, the display will be shifted around in ambient mode. -->
<bool name="config_enableBurnInProtection">false</bool>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b158e0f35bee..8f4018f38403 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4779,6 +4779,7 @@
<java-symbol type="bool" name="config_magnification_area" />
<java-symbol type="bool" name="config_magnification_always_on_enabled" />
+ <java-symbol type="bool" name="config_magnification_keep_zoom_level_when_context_changed" />
<java-symbol type="bool" name="config_trackerAppNeedsPermissions"/>
<!-- FullScreenMagnification thumbnail -->
diff --git a/core/tests/coretests/src/android/os/FileUtilsTest.java b/core/tests/coretests/src/android/os/FileUtilsTest.java
index 66b22a8e8462..774878a0759f 100644
--- a/core/tests/coretests/src/android/os/FileUtilsTest.java
+++ b/core/tests/coretests/src/android/os/FileUtilsTest.java
@@ -54,7 +54,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.os.FileUtils.MemoryPipe;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
import android.platform.test.ravenwood.RavenwoodRule;
import android.provider.DocumentsContract.Document;
import android.system.Os;
@@ -156,7 +156,7 @@ public class FileUtilsTest {
}
@Test
- @IgnoreUnderRavenwood(blockedBy = MemoryPipe.class)
+ @DisabledOnRavenwood(blockedBy = MemoryPipe.class)
public void testCopy_FileToPipe() throws Exception {
for (int size : DATA_SIZES) {
final File src = new File(mTarget, "src");
@@ -177,7 +177,7 @@ public class FileUtilsTest {
}
@Test
- @IgnoreUnderRavenwood(blockedBy = MemoryPipe.class)
+ @DisabledOnRavenwood(blockedBy = MemoryPipe.class)
public void testCopy_PipeToFile() throws Exception {
for (int size : DATA_SIZES) {
final File dest = new File(mTarget, "dest");
@@ -197,7 +197,7 @@ public class FileUtilsTest {
}
@Test
- @IgnoreUnderRavenwood(blockedBy = MemoryPipe.class)
+ @DisabledOnRavenwood(blockedBy = MemoryPipe.class)
public void testCopy_PipeToPipe() throws Exception {
for (int size : DATA_SIZES) {
byte[] expected = new byte[size];
@@ -215,7 +215,7 @@ public class FileUtilsTest {
}
@Test
- @IgnoreUnderRavenwood(blockedBy = MemoryPipe.class)
+ @DisabledOnRavenwood(blockedBy = MemoryPipe.class)
public void testCopy_ShortPipeToFile() throws Exception {
byte[] source = new byte[33_000_000];
new Random().nextBytes(source);
@@ -257,9 +257,9 @@ public class FileUtilsTest {
assertArrayEquals(expected, actual);
}
- //TODO(ravenwood) Remove the _$noRavenwood suffix and add @RavenwoodIgnore instead
@Test
- public void testCopy_SocketToFile_FileToSocket$noRavenwood() throws Exception {
+ @DisabledOnRavenwood(reason = "Missing Os methods in Ravenwood")
+ public void testCopy_SocketToFile_FileToSocket() throws Exception {
for (int size : DATA_SIZES ) {
final File src = new File(mTarget, "src");
final File dest = new File(mTarget, "dest");
@@ -510,7 +510,7 @@ public class FileUtilsTest {
}
@Test
- @IgnoreUnderRavenwood(blockedBy = android.webkit.MimeTypeMap.class)
+ @DisabledOnRavenwood(blockedBy = android.webkit.MimeTypeMap.class)
public void testBuildUniqueFile_normal() throws Exception {
assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test"));
assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg"));
@@ -530,7 +530,7 @@ public class FileUtilsTest {
}
@Test
- @IgnoreUnderRavenwood(blockedBy = android.webkit.MimeTypeMap.class)
+ @DisabledOnRavenwood(blockedBy = android.webkit.MimeTypeMap.class)
public void testBuildUniqueFile_unknown() throws Exception {
assertNameEquals("test",
FileUtils.buildUniqueFile(mTarget, "application/octet-stream", "test"));
@@ -544,7 +544,7 @@ public class FileUtilsTest {
}
@Test
- @IgnoreUnderRavenwood(blockedBy = android.webkit.MimeTypeMap.class)
+ @DisabledOnRavenwood(blockedBy = android.webkit.MimeTypeMap.class)
public void testBuildUniqueFile_dir() throws Exception {
assertNameEquals("test", FileUtils.buildUniqueFile(mTarget, Document.MIME_TYPE_DIR, "test"));
new File(mTarget, "test").mkdir();
@@ -559,7 +559,7 @@ public class FileUtilsTest {
}
@Test
- @IgnoreUnderRavenwood(blockedBy = android.webkit.MimeTypeMap.class)
+ @DisabledOnRavenwood(blockedBy = android.webkit.MimeTypeMap.class)
public void testBuildUniqueFile_increment() throws Exception {
assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg"));
new File(mTarget, "test.jpg").createNewFile();
@@ -579,7 +579,7 @@ public class FileUtilsTest {
}
@Test
- @IgnoreUnderRavenwood(blockedBy = android.webkit.MimeTypeMap.class)
+ @DisabledOnRavenwood(blockedBy = android.webkit.MimeTypeMap.class)
public void testBuildUniqueFile_mimeless() throws Exception {
assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "test.jpg"));
new File(mTarget, "test.jpg").createNewFile();
@@ -675,8 +675,7 @@ public class FileUtilsTest {
}
@Test
- @IgnoreUnderRavenwood(reason = "Requires kernel support")
- public void testTranslateMode() throws Exception {
+ public void testTranslateMode() {
assertTranslate("r", O_RDONLY, MODE_READ_ONLY);
assertTranslate("rw", O_RDWR | O_CREAT,
@@ -695,8 +694,7 @@ public class FileUtilsTest {
}
@Test
- @IgnoreUnderRavenwood(reason = "Requires kernel support")
- public void testMalformedTransate_int() throws Exception {
+ public void testMalformedTransate_int() {
try {
// The non-standard Linux access mode 3 should throw
// an IllegalArgumentException.
@@ -707,8 +705,7 @@ public class FileUtilsTest {
}
@Test
- @IgnoreUnderRavenwood(reason = "Requires kernel support")
- public void testMalformedTransate_string() throws Exception {
+ public void testMalformedTransate_string() {
try {
// The non-standard Linux access mode 3 should throw
// an IllegalArgumentException.
@@ -719,8 +716,7 @@ public class FileUtilsTest {
}
@Test
- @IgnoreUnderRavenwood(reason = "Requires kernel support")
- public void testTranslateMode_Invalid() throws Exception {
+ public void testTranslateMode_Invalid() {
try {
translateModeStringToPosix("rwx");
fail();
@@ -734,8 +730,7 @@ public class FileUtilsTest {
}
@Test
- @IgnoreUnderRavenwood(reason = "Requires kernel support")
- public void testTranslateMode_Access() throws Exception {
+ public void testTranslateMode_Access() {
assertEquals(O_RDONLY, translateModeAccessToPosix(F_OK));
assertEquals(O_RDONLY, translateModeAccessToPosix(R_OK));
assertEquals(O_WRONLY, translateModeAccessToPosix(W_OK));
@@ -744,7 +739,7 @@ public class FileUtilsTest {
}
@Test
- @IgnoreUnderRavenwood(reason = "Requires kernel support")
+ @DisabledOnRavenwood(reason = "Requires kernel support")
public void testConvertToModernFd() throws Exception {
final String nonce = String.valueOf(System.nanoTime());
diff --git a/core/tests/coretests/src/android/widget/TextViewContextMenuTest.java b/core/tests/coretests/src/android/widget/TextViewContextMenuTest.java
index 12f8c9c1efc9..f9da832ba7de 100644
--- a/core/tests/coretests/src/android/widget/TextViewContextMenuTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewContextMenuTest.java
@@ -240,4 +240,45 @@ public class TextViewContextMenuTest {
verify(mockNoIconMenu, times(0)).setIcon(any());
verify(mockNoIconMenu2, times(0)).setIcon(any());
}
+
+ @UiThreadTest
+ @Test
+ public void testAutofillMenuItemEnabledWhenNoTextSelected() {
+ ContextMenu menu = mock(ContextMenu.class);
+ MenuItem mockMenuItem = newMockMenuItem();
+ when(menu.add(anyInt(), anyInt(), anyInt(), anyInt())).thenReturn(mockMenuItem);
+ MenuItem mockAutofillMenuItem = newMockMenuItem();
+ when(menu.add(anyInt(), eq(TextView.ID_AUTOFILL), anyInt(), anyInt()))
+ .thenReturn(mockAutofillMenuItem);
+
+ EditText et = mActivity.findViewById(R.id.editText);
+ et.setText("Test");
+
+ Editor editor = et.getEditorForTesting();
+ editor.onCreateContextMenu(menu);
+
+ verify(menu).add(anyInt(), eq(TextView.ID_AUTOFILL), anyInt(), anyInt());
+ verify(mockAutofillMenuItem).setEnabled(true);
+ }
+
+ @UiThreadTest
+ @Test
+ public void testAutofillMenuItemNotEnabledWhenTextSelected() {
+ ContextMenu menu = mock(ContextMenu.class);
+ MenuItem mockMenuItem = newMockMenuItem();
+ when(menu.add(anyInt(), anyInt(), anyInt(), anyInt())).thenReturn(mockMenuItem);
+ MenuItem mockAutofillMenuItem = newMockMenuItem();
+ when(menu.add(anyInt(), eq(TextView.ID_AUTOFILL), anyInt(), anyInt()))
+ .thenReturn(mockAutofillMenuItem);
+
+ EditText et = mActivity.findViewById(R.id.editText);
+ et.setText("Test");
+ et.selectAll();
+ Editor editor = et.getEditorForTesting();
+ editor.onCreateContextMenu(menu);
+
+ verify(menu).add(anyInt(), eq(TextView.ID_AUTOFILL), anyInt(), anyInt());
+ verify(mockAutofillMenuItem).setEnabled(false);
+ }
+
}
diff --git a/core/tests/coretests/src/com/android/internal/os/DebugStoreTest.java b/core/tests/coretests/src/com/android/internal/os/DebugStoreTest.java
new file mode 100644
index 000000000000..786c2fc63018
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/DebugStoreTest.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ServiceInfo;
+import android.platform.test.annotations.DisabledOnRavenwood;
+import android.platform.test.ravenwood.RavenwoodRule;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.List;
+
+/**
+ * Test class for {@link DebugStore}.
+ *
+ * To run it:
+ * atest FrameworksCoreTests:com.android.internal.os.DebugStoreTest
+ */
+@RunWith(AndroidJUnit4.class)
+@DisabledOnRavenwood(blockedBy = DebugStore.class)
+@SmallTest
+public class DebugStoreTest {
+ @Rule
+ public final RavenwoodRule mRavenwood = new RavenwoodRule();
+
+ @Mock
+ private DebugStore.DebugStoreNative mDebugStoreNativeMock;
+
+ @Captor
+ private ArgumentCaptor<List<String>> mListCaptor;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ DebugStore.setDebugStoreNative(mDebugStoreNativeMock);
+ }
+
+ @Test
+ public void testRecordServiceOnStart() {
+ Intent intent = new Intent();
+ intent.setAction("com.android.ACTION");
+ intent.setComponent(new ComponentName("com.android", "androidService"));
+ intent.setPackage("com.android");
+
+ when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(1L);
+
+ long eventId = DebugStore.recordServiceOnStart(1, 0, intent);
+
+ verify(mDebugStoreNativeMock).beginEvent(eq("SvcStart"), mListCaptor.capture());
+ List<String> capturedList = mListCaptor.getValue();
+ assertThat(capturedList).containsExactly(
+ "stId", "1",
+ "flg", "0",
+ "act", "com.android.ACTION",
+ "comp", "ComponentInfo{com.android/androidService}",
+ "pkg", "com.android"
+ ).inOrder();
+ assertThat(eventId).isEqualTo(1L);
+ }
+
+ @Test
+ public void testRecordServiceCreate() {
+ ServiceInfo serviceInfo = new ServiceInfo();
+ serviceInfo.name = "androidService";
+ serviceInfo.packageName = "com.android";
+
+ when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(2L);
+
+ long eventId = DebugStore.recordServiceCreate(serviceInfo);
+
+ verify(mDebugStoreNativeMock).beginEvent(eq("SvcCreate"), mListCaptor.capture());
+ List<String> capturedList = mListCaptor.getValue();
+ assertThat(capturedList).containsExactly(
+ "name", "androidService",
+ "pkg", "com.android"
+ ).inOrder();
+ assertThat(eventId).isEqualTo(2L);
+ }
+
+ @Test
+ public void testRecordServiceBind() {
+ Intent intent = new Intent();
+ intent.setAction("com.android.ACTION");
+ intent.setComponent(new ComponentName("com.android", "androidService"));
+ intent.setPackage("com.android");
+
+ when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(3L);
+
+ long eventId = DebugStore.recordServiceBind(true, intent);
+
+ verify(mDebugStoreNativeMock).beginEvent(eq("SvcBind"), mListCaptor.capture());
+ List<String> capturedList = mListCaptor.getValue();
+ assertThat(capturedList).containsExactly(
+ "rebind", "true",
+ "act", "com.android.ACTION",
+ "cmp", "ComponentInfo{com.android/androidService}",
+ "pkg", "com.android"
+ ).inOrder();
+ assertThat(eventId).isEqualTo(3L);
+ }
+
+ @Test
+ public void testRecordGoAsync() {
+ DebugStore.recordGoAsync("androidReceiver");
+
+ verify(mDebugStoreNativeMock).recordEvent(eq("GoAsync"), mListCaptor.capture());
+ List<String> capturedList = mListCaptor.getValue();
+ assertThat(capturedList).containsExactly(
+ "tname", Thread.currentThread().getName(),
+ "tid", String.valueOf(Thread.currentThread().getId()),
+ "rcv", "androidReceiver"
+ ).inOrder();
+ }
+
+ @Test
+ public void testRecordFinish() {
+ DebugStore.recordFinish("androidReceiver");
+
+ verify(mDebugStoreNativeMock).recordEvent(eq("Finish"), mListCaptor.capture());
+ List<String> capturedList = mListCaptor.getValue();
+ assertThat(capturedList).containsExactly(
+ "tname", Thread.currentThread().getName(),
+ "tid", String.valueOf(Thread.currentThread().getId()),
+ "rcv", "androidReceiver"
+ ).inOrder();
+ }
+
+ @Test
+ public void testRecordLongLooperMessage() {
+ DebugStore.recordLongLooperMessage(100, "androidHandler", 500L);
+
+ verify(mDebugStoreNativeMock).recordEvent(eq("LooperMsg"), mListCaptor.capture());
+ List<String> capturedList = mListCaptor.getValue();
+ assertThat(capturedList).containsExactly(
+ "code", "100",
+ "trgt", "androidHandler",
+ "elapsed", "500"
+ ).inOrder();
+ }
+
+ @Test
+ public void testRecordBroadcastHandleReceiver() {
+ Intent intent = new Intent();
+ intent.setAction("com.android.ACTION");
+ intent.setComponent(new ComponentName("com.android", "androidReceiver"));
+ intent.setPackage("com.android");
+
+ when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(4L);
+
+ long eventId = DebugStore.recordBroadcastHandleReceiver(intent);
+
+ verify(mDebugStoreNativeMock).beginEvent(eq("HandleReceiver"), mListCaptor.capture());
+ List<String> capturedList = mListCaptor.getValue();
+ assertThat(capturedList).containsExactly(
+ "tname", Thread.currentThread().getName(),
+ "tid", String.valueOf(Thread.currentThread().getId()),
+ "act", "com.android.ACTION",
+ "cmp", "ComponentInfo{com.android/androidReceiver}",
+ "pkg", "com.android"
+ ).inOrder();
+ assertThat(eventId).isEqualTo(4L);
+ }
+
+ @Test
+ public void testRecordEventEnd() {
+ DebugStore.recordEventEnd(1L);
+
+ verify(mDebugStoreNativeMock).endEvent(eq(1L), anyList());
+ }
+
+ @Test
+ public void testRecordServiceOnStartWithNullIntent() {
+ when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(5L);
+
+ long eventId = DebugStore.recordServiceOnStart(1, 0, null);
+
+ verify(mDebugStoreNativeMock).beginEvent(eq("SvcStart"), mListCaptor.capture());
+ List<String> capturedList = mListCaptor.getValue();
+ assertThat(capturedList).containsExactly(
+ "stId", "1",
+ "flg", "0",
+ "act", "null",
+ "comp", "null",
+ "pkg", "null"
+ ).inOrder();
+ assertThat(eventId).isEqualTo(5L);
+ }
+
+ @Test
+ public void testRecordServiceCreateWithNullServiceInfo() {
+ when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(6L);
+
+ long eventId = DebugStore.recordServiceCreate(null);
+
+ verify(mDebugStoreNativeMock).beginEvent(eq("SvcCreate"), mListCaptor.capture());
+ List<String> capturedList = mListCaptor.getValue();
+ assertThat(capturedList).containsExactly(
+ "name", "null",
+ "pkg", "null"
+ ).inOrder();
+ assertThat(eventId).isEqualTo(6L);
+ }
+
+ @Test
+ public void testRecordServiceBindWithNullIntent() {
+ when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(7L);
+
+ long eventId = DebugStore.recordServiceBind(false, null);
+
+ verify(mDebugStoreNativeMock).beginEvent(eq("SvcBind"), mListCaptor.capture());
+ List<String> capturedList = mListCaptor.getValue();
+ assertThat(capturedList).containsExactly(
+ "rebind", "false",
+ "act", "null",
+ "cmp", "null",
+ "pkg", "null"
+ ).inOrder();
+ assertThat(eventId).isEqualTo(7L);
+ }
+
+ @Test
+ public void testRecordBroadcastHandleReceiverWithNullIntent() {
+ when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(8L);
+
+ long eventId = DebugStore.recordBroadcastHandleReceiver(null);
+
+ verify(mDebugStoreNativeMock).beginEvent(eq("HandleReceiver"), mListCaptor.capture());
+ List<String> capturedList = mListCaptor.getValue();
+ assertThat(capturedList).containsExactly(
+ "tname", Thread.currentThread().getName(),
+ "tid", String.valueOf(Thread.currentThread().getId()),
+ "act", "null",
+ "cmp", "null",
+ "pkg", "null"
+ ).inOrder();
+ assertThat(eventId).isEqualTo(8L);
+ }
+
+ @Test
+ public void testRecordGoAsyncWithNullReceiverClassName() {
+ DebugStore.recordGoAsync(null);
+
+ verify(mDebugStoreNativeMock).recordEvent(eq("GoAsync"), mListCaptor.capture());
+ List<String> capturedList = mListCaptor.getValue();
+ assertThat(capturedList).containsExactly(
+ "tname", Thread.currentThread().getName(),
+ "tid", String.valueOf(Thread.currentThread().getId()),
+ "rcv", "null"
+ ).inOrder();
+ }
+
+ @Test
+ public void testRecordFinishWithNullReceiverClassName() {
+ DebugStore.recordFinish(null);
+
+ verify(mDebugStoreNativeMock).recordEvent(eq("Finish"), mListCaptor.capture());
+ List<String> capturedList = mListCaptor.getValue();
+ assertThat(capturedList).containsExactly(
+ "tname", Thread.currentThread().getName(),
+ "tid", String.valueOf(Thread.currentThread().getId()),
+ "rcv", "null"
+ ).inOrder();
+ }
+
+ @Test
+ public void testRecordLongLooperMessageWithNullTargetClass() {
+ DebugStore.recordLongLooperMessage(200, null, 1000L);
+
+ verify(mDebugStoreNativeMock).recordEvent(eq("LooperMsg"), mListCaptor.capture());
+ List<String> capturedList = mListCaptor.getValue();
+ assertThat(capturedList).containsExactly(
+ "code", "200",
+ "trgt", "null",
+ "elapsed", "1000"
+ ).inOrder();
+ }
+}
diff --git a/data/keyboards/Vendor_054c_Product_05c4.idc b/data/keyboards/Vendor_054c_Product_05c4.idc
index 2da622745baf..45b5207c6730 100644
--- a/data/keyboards/Vendor_054c_Product_05c4.idc
+++ b/data/keyboards/Vendor_054c_Product_05c4.idc
@@ -51,7 +51,7 @@ sensor.gyroscope.power = 0.8
# fingers, it prevents tapping to click because it thinks the finger's moving
# too fast.
#
-# Since this touchpad doesn't seem to have to drumroll issues, we can safely
+# Since this touchpad doesn't seem to have drumroll issues, we can safely
# disable drumroll detection.
gestureProp.Drumroll_Suppression_Enable = 0
@@ -60,3 +60,11 @@ gestureProp.Drumroll_Suppression_Enable = 0
# from the palm classifier to increase the usable area of the pad.
gestureProp.Palm_Edge_Zone_Width = 0
gestureProp.Tap_Exclusion_Border_Width = 0
+
+# Touchpad is small, scale up the pointer movements to make it more practical
+# to use.
+gestureProp.Point_X_Out_Scale = 2.5
+gestureProp.Point_Y_Out_Scale = 2.5
+
+# TODO(b/351326684): Ideally "Scroll X Out Scale" and "Scroll Y Out Scale"
+# should be adjusted as well. Currently not supported in IDC files.
diff --git a/data/keyboards/Vendor_054c_Product_09cc.idc b/data/keyboards/Vendor_054c_Product_09cc.idc
index 2a1a4fc62b24..45b5207c6730 100644
--- a/data/keyboards/Vendor_054c_Product_09cc.idc
+++ b/data/keyboards/Vendor_054c_Product_09cc.idc
@@ -60,3 +60,11 @@ gestureProp.Drumroll_Suppression_Enable = 0
# from the palm classifier to increase the usable area of the pad.
gestureProp.Palm_Edge_Zone_Width = 0
gestureProp.Tap_Exclusion_Border_Width = 0
+
+# Touchpad is small, scale up the pointer movements to make it more practical
+# to use.
+gestureProp.Point_X_Out_Scale = 2.5
+gestureProp.Point_Y_Out_Scale = 2.5
+
+# TODO(b/351326684): Ideally "Scroll X Out Scale" and "Scroll Y Out Scale"
+# should be adjusted as well. Currently not supported in IDC files.
diff --git a/data/keyboards/Vendor_054c_Product_0ce6.idc b/data/keyboards/Vendor_054c_Product_0ce6.idc
new file mode 100644
index 000000000000..48027e715649
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_0ce6.idc
@@ -0,0 +1,31 @@
+# Copyright 2024 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.
+
+#
+# Sony Playstation(R) DualSense 5 Controller
+#
+
+## Touchpad ##
+
+# Because of the way this touchpad is positioned, touches around the edges are
+# no more likely to be palms than ones in the middle, so remove the edge zones
+# from the palm classifier to increase the usable area of the pad.
+gestureProp.Palm_Edge_Zone_Width = 0
+gestureProp.Tap_Exclusion_Border_Width = 0
+
+gestureProp.Point_X_Out_Scale = 2.0
+gestureProp.Point_Y_Out_Scale = 2.0
+
+# TODO(b/351326684): Ideally "Scroll X Out Scale" and "Scroll Y Out Scale"
+# should be adjusted as well. Currently not supported in IDC files.
diff --git a/data/keyboards/Vendor_054c_Product_0df2.idc b/data/keyboards/Vendor_054c_Product_0df2.idc
new file mode 100644
index 000000000000..4bcf0bef458a
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_0df2.idc
@@ -0,0 +1,31 @@
+# Copyright 2024 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.
+
+#
+# Sony Playstation(R) DualSense Edge 5 Controller
+#
+
+## Touchpad ##
+
+# Because of the way this touchpad is positioned, touches around the edges are
+# no more likely to be palms than ones in the middle, so remove the edge zones
+# from the palm classifier to increase the usable area of the pad.
+gestureProp.Palm_Edge_Zone_Width = 0
+gestureProp.Tap_Exclusion_Border_Width = 0
+
+gestureProp.Point_X_Out_Scale = 2.0
+gestureProp.Point_Y_Out_Scale = 2.0
+
+# TODO(b/351326684): Ideally "Scroll X Out Scale" and "Scroll Y Out Scale"
+# should be adjusted as well. Currently not supported in IDC files.
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
index b2bc3de1e7f5..37f0067de453 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
@@ -18,8 +18,8 @@ package androidx.window.common;
import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER;
-import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_UNKNOWN;
-import static androidx.window.common.CommonFoldingFeature.parseListFromString;
+import static androidx.window.common.layout.CommonFoldingFeature.COMMON_STATE_UNKNOWN;
+import static androidx.window.common.layout.CommonFoldingFeature.parseListFromString;
import android.annotation.NonNull;
import android.content.Context;
@@ -31,6 +31,9 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.SparseIntArray;
+import androidx.window.common.layout.CommonFoldingFeature;
+import androidx.window.common.layout.DisplayFoldFeatureCommon;
+
import com.android.internal.R;
import java.util.ArrayList;
@@ -200,6 +203,23 @@ public final class DeviceStateManagerFoldingFeatureProducer
/**
+ * Returns the list of supported {@link DisplayFoldFeatureCommon} calculated from the
+ * {@link DeviceStateManagerFoldingFeatureProducer}.
+ */
+ @NonNull
+ public List<DisplayFoldFeatureCommon> getDisplayFeatures() {
+ final List<DisplayFoldFeatureCommon> foldFeatures = new ArrayList<>();
+ final List<CommonFoldingFeature> folds = getFoldsWithUnknownState();
+
+ final boolean isHalfOpenedSupported = isHalfOpenedSupported();
+ for (CommonFoldingFeature fold : folds) {
+ foldFeatures.add(DisplayFoldFeatureCommon.create(fold, isHalfOpenedSupported));
+ }
+ return foldFeatures;
+ }
+
+
+ /**
* Returns {@code true} if the device supports half-opened mode, {@code false} otherwise.
*/
public boolean isHalfOpenedSupported() {
@@ -211,7 +231,7 @@ public final class DeviceStateManagerFoldingFeatureProducer
* @param storeFeaturesConsumer a consumer to collect the data when it is first available.
*/
@Override
- public void getData(Consumer<List<CommonFoldingFeature>> storeFeaturesConsumer) {
+ public void getData(@NonNull Consumer<List<CommonFoldingFeature>> storeFeaturesConsumer) {
mRawFoldSupplier.getData((String displayFeaturesString) -> {
if (TextUtils.isEmpty(displayFeaturesString)) {
storeFeaturesConsumer.accept(new ArrayList<>());
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java
index 6d758f1fb3c1..9651918ef5ca 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java
@@ -26,6 +26,8 @@ import android.os.Looper;
import android.provider.Settings;
import android.text.TextUtils;
+import androidx.window.common.layout.CommonFoldingFeature;
+
import com.android.internal.R;
import java.util.Optional;
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/collections/ListUtil.java b/libs/WindowManager/Jetpack/src/androidx/window/common/collections/ListUtil.java
new file mode 100644
index 000000000000..e72459fe61bf
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/collections/ListUtil.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 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 androidx.window.common.collections;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+
+/**
+ * A class to contain utility methods for {@link List}.
+ */
+public final class ListUtil {
+
+ private ListUtil() {}
+
+ /**
+ * Returns a new {@link List} that is created by applying the {@code transformer} to the
+ * {@code source} list.
+ */
+ public static <T, U> List<U> map(List<T> source, Function<T, U> transformer) {
+ final List<U> target = new ArrayList<>();
+ for (int i = 0; i < source.size(); i++) {
+ target.add(transformer.apply(source.get(i)));
+ }
+ return target;
+ }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java b/libs/WindowManager/Jetpack/src/androidx/window/common/layout/CommonFoldingFeature.java
index b95bca16ef5b..85c4fe1193ee 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/layout/CommonFoldingFeature.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package androidx.window.common;
+package androidx.window.common.layout;
import static androidx.window.common.ExtensionHelper.isZero;
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/layout/DisplayFoldFeatureCommon.java b/libs/WindowManager/Jetpack/src/androidx/window/common/layout/DisplayFoldFeatureCommon.java
new file mode 100644
index 000000000000..594bd9cc3bc6
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/layout/DisplayFoldFeatureCommon.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2024 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 androidx.window.common.layout;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.util.ArraySet;
+
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * A class that represents if a fold is part of the device.
+ */
+public final class DisplayFoldFeatureCommon {
+
+ /**
+ * Returns a new instance of {@link DisplayFoldFeatureCommon} based off of
+ * {@link CommonFoldingFeature} and whether or not half opened is supported.
+ */
+ public static DisplayFoldFeatureCommon create(CommonFoldingFeature foldingFeature,
+ boolean isHalfOpenedSupported) {
+ @FoldType
+ final int foldType;
+ if (foldingFeature.getType() == CommonFoldingFeature.COMMON_TYPE_HINGE) {
+ foldType = DISPLAY_FOLD_FEATURE_TYPE_HINGE;
+ } else {
+ foldType = DISPLAY_FOLD_FEATURE_TYPE_SCREEN_FOLD_IN;
+ }
+
+ final Set<Integer> properties = new ArraySet<>();
+
+ if (isHalfOpenedSupported) {
+ properties.add(DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED);
+ }
+ return new DisplayFoldFeatureCommon(foldType, properties);
+ }
+
+ /**
+ * The type of fold is unknown. This is here for compatibility reasons if a new type is added,
+ * and cannot be reported to an incompatible application.
+ */
+ public static final int DISPLAY_FOLD_FEATURE_TYPE_UNKNOWN = 0;
+
+ /**
+ * The type of fold is a physical hinge separating two display panels.
+ */
+ public static final int DISPLAY_FOLD_FEATURE_TYPE_HINGE = 1;
+
+ /**
+ * The type of fold is a screen that folds from 0-180.
+ */
+ public static final int DISPLAY_FOLD_FEATURE_TYPE_SCREEN_FOLD_IN = 2;
+
+ /**
+ * @hide
+ */
+ @IntDef(value = {DISPLAY_FOLD_FEATURE_TYPE_UNKNOWN, DISPLAY_FOLD_FEATURE_TYPE_HINGE,
+ DISPLAY_FOLD_FEATURE_TYPE_SCREEN_FOLD_IN})
+ public @interface FoldType {
+ }
+
+ /**
+ * The fold supports the half opened state.
+ */
+ public static final int DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED = 1;
+
+ @IntDef(value = {DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED})
+ public @interface FoldProperty {
+ }
+
+ @FoldType
+ private final int mType;
+
+ private final Set<Integer> mProperties;
+
+ /**
+ * Creates an instance of [FoldDisplayFeature].
+ *
+ * @param type the type of fold, either [FoldDisplayFeature.TYPE_HINGE] or
+ * [FoldDisplayFeature.TYPE_FOLDABLE_SCREEN]
+ * @hide
+ */
+ public DisplayFoldFeatureCommon(@FoldType int type, @NonNull Set<Integer> properties) {
+ mType = type;
+ mProperties = new ArraySet<>();
+ assertPropertiesAreValid(properties);
+ mProperties.addAll(properties);
+ }
+
+ /**
+ * Returns the type of fold that is either a hinge or a fold.
+ */
+ @FoldType
+ public int getType() {
+ return mType;
+ }
+
+ /**
+ * Returns {@code true} if the fold has the given property, {@code false} otherwise.
+ */
+ public boolean hasProperty(@FoldProperty int property) {
+ return mProperties.contains(property);
+ }
+ /**
+ * Returns {@code true} if the fold has all the given properties, {@code false} otherwise.
+ */
+ public boolean hasProperties(@NonNull @FoldProperty int... properties) {
+ for (int i = 0; i < properties.length; i++) {
+ if (!mProperties.contains(properties[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns a copy of the set of properties.
+ * @hide
+ */
+ public Set<Integer> getProperties() {
+ return new ArraySet<>(mProperties);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ DisplayFoldFeatureCommon that = (DisplayFoldFeatureCommon) o;
+ return mType == that.mType && Objects.equals(mProperties, that.mProperties);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mType, mProperties);
+ }
+
+ @Override
+ public String toString() {
+ return "DisplayFoldFeatureCommon{mType=" + mType + ", mProperties=" + mProperties + '}';
+ }
+
+ private static void assertPropertiesAreValid(@NonNull Set<Integer> properties) {
+ for (int property : properties) {
+ if (!isProperty(property)) {
+ throw new IllegalArgumentException("Property is not a valid type: " + property);
+ }
+ }
+ }
+
+ private static boolean isProperty(int property) {
+ if (property == DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED) {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index e5551765af05..7be14724643c 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -89,9 +89,9 @@ import android.window.WindowContainerTransaction;
import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.window.common.CommonFoldingFeature;
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
import androidx.window.common.EmptyLifecycleCallbacksAdapter;
+import androidx.window.common.layout.CommonFoldingFeature;
import androidx.window.extensions.WindowExtensions;
import androidx.window.extensions.core.util.function.Consumer;
import androidx.window.extensions.core.util.function.Function;
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/DisplayFoldFeatureUtil.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/DisplayFoldFeatureUtil.java
index a0f481a911ad..870c92e6fdac 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/DisplayFoldFeatureUtil.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/DisplayFoldFeatureUtil.java
@@ -16,48 +16,24 @@
package androidx.window.extensions.layout;
-import androidx.window.common.CommonFoldingFeature;
-import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
-
-import java.util.ArrayList;
-import java.util.List;
+import androidx.window.common.layout.DisplayFoldFeatureCommon;
/**
* Util functions for working with {@link androidx.window.extensions.layout.DisplayFoldFeature}.
*/
-public class DisplayFoldFeatureUtil {
+public final class DisplayFoldFeatureUtil {
private DisplayFoldFeatureUtil() {}
- private static DisplayFoldFeature create(CommonFoldingFeature foldingFeature,
- boolean isHalfOpenedSupported) {
- final int foldType;
- if (foldingFeature.getType() == CommonFoldingFeature.COMMON_TYPE_HINGE) {
- foldType = DisplayFoldFeature.TYPE_HINGE;
- } else {
- foldType = DisplayFoldFeature.TYPE_SCREEN_FOLD_IN;
- }
- DisplayFoldFeature.Builder featureBuilder = new DisplayFoldFeature.Builder(foldType);
-
- if (isHalfOpenedSupported) {
- featureBuilder.addProperty(DisplayFoldFeature.FOLD_PROPERTY_SUPPORTS_HALF_OPENED);
- }
- return featureBuilder.build();
- }
-
/**
- * Returns the list of supported {@link DisplayFeature} calculated from the
- * {@link DeviceStateManagerFoldingFeatureProducer}.
+ * Returns a {@link DisplayFoldFeature} that matches the given {@link DisplayFoldFeatureCommon}.
*/
- public static List<DisplayFoldFeature> extractDisplayFoldFeatures(
- DeviceStateManagerFoldingFeatureProducer producer) {
- List<DisplayFoldFeature> foldFeatures = new ArrayList<>();
- List<CommonFoldingFeature> folds = producer.getFoldsWithUnknownState();
-
- final boolean isHalfOpenedSupported = producer.isHalfOpenedSupported();
- for (CommonFoldingFeature fold : folds) {
- foldFeatures.add(DisplayFoldFeatureUtil.create(fold, isHalfOpenedSupported));
+ public static DisplayFoldFeature translate(DisplayFoldFeatureCommon foldFeatureCommon) {
+ final DisplayFoldFeature.Builder builder =
+ new DisplayFoldFeature.Builder(foldFeatureCommon.getType());
+ for (int property: foldFeatureCommon.getProperties()) {
+ builder.addProperty(property);
}
- return foldFeatures;
+ return builder.build();
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
index a3ef68a15196..f1ea19a60f97 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
@@ -19,11 +19,11 @@ package androidx.window.extensions.layout;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
-import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_FLAT;
-import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_HALF_OPENED;
import static androidx.window.common.ExtensionHelper.isZero;
import static androidx.window.common.ExtensionHelper.rotateRectToDisplayRotation;
import static androidx.window.common.ExtensionHelper.transformToWindowSpaceRect;
+import static androidx.window.common.layout.CommonFoldingFeature.COMMON_STATE_FLAT;
+import static androidx.window.common.layout.CommonFoldingFeature.COMMON_STATE_HALF_OPENED;
import android.app.Activity;
import android.app.ActivityThread;
@@ -45,9 +45,10 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiContext;
import androidx.annotation.VisibleForTesting;
-import androidx.window.common.CommonFoldingFeature;
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
import androidx.window.common.EmptyLifecycleCallbacksAdapter;
+import androidx.window.common.collections.ListUtil;
+import androidx.window.common.layout.CommonFoldingFeature;
import androidx.window.extensions.core.util.function.Consumer;
import androidx.window.extensions.util.DeduplicateConsumer;
@@ -95,8 +96,8 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
.registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
mFoldingFeatureProducer = foldingFeatureProducer;
mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
- final List<DisplayFoldFeature> displayFoldFeatures =
- DisplayFoldFeatureUtil.extractDisplayFoldFeatures(mFoldingFeatureProducer);
+ final List<DisplayFoldFeature> displayFoldFeatures = ListUtil.map(
+ mFoldingFeatureProducer.getDisplayFeatures(), DisplayFoldFeatureUtil::translate);
mSupportedWindowFeatures = new SupportedWindowFeatures.Builder(displayFoldFeatures).build();
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
index b63fd0802e5f..60bc7bedf2ed 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
@@ -26,10 +26,10 @@ import android.os.IBinder;
import androidx.annotation.NonNull;
import androidx.window.common.BaseDataProducer;
-import androidx.window.common.CommonFoldingFeature;
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
import androidx.window.common.EmptyLifecycleCallbacksAdapter;
import androidx.window.common.RawFoldingFeatureProducer;
+import androidx.window.common.layout.CommonFoldingFeature;
import java.util.ArrayList;
import java.util.List;
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarHelper.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarHelper.java
index 4fd03e4bdc0b..6e0e7115cfb1 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarHelper.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarHelper.java
@@ -26,7 +26,7 @@ import android.app.ActivityThread;
import android.graphics.Rect;
import android.os.IBinder;
-import androidx.window.common.CommonFoldingFeature;
+import androidx.window.common.layout.CommonFoldingFeature;
import java.util.ArrayList;
import java.util.Collections;
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/collections/ListUtilTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/collections/ListUtilTest.java
new file mode 100644
index 000000000000..a077bdfef194
--- /dev/null
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/collections/ListUtilTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2024 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 androidx.window.common.collections;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Test class for {@link ListUtil}.
+ *
+ * Build/Install/Run:
+ * atest WMJetpackUnitTests:ListUtil
+ */
+public class ListUtilTest {
+
+ @Test
+ public void test_map_empty_returns_empty() {
+ final List<String> emptyList = new ArrayList<>();
+ final List<Integer> result = ListUtil.map(emptyList, String::length);
+ assertThat(result).isEmpty();
+ }
+
+ @Test
+ public void test_map_maintains_order() {
+ final List<String> source = new ArrayList<>();
+ source.add("a");
+ source.add("aa");
+
+ final List<Integer> result = ListUtil.map(source, String::length);
+
+ assertThat(result).containsExactly(1, 2).inOrder();
+ }
+}
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/layout/DisplayFoldFeatureCommonTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/layout/DisplayFoldFeatureCommonTest.java
new file mode 100644
index 000000000000..6c178511388b
--- /dev/null
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/layout/DisplayFoldFeatureCommonTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2024 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 androidx.window.common.layout;
+
+import static androidx.window.common.layout.CommonFoldingFeature.COMMON_STATE_UNKNOWN;
+import static androidx.window.common.layout.CommonFoldingFeature.COMMON_TYPE_FOLD;
+import static androidx.window.common.layout.CommonFoldingFeature.COMMON_TYPE_HINGE;
+import static androidx.window.common.layout.DisplayFoldFeatureCommon.DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED;
+import static androidx.window.common.layout.DisplayFoldFeatureCommon.DISPLAY_FOLD_FEATURE_TYPE_HINGE;
+import static androidx.window.common.layout.DisplayFoldFeatureCommon.DISPLAY_FOLD_FEATURE_TYPE_SCREEN_FOLD_IN;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.graphics.Rect;
+import android.util.ArraySet;
+
+import org.junit.Test;
+
+import java.util.Set;
+
+/**
+ * Test class for {@link DisplayFoldFeatureCommon}.
+ *
+ * Build/Install/Run:
+ * atest WMJetpackUnitTests:DisplayFoldFeatureCommonTest
+ */
+public class DisplayFoldFeatureCommonTest {
+
+ @Test
+ public void test_different_type_not_equals() {
+ final Set<Integer> properties = new ArraySet<>();
+ final DisplayFoldFeatureCommon first =
+ new DisplayFoldFeatureCommon(DISPLAY_FOLD_FEATURE_TYPE_HINGE, properties);
+ final DisplayFoldFeatureCommon second =
+ new DisplayFoldFeatureCommon(DISPLAY_FOLD_FEATURE_TYPE_SCREEN_FOLD_IN, properties);
+
+ assertThat(first).isEqualTo(second);
+ }
+
+ @Test
+ public void test_different_property_set_not_equals() {
+ final Set<Integer> firstProperties = new ArraySet<>();
+ final Set<Integer> secondProperties = new ArraySet<>();
+ secondProperties.add(DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED);
+ final DisplayFoldFeatureCommon first =
+ new DisplayFoldFeatureCommon(DISPLAY_FOLD_FEATURE_TYPE_HINGE, firstProperties);
+ final DisplayFoldFeatureCommon second =
+ new DisplayFoldFeatureCommon(DISPLAY_FOLD_FEATURE_TYPE_HINGE, secondProperties);
+
+ assertThat(first).isNotEqualTo(second);
+ }
+
+ @Test
+ public void test_check_single_property_exists() {
+ final Set<Integer> properties = new ArraySet<>();
+ properties.add(DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED);
+ final DisplayFoldFeatureCommon foldFeatureCommon =
+ new DisplayFoldFeatureCommon(DISPLAY_FOLD_FEATURE_TYPE_HINGE, properties);
+
+ assertThat(
+ foldFeatureCommon.hasProperty(DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED))
+ .isTrue();
+ }
+
+ @Test
+ public void test_check_multiple_properties_exists() {
+ final Set<Integer> properties = new ArraySet<>();
+ properties.add(DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED);
+ final DisplayFoldFeatureCommon foldFeatureCommon =
+ new DisplayFoldFeatureCommon(DISPLAY_FOLD_FEATURE_TYPE_HINGE, properties);
+
+ assertThat(foldFeatureCommon.hasProperties(
+ DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED))
+ .isTrue();
+ }
+
+ @Test
+ public void test_properties_matches_getter() {
+ final Set<Integer> properties = new ArraySet<>();
+ properties.add(DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED);
+ final DisplayFoldFeatureCommon foldFeatureCommon =
+ new DisplayFoldFeatureCommon(DISPLAY_FOLD_FEATURE_TYPE_HINGE, properties);
+
+ assertThat(foldFeatureCommon.getProperties()).isEqualTo(properties);
+ }
+
+ @Test
+ public void test_type_matches_getter() {
+ final Set<Integer> properties = new ArraySet<>();
+ final DisplayFoldFeatureCommon foldFeatureCommon =
+ new DisplayFoldFeatureCommon(DISPLAY_FOLD_FEATURE_TYPE_HINGE, properties);
+
+ assertThat(foldFeatureCommon.getType()).isEqualTo(DISPLAY_FOLD_FEATURE_TYPE_HINGE);
+ }
+
+ @Test
+ public void test_create_half_opened_feature() {
+ final CommonFoldingFeature foldingFeature =
+ new CommonFoldingFeature(COMMON_TYPE_HINGE, COMMON_STATE_UNKNOWN, new Rect());
+ final DisplayFoldFeatureCommon foldFeatureCommon = DisplayFoldFeatureCommon.create(
+ foldingFeature, true);
+
+ assertThat(foldFeatureCommon.getType()).isEqualTo(DISPLAY_FOLD_FEATURE_TYPE_HINGE);
+ assertThat(
+ foldFeatureCommon.hasProperty(DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED))
+ .isTrue();
+ }
+
+ @Test
+ public void test_create_fold_feature_no_half_opened() {
+ final CommonFoldingFeature foldingFeature =
+ new CommonFoldingFeature(COMMON_TYPE_FOLD, COMMON_STATE_UNKNOWN, new Rect());
+ final DisplayFoldFeatureCommon foldFeatureCommon = DisplayFoldFeatureCommon.create(
+ foldingFeature, true);
+
+ assertThat(foldFeatureCommon.getType()).isEqualTo(DISPLAY_FOLD_FEATURE_TYPE_SCREEN_FOLD_IN);
+ assertThat(
+ foldFeatureCommon.hasProperty(DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED))
+ .isTrue();
+ }
+}
diff --git a/libs/WindowManager/Shell/res/layout/bubble_bar_menu_view.xml b/libs/WindowManager/Shell/res/layout/bubble_bar_menu_view.xml
index 82e5aee41ff2..1cbd0e614e42 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_bar_menu_view.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_bar_menu_view.xml
@@ -71,6 +71,8 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="@dimen/bubble_bar_manage_menu_section_spacing"
+ android:clipChildren="true"
+ android:clipToOutline="true"
android:background="@drawable/bubble_manage_menu_bg"
android:elevation="@dimen/bubble_manage_menu_elevation" />
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt
index 6d63971b0b3e..434885f1089d 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt
@@ -43,6 +43,7 @@ enum class DesktopModeFlags(
APP_HEADER_WITH_TASK_DENSITY(Flags::enableAppHeaderWithTaskDensity, true),
TASK_STACK_OBSERVER_IN_SHELL(Flags::enableTaskStackObserverInShell, true),
SIZE_CONSTRAINTS(Flags::enableDesktopWindowingSizeConstraints, true),
+ DISABLE_SNAP_RESIZE(Flags::disableNonResizableAppSnapResizing, true),
DYNAMIC_INITIAL_BOUNDS(Flags::enableWindowingDynamicInitialBounds, true),
ENABLE_DESKTOP_WINDOWING_TASK_LIMIT(Flags::enableDesktopWindowingTaskLimit, true),
BACK_NAVIGATION(Flags::enableDesktopWindowingBackNavigation, true),
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
index 4e0c82b9628f..c7e8df980a8b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
@@ -170,7 +170,7 @@ abstract class CrossActivityBackAnimation(
initialTouchPos.set(backMotionEvent.touchX, backMotionEvent.touchY)
transaction.setAnimationTransaction()
- isLetterboxed = closingTarget!!.taskInfo.appCompatTaskInfo.topActivityBoundsLetterboxed
+ isLetterboxed = closingTarget!!.taskInfo.appCompatTaskInfo.isTopActivityLetterboxed
enteringHasSameLetterbox =
isLetterboxed && closingTarget!!.localBounds.equals(enteringTarget!!.localBounds)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java
index 211fe0d48e43..d5f492450ca8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java
@@ -17,6 +17,7 @@ package com.android.wm.shell.bubbles.bar;
import android.annotation.ColorInt;
import android.content.Context;
+import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Icon;
import android.util.AttributeSet;
@@ -64,6 +65,14 @@ public class BubbleBarMenuView extends LinearLayout {
mActionsSectionView = findViewById(R.id.bubble_bar_manage_menu_actions_section);
mBubbleIconView = findViewById(R.id.bubble_bar_manage_menu_bubble_icon);
mBubbleTitleView = findViewById(R.id.bubble_bar_manage_menu_bubble_title);
+ updateActionsBackgroundColor();
+ }
+
+ private void updateActionsBackgroundColor() {
+ try (TypedArray ta = mContext.obtainStyledAttributes(new int[]{
+ com.android.internal.R.attr.materialColorSurfaceBright})) {
+ mActionsSectionView.getBackground().setTint(ta.getColor(0, Color.WHITE));
+ }
}
/** Update menu details with bubble info */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
index d7d19f7b8bbd..3fa51a909aaa 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
@@ -468,6 +468,12 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
if (mImeSourceControl == null || mImeSourceControl.getLeash() == null) {
if (DEBUG) Slog.d(TAG, "No leash available, not starting the animation.");
return;
+ } else if (!mImeRequestedVisible && show) {
+ // we have a control with leash, but the IME was not requested visible before,
+ // therefore aborting the show animation.
+ Slog.e(TAG, "IME was not requested visible, not starting the show animation.");
+ // TODO(b/353463205) fail statsToken here
+ return;
}
}
final InsetsSource imeSource = mInsetsState.peekSource(InsetsSource.ID_IME);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
index c02c9cf3fd72..7c0455e17cf2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
@@ -238,7 +238,7 @@ public class CompatUIController implements OnDisplaysChangedListener,
public void onCompatInfoChanged(@NonNull CompatUIInfo compatUIInfo) {
final TaskInfo taskInfo = compatUIInfo.getTaskInfo();
final ShellTaskOrganizer.TaskListener taskListener = compatUIInfo.getListener();
- if (taskInfo != null && !taskInfo.appCompatTaskInfo.topActivityInSizeCompat) {
+ if (taskInfo != null && !taskInfo.appCompatTaskInfo.isTopActivityInSizeCompat()) {
mSetOfTaskIdsShowingRestartDialog.remove(taskInfo.taskId);
}
@@ -256,16 +256,16 @@ public class CompatUIController implements OnDisplaysChangedListener,
// basically cancel all the onboarding flow. We don't have to ignore events in case
// the app is in size compat mode.
if (mIsFirstReachabilityEducationRunning) {
- if (!taskInfo.appCompatTaskInfo.isFromLetterboxDoubleTap
- && !taskInfo.appCompatTaskInfo.topActivityInSizeCompat) {
+ if (!taskInfo.appCompatTaskInfo.isFromLetterboxDoubleTap()
+ && !taskInfo.appCompatTaskInfo.isTopActivityInSizeCompat()) {
return;
}
mIsFirstReachabilityEducationRunning = false;
}
- if (taskInfo.appCompatTaskInfo.topActivityBoundsLetterboxed) {
- if (taskInfo.appCompatTaskInfo.isLetterboxEducationEnabled) {
+ if (taskInfo.appCompatTaskInfo.isTopActivityLetterboxed()) {
+ if (taskInfo.appCompatTaskInfo.isLetterboxEducationEnabled()) {
createOrUpdateLetterboxEduLayout(taskInfo, taskListener);
- } else if (!taskInfo.appCompatTaskInfo.isFromLetterboxDoubleTap) {
+ } else if (!taskInfo.appCompatTaskInfo.isFromLetterboxDoubleTap()) {
// In this case the app is letterboxed and the letterbox education
// is disabled. In this case we need to understand if it's the first
// time we show the reachability education. When this is happening
@@ -282,7 +282,7 @@ public class CompatUIController implements OnDisplaysChangedListener,
// We activate the first reachability education if the double-tap is enabled.
// If the double tap is not enabled (e.g. thin letterbox) we just set the value
// of the education being seen.
- if (taskInfo.appCompatTaskInfo.isLetterboxDoubleTapEnabled) {
+ if (taskInfo.appCompatTaskInfo.isLetterboxDoubleTapEnabled()) {
mIsFirstReachabilityEducationRunning = true;
createOrUpdateReachabilityEduLayout(taskInfo, taskListener);
return;
@@ -293,7 +293,7 @@ public class CompatUIController implements OnDisplaysChangedListener,
createOrUpdateCompatLayout(taskInfo, taskListener);
createOrUpdateRestartDialogLayout(taskInfo, taskListener);
if (mCompatUIConfiguration.getHasSeenLetterboxEducation(taskInfo.userId)) {
- if (taskInfo.appCompatTaskInfo.isLetterboxDoubleTapEnabled) {
+ if (taskInfo.appCompatTaskInfo.isLetterboxDoubleTapEnabled()) {
createOrUpdateReachabilityEduLayout(taskInfo, taskListener);
}
// The user aspect ratio button should not be handled when a new TaskInfo is
@@ -305,7 +305,7 @@ public class CompatUIController implements OnDisplaysChangedListener,
}
return;
}
- if (!taskInfo.appCompatTaskInfo.isFromLetterboxDoubleTap) {
+ if (!taskInfo.appCompatTaskInfo.isFromLetterboxDoubleTap()) {
createOrUpdateUserAspectRatioSettingsLayout(taskInfo, taskListener);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java
index 271c07d4011d..8ce7837e451f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java
@@ -82,7 +82,7 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
onRestartButtonClicked) {
super(context, taskInfo, syncQueue, taskListener, displayLayout);
mCallback = callback;
- mHasSizeCompat = taskInfo.appCompatTaskInfo.topActivityInSizeCompat;
+ mHasSizeCompat = taskInfo.appCompatTaskInfo.isTopActivityInSizeCompat();
if (DESKTOP_WINDOWING_MODE.isEnabled(mContext)
&& DesktopModeFlags.DYNAMIC_INITIAL_BOUNDS.isEnabled(context)) {
// Don't show the SCM button for freeform tasks
@@ -138,7 +138,7 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
public boolean updateCompatInfo(TaskInfo taskInfo, ShellTaskOrganizer.TaskListener taskListener,
boolean canShow) {
final boolean prevHasSizeCompat = mHasSizeCompat;
- mHasSizeCompat = taskInfo.appCompatTaskInfo.topActivityInSizeCompat;
+ mHasSizeCompat = taskInfo.appCompatTaskInfo.isTopActivityInSizeCompat();
if (DESKTOP_WINDOWING_MODE.isEnabled(mContext)
&& DesktopModeFlags.DYNAMIC_INITIAL_BOUNDS.isEnabled(mContext)) {
// Don't show the SCM button for freeform tasks
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduWindowManager.java
index 623feada0172..234703277c7d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduWindowManager.java
@@ -104,7 +104,7 @@ class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
mDockStateReader = dockStateReader;
mCompatUIConfiguration = compatUIConfiguration;
mEligibleForLetterboxEducation =
- taskInfo.appCompatTaskInfo.topActivityEligibleForLetterboxEducation;
+ taskInfo.appCompatTaskInfo.eligibleForLetterboxEducation();
}
@Override
@@ -205,8 +205,7 @@ class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
@Override
public boolean updateCompatInfo(TaskInfo taskInfo, ShellTaskOrganizer.TaskListener taskListener,
boolean canShow) {
- mEligibleForLetterboxEducation =
- taskInfo.appCompatTaskInfo.topActivityEligibleForLetterboxEducation;
+ mEligibleForLetterboxEducation = taskInfo.appCompatTaskInfo.eligibleForLetterboxEducation();
return super.updateCompatInfo(taskInfo, taskListener, canShow);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/ReachabilityEduWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/ReachabilityEduWindowManager.java
index 07082a558744..06f2dd1a3b17 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/ReachabilityEduWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/ReachabilityEduWindowManager.java
@@ -91,7 +91,7 @@ class ReachabilityEduWindowManager extends CompatUIWindowManagerAbstract {
Function<Integer, Integer> disappearTimeSupplier) {
super(context, taskInfo, syncQueue, taskListener, displayLayout);
final AppCompatTaskInfo appCompatTaskInfo = taskInfo.appCompatTaskInfo;
- mIsLetterboxDoubleTapEnabled = appCompatTaskInfo.isLetterboxDoubleTapEnabled;
+ mIsLetterboxDoubleTapEnabled = appCompatTaskInfo.isLetterboxDoubleTapEnabled();
mLetterboxVerticalPosition = appCompatTaskInfo.topActivityLetterboxVerticalPosition;
mLetterboxHorizontalPosition = appCompatTaskInfo.topActivityLetterboxHorizontalPosition;
mTopActivityLetterboxWidth = appCompatTaskInfo.topActivityLetterboxWidth;
@@ -148,12 +148,12 @@ class ReachabilityEduWindowManager extends CompatUIWindowManagerAbstract {
final int prevTopActivityLetterboxWidth = mTopActivityLetterboxWidth;
final int prevTopActivityLetterboxHeight = mTopActivityLetterboxHeight;
final AppCompatTaskInfo appCompatTaskInfo = taskInfo.appCompatTaskInfo;
- mIsLetterboxDoubleTapEnabled = appCompatTaskInfo.isLetterboxDoubleTapEnabled;
+ mIsLetterboxDoubleTapEnabled = appCompatTaskInfo.isLetterboxDoubleTapEnabled();
mLetterboxVerticalPosition = appCompatTaskInfo.topActivityLetterboxVerticalPosition;
mLetterboxHorizontalPosition = appCompatTaskInfo.topActivityLetterboxHorizontalPosition;
mTopActivityLetterboxWidth = appCompatTaskInfo.topActivityLetterboxWidth;
mTopActivityLetterboxHeight = appCompatTaskInfo.topActivityLetterboxHeight;
- mHasUserDoubleTapped = appCompatTaskInfo.isFromLetterboxDoubleTap;
+ mHasUserDoubleTapped = appCompatTaskInfo.isFromLetterboxDoubleTap();
if (!super.updateCompatInfo(taskInfo, taskListener, canShow)) {
return false;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java
index 8fb4bdbea933..3f67172ca636 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java
@@ -238,14 +238,14 @@ class UserAspectRatioSettingsWindowManager extends CompatUIWindowManagerAbstract
// App is not visibly letterboxed if it covers status bar/bottom insets or matches the
// stable bounds, so don't show the button
if (stableBounds.height() <= letterboxHeight && stableBounds.width() <= letterboxWidth
- && !taskInfo.isUserFullscreenOverrideEnabled) {
+ && !taskInfo.isUserFullscreenOverrideEnabled()) {
return false;
}
- return taskInfo.topActivityEligibleForUserAspectRatioButton
- && (taskInfo.topActivityBoundsLetterboxed
- || taskInfo.isUserFullscreenOverrideEnabled)
- && !taskInfo.isSystemFullscreenOverrideEnabled
+ return taskInfo.eligibleForUserAspectRatioButton()
+ && (taskInfo.isTopActivityLetterboxed()
+ || taskInfo.isUserFullscreenOverrideEnabled())
+ && !taskInfo.isSystemFullscreenOverrideEnabled()
&& Intent.ACTION_MAIN.equals(intent.getAction())
&& intent.hasCategory(Intent.CATEGORY_LAUNCHER)
&& (!mUserAspectRatioButtonShownChecker.get() || isShowingButton());
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponent.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponent.kt
new file mode 100644
index 000000000000..9ee50ac3c221
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponent.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.compatui.api
+
+import android.util.Log
+
+/**
+ * The component created after a {@link CompatUISpec} definition
+ */
+class CompatUIComponent(
+ private val spec: CompatUISpec,
+ private val id: String
+) {
+
+ /**
+ * Invoked every time a new CompatUIInfo comes from core
+ * @param newInfo The new CompatUIInfo object
+ * @param sharedState The state shared between all the component
+ */
+ fun update(newInfo: CompatUIInfo, state: CompatUIState) {
+ // TODO(b/322817374): To be removed when the implementation is provided.
+ Log.d("CompatUIComponent", "update() newInfo: $newInfo state:$state")
+ }
+
+ fun release() {
+ // TODO(b/322817374): To be removed when the implementation is provided.
+ Log.d("CompatUIComponent", "release()")
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponentIdGenerator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponentIdGenerator.kt
new file mode 100644
index 000000000000..7d663fa809f3
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponentIdGenerator.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.compatui.api
+
+/**
+ * Any object responsible to generate an id for a component.
+ */
+interface CompatUIComponentIdGenerator {
+
+ /**
+ * Generates the unique id for a component given a {@link CompatUIInfo} and component
+ * {@link CompatUISpec}.
+ * @param compatUIInfo The object encapsulating information about the current Task.
+ * @param spec The {@link CompatUISpec} for the component.
+ */
+ fun generateId(compatUIInfo: CompatUIInfo, spec: CompatUISpec): String
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponentState.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponentState.kt
new file mode 100644
index 000000000000..dcaea000d0a1
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponentState.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.compatui.api
+
+/**
+ * Abstraction of all the component specific state. Each
+ * component can create its own state implementing this
+ * tagging interface.
+ */
+interface CompatUIComponentState \ No newline at end of file
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/education/GestureType.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUISharedState.kt
index 9a5c77ac1679..33e0d468e4bc 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/education/GestureType.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUISharedState.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
@@ -14,8 +14,9 @@
* limitations under the License.
*/
-package com.android.systemui.shared.education
+package com.android.wm.shell.compatui.api
-enum class GestureType {
- BACK_GESTURE,
-}
+/**
+ * Represents the state shared between all the components.
+ */
+class CompatUISharedState \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUISpec.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUISpec.kt
index 24c2c8c2aedf..a520d5e60fe5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUISpec.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUISpec.kt
@@ -17,10 +17,31 @@
package com.android.wm.shell.compatui.api
/**
+ * Defines the predicates to invoke for understanding if a component can be created or destroyed.
+ */
+class CompatUILifecyclePredicates(
+ // Predicate evaluating to true if the component needs to be created
+ val creationPredicate: (CompatUIInfo, CompatUISharedState) -> Boolean,
+ // Predicate evaluating to true if the component needs to be destroyed
+ val removalPredicate: (
+ CompatUIInfo,
+ CompatUISharedState,
+ CompatUIComponentState?
+ ) -> Boolean,
+ // Builder for the initial state of the component
+ val stateBuilder: (
+ CompatUIInfo,
+ CompatUISharedState
+ ) -> CompatUIComponentState? = { _, _ -> null }
+)
+
+/**
* Describes each compat ui component to the framework.
*/
-data class CompatUISpec(
+class CompatUISpec(
// Unique name for the component. It's used for debug and for generating the
// unique component identifier in the system.
- val name: String
-) \ No newline at end of file
+ val name: String,
+ // The lifecycle definition
+ val lifecycle: CompatUILifecyclePredicates
+)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIState.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIState.kt
new file mode 100644
index 000000000000..68307b437efa
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIState.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.compatui.api
+
+/**
+ * Singleton which contains the global state of the compat ui system.
+ */
+class CompatUIState {
+
+ private val components = mutableMapOf<String, CompatUIComponent>()
+
+ val sharedState = CompatUISharedState()
+
+ val componentStates = mutableMapOf<String, CompatUIComponentState>()
+
+ /**
+ * @return The CompatUIComponent for the given componentId if it exists.
+ */
+ fun getUIComponent(componentId: String): CompatUIComponent? =
+ components[componentId]
+
+ /**
+ * Registers a component for a given componentId along with its optional state.
+ * <p/>
+ * @param componentId The identifier for the component to register.
+ * @param comp The {@link CompatUIComponent} instance to register.
+ * @param componentState The optional state specific of the component. Not all components
+ * have a specific state so it can be null.
+ */
+ fun registerUIComponent(
+ componentId: String,
+ comp: CompatUIComponent,
+ componentState: CompatUIComponentState?
+ ) {
+ components[componentId] = comp
+ componentState?.let {
+ componentStates[componentId] = componentState
+ }
+ }
+
+ /**
+ * Unregister a component for a given componentId.
+ * <p/>
+ * @param componentId The identifier for the component to register.
+ */
+ fun unregisterUIComponent(componentId: String) {
+ components.remove(componentId)
+ componentStates.remove(componentId)
+ }
+
+ /**
+ * Get access to the specific {@link CompatUIComponentState} for a {@link CompatUIComponent}
+ * with a given identifier.
+ * <p/>
+ * @param componentId The identifier of the {@link CompatUIComponent}.
+ * @return The optional state for the component of the provided id.
+ */
+ @Suppress("UNCHECKED_CAST")
+ fun <T : CompatUIComponentState> stateForComponent(componentId: String) =
+ componentStates[componentId] as? T
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/CompatUIEvents.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/CompatUIEvents.kt
index 23205c3dca9e..db3fda028ef2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/CompatUIEvents.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/CompatUIEvents.kt
@@ -27,9 +27,9 @@ internal const val SIZE_COMPAT_RESTART_BUTTON_CLICKED = 1
sealed class CompatUIEvents(override val eventId: Int) : CompatUIEvent {
/** Sent when the size compat restart button appears. */
data class SizeCompatRestartButtonAppeared(val taskId: Int) :
- CompatUIEvents(SIZE_COMPAT_RESTART_BUTTON_APPEARED)
+ CompatUIEvents(SIZE_COMPAT_RESTART_BUTTON_APPEARED)
/** Sent when the size compat restart button is clicked. */
data class SizeCompatRestartButtonClicked(val taskId: Int) :
- CompatUIEvents(SIZE_COMPAT_RESTART_BUTTON_CLICKED)
-} \ No newline at end of file
+ CompatUIEvents(SIZE_COMPAT_RESTART_BUTTON_CLICKED)
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandler.kt
index 8408ea6ebc31..a7d1b4218a24 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandler.kt
@@ -16,25 +16,70 @@
package com.android.wm.shell.compatui.impl
+import com.android.wm.shell.compatui.api.CompatUIComponent
+import com.android.wm.shell.compatui.api.CompatUIComponentIdGenerator
import com.android.wm.shell.compatui.api.CompatUIEvent
import com.android.wm.shell.compatui.api.CompatUIHandler
import com.android.wm.shell.compatui.api.CompatUIInfo
import com.android.wm.shell.compatui.api.CompatUIRepository
+import com.android.wm.shell.compatui.api.CompatUIState
import java.util.function.Consumer
+import java.util.function.IntSupplier
/**
* Default implementation of {@link CompatUIHandler} to handle CompatUI components
*/
class DefaultCompatUIHandler(
- private val compatUIRepository: CompatUIRepository
+ private val compatUIRepository: CompatUIRepository,
+ private val compatUIState: CompatUIState,
+ private val componentIdGenerator: CompatUIComponentIdGenerator
) : CompatUIHandler {
private var compatUIEventSender: Consumer<CompatUIEvent>? = null
+
override fun onCompatInfoChanged(compatUIInfo: CompatUIInfo) {
+ compatUIRepository.iterateOn { spec ->
+ // We get the identifier for the component depending on the task and spec
+ val componentId = componentIdGenerator.generateId(compatUIInfo, spec)
+ // We check in the state if the component already exists
+ var comp = compatUIState.getUIComponent(componentId)
+ if (comp == null) {
+ // We evaluate the predicate
+ if (spec.lifecycle.creationPredicate(compatUIInfo, compatUIState.sharedState)) {
+ // We create the component and store in the
+ // global state
+ comp = CompatUIComponent(spec, componentId)
+ // We initialize the state for the component
+ val compState = spec.lifecycle.stateBuilder(
+ compatUIInfo,
+ compatUIState.sharedState
+ )
+ compatUIState.registerUIComponent(componentId, comp, compState)
+ // Now we can invoke the update passing the shared state and
+ // the state specific to the component
+ comp.update(compatUIInfo, compatUIState)
+ }
+ } else {
+ // The component is present. We check if we need to remove it
+ if (spec.lifecycle.removalPredicate(
+ compatUIInfo,
+ compatUIState.sharedState,
+ compatUIState.stateForComponent(componentId)
+ )) {
+ // We clean the component
+ comp.release()
+ // We remove the component
+ compatUIState.unregisterUIComponent(componentId)
+ } else {
+ // The component exists so we need to invoke the update methods
+ comp.update(compatUIInfo, compatUIState)
+ }
+ }
+ }
// Empty at the moment
}
override fun setCallback(compatUIEventSender: Consumer<CompatUIEvent>?) {
this.compatUIEventSender = compatUIEventSender
}
-} \ No newline at end of file
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultComponentIdGenerator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultComponentIdGenerator.kt
new file mode 100644
index 000000000000..446291b3d17b
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultComponentIdGenerator.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.compatui.impl
+
+import com.android.wm.shell.compatui.api.CompatUIComponentIdGenerator
+import com.android.wm.shell.compatui.api.CompatUIInfo
+import com.android.wm.shell.compatui.api.CompatUISpec
+
+/**
+ * Default {@link CompatUIComponentIdGenerator} implementation.
+ */
+class DefaultComponentIdGenerator : CompatUIComponentIdGenerator {
+ /**
+ * Simple implementation generating the id from taskId and component name.
+ */
+ override fun generateId(compatUIInfo: CompatUIInfo, spec: CompatUISpec): String =
+ "${compatUIInfo.taskInfo.taskId}-${spec.name}"
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 717a4146dd31..f22dcce00907 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -18,6 +18,7 @@ package com.android.wm.shell.dagger;
import static com.android.wm.shell.onehanded.OneHandedController.SUPPORT_ONE_HANDED_MODE;
+import android.annotation.NonNull;
import android.app.ActivityTaskManager;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -71,10 +72,13 @@ import com.android.wm.shell.common.pip.SizeSpecSource;
import com.android.wm.shell.compatui.CompatUIConfiguration;
import com.android.wm.shell.compatui.CompatUIController;
import com.android.wm.shell.compatui.CompatUIShellCommandHandler;
+import com.android.wm.shell.compatui.api.CompatUIComponentIdGenerator;
import com.android.wm.shell.compatui.api.CompatUIHandler;
import com.android.wm.shell.compatui.api.CompatUIRepository;
+import com.android.wm.shell.compatui.api.CompatUIState;
import com.android.wm.shell.compatui.impl.DefaultCompatUIHandler;
import com.android.wm.shell.compatui.impl.DefaultCompatUIRepository;
+import com.android.wm.shell.compatui.impl.DefaultComponentIdGenerator;
import com.android.wm.shell.desktopmode.DesktopMode;
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
import com.android.wm.shell.desktopmode.DesktopTasksController;
@@ -248,12 +252,15 @@ public abstract class WMShellBaseModule {
Lazy<CompatUIConfiguration> compatUIConfiguration,
Lazy<CompatUIShellCommandHandler> compatUIShellCommandHandler,
Lazy<AccessibilityManager> accessibilityManager,
- CompatUIRepository compatUIRepository) {
+ CompatUIRepository compatUIRepository,
+ @NonNull CompatUIState compatUIState,
+ @NonNull CompatUIComponentIdGenerator componentIdGenerator) {
if (!context.getResources().getBoolean(R.bool.config_enableCompatUIController)) {
return Optional.empty();
}
if (Flags.appCompatUiFramework()) {
- return Optional.of(new DefaultCompatUIHandler(compatUIRepository));
+ return Optional.of(new DefaultCompatUIHandler(compatUIRepository, compatUIState,
+ componentIdGenerator));
}
return Optional.of(
new CompatUIController(
@@ -274,6 +281,18 @@ public abstract class WMShellBaseModule {
@WMSingleton
@Provides
+ static CompatUIState provideCompatUIState() {
+ return new CompatUIState();
+ }
+
+ @WMSingleton
+ @Provides
+ static CompatUIComponentIdGenerator provideCompatUIComponentIdGenerator() {
+ return new DefaultComponentIdGenerator();
+ }
+
+ @WMSingleton
+ @Provides
static CompatUIRepository provideCompatUIRepository() {
return new DefaultCompatUIRepository();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index 9cfbde4bad41..a18bbadbde69 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -67,6 +67,7 @@ import com.android.wm.shell.desktopmode.DesktopTasksTransitionObserver;
import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler;
import com.android.wm.shell.desktopmode.EnterDesktopTaskTransitionHandler;
import com.android.wm.shell.desktopmode.ExitDesktopTaskTransitionHandler;
+import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator;
import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler;
import com.android.wm.shell.draganddrop.DragAndDropController;
import com.android.wm.shell.draganddrop.GlobalDragListener;
@@ -538,6 +539,7 @@ public abstract class WMShellModule {
DragAndDropController dragAndDropController,
Transitions transitions,
KeyguardManager keyguardManager,
+ ReturnToDragStartAnimator returnToDragStartAnimator,
EnterDesktopTaskTransitionHandler enterDesktopTransitionHandler,
ExitDesktopTaskTransitionHandler exitDesktopTransitionHandler,
ToggleResizeDesktopTaskTransitionHandler toggleResizeDesktopTaskTransitionHandler,
@@ -553,13 +555,13 @@ public abstract class WMShellModule {
InteractionJankMonitor interactionJankMonitor) {
return new DesktopTasksController(context, shellInit, shellCommandHandler, shellController,
displayController, shellTaskOrganizer, syncQueue, rootTaskDisplayAreaOrganizer,
- dragAndDropController, transitions, keyguardManager, enterDesktopTransitionHandler,
+ dragAndDropController, transitions, keyguardManager,
+ returnToDragStartAnimator, enterDesktopTransitionHandler,
exitDesktopTransitionHandler, toggleResizeDesktopTaskTransitionHandler,
dragToDesktopTransitionHandler, desktopModeTaskRepository,
desktopModeLoggerTransitionObserver, launchAdjacentController,
- recentsTransitionHandler, multiInstanceHelper,
- mainExecutor, desktopTasksLimiter, recentTasksController.orElse(null),
- interactionJankMonitor);
+ recentsTransitionHandler, multiInstanceHelper, mainExecutor, desktopTasksLimiter,
+ recentTasksController.orElse(null), interactionJankMonitor);
}
@WMSingleton
@@ -587,6 +589,13 @@ public abstract class WMShellModule {
);
}
+ @WMSingleton
+ @Provides
+ static ReturnToDragStartAnimator provideReturnToDragStartAnimator(
+ InteractionJankMonitor interactionJankMonitor) {
+ return new ReturnToDragStartAnimator(interactionJankMonitor);
+ }
+
@WMSingleton
@Provides
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
index 9fcf73d2c375..3e7b4fe89b45 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
@@ -63,7 +63,8 @@ fun calculateInitialBounds(
if (taskInfo.isResizeable) {
if (isFixedOrientationPortrait(topActivityInfo.screenOrientation)) {
// Respect apps fullscreen width
- Size(taskInfo.appCompatTaskInfo.topActivityLetterboxWidth, idealSize.height)
+ Size(taskInfo.appCompatTaskInfo.topActivityLetterboxAppWidth,
+ idealSize.height)
} else {
idealSize
}
@@ -79,7 +80,7 @@ fun calculateInitialBounds(
// Respect apps fullscreen height and apply custom app width
Size(
customPortraitWidthForLandscapeApp,
- taskInfo.appCompatTaskInfo.topActivityLetterboxHeight
+ taskInfo.appCompatTaskInfo.topActivityLetterboxAppHeight
)
} else {
idealSize
@@ -143,9 +144,9 @@ fun maximizeSizeGivenAspectRatio(
/** Calculates the aspect ratio of an activity from its fullscreen bounds. */
fun calculateAspectRatio(taskInfo: RunningTaskInfo): Float {
- if (taskInfo.appCompatTaskInfo.topActivityBoundsLetterboxed) {
- val appLetterboxWidth = taskInfo.appCompatTaskInfo.topActivityLetterboxWidth
- val appLetterboxHeight = taskInfo.appCompatTaskInfo.topActivityLetterboxHeight
+ val appLetterboxWidth = taskInfo.appCompatTaskInfo.topActivityLetterboxAppWidth
+ val appLetterboxHeight = taskInfo.appCompatTaskInfo.topActivityLetterboxAppHeight
+ if (taskInfo.appCompatTaskInfo.isTopActivityLetterboxed) {
return maxOf(appLetterboxWidth, appLetterboxHeight) /
minOf(appLetterboxWidth, appLetterboxHeight).toFloat()
}
@@ -199,7 +200,7 @@ fun TaskInfo.hasPortraitTopActivity(): Boolean {
}
// Then check if the activity is portrait when letterboxed
- appCompatTaskInfo.topActivityBoundsLetterboxed -> appCompatTaskInfo.isTopActivityPillarboxed
+ appCompatTaskInfo.isTopActivityLetterboxed -> appCompatTaskInfo.isTopActivityPillarboxed
// Then check if the activity is portrait
appBounds != null -> appBounds.height() > appBounds.width()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 2bb172fc53ac..e154da58028a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -66,7 +66,6 @@ import com.android.wm.shell.common.RemoteCallable
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.common.SingleInstanceRemoteListener
import com.android.wm.shell.common.SyncTransactionQueue
-import com.android.wm.shell.shared.desktopmode.DesktopModeFlags.WALLPAPER_ACTIVITY
import com.android.wm.shell.common.desktopmode.DesktopModeTransitionSource
import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
@@ -79,13 +78,14 @@ import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.recents.RecentTasksController
import com.android.wm.shell.recents.RecentsTransitionHandler
import com.android.wm.shell.recents.RecentsTransitionStateListener
+import com.android.wm.shell.shared.TransitionUtil
+import com.android.wm.shell.shared.annotations.ExternalThread
+import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.shared.desktopmode.DesktopModeFlags
+import com.android.wm.shell.shared.desktopmode.DesktopModeFlags.WALLPAPER_ACTIVITY
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus.DESKTOP_DENSITY_OVERRIDE
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus.useDesktopOverrideDensity
-import com.android.wm.shell.shared.TransitionUtil
-import com.android.wm.shell.shared.annotations.ExternalThread
-import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.splitscreen.SplitScreenController
import com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DESKTOP_MODE
import com.android.wm.shell.sysui.ShellCommandHandler
@@ -96,6 +96,7 @@ import com.android.wm.shell.transition.OneShotRemoteHandler
import com.android.wm.shell.transition.Transitions
import com.android.wm.shell.windowdecor.DragPositioningCallbackUtility
import com.android.wm.shell.windowdecor.MoveToDesktopAnimator
+import com.android.wm.shell.windowdecor.OnTaskRepositionAnimationListener
import com.android.wm.shell.windowdecor.OnTaskResizeAnimationListener
import com.android.wm.shell.windowdecor.extension.isFullscreen
import com.android.wm.shell.windowdecor.extension.isMultiWindow
@@ -117,6 +118,7 @@ class DesktopTasksController(
private val dragAndDropController: DragAndDropController,
private val transitions: Transitions,
private val keyguardManager: KeyguardManager,
+ private val returnToDragStartAnimator: ReturnToDragStartAnimator,
private val enterDesktopTaskTransitionHandler: EnterDesktopTaskTransitionHandler,
private val exitDesktopTaskTransitionHandler: ExitDesktopTaskTransitionHandler,
private val toggleResizeDesktopTaskTransitionHandler: ToggleResizeDesktopTaskTransitionHandler,
@@ -214,6 +216,10 @@ class DesktopTasksController(
dragToDesktopTransitionHandler.setOnTaskResizeAnimatorListener(listener)
}
+ fun setOnTaskRepositionAnimationListener(listener: OnTaskRepositionAnimationListener) {
+ returnToDragStartAnimator.setTaskRepositionAnimationListener(listener)
+ }
+
/** Setter needed to avoid cyclic dependency. */
fun setSplitScreenController(controller: SplitScreenController) {
splitScreenController = controller
@@ -639,21 +645,50 @@ class DesktopTasksController(
/**
* Quick-resize to the right or left half of the stable bounds.
*
+ * @param taskInfo current task that is being snap-resized via dragging or maximize menu button
+ * @param currentDragBounds current position of the task leash being dragged (or current task
+ * bounds if being snapped resize via maximize menu button)
* @param position the portion of the screen (RIGHT or LEFT) we want to snap the task to.
*/
- fun snapToHalfScreen(taskInfo: RunningTaskInfo, position: SnapPosition) {
+ fun snapToHalfScreen(
+ taskInfo: RunningTaskInfo,
+ currentDragBounds: Rect,
+ position: SnapPosition
+ ) {
val destinationBounds = getSnapBounds(taskInfo, position)
if (destinationBounds == taskInfo.configuration.windowConfiguration.bounds) return
val wct = WindowContainerTransaction().setBounds(taskInfo.token, destinationBounds)
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
- toggleResizeDesktopTaskTransitionHandler.startTransition(wct)
+ toggleResizeDesktopTaskTransitionHandler.startTransition(wct, currentDragBounds)
} else {
shellTaskOrganizer.applyTransaction(wct)
}
}
+ @VisibleForTesting
+ fun handleSnapResizingTask(
+ taskInfo: RunningTaskInfo,
+ position: SnapPosition,
+ taskSurface: SurfaceControl,
+ currentDragBounds: Rect,
+ dragStartBounds: Rect
+ ) {
+ releaseVisualIndicator()
+ if (!taskInfo.isResizeable && DesktopModeFlags.DISABLE_SNAP_RESIZE.isEnabled(context)) {
+ // reposition non-resizable app back to its original position before being dragged
+ returnToDragStartAnimator.start(
+ taskInfo.taskId,
+ taskSurface,
+ startBounds = currentDragBounds,
+ endBounds = dragStartBounds
+ )
+ } else {
+ snapToHalfScreen(taskInfo, currentDragBounds, position)
+ }
+ }
+
private fun getDefaultDesktopTaskBounds(displayLayout: DisplayLayout): Rect {
// TODO(b/319819547): Account for app constraints so apps do not become letterboxed
val desiredWidth = (displayLayout.width() * DESKTOP_MODE_INITIAL_BOUNDS_SCALE).toInt()
@@ -819,8 +854,12 @@ class DesktopTasksController(
// Check if we should skip handling this transition
var reason = ""
val triggerTask = request.triggerTask
+ var shouldHandleMidRecentsFreeformLaunch =
+ recentsAnimationRunning && isFreeformRelaunch(triggerTask, request)
val shouldHandleRequest =
when {
+ // Handle freeform relaunch during recents animation
+ shouldHandleMidRecentsFreeformLaunch -> true
recentsAnimationRunning -> {
reason = "recents animation is running"
false
@@ -860,6 +899,8 @@ class DesktopTasksController(
val result =
triggerTask?.let { task ->
when {
+ // Check if freeform task launch during recents should be handled
+ shouldHandleMidRecentsFreeformLaunch -> handleMidRecentsFreeformTaskLaunch(task)
// Check if the closing task needs to be handled
TransitionUtil.isClosingType(request.type) -> handleTaskClosing(task)
// Check if the top task shouldn't be allowed to enter desktop mode
@@ -893,6 +934,12 @@ class DesktopTasksController(
.forEach { finishTransaction.setCornerRadius(it.leash, cornerRadius) }
}
+ /** Returns whether an existing desktop task is being relaunched in freeform or not. */
+ private fun isFreeformRelaunch(triggerTask: RunningTaskInfo?, request: TransitionRequestInfo) =
+ (triggerTask != null && triggerTask.windowingMode == WINDOWING_MODE_FREEFORM
+ && TransitionUtil.isOpeningType(request.type)
+ && taskRepository.isActiveTask(triggerTask.taskId))
+
private fun isIncompatibleTask(task: TaskInfo) =
DesktopModeFlags.MODALS_POLICY.isEnabled(context)
&& isTopActivityExemptFromDesktopWindowing(context, task)
@@ -930,9 +977,8 @@ class DesktopTasksController(
val options =
ActivityOptions.makeBasic().apply {
launchWindowingMode = newTaskWindowingMode
- isPendingIntentBackgroundActivityLaunchAllowedByPermission = true
pendingIntentBackgroundActivityStartMode =
- ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS
}
val launchIntent = PendingIntent.getActivity(
context,
@@ -957,6 +1003,21 @@ class DesktopTasksController(
}
}
+ /**
+ * Handles the case where a freeform task is launched from recents.
+ *
+ * This is a special case where we want to launch the task in fullscreen instead of freeform.
+ */
+ private fun handleMidRecentsFreeformTaskLaunch(
+ task: RunningTaskInfo
+ ): WindowContainerTransaction? {
+ logV("DesktopTasksController: handleMidRecentsFreeformTaskLaunch")
+ val wct = WindowContainerTransaction()
+ addMoveToFullscreenChanges(wct, task)
+ wct.reorder(task.token, true)
+ return wct
+ }
+
private fun handleFreeformTaskLaunch(
task: RunningTaskInfo,
transition: IBinder
@@ -1239,7 +1300,7 @@ class DesktopTasksController(
taskSurface: SurfaceControl,
inputX: Float,
taskTop: Float
- ): DesktopModeVisualIndicator.IndicatorType {
+ ): IndicatorType {
// If the visual indicator does not exist, create it.
val indicator =
visualIndicator
@@ -1260,16 +1321,22 @@ class DesktopTasksController(
* that change. Otherwise, ensure bounds are up to date.
*
* @param taskInfo the task being dragged.
+ * @param taskSurface the leash of the task being dragged.
* @param position position of surface when drag ends.
* @param inputCoordinate the coordinates of the motion event
- * @param taskBounds the updated bounds of the task being dragged.
+ * @param currentDragBounds the current bounds of where the visible task is (might be actual
+ * task bounds or just task leash)
+ * @param validDragArea the bounds of where the task can be dragged within the display.
+ * @param dragStartBounds the bounds of the task before starting dragging.
*/
fun onDragPositioningEnd(
taskInfo: RunningTaskInfo,
+ taskSurface: SurfaceControl,
position: Point,
inputCoordinate: PointF,
- taskBounds: Rect,
- validDragArea: Rect
+ currentDragBounds: Rect,
+ validDragArea: Rect,
+ dragStartBounds: Rect,
) {
if (taskInfo.configuration.windowConfiguration.windowingMode != WINDOWING_MODE_FREEFORM) {
return
@@ -1278,41 +1345,44 @@ class DesktopTasksController(
val indicator = visualIndicator ?: return
val indicatorType =
indicator.updateIndicatorType(
- PointF(inputCoordinate.x, taskBounds.top.toFloat()),
+ PointF(inputCoordinate.x, currentDragBounds.top.toFloat()),
taskInfo.windowingMode
)
when (indicatorType) {
- DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR -> {
+ IndicatorType.TO_FULLSCREEN_INDICATOR -> {
moveToFullscreenWithAnimation(
taskInfo,
position,
DesktopModeTransitionSource.TASK_DRAG
)
}
- DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR -> {
- releaseVisualIndicator()
- snapToHalfScreen(taskInfo, SnapPosition.LEFT)
+ IndicatorType.TO_SPLIT_LEFT_INDICATOR -> {
+ handleSnapResizingTask(
+ taskInfo, SnapPosition.LEFT, taskSurface, currentDragBounds, dragStartBounds
+ )
}
- DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR -> {
- releaseVisualIndicator()
- snapToHalfScreen(taskInfo, SnapPosition.RIGHT)
+ IndicatorType.TO_SPLIT_RIGHT_INDICATOR -> {
+ handleSnapResizingTask(
+ taskInfo, SnapPosition.RIGHT, taskSurface, currentDragBounds, dragStartBounds
+ )
}
- DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR -> {
- // If task bounds are outside valid drag area, snap them inward and perform a
- // transaction to set bounds.
- if (
- DragPositioningCallbackUtility.snapTaskBoundsIfNecessary(
- taskBounds,
- validDragArea
- )
- ) {
- val wct = WindowContainerTransaction()
- wct.setBounds(taskInfo.token, taskBounds)
- transitions.startTransition(TRANSIT_CHANGE, wct, null)
- }
+ IndicatorType.NO_INDICATOR -> {
+ // If task bounds are outside valid drag area, snap them inward
+ DragPositioningCallbackUtility.snapTaskBoundsIfNecessary(
+ currentDragBounds,
+ validDragArea
+ )
+
+ if (currentDragBounds == dragStartBounds) return
+
+ // Update task bounds so that the task position will match the position of its leash
+ val wct = WindowContainerTransaction()
+ wct.setBounds(taskInfo.token, currentDragBounds)
+ transitions.startTransition(TRANSIT_CHANGE, wct, null)
+
releaseVisualIndicator()
}
- DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR -> {
+ IndicatorType.TO_DESKTOP_INDICATOR -> {
throw IllegalArgumentException(
"Should not be receiving TO_DESKTOP_INDICATOR for " + "a freeform task."
)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
index 9e79eddb0e59..5221a4592d39 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
@@ -29,10 +29,10 @@ import android.window.TransitionInfo.Change
import android.window.TransitionRequestInfo
import android.window.WindowContainerToken
import android.window.WindowContainerTransaction
-import com.android.internal.protolog.ProtoLog
import com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_HOLD
import com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE
import com.android.internal.jank.InteractionJankMonitor
+import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
@@ -220,16 +220,18 @@ class DragToDesktopTransitionHandler(
startCancelAnimation()
} else if (
state.draggedTaskChange != null &&
- (cancelState == CancelState.CANCEL_SPLIT_LEFT ||
+ (cancelState == CancelState.CANCEL_SPLIT_LEFT ||
cancelState == CancelState.CANCEL_SPLIT_RIGHT)
- ) {
+ ) {
// We have a valid dragged task, but the animation will be handled by
// SplitScreenController; request the transition here.
- @SplitPosition val splitPosition = if (cancelState == CancelState.CANCEL_SPLIT_LEFT) {
- SPLIT_POSITION_TOP_OR_LEFT
- } else {
- SPLIT_POSITION_BOTTOM_OR_RIGHT
- }
+ @SplitPosition
+ val splitPosition =
+ if (cancelState == CancelState.CANCEL_SPLIT_LEFT) {
+ SPLIT_POSITION_TOP_OR_LEFT
+ } else {
+ SPLIT_POSITION_BOTTOM_OR_RIGHT
+ }
val wct = WindowContainerTransaction()
restoreWindowOrder(wct, state)
state.startTransitionFinishTransaction?.apply()
@@ -252,20 +254,20 @@ class DragToDesktopTransitionHandler(
wct: WindowContainerTransaction
) {
val state = requireTransitionState()
- val taskInfo = state.draggedTaskChange?.taskInfo
- ?: error("Expected non-null taskInfo")
+ val taskInfo = state.draggedTaskChange?.taskInfo ?: error("Expected non-null taskInfo")
val taskBounds = Rect(taskInfo.configuration.windowConfiguration.bounds)
val taskScale = state.dragAnimator.scale
val scaledWidth = taskBounds.width() * taskScale
val scaledHeight = taskBounds.height() * taskScale
val dragPosition = PointF(state.dragAnimator.position)
state.dragAnimator.cancelAnimator()
- val animatedTaskBounds = Rect(
- dragPosition.x.toInt(),
- dragPosition.y.toInt(),
- (dragPosition.x + scaledWidth).toInt(),
- (dragPosition.y + scaledHeight).toInt()
- )
+ val animatedTaskBounds =
+ Rect(
+ dragPosition.x.toInt(),
+ dragPosition.y.toInt(),
+ (dragPosition.x + scaledWidth).toInt(),
+ (dragPosition.y + scaledHeight).toInt()
+ )
requestSplitSelect(wct, taskInfo, splitPosition, animatedTaskBounds)
}
@@ -286,12 +288,7 @@ class DragToDesktopTransitionHandler(
}
wct.setWindowingMode(taskInfo.token, WINDOWING_MODE_MULTI_WINDOW)
wct.setDensityDpi(taskInfo.token, context.resources.displayMetrics.densityDpi)
- splitScreenController.requestEnterSplitSelect(
- taskInfo,
- wct,
- splitPosition,
- taskBounds
- )
+ splitScreenController.requestEnterSplitSelect(taskInfo, wct, splitPosition, taskBounds)
}
override fun startAnimation(
@@ -390,7 +387,7 @@ class DragToDesktopTransitionHandler(
// occurred.
if (
change.taskInfo?.taskId == state.draggedTaskId &&
- state.cancelState != CancelState.STANDARD_CANCEL
+ state.cancelState != CancelState.STANDARD_CANCEL
) {
// We need access to the dragged task's change in both non-cancel and split
// cancel cases.
@@ -398,8 +395,8 @@ class DragToDesktopTransitionHandler(
}
if (
change.taskInfo?.taskId == state.draggedTaskId &&
- state.cancelState == CancelState.NO_CANCEL
- ) {
+ state.cancelState == CancelState.NO_CANCEL
+ ) {
taskDisplayAreaOrganizer.reparentToDisplayArea(
change.endDisplayId,
change.leash,
@@ -432,19 +429,20 @@ class DragToDesktopTransitionHandler(
startCancelDragToDesktopTransition()
} else if (
state.cancelState == CancelState.CANCEL_SPLIT_LEFT ||
- state.cancelState == CancelState.CANCEL_SPLIT_RIGHT
- ){
+ state.cancelState == CancelState.CANCEL_SPLIT_RIGHT
+ ) {
// Cancel-early case for split-cancel. The state was flagged already as a cancel for
// requesting split select. Similar to the above, this can happen due to quick fling
// gestures. We can simply request split here without needing to calculate animated
// task bounds as the task has not shrunk at all.
- val splitPosition = if (state.cancelState == CancelState.CANCEL_SPLIT_LEFT) {
- SPLIT_POSITION_TOP_OR_LEFT
- } else {
- SPLIT_POSITION_BOTTOM_OR_RIGHT
- }
- val taskInfo = state.draggedTaskChange?.taskInfo
- ?: error("Expected non-null task info.")
+ val splitPosition =
+ if (state.cancelState == CancelState.CANCEL_SPLIT_LEFT) {
+ SPLIT_POSITION_TOP_OR_LEFT
+ } else {
+ SPLIT_POSITION_BOTTOM_OR_RIGHT
+ }
+ val taskInfo =
+ state.draggedTaskChange?.taskInfo ?: error("Expected non-null task info.")
val wct = WindowContainerTransaction()
restoreWindowOrder(wct)
state.startTransitionFinishTransaction?.apply()
@@ -463,8 +461,10 @@ class DragToDesktopTransitionHandler(
) {
val state = requireTransitionState()
// We don't want to merge the split select animation if that's what we requested.
- if (state.cancelState == CancelState.CANCEL_SPLIT_LEFT ||
- state.cancelState == CancelState.CANCEL_SPLIT_RIGHT) {
+ if (
+ state.cancelState == CancelState.CANCEL_SPLIT_LEFT ||
+ state.cancelState == CancelState.CANCEL_SPLIT_RIGHT
+ ) {
clearState()
return
}
@@ -574,7 +574,8 @@ class DragToDesktopTransitionHandler(
startTransitionFinishCb.onTransitionFinished(null /* null */)
clearState()
interactionJankMonitor.end(
- CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE)
+ CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE
+ )
}
}
)
@@ -673,9 +674,7 @@ class DragToDesktopTransitionHandler(
val wct = WindowContainerTransaction()
restoreWindowOrder(wct, state)
state.cancelTransitionToken =
- transitions.startTransition(
- TRANSIT_DESKTOP_MODE_CANCEL_DRAG_TO_DESKTOP, wct, this
- )
+ transitions.startTransition(TRANSIT_DESKTOP_MODE_CANCEL_DRAG_TO_DESKTOP, wct, this)
}
private fun restoreWindowOrder(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ReturnToDragStartAnimator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ReturnToDragStartAnimator.kt
new file mode 100644
index 000000000000..be67a40560aa
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ReturnToDragStartAnimator.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.desktopmode
+
+import android.animation.Animator
+import android.animation.RectEvaluator
+import android.animation.ValueAnimator
+import android.graphics.Rect
+import android.view.SurfaceControl
+import androidx.core.animation.addListener
+import com.android.internal.jank.InteractionJankMonitor
+import com.android.wm.shell.windowdecor.OnTaskRepositionAnimationListener
+import java.util.function.Supplier
+
+/** Animates the task surface moving from its current drag position to its pre-drag position. */
+class ReturnToDragStartAnimator(
+ private val transactionSupplier: Supplier<SurfaceControl.Transaction>,
+ private val interactionJankMonitor: InteractionJankMonitor
+) {
+ private var boundsAnimator: Animator? = null
+ private lateinit var taskRepositionAnimationListener: OnTaskRepositionAnimationListener
+
+ constructor(interactionJankMonitor: InteractionJankMonitor) :
+ this(Supplier { SurfaceControl.Transaction() }, interactionJankMonitor)
+
+ /** Sets a listener for the start and end of the reposition animation. */
+ fun setTaskRepositionAnimationListener(listener: OnTaskRepositionAnimationListener) {
+ taskRepositionAnimationListener = listener
+ }
+
+ /** Builds new animator and starts animation of task leash reposition. */
+ fun start(taskId: Int, taskSurface: SurfaceControl, startBounds: Rect, endBounds: Rect) {
+ val tx = transactionSupplier.get()
+
+ boundsAnimator?.cancel()
+ boundsAnimator =
+ ValueAnimator.ofObject(RectEvaluator(), startBounds, endBounds)
+ .setDuration(RETURN_TO_DRAG_START_ANIMATION_MS)
+ .apply {
+ addListener(
+ onStart = {
+ val startTransaction = transactionSupplier.get()
+ startTransaction
+ .setPosition(
+ taskSurface,
+ startBounds.left.toFloat(),
+ startBounds.top.toFloat()
+ )
+ .show(taskSurface)
+ .apply()
+ taskRepositionAnimationListener.onAnimationStart(taskId)
+ },
+ onEnd = {
+ val finishTransaction = transactionSupplier.get()
+ finishTransaction
+ .setPosition(
+ taskSurface,
+ endBounds.left.toFloat(),
+ endBounds.top.toFloat()
+ )
+ .show(taskSurface)
+ .apply()
+ taskRepositionAnimationListener.onAnimationEnd(taskId)
+ boundsAnimator = null
+ // TODO(b/354658237) - show toast with relevant string
+ // TODO(b/339582583) - add Jank CUJ using interactionJankMonitor
+ }
+ )
+ addUpdateListener { anim ->
+ val rect = anim.animatedValue as Rect
+ tx.setPosition(taskSurface, rect.left.toFloat(), rect.top.toFloat())
+ .show(taskSurface)
+ .apply()
+ }
+ }
+ .also(ValueAnimator::start)
+ }
+
+ companion object {
+ const val RETURN_TO_DRAG_START_ANIMATION_MS = 300L
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
index c35d77a1d74a..bf185a463b1e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
@@ -45,15 +45,24 @@ class ToggleResizeDesktopTaskTransitionHandler(
private lateinit var onTaskResizeAnimationListener: OnTaskResizeAnimationListener
private var boundsAnimator: Animator? = null
+ private var initialBounds: Rect? = null
constructor(
transitions: Transitions,
interactionJankMonitor: InteractionJankMonitor
) : this(transitions, Supplier { SurfaceControl.Transaction() }, interactionJankMonitor)
- /** Starts a quick resize transition. */
- fun startTransition(wct: WindowContainerTransaction) {
+ /**
+ * Starts a quick resize transition.
+ *
+ * @param wct WindowContainerTransaction that will update core about the task changes applied
+ * @param taskLeashBounds current bounds of the task leash (Note: not guaranteed to be the
+ * bounds of the actual task). This is provided so that the animation
+ * resizing can begin where the task leash currently is for smoother UX.
+ */
+ fun startTransition(wct: WindowContainerTransaction, taskLeashBounds: Rect? = null) {
transitions.startTransition(TRANSIT_DESKTOP_MODE_TOGGLE_RESIZE, wct, this)
+ initialBounds = taskLeashBounds
}
fun setOnTaskResizeAnimationListener(listener: OnTaskResizeAnimationListener) {
@@ -70,7 +79,7 @@ class ToggleResizeDesktopTaskTransitionHandler(
val change = findRelevantChange(info)
val leash = change.leash
val taskId = checkNotNull(change.taskInfo).taskId
- val startBounds = change.startAbsBounds
+ val startBounds = initialBounds ?: change.startAbsBounds
val endBounds = change.endAbsBounds
val tx = transactionSupplier.get()
@@ -92,7 +101,7 @@ class ToggleResizeDesktopTaskTransitionHandler(
onTaskResizeAnimationListener.onAnimationStart(
taskId,
startTransaction,
- startBounds
+ startBounds,
)
},
onEnd = {
@@ -106,6 +115,7 @@ class ToggleResizeDesktopTaskTransitionHandler(
.show(leash)
onTaskResizeAnimationListener.onAnimationEnd(taskId)
finishCallback.onTransitionFinished(null)
+ initialBounds = null
boundsAnimator = null
interactionJankMonitor.end(
Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
index 333c75f92ffc..abec3b9c0c3b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
@@ -170,7 +170,7 @@ public class KeyguardTransitionHandler
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull TransitionFinishCallback finishCallback) {
- if (!handles(info) || mIsLaunchingActivityOverLockscreen) {
+ if (!handles(info)) {
return false;
}
@@ -185,6 +185,9 @@ public class KeyguardTransitionHandler
transition, info, startTransaction, finishTransaction, finishCallback);
}
+ if (mIsLaunchingActivityOverLockscreen) {
+ return false;
+ }
// Occlude/unocclude animations are only played if the keyguard is locked.
if ((info.getFlags() & TRANSIT_FLAG_KEYGUARD_LOCKED) != 0) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
index 94fe286de869..77743844f3c3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
@@ -300,6 +300,10 @@ public class PipController implements ConfigurationChangeListener,
int launcherRotation, Rect hotseatKeepClearArea) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"getSwipePipToHomeBounds: %s", componentName);
+ // preemptively add the keep clear area for Hotseat, so that it is taken into account
+ // when calculating the entry destination bounds of PiP window
+ mPipBoundsState.setNamedUnrestrictedKeepClearArea(
+ PipBoundsState.NAMED_KCA_LAUNCHER_SHELF, hotseatKeepClearArea);
mPipBoundsState.setBoundsStateForEntry(componentName, activityInfo, pictureInPictureParams,
mPipBoundsAlgorithm);
return mPipBoundsAlgorithm.getEntryDestinationBounds();
@@ -328,6 +332,23 @@ public class PipController implements ConfigurationChangeListener,
mPipRecentsAnimationListener.onPipAnimationStarted();
}
+ private void setLauncherKeepClearAreaHeight(boolean visible, int height) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "setLauncherKeepClearAreaHeight: visible=%b, height=%d", visible, height);
+ if (visible) {
+ Rect rect = new Rect(
+ 0, mPipDisplayLayoutState.getDisplayBounds().bottom - height,
+ mPipDisplayLayoutState.getDisplayBounds().right,
+ mPipDisplayLayoutState.getDisplayBounds().bottom);
+ mPipBoundsState.setNamedUnrestrictedKeepClearArea(
+ PipBoundsState.NAMED_KCA_LAUNCHER_SHELF, rect);
+ } else {
+ mPipBoundsState.setNamedUnrestrictedKeepClearArea(
+ PipBoundsState.NAMED_KCA_LAUNCHER_SHELF, null);
+ }
+ mPipTouchHandler.onShelfVisibilityChanged(visible, height);
+ }
+
@Override
public void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState,
@PipTransitionState.TransitionState int newState, @Nullable Bundle extra) {
@@ -349,10 +370,14 @@ public class PipController implements ConfigurationChangeListener,
if (mPipTransitionState.isInSwipePipToHomeTransition()) {
mPipTransitionState.resetSwipePipToHomeState();
}
- mOnIsInPipStateChangedListener.accept(true /* inPip */);
+ if (mOnIsInPipStateChangedListener != null) {
+ mOnIsInPipStateChangedListener.accept(true /* inPip */);
+ }
break;
case PipTransitionState.EXITED_PIP:
- mOnIsInPipStateChangedListener.accept(false /* inPip */);
+ if (mOnIsInPipStateChangedListener != null) {
+ mOnIsInPipStateChangedListener.accept(false /* inPip */);
+ }
break;
}
}
@@ -499,7 +524,10 @@ public class PipController implements ConfigurationChangeListener,
public void setShelfHeight(boolean visible, int height) {}
@Override
- public void setLauncherKeepClearAreaHeight(boolean visible, int height) {}
+ public void setLauncherKeepClearAreaHeight(boolean visible, int height) {
+ executeRemoteCallWithTaskPermission(mController, "setLauncherKeepClearAreaHeight",
+ (controller) -> controller.setLauncherKeepClearAreaHeight(visible, height));
+ }
@Override
public void setLauncherAppIconSize(int iconSizePx) {}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
index f387e72b3da6..d7c225b9e6e1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
@@ -38,6 +38,7 @@ import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Bundle;
+import android.os.SystemProperties;
import android.provider.DeviceConfig;
import android.util.Size;
import android.view.DisplayCutout;
@@ -78,6 +79,8 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
private static final String TAG = "PipTouchHandler";
private static final float DEFAULT_STASH_VELOCITY_THRESHOLD = 18000.f;
+ private static final long PIP_KEEP_CLEAR_AREAS_DELAY =
+ SystemProperties.getLong("persist.wm.debug.pip_keep_clear_areas_delay", 200);
// Allow PIP to resize to a slightly bigger state upon touch
private boolean mEnableResize;
@@ -134,6 +137,10 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
// Temp vars
private final Rect mTmpBounds = new Rect();
+ // Callbacks
+ private final Runnable mMoveOnShelVisibilityChanged;
+
+
/**
* A listener for the PIP menu activity.
*/
@@ -217,6 +224,26 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
mPipPerfHintController);
mPipBoundsState.addOnAspectRatioChangedCallback(this::updateMinMaxSize);
+ mMoveOnShelVisibilityChanged = () -> {
+ if (mIsImeShowing && mImeHeight > mShelfHeight) {
+ // Early bail-out if IME is visible with a larger height present;
+ // this should block unnecessary PiP movement since we delay checking for
+ // KCA triggered movement to wait for other transitions (e.g. due to IME changes).
+ return;
+ }
+ mPipTransitionState.setOnIdlePipTransitionStateRunnable(() -> {
+ boolean hasUserInteracted = (mPipBoundsState.hasUserMovedPip()
+ || mPipBoundsState.hasUserResizedPip());
+ int delta = mPipBoundsAlgorithm.getEntryDestinationBounds().top
+ - mPipBoundsState.getBounds().top;
+
+ if (!mIsImeShowing && !hasUserInteracted && delta != 0) {
+ // If the user hasn't interacted with PiP, we respect the keep clear areas
+ mMotionHelper.animateToOffset(mPipBoundsState.getBounds(), delta);
+ }
+ });
+ };
+
if (PipUtils.isPip2ExperimentEnabled()) {
shellInit.addInitCallback(this::onInit, this);
}
@@ -356,9 +383,14 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
mPipTransitionState.setOnIdlePipTransitionStateRunnable(() -> {
int delta = mPipBoundsState.getMovementBounds().bottom
- mPipBoundsState.getBounds().top;
-
boolean hasUserInteracted = (mPipBoundsState.hasUserMovedPip()
|| mPipBoundsState.hasUserResizedPip());
+
+ if (!imeVisible && !hasUserInteracted) {
+ delta = mPipBoundsAlgorithm.getEntryDestinationBounds().top
+ - mPipBoundsState.getBounds().top;
+ }
+
if ((imeVisible && delta < 0) || (!imeVisible && !hasUserInteracted)) {
// The policy is to ignore an IME disappearing if user has interacted with PiP.
// Otherwise, only offset due to an appearing IME if PiP occludes it.
@@ -370,6 +402,16 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
void onShelfVisibilityChanged(boolean shelfVisible, int shelfHeight) {
mIsShelfShowing = shelfVisible;
mShelfHeight = shelfHeight;
+
+ // We need to remove the callback even if the shelf is visible, in case it the delayed
+ // callback hasn't been executed yet to avoid the wrong final state.
+ mMainExecutor.removeCallbacks(mMoveOnShelVisibilityChanged);
+ if (shelfVisible) {
+ mMoveOnShelVisibilityChanged.run();
+ } else {
+ // Postpone moving in response to hide of Launcher in case there's another change
+ mMainExecutor.executeDelayed(mMoveOnShelVisibilityChanged, PIP_KEEP_CLEAR_AREAS_DELAY);
+ }
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
index 33703ad95a9c..7790c51f3bd3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
@@ -108,10 +108,6 @@ public class PipTransition extends PipTransitionController implements
//
@Nullable
- private WindowContainerToken mPipTaskToken;
- @Nullable
- private SurfaceControl mPipLeash;
- @Nullable
private Transitions.TransitionFinishCallback mFinishCallback;
public PipTransition(
@@ -402,7 +398,6 @@ public class PipTransition extends PipTransitionController implements
finishWct.setBoundsChangeTransaction(pipTaskToken, tx);
animator.setAnimationEndCallback(() -> {
- mPipTransitionState.setState(PipTransitionState.ENTERED_PIP);
finishCallback.onTransitionFinished(finishWct.isEmpty() ? null : finishWct);
});
@@ -444,15 +439,16 @@ public class PipTransition extends PipTransitionController implements
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
- TransitionInfo.Change pipChange = getPipChange(info);
+ WindowContainerToken pipToken = mPipTransitionState.mPipTaskToken;
+
+ TransitionInfo.Change pipChange = getChangeByToken(info, pipToken);
if (pipChange == null) {
return false;
}
Rect startBounds = pipChange.getStartAbsBounds();
Rect endBounds = pipChange.getEndAbsBounds();
- SurfaceControl pipLeash = mPipTransitionState.mPinnedTaskLeash;
- Preconditions.checkNotNull(pipLeash, "Leash is null for bounds transition.");
+ SurfaceControl pipLeash = pipChange.getLeash();
PipEnterExitAnimator animator = new PipEnterExitAnimator(mContext, pipLeash,
startTransaction, startBounds, startBounds, endBounds,
@@ -491,6 +487,18 @@ public class PipTransition extends PipTransitionController implements
return null;
}
+ @Nullable
+ private TransitionInfo.Change getChangeByToken(TransitionInfo info,
+ WindowContainerToken token) {
+ for (TransitionInfo.Change change : info.getChanges()) {
+ if (change.getTaskInfo() != null
+ && change.getTaskInfo().getToken().equals(token)) {
+ return change;
+ }
+ }
+ return null;
+ }
+
private WindowContainerTransaction getEnterPipTransaction(@NonNull IBinder transition,
@NonNull TransitionRequestInfo request) {
// cache the original task token to check for multi-activity case later
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index 234b4d0f86db..ad3f4f8c9beb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -19,12 +19,14 @@ package com.android.wm.shell.recents;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.WindowManager.KEYGUARD_VISIBILITY_TRANSIT_FLAGS;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED;
import static android.view.WindowManager.TRANSIT_PIP;
import static android.view.WindowManager.TRANSIT_SLEEP;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
+import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP;
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_CAN_HAND_OFF_ANIMATION;
@@ -775,6 +777,20 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
// Don't consider order-only & non-leaf changes as changing apps.
if (!TransitionUtil.isOrderOnly(change) && isLeafTask) {
hasChangingApp = true;
+ // Check if the changing app is moving to top and fullscreen. This handles
+ // the case where we moved from desktop to recents and launching a desktop
+ // task in fullscreen.
+ if ((change.getFlags() & FLAG_MOVED_TO_TOP) != 0
+ && taskInfo != null
+ && taskInfo.getWindowingMode()
+ == WINDOWING_MODE_FULLSCREEN) {
+ if (openingTasks == null) {
+ openingTasks = new ArrayList<>();
+ openingTaskIsLeafs = new IntArray();
+ }
+ openingTasks.add(change);
+ openingTaskIsLeafs.add(1);
+ }
} else if (isLeafTask && taskInfo.topActivityType == ACTIVITY_TYPE_HOME
&& !isRecentsTask ) {
// Unless it is a 3p launcher. This means that the 3p launcher was already
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl
index 0ca244c4b96a..59aa7926ce8f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl
@@ -109,35 +109,6 @@ interface ISplitScreen {
in RemoteTransition remoteTransition, in InstanceId instanceId) = 17;
/**
- * Version of startTasks using legacy transition system.
- */
- oneway void startTasksWithLegacyTransition(int taskId1, in Bundle options1, int taskId2,
- in Bundle options2, int splitPosition, int snapPosition,
- in RemoteAnimationAdapter adapter, in InstanceId instanceId) = 11;
-
- /**
- * Starts a pair of intent and task using legacy transition system.
- */
- oneway void startIntentAndTaskWithLegacyTransition(in PendingIntent pendingIntent, int userId1,
- in Bundle options1, int taskId, in Bundle options2, int splitPosition, int snapPosition,
- in RemoteAnimationAdapter adapter, in InstanceId instanceId) = 12;
-
- /**
- * Starts a pair of shortcut and task using legacy transition system.
- */
- oneway void startShortcutAndTaskWithLegacyTransition(in ShortcutInfo shortcutInfo,
- in Bundle options1, int taskId, in Bundle options2, int splitPosition, int snapPosition,
- in RemoteAnimationAdapter adapter, in InstanceId instanceId) = 15;
-
- /**
- * Start a pair of intents using legacy transition system.
- */
- oneway void startIntentsWithLegacyTransition(in PendingIntent pendingIntent1, int userId1,
- in ShortcutInfo shortcutInfo1, in Bundle options1, in PendingIntent pendingIntent2,
- int userId2, in ShortcutInfo shortcutInfo2, in Bundle options2, int splitPosition,
- int snapPosition, in RemoteAnimationAdapter adapter, in InstanceId instanceId) = 18;
-
- /**
* Start a pair of intents in one transition.
*/
oneway void startIntents(in PendingIntent pendingIntent1, int userId1,
@@ -146,20 +117,6 @@ interface ISplitScreen {
int snapPosition, in RemoteTransition remoteTransition, in InstanceId instanceId) = 19;
/**
- * Blocking call that notifies and gets additional split-screen targets when entering
- * recents (for example: the dividerBar).
- * @param appTargets apps that will be re-parented to display area
- */
- RemoteAnimationTarget[] onGoingToRecentsLegacy(in RemoteAnimationTarget[] appTargets) = 13;
-
- /**
- * Blocking call that notifies and gets additional split-screen targets when entering
- * recents (for example: the dividerBar). Different than the method above in that this one
- * does not expect split to currently be running.
- */
- RemoteAnimationTarget[] onStartingSplitLegacy(in RemoteAnimationTarget[] appTargets) = 14;
-
- /**
* Reverse the split.
*/
oneway void switchSplitPosition() = 22;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index c4af14882a34..83f827ae54da 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -23,7 +23,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.RemoteAnimationTarget.MODE_OPENING;
import static com.android.wm.shell.common.MultiInstanceHelper.getComponent;
import static com.android.wm.shell.common.MultiInstanceHelper.getShortcutComponent;
@@ -35,9 +34,9 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSIT
import static com.android.wm.shell.common.split.SplitScreenUtils.isValidToSplit;
import static com.android.wm.shell.common.split.SplitScreenUtils.reverseSplitPosition;
import static com.android.wm.shell.common.split.SplitScreenUtils.splitFailureMessage;
+import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_SPLIT_SCREEN;
-import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
import android.app.ActivityManager;
import android.app.ActivityOptions;
@@ -201,11 +200,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
@VisibleForTesting
StageCoordinator mStageCoordinator;
- // Only used for the legacy recents animation from splitscreen to allow the tasks to be animated
- // outside the bounds of the roots by being reparented into a higher level fullscreen container
- private SurfaceControl mGoingToRecentsTasksLayer;
- private SurfaceControl mStartingSplitTasksLayer;
-
/**
* @param stageCoordinator if null, a stage coordinator will be created when this controller is
* initialized. Can be non-null for testing purposes.
@@ -457,11 +451,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
}
public void exitSplitScreen(int toTopTaskId, @ExitReason int exitReason) {
- if (ENABLE_SHELL_TRANSITIONS) {
- mStageCoordinator.dismissSplitScreen(toTopTaskId, exitReason);
- } else {
- mStageCoordinator.exitSplitScreen(toTopTaskId, exitReason);
- }
+ mStageCoordinator.dismissSplitScreen(toTopTaskId, exitReason);
}
@Override
@@ -606,7 +596,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
*/
public void startShortcut(String packageName, String shortcutId, @SplitPosition int position,
@Nullable Bundle options, UserHandle user, @NonNull InstanceId instanceId) {
- mStageCoordinator.onRequestToSplit(instanceId, ENTER_REASON_LAUNCHER);
+ ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "startShortcut: reason=%d", ENTER_REASON_LAUNCHER);
+ mStageCoordinator.getLogger().enterRequested(instanceId, ENTER_REASON_LAUNCHER);
startShortcut(packageName, shortcutId, position, options, user);
}
@@ -640,37 +631,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
activityOptions.toBundle(), user);
}
- void startShortcutAndTaskWithLegacyTransition(@NonNull ShortcutInfo shortcutInfo,
- @Nullable Bundle options1, int taskId, @Nullable Bundle options2,
- @SplitPosition int splitPosition, @PersistentSnapPosition int snapPosition,
- RemoteAnimationAdapter adapter, InstanceId instanceId) {
- if (options1 == null) options1 = new Bundle();
- final ActivityOptions activityOptions = ActivityOptions.fromBundle(options1);
-
- final String packageName1 = shortcutInfo.getPackage();
- final String packageName2 = SplitScreenUtils.getPackageName(taskId, mTaskOrganizer);
- final int userId1 = shortcutInfo.getUserId();
- final int userId2 = SplitScreenUtils.getUserId(taskId, mTaskOrganizer);
- if (samePackage(packageName1, packageName2, userId1, userId2)) {
- if (mMultiInstanceHelpher.supportsMultiInstanceSplit(shortcutInfo.getActivity())) {
- activityOptions.setApplyMultipleTaskFlagForShortcut(true);
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK");
- } else {
- taskId = INVALID_TASK_ID;
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
- "Cancel entering split as not supporting multi-instances");
- Log.w(TAG, splitFailureMessage("startShortcutAndTaskWithLegacyTransition",
- "app package " + packageName1 + " does not support multi-instance"));
- Toast.makeText(mContext, R.string.dock_multi_instances_not_supported_text,
- Toast.LENGTH_SHORT).show();
- }
- }
-
- mStageCoordinator.startShortcutAndTaskWithLegacyTransition(shortcutInfo,
- activityOptions.toBundle(), taskId, options2, splitPosition, snapPosition, adapter,
- instanceId);
- }
-
void startShortcutAndTask(@NonNull ShortcutInfo shortcutInfo, @Nullable Bundle options1,
int taskId, @Nullable Bundle options2, @SplitPosition int splitPosition,
@PersistentSnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition,
@@ -711,37 +671,12 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
public void startIntentWithInstanceId(PendingIntent intent, int userId,
@Nullable Intent fillInIntent, @SplitPosition int position, @Nullable Bundle options,
@NonNull InstanceId instanceId) {
- mStageCoordinator.onRequestToSplit(instanceId, ENTER_REASON_LAUNCHER);
+ ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "startIntentWithInstanceId: reason=%d",
+ ENTER_REASON_LAUNCHER);
+ mStageCoordinator.getLogger().enterRequested(instanceId, ENTER_REASON_LAUNCHER);
startIntent(intent, userId, fillInIntent, position, options, null /* hideTaskToken */);
}
- private void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, int userId1,
- @Nullable Bundle options1, int taskId, @Nullable Bundle options2,
- @SplitPosition int splitPosition, @PersistentSnapPosition int snapPosition,
- RemoteAnimationAdapter adapter, InstanceId instanceId) {
- Intent fillInIntent = null;
- final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent);
- final String packageName2 = SplitScreenUtils.getPackageName(taskId, mTaskOrganizer);
- final int userId2 = SplitScreenUtils.getUserId(taskId, mTaskOrganizer);
- if (samePackage(packageName1, packageName2, userId1, userId2)) {
- if (mMultiInstanceHelpher.supportsMultiInstanceSplit(getComponent(pendingIntent))) {
- fillInIntent = new Intent();
- fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK");
- } else {
- taskId = INVALID_TASK_ID;
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
- "Cancel entering split as not supporting multi-instances");
- Log.w(TAG, splitFailureMessage("startIntentAndTaskWithLegacyTransition",
- "app package " + packageName1 + " does not support multi-instance"));
- Toast.makeText(mContext, R.string.dock_multi_instances_not_supported_text,
- Toast.LENGTH_SHORT).show();
- }
- }
- mStageCoordinator.startIntentAndTaskWithLegacyTransition(pendingIntent, fillInIntent,
- options1, taskId, options2, splitPosition, snapPosition, adapter, instanceId);
- }
-
private void startIntentAndTask(PendingIntent pendingIntent, int userId1,
@Nullable Bundle options1, int taskId, @Nullable Bundle options2,
@SplitPosition int splitPosition, @PersistentSnapPosition int snapPosition,
@@ -778,38 +713,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
options2, splitPosition, snapPosition, remoteTransition, instanceId);
}
- private void startIntentsWithLegacyTransition(PendingIntent pendingIntent1, int userId1,
- @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1,
- PendingIntent pendingIntent2, int userId2, @Nullable ShortcutInfo shortcutInfo2,
- @Nullable Bundle options2, @SplitPosition int splitPosition,
- @PersistentSnapPosition int snapPosition, RemoteAnimationAdapter adapter,
- InstanceId instanceId) {
- Intent fillInIntent1 = null;
- Intent fillInIntent2 = null;
- final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent1);
- final String packageName2 = SplitScreenUtils.getPackageName(pendingIntent2);
- if (samePackage(packageName1, packageName2, userId1, userId2)) {
- if (mMultiInstanceHelpher.supportsMultiInstanceSplit(getComponent(pendingIntent1))) {
- fillInIntent1 = new Intent();
- fillInIntent1.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
- fillInIntent2 = new Intent();
- fillInIntent2.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK");
- } else {
- pendingIntent2 = null;
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
- "Cancel entering split as not supporting multi-instances");
- Log.w(TAG, splitFailureMessage("startIntentsWithLegacyTransition",
- "app package " + packageName1 + " does not support multi-instance"));
- Toast.makeText(mContext, R.string.dock_multi_instances_not_supported_text,
- Toast.LENGTH_SHORT).show();
- }
- }
- mStageCoordinator.startIntentsWithLegacyTransition(pendingIntent1, fillInIntent1,
- shortcutInfo1, options1, pendingIntent2, fillInIntent2, shortcutInfo2, options2,
- splitPosition, snapPosition, adapter, instanceId);
- }
-
private void startIntents(PendingIntent pendingIntent1, int userId1,
@Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1,
PendingIntent pendingIntent2, int userId2, @Nullable ShortcutInfo shortcutInfo2,
@@ -891,11 +794,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
if (taskInfo != null) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
"Found suitable background task=%s", taskInfo);
- if (ENABLE_SHELL_TRANSITIONS) {
- mStageCoordinator.startTask(taskInfo.taskId, position, options, hideTaskToken);
- } else {
- startTask(taskInfo.taskId, position, options, hideTaskToken);
- }
+ mStageCoordinator.startTask(taskInfo.taskId, position, options, hideTaskToken);
+
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Start task in background");
return;
}
@@ -995,63 +895,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
return fillInIntent2;
}
- RemoteAnimationTarget[] onGoingToRecentsLegacy(RemoteAnimationTarget[] apps) {
- if (ENABLE_SHELL_TRANSITIONS) return null;
-
- if (isSplitScreenVisible()) {
- // Evict child tasks except the top visible one under split root to ensure it could be
- // launched as full screen when switching to it on recents.
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- mStageCoordinator.prepareEvictInvisibleChildTasks(wct);
- mSyncQueue.queue(wct);
- } else {
- return null;
- }
-
- SurfaceControl.Transaction t = mTransactionPool.acquire();
- if (mGoingToRecentsTasksLayer != null) {
- t.remove(mGoingToRecentsTasksLayer);
- }
- mGoingToRecentsTasksLayer = reparentSplitTasksForAnimation(apps, t,
- "SplitScreenController#onGoingToRecentsLegacy" /* callsite */);
- t.apply();
- mTransactionPool.release(t);
-
- return new RemoteAnimationTarget[]{mStageCoordinator.getDividerBarLegacyTarget()};
- }
-
- RemoteAnimationTarget[] onStartingSplitLegacy(RemoteAnimationTarget[] apps) {
- if (ENABLE_SHELL_TRANSITIONS) return null;
-
- int openingApps = 0;
- for (int i = 0; i < apps.length; ++i) {
- if (apps[i].mode == MODE_OPENING) openingApps++;
- }
- if (openingApps < 2) {
- // Not having enough apps to enter split screen
- return null;
- }
-
- SurfaceControl.Transaction t = mTransactionPool.acquire();
- if (mStartingSplitTasksLayer != null) {
- t.remove(mStartingSplitTasksLayer);
- }
- mStartingSplitTasksLayer = reparentSplitTasksForAnimation(apps, t,
- "SplitScreenController#onStartingSplitLegacy" /* callsite */);
- t.apply();
- mTransactionPool.release(t);
-
- try {
- return new RemoteAnimationTarget[]{mStageCoordinator.getDividerBarLegacyTarget()};
- } finally {
- for (RemoteAnimationTarget appTarget : apps) {
- if (appTarget.leash != null) {
- appTarget.leash.release();
- }
- }
- }
- }
-
private SurfaceControl reparentSplitTasksForAnimation(RemoteAnimationTarget[] apps,
SurfaceControl.Transaction t, String callsite) {
final SurfaceControl.Builder builder = new SurfaceControl.Builder(new SurfaceSession())
@@ -1348,41 +1191,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
}
@Override
- public void startTasksWithLegacyTransition(int taskId1, @Nullable Bundle options1,
- int taskId2, @Nullable Bundle options2, @SplitPosition int splitPosition,
- @PersistentSnapPosition int snapPosition, RemoteAnimationAdapter adapter,
- InstanceId instanceId) {
- executeRemoteCallWithTaskPermission(mController, "startTasks",
- (controller) -> controller.mStageCoordinator.startTasksWithLegacyTransition(
- taskId1, options1, taskId2, options2, splitPosition, snapPosition,
- adapter, instanceId));
- }
-
- @Override
- public void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, int userId1,
- Bundle options1, int taskId, Bundle options2, int splitPosition,
- @PersistentSnapPosition int snapPosition, RemoteAnimationAdapter adapter,
- InstanceId instanceId) {
- executeRemoteCallWithTaskPermission(mController,
- "startIntentAndTaskWithLegacyTransition", (controller) ->
- controller.startIntentAndTaskWithLegacyTransition(pendingIntent,
- userId1, options1, taskId, options2, splitPosition,
- snapPosition, adapter, instanceId));
- }
-
- @Override
- public void startShortcutAndTaskWithLegacyTransition(ShortcutInfo shortcutInfo,
- @Nullable Bundle options1, int taskId, @Nullable Bundle options2,
- @SplitPosition int splitPosition, @PersistentSnapPosition int snapPosition,
- RemoteAnimationAdapter adapter, InstanceId instanceId) {
- executeRemoteCallWithTaskPermission(mController,
- "startShortcutAndTaskWithLegacyTransition", (controller) ->
- controller.startShortcutAndTaskWithLegacyTransition(
- shortcutInfo, options1, taskId, options2, splitPosition,
- snapPosition, adapter, instanceId));
- }
-
- @Override
public void startTasks(int taskId1, @Nullable Bundle options1, int taskId2,
@Nullable Bundle options2, @SplitPosition int splitPosition,
@PersistentSnapPosition int snapPosition,
@@ -1415,21 +1223,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
}
@Override
- public void startIntentsWithLegacyTransition(PendingIntent pendingIntent1, int userId1,
- @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1,
- PendingIntent pendingIntent2, int userId2, @Nullable ShortcutInfo shortcutInfo2,
- @Nullable Bundle options2, @SplitPosition int splitPosition,
- @PersistentSnapPosition int snapPosition, RemoteAnimationAdapter adapter,
- InstanceId instanceId) {
- executeRemoteCallWithTaskPermission(mController, "startIntentsWithLegacyTransition",
- (controller) ->
- controller.startIntentsWithLegacyTransition(pendingIntent1, userId1,
- shortcutInfo1, options1, pendingIntent2, userId2, shortcutInfo2,
- options2, splitPosition, snapPosition, adapter, instanceId)
- );
- }
-
- @Override
public void startIntents(PendingIntent pendingIntent1, int userId1,
@Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1,
PendingIntent pendingIntent2, int userId2, @Nullable ShortcutInfo shortcutInfo2,
@@ -1461,24 +1254,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
}
@Override
- public RemoteAnimationTarget[] onGoingToRecentsLegacy(RemoteAnimationTarget[] apps) {
- final RemoteAnimationTarget[][] out = new RemoteAnimationTarget[][]{null};
- executeRemoteCallWithTaskPermission(mController, "onGoingToRecentsLegacy",
- (controller) -> out[0] = controller.onGoingToRecentsLegacy(apps),
- true /* blocking */);
- return out[0];
- }
-
- @Override
- public RemoteAnimationTarget[] onStartingSplitLegacy(RemoteAnimationTarget[] apps) {
- final RemoteAnimationTarget[][] out = new RemoteAnimationTarget[][]{null};
- executeRemoteCallWithTaskPermission(mController, "onStartingSplitLegacy",
- (controller) -> out[0] = controller.onStartingSplitLegacy(apps),
- true /* blocking */);
- return out[0];
- }
-
- @Override
public void switchSplitPosition() {
executeRemoteCallWithTaskPermission(mController, "switchSplitPosition",
(controller) -> controller.switchSplitPosition("remoteCall"));
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 2531ff150f43..a7551bddc42d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -24,8 +24,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
import static android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.RemoteAnimationTarget.MODE_OPENING;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
@@ -59,14 +57,12 @@ import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_FULLSCREEN_REQUEST;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_FULLSCREEN_SHORTCUT;
-import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RECREATE_SPLIT;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RETURN_HOME;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_ROOT_TASK_VANISHED;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_UNKNOWN;
import static com.android.wm.shell.splitscreen.SplitScreenController.exitReasonToString;
import static com.android.wm.shell.transition.MixedTransitionHelper.getPipReplacingChange;
-import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
import static com.android.wm.shell.transition.Transitions.TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE;
import static com.android.wm.shell.transition.Transitions.TRANSIT_SPLIT_SCREEN_PAIR_OPEN;
@@ -81,7 +77,6 @@ import android.app.ActivityOptions;
import android.app.IActivityTaskManager;
import android.app.PendingIntent;
import android.app.TaskInfo;
-import android.app.WindowConfiguration;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
@@ -121,7 +116,6 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.InstanceId;
import com.android.internal.policy.FoldLockSettingsObserver;
import com.android.internal.protolog.ProtoLog;
-import com.android.internal.util.ArrayUtils;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
@@ -143,9 +137,7 @@ import com.android.wm.shell.recents.RecentTasksController;
import com.android.wm.shell.shared.TransitionUtil;
import com.android.wm.shell.splitscreen.SplitScreen.StageType;
import com.android.wm.shell.splitscreen.SplitScreenController.ExitReason;
-import com.android.wm.shell.splitscreen.SplitScreenController.SplitEnterReason;
import com.android.wm.shell.transition.DefaultMixedHandler;
-import com.android.wm.shell.transition.LegacyTransitions;
import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.util.SplitBounds;
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
@@ -227,7 +219,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// Tracks whether we should update the recent tasks. Only allow this to happen in between enter
// and exit, since exit itself can trigger a number of changes that update the stages.
- private boolean mShouldUpdateRecents;
+ private boolean mShouldUpdateRecents = true;
private boolean mExitSplitScreenOnHide;
private boolean mIsDividerRemoteAnimating;
private boolean mIsDropEntering;
@@ -368,11 +360,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
transitions.addHandler(this);
mSplitUnsupportedToast = Toast.makeText(mContext,
R.string.dock_non_resizeble_failed_to_dock_text, Toast.LENGTH_SHORT);
- // With shell transition, we should update recents tile each callback so set this to true by
- // default.
- mShouldUpdateRecents = ENABLE_SHELL_TRANSITIONS;
- mFoldLockSettingsObserver =
- new FoldLockSettingsObserver(mainHandler, context);
+ mFoldLockSettingsObserver = new FoldLockSettingsObserver(mainHandler, context);
mFoldLockSettingsObserver.register();
}
@@ -491,18 +479,12 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "moveToStage: task=%d position=%d", task.taskId,
stagePosition);
prepareEnterSplitScreen(wct, task, stagePosition, false /* resizeAnim */);
- if (ENABLE_SHELL_TRANSITIONS) {
- mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct,
- null, this,
- isSplitScreenVisible()
- ? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN,
- !mIsDropEntering);
- } else {
- mSyncQueue.queue(wct);
- mSyncQueue.runInSync(t -> {
- updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
- });
- }
+ mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct,
+ null, this,
+ isSplitScreenVisible()
+ ? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN,
+ !mIsDropEntering);
+
// Due to drag already pip task entering split by this method so need to reset flag here.
mIsDropEntering = false;
mSkipEvictingMainStageChildren = false;
@@ -653,10 +635,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "startIntent: intent=%s position=%d", intent.getIntent(),
position);
mSplitRequest = new SplitRequest(intent.getIntent(), position);
- if (!ENABLE_SHELL_TRANSITIONS) {
- startIntentLegacy(intent, fillInIntent, position, options);
- return;
- }
final WindowContainerTransaction wct = new WindowContainerTransaction();
options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, null /* wct */);
@@ -690,63 +668,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
extraTransitType, !mIsDropEntering);
}
- /** Launches an activity into split by legacy transition. */
- void startIntentLegacy(PendingIntent intent, Intent fillInIntent, @SplitPosition int position,
- @Nullable Bundle options) {
- final boolean isEnteringSplit = !isSplitActive();
-
- LegacyTransitions.ILegacyTransition transition = new LegacyTransitions.ILegacyTransition() {
- @Override
- public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
- RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
- IRemoteAnimationFinishedCallback finishedCallback,
- SurfaceControl.Transaction t) {
- if (isEnteringSplit && mSideStage.getChildCount() == 0) {
- mMainExecutor.execute(() -> exitSplitScreen(
- null /* childrenToTop */, EXIT_REASON_UNKNOWN));
- Log.w(TAG, splitFailureMessage("startIntentLegacy",
- "side stage was not populated"));
- handleUnsupportedSplitStart();
- }
-
- if (apps != null) {
- for (int i = 0; i < apps.length; ++i) {
- if (apps[i].mode == MODE_OPENING) {
- t.show(apps[i].leash);
- }
- }
- }
- t.apply();
-
- if (finishedCallback != null) {
- try {
- finishedCallback.onAnimationFinished();
- } catch (RemoteException e) {
- Slog.e(TAG, "Error finishing legacy transition: ", e);
- }
- }
-
-
- if (!isEnteringSplit && apps != null) {
- final WindowContainerTransaction evictWct = new WindowContainerTransaction();
- prepareEvictNonOpeningChildTasks(position, apps, evictWct);
- mSyncQueue.queue(evictWct);
- }
- }
- };
-
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, wct);
-
- // If split still not active, apply windows bounds first to avoid surface reset to
- // wrong pos by SurfaceAnimator from wms.
- if (isEnteringSplit && mLogger.isEnterRequestedByDrag()) {
- updateWindowBounds(mSplitLayout, wct);
- }
- wct.sendPendingIntent(intent, fillInIntent, options);
- mSyncQueue.queue(transition, WindowManager.TRANSIT_OPEN, wct);
- }
-
/** Starts 2 tasks in one transition. */
void startTasks(int taskId1, @Nullable Bundle options1, int taskId2, @Nullable Bundle options2,
@SplitPosition int splitPosition, @PersistentSnapPosition int snapPosition,
@@ -991,373 +912,12 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSplitTransitions.startFullscreenTransition(wct, remoteTransition);
}
- /** Starts a pair of tasks using legacy transition. */
- void startTasksWithLegacyTransition(int taskId1, @Nullable Bundle options1,
- int taskId2, @Nullable Bundle options2, @SplitPosition int splitPosition,
- @PersistentSnapPosition int snapPosition, RemoteAnimationAdapter adapter,
- InstanceId instanceId) {
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- if (options1 == null) options1 = new Bundle();
- if (taskId2 == INVALID_TASK_ID) {
- // Launching a solo task.
- // Exit split first if this task under split roots.
- if (mMainStage.containsTask(taskId1) || mSideStage.containsTask(taskId1)) {
- exitSplitScreen(null /* childrenToTop */, EXIT_REASON_RECREATE_SPLIT);
- }
- ActivityOptions activityOptions = ActivityOptions.fromBundle(options1);
- activityOptions.update(ActivityOptions.makeRemoteAnimation(adapter));
- options1 = activityOptions.toBundle();
- addActivityOptions(options1, null /* launchTarget */);
- wct.startTask(taskId1, options1);
- mSyncQueue.queue(wct);
- return;
- }
-
- addActivityOptions(options1, mSideStage);
- wct.startTask(taskId1, options1);
- mSplitRequest = new SplitRequest(taskId1, taskId2, splitPosition);
- startWithLegacyTransition(wct, taskId2, options2, splitPosition, snapPosition, adapter,
- instanceId);
- }
-
- /** Starts a pair of intents using legacy transition. */
- void startIntentsWithLegacyTransition(PendingIntent pendingIntent1, Intent fillInIntent1,
- @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1,
- @Nullable PendingIntent pendingIntent2, Intent fillInIntent2,
- @Nullable ShortcutInfo shortcutInfo2, @Nullable Bundle options2,
- @SplitPosition int splitPosition, @PersistentSnapPosition int snapPosition,
- RemoteAnimationAdapter adapter, InstanceId instanceId) {
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- if (options1 == null) options1 = new Bundle();
- if (pendingIntent2 == null) {
- // Launching a solo intent or shortcut as fullscreen.
- launchAsFullscreenWithRemoteAnimation(pendingIntent1, fillInIntent1, shortcutInfo1,
- options1, adapter, wct);
- return;
- }
-
- addActivityOptions(options1, mSideStage);
- if (shortcutInfo1 != null) {
- wct.startShortcut(mContext.getPackageName(), shortcutInfo1, options1);
- } else {
- wct.sendPendingIntent(pendingIntent1, fillInIntent1, options1);
- mSplitRequest = new SplitRequest(pendingIntent1.getIntent(),
- pendingIntent2 != null ? pendingIntent2.getIntent() : null, splitPosition);
- }
- startWithLegacyTransition(wct, pendingIntent2, fillInIntent2, shortcutInfo2, options2,
- splitPosition, snapPosition, adapter, instanceId);
- }
-
- void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, Intent fillInIntent,
- @Nullable Bundle options1, int taskId, @Nullable Bundle options2,
- @SplitPosition int splitPosition, @PersistentSnapPosition int snapPosition,
- RemoteAnimationAdapter adapter, InstanceId instanceId) {
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- if (options1 == null) options1 = new Bundle();
- if (taskId == INVALID_TASK_ID) {
- // Launching a solo intent as fullscreen.
- launchAsFullscreenWithRemoteAnimation(pendingIntent, fillInIntent, null, options1,
- adapter, wct);
- return;
- }
-
- addActivityOptions(options1, mSideStage);
- wct.sendPendingIntent(pendingIntent, fillInIntent, options1);
- mSplitRequest = new SplitRequest(taskId, pendingIntent.getIntent(), splitPosition);
- startWithLegacyTransition(wct, taskId, options2, splitPosition, snapPosition, adapter,
- instanceId);
- }
-
- /** Starts a pair of shortcut and task using legacy transition. */
- void startShortcutAndTaskWithLegacyTransition(ShortcutInfo shortcutInfo,
- @Nullable Bundle options1, int taskId, @Nullable Bundle options2,
- @SplitPosition int splitPosition, @PersistentSnapPosition int snapPosition,
- RemoteAnimationAdapter adapter, InstanceId instanceId) {
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- if (options1 == null) options1 = new Bundle();
- if (taskId == INVALID_TASK_ID) {
- // Launching a solo shortcut as fullscreen.
- launchAsFullscreenWithRemoteAnimation(null, null, shortcutInfo, options1, adapter, wct);
- return;
- }
-
- addActivityOptions(options1, mSideStage);
- wct.startShortcut(mContext.getPackageName(), shortcutInfo, options1);
- startWithLegacyTransition(wct, taskId, options2, splitPosition, snapPosition, adapter,
- instanceId);
- }
-
- private void launchAsFullscreenWithRemoteAnimation(@Nullable PendingIntent pendingIntent,
- @Nullable Intent fillInIntent, @Nullable ShortcutInfo shortcutInfo,
- @Nullable Bundle options, RemoteAnimationAdapter adapter,
- WindowContainerTransaction wct) {
- LegacyTransitions.ILegacyTransition transition =
- (transit, apps, wallpapers, nonApps, finishedCallback, t) -> {
- if (apps == null || apps.length == 0) {
- onRemoteAnimationFinished(apps);
- t.apply();
- try {
- adapter.getRunner().onAnimationCancelled();
- } catch (RemoteException e) {
- Slog.e(TAG, "Error starting remote animation", e);
- }
- return;
- }
-
- for (int i = 0; i < apps.length; ++i) {
- if (apps[i].mode == MODE_OPENING) {
- t.show(apps[i].leash);
- }
- }
- t.apply();
-
- try {
- adapter.getRunner().onAnimationStart(
- transit, apps, wallpapers, nonApps, finishedCallback);
- } catch (RemoteException e) {
- Slog.e(TAG, "Error starting remote animation", e);
- }
- };
-
- addActivityOptions(options, null /* launchTarget */);
- if (shortcutInfo != null) {
- wct.startShortcut(mContext.getPackageName(), shortcutInfo, options);
- } else if (pendingIntent != null) {
- wct.sendPendingIntent(pendingIntent, fillInIntent, options);
- } else {
- Slog.e(TAG, "Pending intent and shortcut are null is invalid case.");
- }
- mSyncQueue.queue(transition, WindowManager.TRANSIT_OPEN, wct);
- }
-
- private void startWithLegacyTransition(WindowContainerTransaction wct,
- @Nullable PendingIntent mainPendingIntent, @Nullable Intent mainFillInIntent,
- @Nullable ShortcutInfo mainShortcutInfo, @Nullable Bundle mainOptions,
- @SplitPosition int sidePosition, @PersistentSnapPosition int snapPosition,
- RemoteAnimationAdapter adapter, InstanceId instanceId) {
- startWithLegacyTransition(wct, INVALID_TASK_ID, mainPendingIntent, mainFillInIntent,
- mainShortcutInfo, mainOptions, sidePosition, snapPosition, adapter, instanceId);
- }
-
- private void startWithLegacyTransition(WindowContainerTransaction wct, int mainTaskId,
- @Nullable Bundle mainOptions, @SplitPosition int sidePosition,
- @PersistentSnapPosition int snapPosition, RemoteAnimationAdapter adapter,
- InstanceId instanceId) {
- startWithLegacyTransition(wct, mainTaskId, null /* mainPendingIntent */,
- null /* mainFillInIntent */, null /* mainShortcutInfo */, mainOptions, sidePosition,
- snapPosition, adapter, instanceId);
- }
-
- /**
- * @param wct transaction to start the first task
- * @param instanceId if {@code null}, will not log. Otherwise it will be used in
- * {@link SplitscreenEventLogger#logEnter(float, int, int, int, int, boolean)}
- */
- private void startWithLegacyTransition(WindowContainerTransaction wct, int mainTaskId,
- @Nullable PendingIntent mainPendingIntent, @Nullable Intent mainFillInIntent,
- @Nullable ShortcutInfo mainShortcutInfo, @Nullable Bundle options,
- @SplitPosition int sidePosition, @PersistentSnapPosition int snapPosition,
- RemoteAnimationAdapter adapter, InstanceId instanceId) {
- if (!isSplitScreenVisible()) {
- exitSplitScreen(null /* childrenToTop */, EXIT_REASON_RECREATE_SPLIT);
- }
-
- // Init divider first to make divider leash for remote animation target.
- mSplitLayout.init();
- mSplitLayout.setDivideRatio(snapPosition);
-
- // Apply surface bounds before animation start.
- SurfaceControl.Transaction startT = mTransactionPool.acquire();
- updateSurfaceBounds(mSplitLayout, startT, false /* applyResizingOffset */);
- startT.apply();
- mTransactionPool.release(startT);
-
- // Set false to avoid record new bounds with old task still on top;
- mShouldUpdateRecents = false;
- mIsDividerRemoteAnimating = true;
- if (mSplitRequest == null) {
- mSplitRequest = new SplitRequest(mainTaskId,
- mainPendingIntent != null ? mainPendingIntent.getIntent() : null,
- sidePosition);
- }
- setSideStagePosition(sidePosition, wct);
- if (!mMainStage.isActive()) {
- mMainStage.activate(wct, false /* reparent */);
- }
-
- if (options == null) options = new Bundle();
- addActivityOptions(options, mMainStage);
-
- updateWindowBounds(mSplitLayout, wct);
- wct.reorder(mRootTaskInfo.token, true);
- setRootForceTranslucent(false, wct);
-
- // TODO(b/268008375): Merge APIs to start a split pair into one.
- if (mainTaskId != INVALID_TASK_ID) {
- options = wrapAsSplitRemoteAnimation(adapter, options);
- wct.startTask(mainTaskId, options);
- mSyncQueue.queue(wct);
- } else {
- if (mainShortcutInfo != null) {
- wct.startShortcut(mContext.getPackageName(), mainShortcutInfo, options);
- } else {
- wct.sendPendingIntent(mainPendingIntent, mainFillInIntent, options);
- }
- mSyncQueue.queue(wrapAsSplitRemoteAnimation(adapter), WindowManager.TRANSIT_OPEN, wct);
- }
-
- setEnterInstanceId(instanceId);
- }
-
- private Bundle wrapAsSplitRemoteAnimation(RemoteAnimationAdapter adapter, Bundle options) {
- final WindowContainerTransaction evictWct = new WindowContainerTransaction();
- if (isSplitScreenVisible()) {
- mMainStage.evictAllChildren(evictWct);
- mSideStage.evictAllChildren(evictWct);
- }
-
- IRemoteAnimationRunner wrapper = new IRemoteAnimationRunner.Stub() {
- @Override
- public void onAnimationStart(@WindowManager.TransitionOldType int transit,
- RemoteAnimationTarget[] apps,
- RemoteAnimationTarget[] wallpapers,
- RemoteAnimationTarget[] nonApps,
- final IRemoteAnimationFinishedCallback finishedCallback) {
- IRemoteAnimationFinishedCallback wrapCallback =
- new IRemoteAnimationFinishedCallback.Stub() {
- @Override
- public void onAnimationFinished() throws RemoteException {
- onRemoteAnimationFinishedOrCancelled(evictWct);
- finishedCallback.onAnimationFinished();
- }
- };
- Transitions.setRunningRemoteTransitionDelegate(adapter.getCallingApplication());
- try {
- adapter.getRunner().onAnimationStart(transit, apps, wallpapers,
- ArrayUtils.appendElement(RemoteAnimationTarget.class, nonApps,
- getDividerBarLegacyTarget()), wrapCallback);
- } catch (RemoteException e) {
- Slog.e(TAG, "Error starting remote animation", e);
- }
- }
-
- @Override
- public void onAnimationCancelled() {
- onRemoteAnimationFinishedOrCancelled(evictWct);
- setDividerVisibility(true, null);
- try {
- adapter.getRunner().onAnimationCancelled();
- } catch (RemoteException e) {
- Slog.e(TAG, "Error starting remote animation", e);
- }
- }
- };
- RemoteAnimationAdapter wrappedAdapter = new RemoteAnimationAdapter(
- wrapper, adapter.getDuration(), adapter.getStatusBarTransitionDelay());
- ActivityOptions activityOptions = ActivityOptions.fromBundle(options);
- activityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter));
- return activityOptions.toBundle();
- }
-
- private LegacyTransitions.ILegacyTransition wrapAsSplitRemoteAnimation(
- RemoteAnimationAdapter adapter) {
- LegacyTransitions.ILegacyTransition transition =
- (transit, apps, wallpapers, nonApps, finishedCallback, t) -> {
- if (apps == null || apps.length == 0) {
- onRemoteAnimationFinished(apps);
- t.apply();
- try {
- adapter.getRunner().onAnimationCancelled();
- } catch (RemoteException e) {
- Slog.e(TAG, "Error starting remote animation", e);
- }
- return;
- }
-
- // Wrap the divider bar into non-apps target to animate together.
- nonApps = ArrayUtils.appendElement(RemoteAnimationTarget.class, nonApps,
- getDividerBarLegacyTarget());
-
- for (int i = 0; i < apps.length; ++i) {
- if (apps[i].mode == MODE_OPENING) {
- t.show(apps[i].leash);
- // Reset the surface position of the opening app to prevent offset.
- t.setPosition(apps[i].leash, 0, 0);
- }
- }
- setDividerVisibility(true, t);
- t.apply();
-
- IRemoteAnimationFinishedCallback wrapCallback =
- new IRemoteAnimationFinishedCallback.Stub() {
- @Override
- public void onAnimationFinished() throws RemoteException {
- onRemoteAnimationFinished(apps);
- finishedCallback.onAnimationFinished();
- }
- };
- Transitions.setRunningRemoteTransitionDelegate(adapter.getCallingApplication());
- try {
- adapter.getRunner().onAnimationStart(
- transit, apps, wallpapers, nonApps, wrapCallback);
- } catch (RemoteException e) {
- Slog.e(TAG, "Error starting remote animation", e);
- }
- };
-
- return transition;
- }
-
private void setEnterInstanceId(InstanceId instanceId) {
if (instanceId != null) {
mLogger.enterRequested(instanceId, ENTER_REASON_LAUNCHER);
}
}
- private void onRemoteAnimationFinishedOrCancelled(WindowContainerTransaction evictWct) {
- mIsDividerRemoteAnimating = false;
- mShouldUpdateRecents = true;
- clearRequestIfPresented();
- // If any stage has no child after animation finished, it means that split will display
- // nothing, such status will happen if task and intent is same app but not support
- // multi-instance, we should exit split and expand that app as full screen.
- if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0) {
- mMainExecutor.execute(() ->
- exitSplitScreen(mMainStage.getChildCount() == 0
- ? mSideStage : mMainStage, EXIT_REASON_UNKNOWN));
- Log.w(TAG, splitFailureMessage("onRemoteAnimationFinishedOrCancelled",
- "main or side stage was not populated."));
- handleUnsupportedSplitStart();
- } else {
- mSyncQueue.queue(evictWct);
- mSyncQueue.runInSync(t -> {
- updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
- });
- }
- }
-
- private void onRemoteAnimationFinished(RemoteAnimationTarget[] apps) {
- mIsDividerRemoteAnimating = false;
- mShouldUpdateRecents = true;
- clearRequestIfPresented();
- // If any stage has no child after finished animation, that side of the split will display
- // nothing. This might happen if starting the same app on the both sides while not
- // supporting multi-instance. Exit the split screen and expand that app to full screen.
- if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0) {
- mMainExecutor.execute(() -> exitSplitScreen(mMainStage.getChildCount() == 0
- ? mSideStage : mMainStage, EXIT_REASON_UNKNOWN));
- Log.w(TAG, splitFailureMessage("onRemoteAnimationFinished",
- "main or side stage was not populated"));
- handleUnsupportedSplitStart();
- return;
- }
-
- final WindowContainerTransaction evictWct = new WindowContainerTransaction();
- mMainStage.evictNonOpeningChildren(apps, evictWct);
- mSideStage.evictNonOpeningChildren(apps, evictWct);
- mSyncQueue.queue(evictWct);
- }
-
void prepareEvictNonOpeningChildTasks(@SplitPosition int position, RemoteAnimationTarget[] apps,
WindowContainerTransaction wct) {
if (position == mSideStagePosition) {
@@ -1576,18 +1136,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
return;
}
- if (ENABLE_SHELL_TRANSITIONS) {
- // Need manually clear here due to this transition might be aborted due to keyguard
- // on top and lead to no visible change.
- clearSplitPairedInRecents(reason);
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- prepareExitSplitScreen(mLastActiveStage, wct);
- mSplitTransitions.startDismissTransition(wct, this, mLastActiveStage, reason);
- setSplitsVisible(false);
- } else {
- exitSplitScreen(mLastActiveStage == STAGE_TYPE_MAIN ? mMainStage : mSideStage, reason);
- }
-
+ // Need manually clear here due to this transition might be aborted due to keyguard
+ // on top and lead to no visible change.
+ clearSplitPairedInRecents(reason);
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ prepareExitSplitScreen(mLastActiveStage, wct);
+ mSplitTransitions.startDismissTransition(wct, this, mLastActiveStage, reason);
+ setSplitsVisible(false);
mBreakOnNextWake = false;
}
@@ -1596,26 +1151,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
/** Exits split screen with legacy transition */
- void exitSplitScreen(int toTopTaskId, @ExitReason int exitReason) {
- ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "exitSplitScreen: topTaskId=%d reason=%s active=%b",
- toTopTaskId, exitReasonToString(exitReason), mMainStage.isActive());
- if (!mMainStage.isActive()) return;
-
- StageTaskListener childrenToTop = null;
- if (mMainStage.containsTask(toTopTaskId)) {
- childrenToTop = mMainStage;
- } else if (mSideStage.containsTask(toTopTaskId)) {
- childrenToTop = mSideStage;
- }
-
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- if (childrenToTop != null) {
- childrenToTop.reorderChild(toTopTaskId, true /* onTop */, wct);
- }
- applyExitSplitScreen(childrenToTop, wct, exitReason);
- }
-
- /** Exits split screen with legacy transition */
private void exitSplitScreen(@Nullable StageTaskListener childrenToTop,
@ExitReason int exitReason) {
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "exitSplitScreen: mainStageToTop=%b reason=%s active=%b",
@@ -1865,15 +1400,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
boolean resizeAnim) {
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "prepareActiveSplit: task=%d isSplitVisible=%b",
taskInfo != null ? taskInfo.taskId : -1, isSplitScreenVisible());
- if (!ENABLE_SHELL_TRANSITIONS) {
- // Legacy transition we need to create divider here, shell transition case we will
- // create it on #finishEnterSplitScreen
- mSplitLayout.init();
- } else {
- // We handle split visibility itself on shell transition, but sometimes we didn't
- // reset it correctly after dismiss by some reason, so just set invisible before active.
- setSplitsVisible(false);
- }
+ // We handle split visibility itself on shell transition, but sometimes we didn't
+ // reset it correctly after dismiss by some reason, so just set invisible before active.
+ setSplitsVisible(false);
if (taskInfo != null) {
setSideStagePosition(startPosition, wct);
mSideStage.addTask(taskInfo, wct);
@@ -2420,10 +1949,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
bottomOrRight ? mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
: mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT;
final StageTaskListener toTopStage = mainStageToTop ? mMainStage : mSideStage;
- if (!ENABLE_SHELL_TRANSITIONS) {
- exitSplitScreen(toTopStage, exitReason);
- return;
- }
final int dismissTop = mainStageToTop ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE;
final WindowContainerTransaction wct = new WindowContainerTransaction();
@@ -2481,28 +2006,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
sendOnBoundsChanged();
- if (ENABLE_SHELL_TRANSITIONS) {
- mSplitLayout.setDividerInteractive(false, false, "onSplitResizeStart");
- mSplitTransitions.startResizeTransition(wct, this, (aborted) -> {
- mSplitLayout.setDividerInteractive(true, false, "onSplitResizeConsumed");
- }, (finishWct, t) -> {
- mSplitLayout.setDividerInteractive(true, false, "onSplitResizeFinish");
- }, mMainStage.getSplitDecorManager(), mSideStage.getSplitDecorManager());
- } else {
- // Only need screenshot for legacy case because shell transition should screenshot
- // itself during transition.
- final SurfaceControl.Transaction startT = mTransactionPool.acquire();
- mMainStage.screenshotIfNeeded(startT);
- mSideStage.screenshotIfNeeded(startT);
- mTransactionPool.release(startT);
+ mSplitLayout.setDividerInteractive(false, false, "onSplitResizeStart");
+ mSplitTransitions.startResizeTransition(wct, this, (aborted) -> {
+ mSplitLayout.setDividerInteractive(true, false, "onSplitResizeConsumed");
+ }, (finishWct, t) -> {
+ mSplitLayout.setDividerInteractive(true, false, "onSplitResizeFinish");
+ }, mMainStage.getSplitDecorManager(), mSideStage.getSplitDecorManager());
- mSyncQueue.queue(wct);
- mSyncQueue.runInSync(t -> {
- updateSurfaceBounds(layout, t, false /* applyResizingOffset */);
- mMainStage.onResized(t);
- mSideStage.onResized(t);
- });
- }
mLogger.logResize(mSplitLayout.getDividerPositionAsFraction());
}
@@ -3603,16 +3113,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
info.addChange(barChange);
}
- RemoteAnimationTarget getDividerBarLegacyTarget() {
- final Rect bounds = mSplitLayout.getDividerBounds();
- return new RemoteAnimationTarget(-1 /* taskId */, -1 /* mode */,
- mSplitLayout.getDividerLeash(), false /* isTranslucent */, null /* clipRect */,
- null /* contentInsets */, Integer.MAX_VALUE /* prefixOrderIndex */,
- new android.graphics.Point(0, 0) /* position */, bounds, bounds,
- new WindowConfiguration(), true, null /* startLeash */, null /* startBounds */,
- null /* taskInfo */, false /* allowEnterPip */, TYPE_DOCK_DIVIDER);
- }
-
@NeverCompile
@Override
public void dump(@NonNull PrintWriter pw, String prefix) {
@@ -3663,30 +3163,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mIsDropEntering = true;
mSkipEvictingMainStageChildren = true;
}
- if (!isSplitScreenVisible() && !ENABLE_SHELL_TRANSITIONS) {
- // If split running background, exit split first.
- // Skip this on shell transition due to we could evict existing tasks on transition
- // finished.
- exitSplitScreen(null /* childrenToTop */, EXIT_REASON_RECREATE_SPLIT);
- }
mLogger.enterRequestedByDrag(position, dragSessionId);
}
/**
- * Sets info to be logged when splitscreen is next entered.
- */
- public void onRequestToSplit(InstanceId sessionId, @SplitEnterReason int enterReason) {
- ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onRequestToSplit: reason=%d", enterReason);
- if (!isSplitScreenVisible() && !ENABLE_SHELL_TRANSITIONS) {
- // If split running background, exit split first.
- // Skip this on shell transition due to we could evict existing tasks on transition
- // finished.
- exitSplitScreen(null /* childrenToTop */, EXIT_REASON_RECREATE_SPLIT);
- }
- mLogger.enterRequested(sessionId, enterReason);
- }
-
- /**
* Logs the exit of splitscreen.
*/
private void logExit(@ExitReason int exitReason) {
@@ -3768,12 +3248,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onNoLongerSupportMultiWindow: task=%s", taskInfo);
if (mMainStage.isActive()) {
final boolean isMainStage = mMainStageListener == this;
- if (!ENABLE_SHELL_TRANSITIONS) {
- StageCoordinator.this.exitSplitScreen(isMainStage ? mMainStage : mSideStage,
- EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW);
- handleUnsupportedSplitStart();
- return;
- }
// If visible, we preserve the app and keep it running. If an app becomes
// unsupported in the bg, break split without putting anything on top
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
index 90eb22f369df..759f97f54a9e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
@@ -17,6 +17,7 @@
package com.android.wm.shell.startingsurface;
import static android.content.Context.CONTEXT_RESTRICTED;
+import static android.content.res.Configuration.UI_MODE_NIGHT_MASK;
import static android.os.Process.THREAD_PRIORITY_TOP_APP_BOOST;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -191,31 +192,15 @@ public class SplashscreenContentDrawer {
}
final Configuration taskConfig = taskInfo.getConfiguration();
- if (taskConfig.diffPublicOnly(context.getResources().getConfiguration()) != 0) {
+ final Configuration contextConfig = context.getResources().getConfiguration();
+ if ((taskConfig.uiMode & UI_MODE_NIGHT_MASK)
+ != (contextConfig.uiMode & UI_MODE_NIGHT_MASK)) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
"addSplashScreen: creating context based on task Configuration %s",
taskConfig);
final Context overrideContext = context.createConfigurationContext(taskConfig);
overrideContext.setTheme(theme);
- final TypedArray typedArray = overrideContext.obtainStyledAttributes(
- com.android.internal.R.styleable.Window);
- final int resId = typedArray.getResourceId(R.styleable.Window_windowBackground, 0);
- try {
- if (resId != 0 && overrideContext.getDrawable(resId) != null) {
- // We want to use the windowBackground for the override context if it is
- // available, otherwise we use the default one to make sure a themed starting
- // window is displayed for the app.
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
- "addSplashScreen: apply overrideConfig %s",
- taskConfig);
- context = overrideContext;
- }
- } catch (Resources.NotFoundException e) {
- Slog.w(TAG, "failed creating starting window for overrideConfig at taskId: "
- + taskId, e);
- return null;
- }
- typedArray.recycle();
+ context = overrideContext;
}
return context;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
index 9de065129e47..401b78df026a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -30,6 +30,7 @@ import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Color;
+import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.GradientDrawable;
@@ -37,10 +38,12 @@ import android.graphics.drawable.VectorDrawable;
import android.os.Handler;
import android.util.Size;
import android.view.Choreographer;
+import android.view.InsetsState;
import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewConfiguration;
+import android.view.WindowInsets;
import android.view.WindowManager;
import android.window.WindowContainerTransaction;
@@ -195,7 +198,8 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
RelayoutParams relayoutParams,
ActivityManager.RunningTaskInfo taskInfo,
boolean applyStartTransactionOnDraw,
- boolean setTaskCropAndPosition) {
+ boolean setTaskCropAndPosition,
+ InsetsState displayInsetsState) {
relayoutParams.reset();
relayoutParams.mRunningTaskInfo = taskInfo;
relayoutParams.mLayoutResId = R.layout.caption_window_decor;
@@ -223,6 +227,8 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
controlsElement.mWidthResId = R.dimen.caption_right_buttons_width;
controlsElement.mAlignment = RelayoutParams.OccludingCaptionElement.Alignment.END;
relayoutParams.mOccludingCaptionElements.add(controlsElement);
+ relayoutParams.mCaptionTopPadding = getTopPadding(relayoutParams,
+ taskInfo.getConfiguration().windowConfiguration.getBounds(), displayInsetsState);
}
@SuppressLint("MissingPermission")
@@ -238,7 +244,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
final WindowContainerTransaction wct = new WindowContainerTransaction();
updateRelayoutParams(mRelayoutParams, taskInfo, applyStartTransactionOnDraw,
- setTaskCropAndPosition);
+ setTaskCropAndPosition, mDisplayController.getInsetsState(taskInfo.displayId));
relayout(mRelayoutParams, startT, finishT, wct, oldRootView, mResult);
// After this line, mTaskInfo is up-to-date and should be used instead of taskInfo
@@ -344,6 +350,18 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
mDragResizeListener = null;
}
+ private static int getTopPadding(RelayoutParams params, Rect taskBounds,
+ InsetsState insetsState) {
+ if (!params.mRunningTaskInfo.isFreeform()) {
+ Insets systemDecor = insetsState.calculateInsets(taskBounds,
+ WindowInsets.Type.systemBars() & ~WindowInsets.Type.captionBar(),
+ false /* ignoreVisibility */);
+ return systemDecor.top;
+ } else {
+ return 0;
+ }
+ }
+
/**
* Checks whether the touch event falls inside the customizable caption region.
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index 5a241986a5ba..a242b8a4fdd3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -89,6 +89,7 @@ import com.android.wm.shell.R;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.apptoweb.AppToWebGenericLinksParser;
+import com.android.wm.shell.common.DisplayChangeController;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.DisplayLayout;
@@ -175,6 +176,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
private boolean mInImmersiveMode;
private final String mSysUIPackageName;
+ private final DisplayChangeController.OnDisplayChangingListener mOnDisplayChangingListener;
private final ISystemGestureExclusionListener mGestureExclusionListener =
new ISystemGestureExclusionListener.Stub() {
@Override
@@ -287,6 +289,31 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
mSysUIPackageName = mContext.getResources().getString(
com.android.internal.R.string.config_systemUi);
mInteractionJankMonitor = interactionJankMonitor;
+ mOnDisplayChangingListener = (displayId, fromRotation, toRotation, displayAreaInfo, t) -> {
+ DesktopModeWindowDecoration decoration;
+ RunningTaskInfo taskInfo;
+ for (int i = 0; i < mWindowDecorByTaskId.size(); i++) {
+ decoration = mWindowDecorByTaskId.valueAt(i);
+ if (decoration == null) {
+ continue;
+ } else {
+ taskInfo = decoration.mTaskInfo;
+ }
+
+ // Check if display has been rotated between portrait & landscape
+ if (displayId == taskInfo.displayId && taskInfo.isFreeform()
+ && (fromRotation % 2 != toRotation % 2)) {
+ // Check if the task bounds on the rotated display will be out of bounds.
+ // If so, then update task bounds to be within reachable area.
+ final Rect taskBounds = new Rect(
+ taskInfo.configuration.windowConfiguration.getBounds());
+ if (DragPositioningCallbackUtility.snapTaskBoundsIfNecessary(
+ taskBounds, decoration.calculateValidDragArea())) {
+ t.setBounds(taskInfo.token, taskBounds);
+ }
+ }
+ }
+ };
shellInit.addInitCallback(this::onInit, this);
}
@@ -297,7 +324,10 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
mDisplayInsetsController.addInsetsChangedListener(mContext.getDisplayId(),
new DesktopModeOnInsetsChangedListener());
mDesktopTasksController.setOnTaskResizeAnimationListener(
- new DeskopModeOnTaskResizeAnimationListener());
+ new DesktopModeOnTaskResizeAnimationListener());
+ mDesktopTasksController.setOnTaskRepositionAnimationListener(
+ new DesktopModeOnTaskRepositionAnimationListener());
+ mDisplayController.addDisplayChangingController(mOnDisplayChangingListener);
try {
mWindowManager.registerSystemGestureExclusionListener(mGestureExclusionListener,
mContext.getDisplayId());
@@ -436,8 +466,16 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
if (decoration == null) {
return;
}
- mDesktopTasksController.snapToHalfScreen(decoration.mTaskInfo,
- left ? SnapPosition.LEFT : SnapPosition.RIGHT);
+
+ if (!decoration.mTaskInfo.isResizeable
+ && DesktopModeFlags.DISABLE_SNAP_RESIZE.isEnabled(mContext)) {
+ //TODO(b/354658237) - show toast with relevant string
+ } else {
+ mDesktopTasksController.snapToHalfScreen(decoration.mTaskInfo,
+ decoration.mTaskInfo.configuration.windowConfiguration.getBounds(),
+ left ? SnapPosition.LEFT : SnapPosition.RIGHT);
+ }
+
decoration.closeHandleMenu();
decoration.closeMaximizeMenu();
}
@@ -520,6 +558,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
private final DragDetector mDragDetector;
private final GestureDetector mGestureDetector;
private final int mDisplayId;
+ private final Rect mOnDragStartInitialBounds = new Rect();
/**
* Whether to pilfer the next motion event to send cancellations to the windows below.
@@ -590,13 +629,21 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
&& id != R.id.maximize_window) {
return false;
}
- moveTaskToFront(decoration.mTaskInfo);
final int actionMasked = e.getActionMasked();
final boolean isDown = actionMasked == MotionEvent.ACTION_DOWN;
final boolean isUpOrCancel = actionMasked == MotionEvent.ACTION_CANCEL
|| actionMasked == MotionEvent.ACTION_UP;
if (isDown) {
+ // Only move to front on down to prevent 2+ tasks from fighting
+ // (and thus flickering) for front status when drag-moving them simultaneously with
+ // two pointers.
+ // TODO(b/356962065): during a drag-move, this shouldn't be a WCT - just move the
+ // task surface to the top of other tasks and reorder once the user releases the
+ // gesture together with the bounds' WCT. This is probably still valid for other
+ // gestures like simple clicks.
+ moveTaskToFront(decoration.mTaskInfo);
+
final boolean downInCustomizableCaptionRegion =
decoration.checkTouchEventInCustomizableRegion(e);
final boolean downInExclusionRegion = mExclusionRegion.contains(
@@ -723,10 +770,11 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
switch (e.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
mDragPointerId = e.getPointerId(0);
- mDragPositioningCallback.onDragPositioningStart(
+ final Rect initialBounds = mDragPositioningCallback.onDragPositioningStart(
0 /* ctrlType */, e.getRawX(0),
e.getRawY(0));
updateDragStatus(e.getActionMasked());
+ mOnDragStartInitialBounds.set(initialBounds);
mHasLongClicked = false;
// Do not consume input event if a button is touched, otherwise it would
// prevent the button's ripple effect from showing.
@@ -767,9 +815,14 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
(int) (e.getRawY(dragPointerIdx) - e.getY(dragPointerIdx)));
final Rect newTaskBounds = mDragPositioningCallback.onDragPositioningEnd(
e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
- mDesktopTasksController.onDragPositioningEnd(taskInfo, position,
+ // Tasks bounds haven't actually been updated (only its leash), so pass to
+ // DesktopTasksController to allow secondary transformations (i.e. snap resizing
+ // or transforming to fullscreen) before setting new task bounds.
+ mDesktopTasksController.onDragPositioningEnd(
+ taskInfo, decoration.mTaskSurface, position,
new PointF(e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx)),
- newTaskBounds, decoration.calculateValidDragArea());
+ newTaskBounds, decoration.calculateValidDragArea(),
+ new Rect(mOnDragStartInitialBounds));
if (touchingButton && !mHasLongClicked) {
// We need the input event to not be consumed here to end the ripple
// effect on the touched button. We will reset drag state in the ensuing
@@ -1188,13 +1241,13 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
final DragPositioningCallback dragPositioningCallback;
if (!DesktopModeStatus.isVeiledResizeEnabled()) {
- dragPositioningCallback = new FluidResizeTaskPositioner(
+ dragPositioningCallback = new FluidResizeTaskPositioner(
mTaskOrganizer, mTransitions, windowDecoration, mDisplayController,
mDragStartListener, mTransactionFactory);
windowDecoration.setTaskDragResizer(
(FluidResizeTaskPositioner) dragPositioningCallback);
} else {
- dragPositioningCallback = new VeiledResizeTaskPositioner(
+ dragPositioningCallback = new VeiledResizeTaskPositioner(
mTaskOrganizer, windowDecoration, mDisplayController,
mDragStartListener, mTransitions, mInteractionJankMonitor);
windowDecoration.setTaskDragResizer(
@@ -1267,7 +1320,26 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
pw.println(innerPrefix + "mWindowDecorByTaskId=" + mWindowDecorByTaskId);
}
- private class DeskopModeOnTaskResizeAnimationListener
+ private class DesktopModeOnTaskRepositionAnimationListener
+ implements OnTaskRepositionAnimationListener {
+ @Override
+ public void onAnimationStart(int taskId) {
+ final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId);
+ if (decoration != null) {
+ decoration.setAnimatingTaskResizeOrReposition(true);
+ }
+ }
+
+ @Override
+ public void onAnimationEnd(int taskId) {
+ final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId);
+ if (decoration != null) {
+ decoration.setAnimatingTaskResizeOrReposition(false);
+ }
+ }
+ }
+
+ private class DesktopModeOnTaskResizeAnimationListener
implements OnTaskResizeAnimationListener {
@Override
public void onAnimationStart(int taskId, Transaction t, Rect bounds) {
@@ -1277,7 +1349,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
return;
}
decoration.showResizeVeil(t, bounds);
- decoration.setAnimatingTaskResize(true);
+ decoration.setAnimatingTaskResizeOrReposition(true);
}
@Override
@@ -1292,7 +1364,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId);
if (decoration == null) return;
decoration.hideResizeVeil();
- decoration.setAnimatingTaskResize(false);
+ decoration.setAnimatingTaskResizeOrReposition(false);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 24fb97197f39..538d0fb9cbf6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -312,8 +312,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
// transaction (that applies task crop) is synced with the buffer transaction (that draws
// the View). Both will be shown on screen at the same, whereas applying them independently
// causes flickering. See b/270202228.
- final boolean applyTransactionOnDraw =
- taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM;
+ final boolean applyTransactionOnDraw = taskInfo.isFreeform();
relayout(taskInfo, t, t, applyTransactionOnDraw, shouldSetTaskPositionAndCrop);
if (!applyTransactionOnDraw) {
t.apply();
@@ -324,7 +323,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop) {
Trace.beginSection("DesktopModeWindowDecoration#relayout");
- if (taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
+ if (taskInfo.isFreeform()) {
// The Task is in Freeform mode -> show its header in sync since it's an integral part
// of the window itself - a delayed header might cause bad UX.
relayoutInSync(taskInfo, startT, finishT, applyStartTransactionOnDraw,
@@ -524,9 +523,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
}
private static boolean isDragResizable(ActivityManager.RunningTaskInfo taskInfo) {
- final boolean isFreeform =
- taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM;
- return isFreeform && taskInfo.isResizeable;
+ return taskInfo.isFreeform() && taskInfo.isResizeable;
}
private void updateMaximizeMenu(SurfaceControl.Transaction startT) {
@@ -1271,10 +1268,10 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
return R.id.desktop_mode_caption;
}
- void setAnimatingTaskResize(boolean animatingTaskResize) {
+ void setAnimatingTaskResizeOrReposition(boolean animatingTaskResizeOrReposition) {
if (mRelayoutParams.mLayoutResId == R.layout.desktop_mode_app_handle) return;
((AppHeaderViewHolder) mWindowDecorViewHolder)
- .setAnimatingTaskResize(animatingTaskResize);
+ .setAnimatingTaskResizeOrReposition(animatingTaskResizeOrReposition);
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
index 17295481fba1..a27c506e3e60 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -17,6 +17,7 @@
package com.android.wm.shell.windowdecor;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_SPY;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
@@ -112,7 +113,7 @@ class DragResizeInputListener implements AutoCloseable {
mDecorationSurface,
mClientToken,
null /* hostInputToken */,
- FLAG_NOT_FOCUSABLE,
+ FLAG_NOT_FOCUSABLE | FLAG_SPLIT_TOUCH,
PRIVATE_FLAG_TRUSTED_OVERLAY,
INPUT_FEATURE_SPY,
TYPE_APPLICATION,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java
index 76096b0c59f3..e2d42b2783da 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java
@@ -152,11 +152,8 @@ class FluidResizeTaskPositioner implements DragPositioningCallback,
}
mDragResizeEndTransition = mTransitions.startTransition(TRANSIT_CHANGE, wct, this);
} else if (mCtrlType == CTRL_TYPE_UNDEFINED) {
- final WindowContainerTransaction wct = new WindowContainerTransaction();
DragPositioningCallbackUtility.updateTaskBounds(mRepositionTaskBounds,
mTaskBoundsAtDragStart, mRepositionStartPoint, x, y);
- wct.setBounds(mWindowDecoration.mTaskInfo.token, mRepositionTaskBounds);
- mTransitions.startTransition(TRANSIT_CHANGE, wct, this);
}
mTaskBoundsAtDragStart.setEmpty();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
index b348d656dd6b..c16c16f5dfa2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
@@ -185,7 +185,8 @@ class HandleMenu(
width = menuWidth,
height = menuHeight,
flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
- WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
+ WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH or
+ WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
view = handleMenuView.rootView
)
} else {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
index 013f50678354..54b33e931830 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
@@ -146,7 +146,8 @@ class MaximizeMenu(
menuHeight,
WindowManager.LayoutParams.TYPE_APPLICATION,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
+ or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+ or WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.TRANSPARENT
)
lp.title = "Maximize Menu for Task=" + taskInfo.taskId
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/OnTaskRepositionAnimationListener.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/OnTaskRepositionAnimationListener.kt
new file mode 100644
index 000000000000..214a6fa0b200
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/OnTaskRepositionAnimationListener.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.windowdecor
+
+/**
+ * Listener that allows notifies when an animation that is repositioning a task is starting
+ * and finishing the animation.
+ */
+interface OnTaskRepositionAnimationListener {
+ /**
+ * Notifies that an animation is about to be started.
+ */
+ fun onAnimationStart(taskId: Int)
+
+ /**
+ * Notifies that an animation is about to be finished.
+ */
+ fun onAnimationEnd(taskId: Int)
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.kt
index cd2dac806a7f..fd6c4d8e604d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.kt
@@ -32,6 +32,7 @@ import android.view.SurfaceControl
import android.view.SurfaceControlViewHost
import android.view.SurfaceSession
import android.view.WindowManager
+import android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL
import android.view.WindowlessWindowManager
import android.widget.ImageView
import android.window.TaskConstants
@@ -151,6 +152,7 @@ class ResizeVeil @JvmOverloads constructor(
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSPARENT)
lp.title = "Resize veil icon window of Task=" + taskInfo.taskId
+ lp.inputFeatures = INPUT_FEATURE_NO_INPUT_CHANNEL
lp.setTrustedOverlay()
val wwm = WindowlessWindowManager(taskInfo.configuration,
iconSurface, null /* hostInputToken */)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
index b5b476d90d0e..7f2c1a81d20c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
@@ -163,14 +163,7 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback,
} else {
DragPositioningCallbackUtility.updateTaskBounds(mRepositionTaskBounds,
mTaskBoundsAtDragStart, mRepositionStartPoint, x, y);
- if (!mTaskBoundsAtDragStart.equals(mRepositionTaskBounds)) {
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- wct.setBounds(mDesktopWindowDecoration.mTaskInfo.token, mRepositionTaskBounds);
- mTransitions.startTransition(TRANSIT_CHANGE, wct, this);
- } else {
- // Drag-move ended where it originally started, no need to update WM.
- mInteractionJankMonitor.end(CUJ_DESKTOP_MODE_DRAG_WINDOW);
- }
+ mInteractionJankMonitor.end(CUJ_DESKTOP_MODE_DRAG_WINDOW);
}
mCtrlType = CTRL_TYPE_UNDEFINED;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index 4cab6e483430..0c5898710983 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -22,6 +22,8 @@ import static android.content.res.Configuration.DENSITY_DPI_UNDEFINED;
import static android.view.WindowInsets.Type.captionBar;
import static android.view.WindowInsets.Type.mandatorySystemGestures;
import static android.view.WindowInsets.Type.statusBars;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
@@ -239,7 +241,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
outResult.mHeight = taskBounds.height();
outResult.mRootView.setTaskFocusState(mTaskInfo.isFocused);
final Resources resources = mDecorWindowContext.getResources();
- outResult.mCaptionHeight = loadDimensionPixelSize(resources, params.mCaptionHeightId);
+ outResult.mCaptionHeight = loadDimensionPixelSize(resources, params.mCaptionHeightId)
+ + params.mCaptionTopPadding;
outResult.mCaptionWidth = params.mCaptionWidthId != Resources.ID_NULL
? loadDimensionPixelSize(resources, params.mCaptionWidthId) : taskBounds.width();
outResult.mCaptionX = (outResult.mWidth - outResult.mCaptionWidth) / 2;
@@ -443,9 +446,12 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
}
mCaptionWindowManager.setConfiguration(mTaskInfo.getConfiguration());
final WindowManager.LayoutParams lp =
- new WindowManager.LayoutParams(outResult.mCaptionWidth, outResult.mCaptionHeight,
+ new WindowManager.LayoutParams(
+ outResult.mCaptionWidth,
+ outResult.mCaptionHeight,
TYPE_APPLICATION,
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT);
+ FLAG_NOT_FOCUSABLE | FLAG_SPLIT_TOUCH,
+ PixelFormat.TRANSPARENT);
lp.setTitle("Caption of Task=" + mTaskInfo.taskId);
lp.setTrustedOverlay();
lp.inputFeatures = params.mInputFeatures;
@@ -459,6 +465,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
}
mViewHost.getRootSurfaceControl().applyTransactionOnDraw(onDrawTransaction);
}
+ outResult.mRootView.setPadding(0, params.mCaptionTopPadding, 0, 0);
mViewHost.setView(outResult.mRootView, lp);
Trace.endSection();
} else {
@@ -469,6 +476,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
}
mViewHost.getRootSurfaceControl().applyTransactionOnDraw(onDrawTransaction);
}
+ outResult.mRootView.setPadding(0, params.mCaptionTopPadding, 0, 0);
mViewHost.relayout(lp);
Trace.endSection();
}
@@ -635,9 +643,11 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
.setWindowCrop(windowSurfaceControl, width, height)
.show(windowSurfaceControl);
final WindowManager.LayoutParams lp =
- new WindowManager.LayoutParams(width, height, TYPE_APPLICATION,
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | FLAG_WATCH_OUTSIDE_TOUCH,
+ new WindowManager.LayoutParams(
+ width,
+ height,
+ TYPE_APPLICATION,
+ FLAG_NOT_FOCUSABLE | FLAG_WATCH_OUTSIDE_TOUCH | FLAG_SPLIT_TOUCH,
PixelFormat.TRANSPARENT);
lp.setTitle("Additional window of Task=" + mTaskInfo.taskId);
lp.setTrustedOverlay();
@@ -700,6 +710,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
int mShadowRadiusId;
int mCornerRadius;
+ int mCaptionTopPadding;
+
Configuration mWindowDecorConfig;
boolean mApplyStartTransactionOnDraw;
@@ -716,6 +728,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
mShadowRadiusId = Resources.ID_NULL;
mCornerRadius = 0;
+ mCaptionTopPadding = 0;
+
mApplyStartTransactionOnDraw = false;
mSetTaskPositionAndCrop = false;
mWindowDecorConfig = null;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
index 17b3dea5db75..d0eb6da36702 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
@@ -238,12 +238,12 @@ internal class AppHeaderViewHolder(
override fun onHandleMenuClosed() {}
- fun setAnimatingTaskResize(animatingTaskResize: Boolean) {
- // If animating a task resize, cancel any running hover animations
- if (animatingTaskResize) {
+ fun setAnimatingTaskResizeOrReposition(animatingTaskResizeOrReposition: Boolean) {
+ // If animating a task resize or reposition, cancel any running hover animations
+ if (animatingTaskResizeOrReposition) {
maximizeButtonView.cancelHoverAnimation()
}
- maximizeButtonView.hoverDisabled = animatingTaskResize
+ maximizeButtonView.hoverDisabled = animatingTaskResizeOrReposition
}
fun onMaximizeWindowHoverExit() {
diff --git a/libs/WindowManager/Shell/tests/OWNERS b/libs/WindowManager/Shell/tests/OWNERS
index a77fd51d5fcb..9f735c46eceb 100644
--- a/libs/WindowManager/Shell/tests/OWNERS
+++ b/libs/WindowManager/Shell/tests/OWNERS
@@ -1,4 +1,4 @@
-# Bug component: 1157642
+# Bug component: 928594
# includes OWNERS from parent directories
natanieljr@google.com
pablogamito@google.com
diff --git a/libs/WindowManager/Shell/tests/flicker/OWNERS b/libs/WindowManager/Shell/tests/flicker/OWNERS
new file mode 100644
index 000000000000..4db0babdaf99
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 1157642
+# includes OWNERS from parent directories
+include platform/development:/tools/winscope/OWNERS
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/CloseAllAppsWithAppHeaderExitTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/CloseAllAppsWithAppHeaderExitTest.kt
new file mode 100644
index 000000000000..9ba3a45fb5b7
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/CloseAllAppsWithAppHeaderExitTest.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.flicker.service.desktopmode.functional
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.flicker.service.desktopmode.scenarios.CloseAllAppsWithAppHeaderExit
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/** Functional test for [CloseAllAppsWithAppHeaderExit]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class CloseAllAppsWithAppHeaderExitTest : CloseAllAppsWithAppHeaderExit() {
+
+ @Test
+ override fun closeAllAppsInDesktop() {
+ super.closeAllAppsInDesktop()
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/DragAppWindowMultiWindowTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/DragAppWindowMultiWindowTest.kt
new file mode 100644
index 000000000000..ed1d4887e818
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/DragAppWindowMultiWindowTest.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.flicker.service.desktopmode.functional
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.flicker.service.desktopmode.scenarios.DragAppWindowMultiWindow
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/** Functional test for [DragAppWindowMultiWindow]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class DragAppWindowMultiWindowTest : DragAppWindowMultiWindow()
+{
+ @Test
+ override fun dragAppWindow() {
+ super.dragAppWindow()
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/DragAppWindowSingleWindowTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/DragAppWindowSingleWindowTest.kt
new file mode 100644
index 000000000000..d8b93482854a
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/DragAppWindowSingleWindowTest.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.flicker.service.desktopmode.functional
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.flicker.service.desktopmode.scenarios.DragAppWindowSingleWindow
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/** Functional test for [DragAppWindowSingleWindow]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class DragAppWindowSingleWindowTest : DragAppWindowSingleWindow()
+{
+ @Test
+ override fun dragAppWindow() {
+ super.dragAppWindow()
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/EnterDesktopWithAppHandleMenuTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/EnterDesktopWithAppHandleMenuTest.kt
new file mode 100644
index 000000000000..546ce2d10a7d
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/EnterDesktopWithAppHandleMenuTest.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.flicker.service.desktopmode.functional
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.flicker.service.desktopmode.scenarios.EnterDesktopWithAppHandleMenu
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/** Functional test for [EnterDesktopWithAppHandleMenu]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class EnterDesktopWithAppHandleMenuTest : EnterDesktopWithAppHandleMenu() {
+ @Test
+ override fun enterDesktopWithAppHandleMenu() {
+ super.enterDesktopWithAppHandleMenu()
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/EnterDesktopWithDragTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/EnterDesktopWithDragTest.kt
new file mode 100644
index 000000000000..b5fdb168c8ed
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/EnterDesktopWithDragTest.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.flicker.service.desktopmode.functional
+
+import android.platform.test.annotations.Postsubmit
+import android.tools.Rotation
+import com.android.wm.shell.flicker.service.desktopmode.scenarios.EnterDesktopWithDrag
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/** Functional test for [EnterDesktopWithDrag]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class EnterDesktopWithDragTest : EnterDesktopWithDrag(Rotation.ROTATION_0) {
+
+ @Test
+ override fun enterDesktopWithDrag() {
+ super.enterDesktopWithDrag()
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/ExitDesktopWithDragToTopDragZoneTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/ExitDesktopWithDragToTopDragZoneTest.kt
new file mode 100644
index 000000000000..8f802d245275
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/ExitDesktopWithDragToTopDragZoneTest.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.flicker.service.desktopmode.functional
+
+import android.platform.test.annotations.Postsubmit
+import android.tools.Rotation
+import com.android.wm.shell.flicker.service.desktopmode.scenarios.ExitDesktopWithDragToTopDragZone
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/** Functional test for [ExitDesktopWithDragToTopDragZone]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class ExitDesktopWithDragToTopDragZoneTest :
+ ExitDesktopWithDragToTopDragZone(Rotation.ROTATION_0) {
+ @Test
+ override fun exitDesktopWithDragToTopDragZone() {
+ super.exitDesktopWithDragToTopDragZone()
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/MaximizeAppWindowTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/MaximizeAppWindowTest.kt
new file mode 100644
index 000000000000..f89908228bbf
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/MaximizeAppWindowTest.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.flicker.service.desktopmode.functional
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.flicker.service.desktopmode.scenarios.MaximizeAppWindow
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/** Functional test for [MaximizeAppWindow]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class MaximizeAppWindowTest : MaximizeAppWindow()
+{
+ @Test
+ override fun maximizeAppWindow() {
+ super.maximizeAppWindow()
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/MinimizeWindowOnAppOpenTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/MinimizeWindowOnAppOpenTest.kt
new file mode 100644
index 000000000000..63c428a0451f
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/MinimizeWindowOnAppOpenTest.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.flicker.service.desktopmode.functional
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.flicker.service.desktopmode.scenarios.MinimizeWindowOnAppOpen
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/** Functional test for [MinimizeWindowOnAppOpen]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class MinimizeWindowOnAppOpenTest : MinimizeWindowOnAppOpen()
+{
+ @Test
+ override fun openAppToMinimizeWindow() {
+ // Launch a new app while 4 apps are already open on desktop. This should result in the
+ // first app we opened to be minimized.
+ super.openAppToMinimizeWindow()
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/ResizeAppWithCornerResizeTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/ResizeAppWithCornerResizeTest.kt
new file mode 100644
index 000000000000..4797aaf553af
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/ResizeAppWithCornerResizeTest.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.flicker.service.desktopmode.functional
+
+import android.platform.test.annotations.Postsubmit
+import android.tools.Rotation
+import com.android.wm.shell.flicker.service.desktopmode.scenarios.ResizeAppWithCornerResize
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/** Functional test for [ResizeAppWithCornerResize]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class ResizeAppWithCornerResizeTest : ResizeAppWithCornerResize(Rotation.ROTATION_0) {
+ @Test
+ override fun resizeAppWithCornerResize() {
+ super.resizeAppWithCornerResize()
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/SwitchToOverviewFromDesktopTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/SwitchToOverviewFromDesktopTest.kt
new file mode 100644
index 000000000000..9a7136103cd4
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/SwitchToOverviewFromDesktopTest.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.flicker.service.desktopmode.functional
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.flicker.service.desktopmode.scenarios.SwitchToOverviewFromDesktop
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/** Functional test for [SwitchToOverviewFromDesktop]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class SwitchToOverviewFromDesktopTest : SwitchToOverviewFromDesktop() {
+ @Test
+ override fun switchToOverview() {
+ super.switchToOverview()
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
index 716a148175df..413e49562435 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
@@ -365,7 +365,7 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
final RunningTaskInfo taskInfo1 = createTaskInfo(/* taskId= */ 12,
WINDOWING_MODE_FULLSCREEN);
taskInfo1.displayId = DEFAULT_DISPLAY;
- taskInfo1.appCompatTaskInfo.topActivityInSizeCompat = false;
+ taskInfo1.appCompatTaskInfo.setTopActivityInSizeCompat(false);
final TrackingTaskListener taskListener = new TrackingTaskListener();
mOrganizer.addListenerForType(taskListener, TASK_LISTENER_TYPE_FULLSCREEN);
mOrganizer.onTaskAppeared(taskInfo1, /* leash= */ null);
@@ -378,7 +378,7 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
final RunningTaskInfo taskInfo2 =
createTaskInfo(taskInfo1.taskId, taskInfo1.getWindowingMode());
taskInfo2.displayId = taskInfo1.displayId;
- taskInfo2.appCompatTaskInfo.topActivityInSizeCompat = true;
+ taskInfo2.appCompatTaskInfo.setTopActivityInSizeCompat(true);
taskInfo2.isVisible = true;
mOrganizer.onTaskInfoChanged(taskInfo2);
verifyOnCompatInfoChangedInvokedWith(taskInfo2, taskListener);
@@ -388,7 +388,7 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
final RunningTaskInfo taskInfo3 =
createTaskInfo(taskInfo1.taskId, taskInfo1.getWindowingMode());
taskInfo3.displayId = taskInfo1.displayId;
- taskInfo3.appCompatTaskInfo.topActivityInSizeCompat = true;
+ taskInfo3.appCompatTaskInfo.setTopActivityInSizeCompat(true);
taskInfo3.isVisible = false;
mOrganizer.onTaskInfoChanged(taskInfo3);
verifyOnCompatInfoChangedInvokedWith(taskInfo3, null /* taskListener */);
@@ -403,7 +403,7 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
final RunningTaskInfo taskInfo1 = createTaskInfo(/* taskId= */ 12,
WINDOWING_MODE_FULLSCREEN);
taskInfo1.displayId = DEFAULT_DISPLAY;
- taskInfo1.appCompatTaskInfo.topActivityEligibleForLetterboxEducation = false;
+ taskInfo1.appCompatTaskInfo.setEligibleForLetterboxEducation(false);
final TrackingTaskListener taskListener = new TrackingTaskListener();
mOrganizer.addListenerForType(taskListener, TASK_LISTENER_TYPE_FULLSCREEN);
mOrganizer.onTaskAppeared(taskInfo1, /* leash= */ null);
@@ -418,7 +418,7 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
final RunningTaskInfo taskInfo2 =
createTaskInfo(taskInfo1.taskId, WINDOWING_MODE_FULLSCREEN);
taskInfo2.displayId = taskInfo1.displayId;
- taskInfo2.appCompatTaskInfo.topActivityEligibleForLetterboxEducation = true;
+ taskInfo2.appCompatTaskInfo.setEligibleForLetterboxEducation(true);
taskInfo2.isVisible = true;
mOrganizer.onTaskInfoChanged(taskInfo2);
verifyOnCompatInfoChangedInvokedWith(taskInfo2, taskListener);
@@ -428,7 +428,7 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
final RunningTaskInfo taskInfo3 =
createTaskInfo(taskInfo1.taskId, WINDOWING_MODE_FULLSCREEN);
taskInfo3.displayId = taskInfo1.displayId;
- taskInfo3.appCompatTaskInfo.topActivityEligibleForLetterboxEducation = true;
+ taskInfo3.appCompatTaskInfo.setEligibleForLetterboxEducation(true);
taskInfo3.isVisible = false;
mOrganizer.onTaskInfoChanged(taskInfo3);
verifyOnCompatInfoChangedInvokedWith(taskInfo3, null /* taskListener */);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
index 764d5a97e3e1..654d7a8ecf91 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
@@ -119,7 +119,7 @@ public class DisplayImeControllerTest extends ShellTestCase {
@Test
public void reappliesVisibilityToChangedLeash() {
verifyZeroInteractions(mT);
- mPerDisplay.mImeShowing = true;
+ mPerDisplay.mImeShowing = false;
mPerDisplay.insetsControlChanged(insetsStateWithIme(false), insetsSourceControl());
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
index 77e22cd17f6f..de1659b1a163 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
@@ -681,7 +681,7 @@ public class CompatUIControllerTest extends ShellTestCase {
@Test
public void testLetterboxEduLayout_notCreatedWhenLetterboxEducationIsDisabled() {
TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
- taskInfo.appCompatTaskInfo.isLetterboxEducationEnabled = false;
+ taskInfo.appCompatTaskInfo.setLetterboxEducationEnabled(false);
mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
@@ -705,12 +705,12 @@ public class CompatUIControllerTest extends ShellTestCase {
RunningTaskInfo taskInfo = new RunningTaskInfo();
taskInfo.taskId = taskId;
taskInfo.displayId = displayId;
- taskInfo.appCompatTaskInfo.topActivityInSizeCompat = hasSizeCompat;
+ taskInfo.appCompatTaskInfo.setTopActivityInSizeCompat(hasSizeCompat);
taskInfo.isVisible = isVisible;
taskInfo.isFocused = isFocused;
taskInfo.isTopActivityTransparent = isTopActivityTransparent;
- taskInfo.appCompatTaskInfo.isLetterboxEducationEnabled = true;
- taskInfo.appCompatTaskInfo.topActivityBoundsLetterboxed = true;
+ taskInfo.appCompatTaskInfo.setLetterboxEducationEnabled(true);
+ taskInfo.appCompatTaskInfo.setTopActivityLetterboxed(true);
return taskInfo;
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUILayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUILayoutTest.java
index 3b93861d6cd2..e5d1919decf4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUILayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUILayoutTest.java
@@ -146,7 +146,7 @@ public class CompatUILayoutTest extends ShellTestCase {
private static TaskInfo createTaskInfo(boolean hasSizeCompat) {
ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
taskInfo.taskId = TASK_ID;
- taskInfo.appCompatTaskInfo.topActivityInSizeCompat = hasSizeCompat;
+ taskInfo.appCompatTaskInfo.setTopActivityInSizeCompat(hasSizeCompat);
taskInfo.appCompatTaskInfo.topActivityLetterboxHeight = 1000;
taskInfo.appCompatTaskInfo.topActivityLetterboxWidth = 1000;
taskInfo.configuration.windowConfiguration.setBounds(new Rect(0, 0, 2000, 2000));
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java
index c5033f3ae64b..1c0175603df9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java
@@ -446,7 +446,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
private static TaskInfo createTaskInfo(boolean hasSizeCompat) {
ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
taskInfo.taskId = TASK_ID;
- taskInfo.appCompatTaskInfo.topActivityInSizeCompat = hasSizeCompat;
+ taskInfo.appCompatTaskInfo.setTopActivityInSizeCompat(hasSizeCompat);
taskInfo.configuration.uiMode &= ~Configuration.UI_MODE_TYPE_DESK;
// Letterboxed activity that takes half the screen should show size compat restart button
taskInfo.appCompatTaskInfo.topActivityLetterboxHeight = 1000;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java
index b5664ac113fa..7617269cf5d3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java
@@ -499,7 +499,7 @@ public class LetterboxEduWindowManagerTest extends ShellTestCase {
ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
taskInfo.userId = userId;
taskInfo.taskId = TASK_ID;
- taskInfo.appCompatTaskInfo.topActivityEligibleForLetterboxEducation = eligible;
+ taskInfo.appCompatTaskInfo.setEligibleForLetterboxEducation(eligible);
taskInfo.configuration.windowConfiguration.setBounds(bounds);
return taskInfo;
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java
index 7a641960a2c5..e8e68bdbd940 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java
@@ -155,7 +155,7 @@ public class UserAspectRatioSettingsLayoutTest extends ShellTestCase {
private static TaskInfo createTaskInfo(boolean hasSizeCompat) {
ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
taskInfo.taskId = TASK_ID;
- taskInfo.appCompatTaskInfo.topActivityInSizeCompat = hasSizeCompat;
+ taskInfo.appCompatTaskInfo.setTopActivityInSizeCompat(hasSizeCompat);
taskInfo.realActivity = new ComponentName("com.mypackage.test", "TestActivity");
return taskInfo;
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java
index 9f288cc4bd93..9f86d49b52c4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java
@@ -317,7 +317,7 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
// layout should be inflated
taskInfo.appCompatTaskInfo.topActivityLetterboxHeight = stableBounds.height();
taskInfo.appCompatTaskInfo.topActivityLetterboxWidth = stableBounds.width();
- taskInfo.appCompatTaskInfo.isUserFullscreenOverrideEnabled = true;
+ taskInfo.appCompatTaskInfo.setUserFullscreenOverrideEnabled(true);
mWindowManager.updateCompatInfo(taskInfo, mTaskListener, /* canShow= */ true);
@@ -482,9 +482,9 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
boolean topActivityBoundsLetterboxed, String action, String category) {
ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
taskInfo.taskId = TASK_ID;
- taskInfo.appCompatTaskInfo.topActivityEligibleForUserAspectRatioButton =
- eligibleForUserAspectRatioButton;
- taskInfo.appCompatTaskInfo.topActivityBoundsLetterboxed = topActivityBoundsLetterboxed;
+ taskInfo.appCompatTaskInfo.setEligibleForUserAspectRatioButton(
+ eligibleForUserAspectRatioButton);
+ taskInfo.appCompatTaskInfo.setTopActivityLetterboxed(topActivityBoundsLetterboxed);
taskInfo.configuration.uiMode &= ~Configuration.UI_MODE_TYPE_DESK;
taskInfo.realActivity = new ComponentName("com.mypackage.test", "TestActivity");
taskInfo.baseIntent = new Intent(action).addCategory(category);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/CompatUIStateUtil.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/CompatUIStateUtil.kt
new file mode 100644
index 000000000000..43bd41275daa
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/CompatUIStateUtil.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.compatui.impl
+
+import com.android.wm.shell.compatui.api.CompatUIComponentState
+import com.android.wm.shell.compatui.api.CompatUISpec
+import com.android.wm.shell.compatui.api.CompatUIState
+import junit.framework.Assert.assertEquals
+import junit.framework.Assert.assertNotNull
+import junit.framework.Assert.assertNull
+
+/**
+ * Asserts no component state exists for the given CompatUISpec
+ */
+internal fun CompatUIState.assertHasNoStateFor(componentId: String) =
+ assertNull(stateForComponent(componentId))
+
+/**
+ * Asserts component state for the given CompatUISpec
+ */
+internal fun CompatUIState.assertHasStateEqualsTo(
+ componentId: String,
+ expected: CompatUIComponentState
+) =
+ assertEquals(stateForComponent(componentId), expected)
+
+/**
+ * Asserts no component exists for the given CompatUISpec
+ */
+internal fun CompatUIState.assertHasNoComponentFor(componentId: String) =
+ assertNull(getUIComponent(componentId))
+
+/**
+ * Asserts component for the given CompatUISpec
+ */
+internal fun CompatUIState.assertHasComponentFor(componentId: String) =
+ assertNotNull(getUIComponent(componentId))
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandlerTest.kt
new file mode 100644
index 000000000000..8136074b7aa6
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandlerTest.kt
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.compatui.impl
+
+import android.app.ActivityManager
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.compatui.api.CompatUIComponentState
+import com.android.wm.shell.compatui.api.CompatUIInfo
+import com.android.wm.shell.compatui.api.CompatUIState
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Tests for {@link DefaultCompatUIHandler}.
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:DefaultCompatUIHandlerTest
+ */
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class DefaultCompatUIHandlerTest {
+
+ lateinit var compatUIRepository: FakeCompatUIRepository
+ lateinit var compatUIHandler: DefaultCompatUIHandler
+ lateinit var compatUIState: CompatUIState
+ lateinit var fakeIdGenerator: FakeCompatUIComponentIdGenerator
+
+ @Before
+ fun setUp() {
+ compatUIRepository = FakeCompatUIRepository()
+ compatUIState = CompatUIState()
+ fakeIdGenerator = FakeCompatUIComponentIdGenerator("compId")
+ compatUIHandler = DefaultCompatUIHandler(compatUIRepository, compatUIState,
+ fakeIdGenerator)
+ }
+
+ @Test
+ fun `when creationReturn is false no state is stored`() {
+ // We add a spec to the repository
+ val fakeLifecycle = FakeCompatUILifecyclePredicates(
+ creationReturn = false,
+ removalReturn = false
+ )
+ val fakeCompatUISpec = FakeCompatUISpec("one", fakeLifecycle).getSpec()
+ compatUIRepository.addSpec(fakeCompatUISpec)
+
+ val generatedId = fakeIdGenerator.generatedComponentId
+
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+
+ fakeIdGenerator.assertGenerateInvocations(1)
+ fakeLifecycle.assertCreationInvocation(1)
+ fakeLifecycle.assertRemovalInvocation(0)
+ fakeLifecycle.assertInitialStateInvocation(0)
+ compatUIState.assertHasNoStateFor(generatedId)
+ compatUIState.assertHasNoComponentFor(generatedId)
+
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ fakeLifecycle.assertCreationInvocation(2)
+ fakeLifecycle.assertRemovalInvocation(0)
+ fakeLifecycle.assertInitialStateInvocation(0)
+ compatUIState.assertHasNoStateFor(generatedId)
+ compatUIState.assertHasNoComponentFor(generatedId)
+ }
+
+ @Test
+ fun `when creationReturn is true and no state is created no state is stored`() {
+ // We add a spec to the repository
+ val fakeLifecycle = FakeCompatUILifecyclePredicates(
+ creationReturn = true,
+ removalReturn = false
+ )
+ val fakeCompatUISpec = FakeCompatUISpec("one", fakeLifecycle).getSpec()
+ compatUIRepository.addSpec(fakeCompatUISpec)
+
+ val generatedId = fakeIdGenerator.generatedComponentId
+
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+
+ fakeLifecycle.assertCreationInvocation(1)
+ fakeLifecycle.assertRemovalInvocation(0)
+ fakeLifecycle.assertInitialStateInvocation(1)
+ compatUIState.assertHasNoStateFor(generatedId)
+ compatUIState.assertHasComponentFor(generatedId)
+
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+
+ fakeLifecycle.assertCreationInvocation(1)
+ fakeLifecycle.assertRemovalInvocation(1)
+ fakeLifecycle.assertInitialStateInvocation(1)
+ compatUIState.assertHasNoStateFor(generatedId)
+ compatUIState.assertHasComponentFor(generatedId)
+ }
+
+ @Test
+ fun `when creationReturn is true and state is created state is stored`() {
+ val fakeComponentState = object : CompatUIComponentState {}
+ // We add a spec to the repository
+ val fakeLifecycle = FakeCompatUILifecyclePredicates(
+ creationReturn = true,
+ removalReturn = false,
+ initialState = { _, _ -> fakeComponentState }
+ )
+ val fakeCompatUISpec = FakeCompatUISpec("one", fakeLifecycle).getSpec()
+ compatUIRepository.addSpec(fakeCompatUISpec)
+
+ val generatedId = fakeIdGenerator.generatedComponentId
+
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+
+ fakeLifecycle.assertCreationInvocation(1)
+ fakeLifecycle.assertRemovalInvocation(0)
+ fakeLifecycle.assertInitialStateInvocation(1)
+ compatUIState.assertHasStateEqualsTo(generatedId, fakeComponentState)
+ compatUIState.assertHasComponentFor(generatedId)
+
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+
+ fakeLifecycle.assertCreationInvocation(1)
+ fakeLifecycle.assertRemovalInvocation(1)
+ fakeLifecycle.assertInitialStateInvocation(1)
+ compatUIState.assertHasStateEqualsTo(generatedId, fakeComponentState)
+ compatUIState.assertHasComponentFor(generatedId)
+ }
+
+ @Test
+ fun `when lifecycle is complete and state is created state is stored and removed`() {
+ val fakeComponentState = object : CompatUIComponentState {}
+ // We add a spec to the repository
+ val fakeLifecycle = FakeCompatUILifecyclePredicates(
+ creationReturn = true,
+ removalReturn = true,
+ initialState = { _, _ -> fakeComponentState }
+ )
+ val fakeCompatUISpec = FakeCompatUISpec("one", fakeLifecycle).getSpec()
+ compatUIRepository.addSpec(fakeCompatUISpec)
+
+ val generatedId = fakeIdGenerator.generatedComponentId
+
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+
+ fakeLifecycle.assertCreationInvocation(1)
+ fakeLifecycle.assertRemovalInvocation(0)
+ fakeLifecycle.assertInitialStateInvocation(1)
+ compatUIState.assertHasStateEqualsTo(generatedId, fakeComponentState)
+ compatUIState.assertHasComponentFor(generatedId)
+
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+
+ fakeLifecycle.assertCreationInvocation(1)
+ fakeLifecycle.assertRemovalInvocation(1)
+ fakeLifecycle.assertInitialStateInvocation(1)
+ compatUIState.assertHasNoStateFor(generatedId)
+ compatUIState.assertHasNoComponentFor(generatedId)
+ }
+
+ @Test
+ fun `idGenerator is invoked every time a component is created`() {
+ // We add a spec to the repository
+ val fakeLifecycle = FakeCompatUILifecyclePredicates(
+ creationReturn = true,
+ removalReturn = true,
+ )
+ val fakeCompatUISpec = FakeCompatUISpec("one", fakeLifecycle).getSpec()
+ compatUIRepository.addSpec(fakeCompatUISpec)
+ // Component creation
+ fakeIdGenerator.assertGenerateInvocations(0)
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ fakeIdGenerator.assertGenerateInvocations(1)
+
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ fakeIdGenerator.assertGenerateInvocations(2)
+ }
+
+ private fun testCompatUIInfo(): CompatUIInfo {
+ val taskInfo = ActivityManager.RunningTaskInfo()
+ taskInfo.taskId = 1
+ return CompatUIInfo(taskInfo, null)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIRepositoryTest.kt
index 1a86cfd6b69e..e35acb2ca0e9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIRepositoryTest.kt
@@ -19,6 +19,7 @@ package com.android.wm.shell.compatui.impl
import android.platform.test.flag.junit.DeviceFlagsValueProvider
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
+import com.android.wm.shell.compatui.api.CompatUILifecyclePredicates
import com.android.wm.shell.compatui.api.CompatUIRepository
import com.android.wm.shell.compatui.api.CompatUISpec
import org.junit.Assert.assertEquals
@@ -50,16 +51,16 @@ class DefaultCompatUIRepositoryTest {
@Test(expected = IllegalStateException::class)
fun `addSpec throws exception with specs with duplicate id`() {
- repository.addSpec(CompatUISpec("one"))
- repository.addSpec(CompatUISpec("one"))
+ repository.addSpec(specById("one"))
+ repository.addSpec(specById("one"))
}
@Test
fun `iterateOn invokes the consumer`() {
with(repository) {
- addSpec(CompatUISpec("one"))
- addSpec(CompatUISpec("two"))
- addSpec(CompatUISpec("three"))
+ addSpec(specById("one"))
+ addSpec(specById("two"))
+ addSpec(specById("three"))
val consumer = object : (CompatUISpec) -> Unit {
var acc = ""
override fun invoke(spec: CompatUISpec) {
@@ -74,9 +75,9 @@ class DefaultCompatUIRepositoryTest {
@Test
fun `findSpec returns existing specs`() {
with(repository) {
- val one = CompatUISpec("one")
- val two = CompatUISpec("two")
- val three = CompatUISpec("three")
+ val one = specById("one")
+ val two = specById("two")
+ val three = specById("three")
addSpec(one)
addSpec(two)
addSpec(three)
@@ -86,4 +87,10 @@ class DefaultCompatUIRepositoryTest {
assertNull(findSpec("abc"))
}
}
+
+ private fun specById(name: String): CompatUISpec =
+ CompatUISpec(name = name, lifecycle = CompatUILifecyclePredicates(
+ creationPredicate = { _, _ -> true },
+ removalPredicate = { _, _, _ -> true }
+ ))
} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUIComponentIdGenerator.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUIComponentIdGenerator.kt
new file mode 100644
index 000000000000..bc743edc465d
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUIComponentIdGenerator.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.compatui.impl
+
+import com.android.wm.shell.compatui.api.CompatUIComponentIdGenerator
+import com.android.wm.shell.compatui.api.CompatUIInfo
+import com.android.wm.shell.compatui.api.CompatUISpec
+import junit.framework.Assert.assertEquals
+
+/**
+ * A Fake {@link CompatUIComponentIdGenerator} implementation.
+ */
+class FakeCompatUIComponentIdGenerator(var generatedComponentId: String = "compId") :
+ CompatUIComponentIdGenerator {
+
+ var generateInvocations = 0
+
+ override fun generateId(compatUIInfo: CompatUIInfo, spec: CompatUISpec): String {
+ generateInvocations++
+ return generatedComponentId
+ }
+
+ fun resetInvocations() {
+ generateInvocations = 0
+ }
+
+ fun assertGenerateInvocations(expected: Int) =
+ assertEquals(expected, generateInvocations)
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUILifecyclePredicates.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUILifecyclePredicates.kt
new file mode 100644
index 000000000000..bbaa2db07aaa
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUILifecyclePredicates.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.compatui.impl
+
+import com.android.wm.shell.compatui.api.CompatUIComponentState
+import com.android.wm.shell.compatui.api.CompatUIInfo
+import com.android.wm.shell.compatui.api.CompatUILifecyclePredicates
+import com.android.wm.shell.compatui.api.CompatUISharedState
+import junit.framework.Assert.assertEquals
+
+/**
+ * Fake class for {@link CompatUILifecycle}
+ */
+class FakeCompatUILifecyclePredicates(
+ private val creationReturn: Boolean,
+ private val removalReturn: Boolean,
+ private val initialState: (
+ CompatUIInfo,
+ CompatUISharedState
+ ) -> CompatUIComponentState? = { _, _ -> null }
+) {
+ var creationInvocation = 0
+ var removalInvocation = 0
+ var initialStateInvocation = 0
+ var lastCreationCompatUIInfo: CompatUIInfo? = null
+ var lastCreationSharedState: CompatUISharedState? = null
+ var lastRemovalCompatUIInfo: CompatUIInfo? = null
+ var lastRemovalSharedState: CompatUISharedState? = null
+ var lastRemovalCompState: CompatUIComponentState? = null
+ fun getLifecycle() = CompatUILifecyclePredicates(
+ creationPredicate = { uiInfo, sharedState ->
+ lastCreationCompatUIInfo = uiInfo
+ lastCreationSharedState = sharedState
+ creationInvocation++
+ creationReturn
+ },
+ removalPredicate = { uiInfo, sharedState, compState ->
+ lastRemovalCompatUIInfo = uiInfo
+ lastRemovalSharedState = sharedState
+ lastRemovalCompState = compState
+ removalInvocation++
+ removalReturn
+ },
+ stateBuilder = { a, b -> initialStateInvocation++; initialState(a, b) }
+ )
+
+ fun assertCreationInvocation(expected: Int) =
+ assertEquals(expected, creationInvocation)
+
+ fun assertRemovalInvocation(expected: Int) =
+ assertEquals(expected, removalInvocation)
+
+ fun assertInitialStateInvocation(expected: Int) =
+ assertEquals(expected, initialStateInvocation)
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUISpec.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUISpec.kt
new file mode 100644
index 000000000000..1ecd52e2b3ff
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUISpec.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.compatui.impl
+
+import com.android.wm.shell.compatui.api.CompatUISpec
+
+/**
+ * Fake implementation for {@link ompatUISpec}
+ */
+class FakeCompatUISpec(
+ val name: String,
+ val lifecycle: FakeCompatUILifecyclePredicates
+) {
+ fun getSpec(): CompatUISpec = CompatUISpec(
+ name = name,
+ lifecycle = lifecycle.getLifecycle()
+ )
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index c3d31ba79646..92f705097c33 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -85,6 +85,7 @@ import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.common.desktopmode.DesktopModeTransitionSource.UNKNOWN
import com.android.wm.shell.common.split.SplitScreenConstants
+import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFullscreenTask
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createHomeTask
@@ -117,7 +118,6 @@ 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.ArgumentMatchers.isA
import org.mockito.ArgumentMatchers.isNull
import org.mockito.Mock
@@ -128,10 +128,11 @@ import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.mock
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.atLeastOnce
+import org.mockito.kotlin.eq
import org.mockito.kotlin.capture
+import org.mockito.kotlin.whenever
import org.mockito.quality.Strictness
/**
@@ -156,6 +157,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
@Mock lateinit var rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer
@Mock lateinit var transitions: Transitions
@Mock lateinit var keyguardManager: KeyguardManager
+ @Mock lateinit var mReturnToDragStartAnimator: ReturnToDragStartAnimator
@Mock lateinit var exitDesktopTransitionHandler: ExitDesktopTaskTransitionHandler
@Mock lateinit var enterDesktopTransitionHandler: EnterDesktopTaskTransitionHandler
@Mock
@@ -249,6 +251,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
dragAndDropController,
transitions,
keyguardManager,
+ mReturnToDragStartAnimator,
enterDesktopTransitionHandler,
exitDesktopTransitionHandler,
toggleResizeDesktopTaskTransitionHandler,
@@ -1566,6 +1569,21 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ fun handleRequest_recentsAnimationRunning_relaunchActiveTask_taskBecomesUndefined() {
+ // Set up a visible freeform task
+ val freeformTask = setUpFreeformTask()
+ markTaskVisible(freeformTask)
+
+ // Mark recents animation running
+ recentsTransitionStateListener.onAnimationStateChanged(true)
+
+ // Should become undefined as the TDA is set to fullscreen. It will inherit from the TDA.
+ val result = controller.handleRequest(Binder(), createTransition(freeformTask))
+ assertThat(result?.changes?.get(freeformTask.token.asBinder())?.windowingMode)
+ .isEqualTo(WINDOWING_MODE_UNDEFINED)
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
fun handleRequest_topActivityTransparentWithStyleFloating_returnSwitchToFreeformWCT() {
val freeformTask = setUpFreeformTask()
@@ -2359,10 +2377,12 @@ class DesktopTasksControllerTest : ShellTestCase() {
controller.onDragPositioningEnd(
task,
+ mockSurface,
Point(100, -100), /* position */
PointF(200f, -200f), /* inputCoordinate */
- Rect(100, -100, 500, 1000), /* taskBounds */
- Rect(0, 50, 2000, 2000) /* validDragArea */)
+ Rect(100, -100, 500, 1000), /* currentDragBounds */
+ Rect(0, 50, 2000, 2000), /* validDragArea */
+ Rect() /* dragStartBounds */ )
val rectAfterEnd = Rect(100, 50, 500, 1150)
verify(transitions)
.startTransition(
@@ -2376,6 +2396,42 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ fun onDesktopDragEnd_noIndicator_updatesTaskBounds() {
+ val task = setUpFreeformTask()
+ val spyController = spy(controller)
+ val mockSurface = mock(SurfaceControl::class.java)
+ val mockDisplayLayout = mock(DisplayLayout::class.java)
+ whenever(displayController.getDisplayLayout(task.displayId)).thenReturn(mockDisplayLayout)
+ whenever(mockDisplayLayout.stableInsets()).thenReturn(Rect(0, 100, 2000, 2000))
+ spyController.onDragPositioningMove(task, mockSurface, 200f, Rect(100, 200, 500, 1000))
+
+ val currentDragBounds = Rect(100, 200, 500, 1000)
+ whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator)
+ whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull(), anyOrNull()))
+ .thenReturn(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR)
+
+ spyController.onDragPositioningEnd(
+ task,
+ mockSurface,
+ Point(100, 200), /* position */
+ PointF(200f, 300f), /* inputCoordinate */
+ currentDragBounds, /* currentDragBounds */
+ Rect(0, 50, 2000, 2000) /* validDragArea */,
+ Rect() /* dragStartBounds */)
+
+
+ verify(transitions)
+ .startTransition(
+ eq(TRANSIT_CHANGE),
+ Mockito.argThat { wct ->
+ return@argThat wct.changes.any { (token, change) ->
+ change.configuration.windowConfiguration.bounds == currentDragBounds
+ }
+ },
+ eq(null))
+ }
+
+ @Test
fun enterSplit_freeformTaskIsMovedToSplit() {
val task1 = setUpFreeformTask()
val task2 = setUpFreeformTask()
@@ -2460,6 +2516,63 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ fun getSnapBounds_calculatesBoundsForResizable() {
+ val bounds = Rect(100, 100, 300, 300)
+ val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds).apply {
+ topActivityInfo = ActivityInfo().apply {
+ screenOrientation = SCREEN_ORIENTATION_LANDSCAPE
+ configuration.windowConfiguration.appBounds = bounds
+ }
+ isResizeable = true
+ }
+
+ val currentDragBounds = Rect(0, 100, 200, 300)
+ val expectedBounds = Rect(
+ STABLE_BOUNDS.left, STABLE_BOUNDS.top, STABLE_BOUNDS.right / 2, STABLE_BOUNDS.bottom
+ )
+
+ controller.snapToHalfScreen(task, currentDragBounds, SnapPosition.LEFT)
+ // Assert bounds set to stable bounds
+ val wct = getLatestToggleResizeDesktopTaskWct(currentDragBounds)
+ assertThat(findBoundsChange(wct, task)).isEqualTo(expectedBounds)
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_DISABLE_NON_RESIZABLE_APP_SNAP_RESIZING)
+ fun handleSnapResizingTask_nonResizable_snapsToHalfScreen() {
+ val task = setUpFreeformTask(DEFAULT_DISPLAY, Rect(0, 0, 200, 100)).apply {
+ isResizeable = false
+ }
+ val preDragBounds = Rect(100, 100, 400, 500)
+ val currentDragBounds = Rect(0, 100, 300, 500)
+
+ controller.handleSnapResizingTask(
+ task, SnapPosition.LEFT, mockSurface, currentDragBounds, preDragBounds)
+ val wct = getLatestToggleResizeDesktopTaskWct(currentDragBounds)
+ assertThat(findBoundsChange(wct, task)).isEqualTo(
+ Rect(STABLE_BOUNDS.left, STABLE_BOUNDS.top, STABLE_BOUNDS.right / 2, STABLE_BOUNDS.bottom))
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_DISABLE_NON_RESIZABLE_APP_SNAP_RESIZING)
+ fun handleSnapResizingTask_nonResizable_startsRepositionAnimation() {
+ val task = setUpFreeformTask(DEFAULT_DISPLAY, Rect(0, 0, 200, 100)).apply {
+ isResizeable = false
+ }
+ val preDragBounds = Rect(100, 100, 400, 500)
+ val currentDragBounds = Rect(0, 100, 300, 500)
+
+ controller.handleSnapResizingTask(
+ task, SnapPosition.LEFT, mockSurface, currentDragBounds, preDragBounds)
+ verify(mReturnToDragStartAnimator).start(
+ eq(task.taskId),
+ eq(mockSurface),
+ eq(currentDragBounds),
+ eq(preDragBounds)
+ )
+ }
+
+ @Test
fun toggleBounds_togglesToCalculatedBoundsForNonResizable() {
val bounds = Rect(0, 0, 200, 100)
val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds).apply {
@@ -2621,18 +2734,16 @@ class DesktopTasksControllerTest : ShellTestCase() {
if (deviceOrientation == ORIENTATION_LANDSCAPE &&
screenOrientation == SCREEN_ORIENTATION_PORTRAIT) {
// Letterbox to portrait size
- appCompatTaskInfo.topActivityBoundsLetterboxed = true
- appCompatTaskInfo.topActivityLetterboxWidth = 1200
- appCompatTaskInfo.topActivityLetterboxHeight = 1600
+ appCompatTaskInfo.setTopActivityLetterboxed(true)
+ appCompatTaskInfo.topActivityLetterboxAppWidth = 1200
+ appCompatTaskInfo.topActivityLetterboxAppHeight = 1600
} else if (deviceOrientation == ORIENTATION_PORTRAIT &&
screenOrientation == SCREEN_ORIENTATION_LANDSCAPE) {
// Letterbox to landscape size
- appCompatTaskInfo.topActivityBoundsLetterboxed = true
- appCompatTaskInfo.topActivityLetterboxWidth = 1600
- appCompatTaskInfo.topActivityLetterboxHeight = 1200
+ appCompatTaskInfo.setTopActivityLetterboxed(true)
+ appCompatTaskInfo.topActivityLetterboxAppWidth = 1600
+ appCompatTaskInfo.topActivityLetterboxAppHeight = 1200
}
- } else {
- appCompatTaskInfo.topActivityBoundsLetterboxed = false
}
if (deviceOrientation == ORIENTATION_LANDSCAPE) {
@@ -2705,11 +2816,14 @@ class DesktopTasksControllerTest : ShellTestCase() {
return arg.value
}
- private fun getLatestToggleResizeDesktopTaskWct(): WindowContainerTransaction {
+ private fun getLatestToggleResizeDesktopTaskWct(
+ currentBounds: Rect? = null
+ ): WindowContainerTransaction {
val arg: ArgumentCaptor<WindowContainerTransaction> =
ArgumentCaptor.forClass(WindowContainerTransaction::class.java)
if (ENABLE_SHELL_TRANSITIONS) {
- verify(toggleResizeDesktopTaskTransitionHandler, atLeastOnce()).startTransition(capture(arg))
+ verify(toggleResizeDesktopTaskTransitionHandler, atLeastOnce())
+ .startTransition(capture(arg), eq(currentBounds))
} else {
verify(shellTaskOrganizer).applyTransaction(capture(arg))
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
index eaef704b7d78..ff6c7eeb9d1a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
@@ -245,38 +245,6 @@ public class StageCoordinatorTests extends ShellTestCase {
}
@Test
- public void testExitSplitScreen() {
- when(mMainStage.isActive()).thenReturn(true);
- mStageCoordinator.exitSplitScreen(INVALID_TASK_ID, EXIT_REASON_RETURN_HOME);
- verify(mSideStage).removeAllTasks(any(WindowContainerTransaction.class), eq(false));
- verify(mMainStage).deactivate(any(WindowContainerTransaction.class), eq(false));
- }
-
- @Test
- public void testExitSplitScreenToMainStage() {
- when(mMainStage.isActive()).thenReturn(true);
- final int testTaskId = 12345;
- when(mMainStage.containsTask(eq(testTaskId))).thenReturn(true);
- when(mSideStage.containsTask(eq(testTaskId))).thenReturn(false);
- mStageCoordinator.exitSplitScreen(testTaskId, EXIT_REASON_RETURN_HOME);
- verify(mMainStage).reorderChild(eq(testTaskId), eq(true),
- any(WindowContainerTransaction.class));
- verify(mMainStage).resetBounds(any(WindowContainerTransaction.class));
- }
-
- @Test
- public void testExitSplitScreenToSideStage() {
- when(mMainStage.isActive()).thenReturn(true);
- final int testTaskId = 12345;
- when(mMainStage.containsTask(eq(testTaskId))).thenReturn(false);
- when(mSideStage.containsTask(eq(testTaskId))).thenReturn(true);
- mStageCoordinator.exitSplitScreen(testTaskId, EXIT_REASON_RETURN_HOME);
- verify(mSideStage).reorderChild(eq(testTaskId), eq(true),
- any(WindowContainerTransaction.class));
- verify(mSideStage).resetBounds(any(WindowContainerTransaction.class));
- }
-
- @Test
public void testResolveStartStage_beforeSplitActivated_setsStagePosition() {
mStageCoordinator.setSideStagePosition(SPLIT_POSITION_TOP_OR_LEFT, null /* wct */);
@@ -367,12 +335,7 @@ public class StageCoordinatorTests extends ShellTestCase {
mStageCoordinator.onFinishedWakingUp();
- if (Transitions.ENABLE_SHELL_TRANSITIONS) {
- verify(mTaskOrganizer).startNewTransition(eq(TRANSIT_SPLIT_DISMISS), notNull());
- } else {
- verify(mStageCoordinator).onSplitScreenExit();
- verify(mMainStage).deactivate(any(WindowContainerTransaction.class), eq(false));
- }
+ verify(mTaskOrganizer).startNewTransition(eq(TRANSIT_SPLIT_DISMISS), notNull());
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorationTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorationTests.kt
index 261d4b5e7d1a..d141c2d771ce 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorationTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/CaptionWindowDecorationTests.kt
@@ -21,6 +21,7 @@ import android.app.WindowConfiguration
import android.content.ComponentName
import android.testing.AndroidTestingRunner
import android.view.Display
+import android.view.InsetsState
import android.view.WindowInsetsController
import androidx.test.filters.SmallTest
import com.android.wm.shell.ShellTestCase
@@ -45,7 +46,8 @@ class CaptionWindowDecorationTests : ShellTestCase() {
relayoutParams,
taskInfo,
true,
- false
+ false,
+ InsetsState()
)
Truth.assertThat(relayoutParams.hasInputFeatureSpy()).isTrue()
@@ -63,7 +65,8 @@ class CaptionWindowDecorationTests : ShellTestCase() {
relayoutParams,
taskInfo,
true,
- false
+ false,
+ InsetsState()
)
Truth.assertThat(relayoutParams.hasInputFeatureSpy()).isFalse()
@@ -77,7 +80,8 @@ class CaptionWindowDecorationTests : ShellTestCase() {
relayoutParams,
taskInfo,
true,
- false
+ false,
+ InsetsState()
)
Truth.assertThat(relayoutParams.mOccludingCaptionElements.size).isEqualTo(2)
Truth.assertThat(relayoutParams.mOccludingCaptionElements[0].mAlignment).isEqualTo(
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index 5e6d01b765e4..68975ec3556e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -21,6 +21,7 @@ import android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED
import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW
+import android.app.WindowConfiguration.WINDOWING_MODE_PINNED
import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
import android.app.WindowConfiguration.WindowingMode
import android.content.ComponentName
@@ -51,11 +52,13 @@ import android.view.InputMonitor
import android.view.InsetsSource
import android.view.InsetsState
import android.view.KeyEvent
+import android.view.Surface
import android.view.SurfaceControl
import android.view.SurfaceView
import android.view.View
import android.view.WindowInsets.Type.navigationBars
import android.view.WindowInsets.Type.statusBars
+import android.window.WindowContainerTransaction
import androidx.test.filters.SmallTest
import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
@@ -69,6 +72,7 @@ import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.TestRunningTaskInfoBuilder
import com.android.wm.shell.TestShellExecutor
import com.android.wm.shell.apptoweb.AppToWebGenericLinksParser
+import com.android.wm.shell.common.DisplayChangeController
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayInsetsController
import com.android.wm.shell.common.DisplayLayout
@@ -110,6 +114,7 @@ import org.mockito.kotlin.argThat
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.doNothing
import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
import org.mockito.kotlin.spy
import org.mockito.kotlin.whenever
import org.mockito.quality.Strictness
@@ -166,6 +171,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
private lateinit var mockitoSession: StaticMockitoSession
private lateinit var shellInit: ShellInit
private lateinit var desktopModeOnInsetsChangedListener: DesktopModeOnInsetsChangedListener
+ private lateinit var displayChangingListener: DisplayChangeController.OnDisplayChangingListener
private lateinit var desktopModeWindowDecorViewModel: DesktopModeWindowDecorViewModel
@Before
@@ -174,6 +180,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
mockitoSession()
.strictness(Strictness.LENIENT)
.spyStatic(DesktopModeStatus::class.java)
+ .spyStatic(DragPositioningCallbackUtility::class.java)
.startMocking()
doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(Mockito.any()) }
@@ -218,10 +225,17 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
shellInit.init()
- val listenerCaptor =
- argumentCaptor<DesktopModeWindowDecorViewModel.DesktopModeOnInsetsChangedListener>()
- verify(displayInsetsController).addInsetsChangedListener(anyInt(), listenerCaptor.capture())
- desktopModeOnInsetsChangedListener = listenerCaptor.firstValue
+ val insetListenerCaptor =
+ argumentCaptor<DesktopModeWindowDecorViewModel.DesktopModeOnInsetsChangedListener>()
+ verify(displayInsetsController)
+ .addInsetsChangedListener(anyInt(), insetListenerCaptor.capture())
+ desktopModeOnInsetsChangedListener = insetListenerCaptor.firstValue
+
+ val displayChangingListenerCaptor =
+ argumentCaptor<DisplayChangeController.OnDisplayChangingListener>()
+ verify(mockDisplayController)
+ .addDisplayChangingController(displayChangingListenerCaptor.capture())
+ displayChangingListener = displayChangingListenerCaptor.firstValue
}
@After
@@ -561,9 +575,11 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
onLeftSnapClickListenerCaptor = onLeftSnapClickListenerCaptor
)
+ val currentBounds = decor.mTaskInfo.configuration.windowConfiguration.bounds
onLeftSnapClickListenerCaptor.value.invoke()
- verify(mockDesktopTasksController).snapToHalfScreen(decor.mTaskInfo, SnapPosition.LEFT)
+ verify(mockDesktopTasksController)
+ .snapToHalfScreen(decor.mTaskInfo, currentBounds, SnapPosition.LEFT)
}
@Test
@@ -582,6 +598,40 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
}
@Test
+ @DisableFlags(Flags.FLAG_DISABLE_NON_RESIZABLE_APP_SNAP_RESIZING)
+ fun testOnSnapResizeLeft_nonResizable_decorSnappedLeft() {
+ val onLeftSnapClickListenerCaptor = forClass(Function0::class.java)
+ as ArgumentCaptor<Function0<Unit>>
+ val decor = createOpenTaskDecoration(
+ windowingMode = WINDOWING_MODE_FREEFORM,
+ onLeftSnapClickListenerCaptor = onLeftSnapClickListenerCaptor
+ ).also { it.mTaskInfo.isResizeable = false }
+
+ val currentBounds = decor.mTaskInfo.configuration.windowConfiguration.bounds
+ onLeftSnapClickListenerCaptor.value.invoke()
+
+ verify(mockDesktopTasksController)
+ .snapToHalfScreen(decor.mTaskInfo, currentBounds, SnapPosition.LEFT)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_DISABLE_NON_RESIZABLE_APP_SNAP_RESIZING)
+ fun testOnSnapResizeLeft_nonResizable_decorNotSnapped() {
+ val onLeftSnapClickListenerCaptor = forClass(Function0::class.java)
+ as ArgumentCaptor<Function0<Unit>>
+ val decor = createOpenTaskDecoration(
+ windowingMode = WINDOWING_MODE_FREEFORM,
+ onLeftSnapClickListenerCaptor = onLeftSnapClickListenerCaptor
+ ).also { it.mTaskInfo.isResizeable = false }
+
+ val currentBounds = decor.mTaskInfo.configuration.windowConfiguration.bounds
+ onLeftSnapClickListenerCaptor.value.invoke()
+
+ verify(mockDesktopTasksController, never())
+ .snapToHalfScreen(decor.mTaskInfo, currentBounds, SnapPosition.LEFT)
+ }
+
+ @Test
fun testOnDecorSnappedRight_snapResizes() {
val onRightSnapClickListenerCaptor = forClass(Function0::class.java)
as ArgumentCaptor<Function0<Unit>>
@@ -590,9 +640,11 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
onRightSnapClickListenerCaptor = onRightSnapClickListenerCaptor
)
+ val currentBounds = decor.mTaskInfo.configuration.windowConfiguration.bounds
onRightSnapClickListenerCaptor.value.invoke()
- verify(mockDesktopTasksController).snapToHalfScreen(decor.mTaskInfo, SnapPosition.RIGHT)
+ verify(mockDesktopTasksController)
+ .snapToHalfScreen(decor.mTaskInfo, currentBounds, SnapPosition.RIGHT)
}
@Test
@@ -611,6 +663,40 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
}
@Test
+ @DisableFlags(Flags.FLAG_DISABLE_NON_RESIZABLE_APP_SNAP_RESIZING)
+ fun testOnSnapResizeRight_nonResizable_decorSnappedRight() {
+ val onRightSnapClickListenerCaptor = forClass(Function0::class.java)
+ as ArgumentCaptor<Function0<Unit>>
+ val decor = createOpenTaskDecoration(
+ windowingMode = WINDOWING_MODE_FREEFORM,
+ onRightSnapClickListenerCaptor = onRightSnapClickListenerCaptor
+ ).also { it.mTaskInfo.isResizeable = false }
+
+ val currentBounds = decor.mTaskInfo.configuration.windowConfiguration.bounds
+ onRightSnapClickListenerCaptor.value.invoke()
+
+ verify(mockDesktopTasksController)
+ .snapToHalfScreen(decor.mTaskInfo, currentBounds, SnapPosition.RIGHT)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_DISABLE_NON_RESIZABLE_APP_SNAP_RESIZING)
+ fun testOnSnapResizeRight_nonResizable_decorNotSnapped() {
+ val onRightSnapClickListenerCaptor = forClass(Function0::class.java)
+ as ArgumentCaptor<Function0<Unit>>
+ val decor = createOpenTaskDecoration(
+ windowingMode = WINDOWING_MODE_FREEFORM,
+ onRightSnapClickListenerCaptor = onRightSnapClickListenerCaptor
+ ).also { it.mTaskInfo.isResizeable = false }
+
+ val currentBounds = decor.mTaskInfo.configuration.windowConfiguration.bounds
+ onRightSnapClickListenerCaptor.value.invoke()
+
+ verify(mockDesktopTasksController, never())
+ .snapToHalfScreen(decor.mTaskInfo, currentBounds, SnapPosition.RIGHT)
+ }
+
+ @Test
fun testDecor_onClickToDesktop_movesToDesktopWithSource() {
val toDesktopListenerCaptor = forClass(Consumer::class.java)
as ArgumentCaptor<Consumer<DesktopModeTransitionSource>>
@@ -782,6 +868,135 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
})
}
+ @Test
+ fun testOnDisplayRotation_tasksOutOfValidArea_taskBoundsUpdated() {
+ val task = createTask(focused = true, windowingMode = WINDOWING_MODE_FREEFORM)
+ val secondTask =
+ createTask(displayId = task.displayId, windowingMode = WINDOWING_MODE_FREEFORM)
+ val thirdTask =
+ createTask(displayId = task.displayId, windowingMode = WINDOWING_MODE_FREEFORM)
+
+ doReturn(true).`when` {
+ DragPositioningCallbackUtility.snapTaskBoundsIfNecessary(any(), any())
+ }
+ setUpMockDecorationsForTasks(task, secondTask, thirdTask)
+
+ onTaskOpening(task)
+ onTaskOpening(secondTask)
+ onTaskOpening(thirdTask)
+
+ val wct = mock<WindowContainerTransaction>()
+
+ displayChangingListener.onDisplayChange(
+ task.displayId, Surface.ROTATION_0, Surface.ROTATION_90, null, wct
+ )
+
+ verify(wct).setBounds(eq(task.token), any())
+ verify(wct).setBounds(eq(secondTask.token), any())
+ verify(wct).setBounds(eq(thirdTask.token), any())
+ }
+
+ @Test
+ fun testOnDisplayRotation_taskInValidArea_taskBoundsNotUpdated() {
+ val task = createTask(focused = true, windowingMode = WINDOWING_MODE_FREEFORM)
+ val secondTask =
+ createTask(displayId = task.displayId, windowingMode = WINDOWING_MODE_FREEFORM)
+ val thirdTask =
+ createTask(displayId = task.displayId, windowingMode = WINDOWING_MODE_FREEFORM)
+
+ doReturn(false).`when` {
+ DragPositioningCallbackUtility.snapTaskBoundsIfNecessary(any(), any())
+ }
+ setUpMockDecorationsForTasks(task, secondTask, thirdTask)
+
+ onTaskOpening(task)
+ onTaskOpening(secondTask)
+ onTaskOpening(thirdTask)
+
+ val wct = mock<WindowContainerTransaction>()
+ displayChangingListener.onDisplayChange(
+ task.displayId, Surface.ROTATION_0, Surface.ROTATION_90, null, wct
+ )
+
+ verify(wct, never()).setBounds(eq(task.token), any())
+ verify(wct, never()).setBounds(eq(secondTask.token), any())
+ verify(wct, never()).setBounds(eq(thirdTask.token), any())
+ }
+
+ @Test
+ fun testOnDisplayRotation_sameOrientationRotation_taskBoundsNotUpdated() {
+ val task = createTask(focused = true, windowingMode = WINDOWING_MODE_FREEFORM)
+ val secondTask =
+ createTask(displayId = task.displayId, windowingMode = WINDOWING_MODE_FREEFORM)
+ val thirdTask =
+ createTask(displayId = task.displayId, windowingMode = WINDOWING_MODE_FREEFORM)
+
+ setUpMockDecorationsForTasks(task, secondTask, thirdTask)
+
+ onTaskOpening(task)
+ onTaskOpening(secondTask)
+ onTaskOpening(thirdTask)
+
+ val wct = mock<WindowContainerTransaction>()
+ displayChangingListener.onDisplayChange(
+ task.displayId, Surface.ROTATION_0, Surface.ROTATION_180, null, wct
+ )
+
+ verify(wct, never()).setBounds(eq(task.token), any())
+ verify(wct, never()).setBounds(eq(secondTask.token), any())
+ verify(wct, never()).setBounds(eq(thirdTask.token), any())
+ }
+
+ @Test
+ fun testOnDisplayRotation_differentDisplayId_taskBoundsNotUpdated() {
+ val task = createTask(focused = true, windowingMode = WINDOWING_MODE_FREEFORM)
+ val secondTask = createTask(displayId = -2, windowingMode = WINDOWING_MODE_FREEFORM)
+ val thirdTask = createTask(displayId = -3, windowingMode = WINDOWING_MODE_FREEFORM)
+
+ doReturn(true).`when` {
+ DragPositioningCallbackUtility.snapTaskBoundsIfNecessary(any(), any())
+ }
+ setUpMockDecorationsForTasks(task, secondTask, thirdTask)
+
+ onTaskOpening(task)
+ onTaskOpening(secondTask)
+ onTaskOpening(thirdTask)
+
+ val wct = mock<WindowContainerTransaction>()
+ displayChangingListener.onDisplayChange(
+ task.displayId, Surface.ROTATION_0, Surface.ROTATION_90, null, wct
+ )
+
+ verify(wct).setBounds(eq(task.token), any())
+ verify(wct, never()).setBounds(eq(secondTask.token), any())
+ verify(wct, never()).setBounds(eq(thirdTask.token), any())
+ }
+
+ @Test
+ fun testOnDisplayRotation_nonFreeformTask_taskBoundsNotUpdated() {
+ val task = createTask(focused = true, windowingMode = WINDOWING_MODE_FREEFORM)
+ val secondTask = createTask(displayId = -2, windowingMode = WINDOWING_MODE_FULLSCREEN)
+ val thirdTask = createTask(displayId = -3, windowingMode = WINDOWING_MODE_PINNED)
+
+ doReturn(true).`when` {
+ DragPositioningCallbackUtility.snapTaskBoundsIfNecessary(any(), any())
+ }
+ setUpMockDecorationsForTasks(task, secondTask, thirdTask)
+
+ onTaskOpening(task)
+ onTaskOpening(secondTask)
+ onTaskOpening(thirdTask)
+
+ val wct = mock<WindowContainerTransaction>()
+ displayChangingListener.onDisplayChange(
+ task.displayId, Surface.ROTATION_0, Surface.ROTATION_90, null, wct
+ )
+
+ verify(wct).setBounds(eq(task.token), any())
+ verify(wct, never()).setBounds(eq(secondTask.token), any())
+ verify(wct, never()).setBounds(eq(thirdTask.token), any())
+ }
+
private fun createOpenTaskDecoration(
@WindowingMode windowingMode: Int,
onMaxOrRestoreListenerCaptor: ArgumentCaptor<Function0<Unit>> =
@@ -844,6 +1059,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
.build().apply {
topActivityInfo = activityInfo
isFocused = focused
+ isResizeable = true
}
}
@@ -860,6 +1076,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
whenever(mockSplitScreenController.isTaskInSplitScreen(task.taskId))
.thenReturn(true)
}
+ whenever(decoration.calculateValidDragArea()).thenReturn(Rect(0, 60, 2560, 1600))
return decoration
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt
index 666750485ef2..2ce59ff0a4a9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt
@@ -35,7 +35,6 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
-import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.any
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
index 943c313e5b40..08a6e1ba676b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
@@ -200,7 +200,7 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() {
verify(mockTransaction).setPosition(any(), eq(rectAfterMove.left.toFloat()),
eq(rectAfterMove.top.toFloat()))
- taskPositioner.onDragPositioningEnd(
+ val endBounds = taskPositioner.onDragPositioningEnd(
STARTING_BOUNDS.left.toFloat() + 70,
STARTING_BOUNDS.top.toFloat() + 20
)
@@ -212,12 +212,7 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() {
verify(mockDesktopWindowDecoration, never()).showResizeVeil(any())
verify(mockDesktopWindowDecoration, never()).hideResizeVeil()
- verify(mockTransitions).startTransition(eq(TRANSIT_CHANGE), argThat { wct ->
- return@argThat wct.changes.any { (token, change) ->
- token == taskBinder &&
- (change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 &&
- change.configuration.windowConfiguration.bounds == rectAfterEnd }},
- eq(taskPositioner))
+ Assert.assertEquals(rectAfterEnd, endBounds)
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
index e6e2d0928240..2ec3ab52725e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
@@ -867,6 +867,7 @@ public class WindowDecorationTests extends ShellTestCase {
final TestWindowDecoration windowDecor = createWindowDecoration(
new TestRunningTaskInfoBuilder().build());
mRelayoutParams.mApplyStartTransactionOnDraw = true;
+ mRelayoutResult.mRootView = mMockView;
windowDecor.updateViewHost(mRelayoutParams, mMockSurfaceControlStartT, mRelayoutResult);
@@ -878,6 +879,7 @@ public class WindowDecorationTests extends ShellTestCase {
final TestWindowDecoration windowDecor = createWindowDecoration(
new TestRunningTaskInfoBuilder().build());
mRelayoutParams.mApplyStartTransactionOnDraw = true;
+ mRelayoutResult.mRootView = mMockView;
assertThrows(IllegalArgumentException.class,
() -> windowDecor.updateViewHost(
@@ -889,6 +891,7 @@ public class WindowDecorationTests extends ShellTestCase {
final TestWindowDecoration windowDecor = createWindowDecoration(
new TestRunningTaskInfoBuilder().build());
mRelayoutParams.mApplyStartTransactionOnDraw = false;
+ mRelayoutResult.mRootView = mMockView;
windowDecor.updateViewHost(mRelayoutParams, null /* onDrawTransaction */, mRelayoutResult);
}
diff --git a/media/java/android/media/tv/flags/media_tv.aconfig b/media/java/android/media/tv/flags/media_tv.aconfig
index 97971e134f02..3196ba124d76 100644
--- a/media/java/android/media/tv/flags/media_tv.aconfig
+++ b/media/java/android/media/tv/flags/media_tv.aconfig
@@ -23,4 +23,12 @@ flag {
namespace: "media_tv"
description: "TIAF V3.0 APIs for Android V"
bug: "303323657"
+}
+
+flag {
+ name: "tis_always_bound_permission"
+ is_exported: true
+ namespace: "media_tv"
+ description: "Introduce ALWAYS_BOUND_TV_INPUT for TIS."
+ bug: "332201346"
} \ No newline at end of file
diff --git a/native/graphics/jni/Android.bp b/native/graphics/jni/Android.bp
index 8f16f762f7ef..0fb3049f63d8 100644
--- a/native/graphics/jni/Android.bp
+++ b/native/graphics/jni/Android.bp
@@ -127,3 +127,30 @@ cc_fuzz {
"-DPNG_MUTATOR_DEFINE_LIBFUZZER_CUSTOM_MUTATOR",
],
}
+
+cc_fuzz {
+ name: "imagedecoder_heif_fuzzer",
+ defaults: ["imagedecoder_fuzzer_defaults"],
+ team: "trendy_team_android_core_graphics_stack",
+ shared_libs: [
+ "libfakeservicemanager",
+ ],
+ target: {
+ android: {
+ shared_libs: [
+ "libmediaplayerservice",
+ "libmediaextractorservice",
+ ],
+ },
+ host: {
+ static_libs: [
+ "libbinder_random_parcel",
+ "libcutils",
+ ],
+ },
+ },
+ include_dirs: ["frameworks/av/services/mediaextractor"],
+ cflags: [
+ "-DFUZZ_HEIF_FORMAT",
+ ],
+}
diff --git a/native/graphics/jni/fuzz/fuzz_imagedecoder.cpp b/native/graphics/jni/fuzz/fuzz_imagedecoder.cpp
index 6743997fb152..f739e4a1d1a2 100644
--- a/native/graphics/jni/fuzz/fuzz_imagedecoder.cpp
+++ b/native/graphics/jni/fuzz/fuzz_imagedecoder.cpp
@@ -18,6 +18,16 @@
#include <binder/IPCThreadState.h>
#include <fuzzer/FuzzedDataProvider.h>
+#ifdef FUZZ_HEIF_FORMAT
+#include <fakeservicemanager/FakeServiceManager.h>
+#ifdef __ANDROID__
+#include <MediaExtractorService.h>
+#include <MediaPlayerService.h>
+#else
+#include <fuzzbinder/random_binder.h>
+#endif //__ANDROID__
+#endif // FUZZ_HEIF_FORMAT
+
#ifdef PNG_MUTATOR_DEFINE_LIBFUZZER_CUSTOM_MUTATOR
#include <fuzz/png_mutator.h>
#endif
@@ -31,8 +41,42 @@ struct PixelFreer {
using PixelPointer = std::unique_ptr<void, PixelFreer>;
+#ifndef FUZZ_HEIF_FORMAT
+#define FOURCC(c1, c2, c3, c4) ((c1) << 24 | (c2) << 16 | (c3) << 8 | (c4))
+/** Reverse all 4 bytes in a 32bit value.
+ e.g. 0x12345678 -> 0x78563412
+*/
+static uint32_t endianSwap32(uint32_t value) {
+ return ((value & 0xFF) << 24) | ((value & 0xFF00) << 8) | ((value & 0xFF0000) >> 8) |
+ (value >> 24);
+}
+
+static bool isFtyp(const uint8_t* data, size_t size) {
+ constexpr int32_t headerSize = 8;
+ constexpr int32_t chunkTypeOffset = 4;
+ constexpr int32_t ftypFourCCVal = FOURCC('f', 't', 'y', 'p');
+ if (size >= headerSize) {
+ const uint32_t* chunk = reinterpret_cast<const uint32_t*>(data + chunkTypeOffset);
+ if (endianSwap32(*chunk) == ftypFourCCVal) {
+ return true;
+ }
+ }
+ return false;
+}
+#endif
+
AImageDecoder* init(const uint8_t* data, size_t size, bool useFileDescriptor) {
AImageDecoder* decoder = nullptr;
+#ifndef FUZZ_HEIF_FORMAT
+ if (isFtyp(data, size)) {
+ /* We want to ignore HEIF data when fuzzing non-HEIF image decoders. Use 'FTYP'
+ * as a signal to ignore, though note that this excludes more than just HEIF.
+ * But when this code was added, `AImageDecoder` did not support any formats
+ * in 'FTYP' besides HEIF.
+ */
+ return nullptr;
+ }
+#endif // FUZZ_HEIF_FORMAT
if (useFileDescriptor) {
constexpr char testFd[] = "tempFd";
int32_t fileDesc = open(testFd, O_RDWR | O_CREAT | O_TRUNC);
@@ -47,6 +91,27 @@ AImageDecoder* init(const uint8_t* data, size_t size, bool useFileDescriptor) {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
FuzzedDataProvider dataProvider = FuzzedDataProvider(data, size);
+#ifdef FUZZ_HEIF_FORMAT
+ /**
+ * For image formats like HEIF, a new metadata object is
+ * created which requires "media.player" service running
+ */
+ static std::once_flag callOnceHEIF;
+ std::call_once(callOnceHEIF, [&]() {
+ android::sp<android::IServiceManager> fakeServiceManager =
+ new android::FakeServiceManager();
+ setDefaultServiceManager(fakeServiceManager);
+#ifdef __ANDROID__
+ android::MediaPlayerService::instantiate();
+ android::MediaExtractorService::instantiate();
+#else
+ auto binderExtractor = android::getRandomBinder(&dataProvider);
+ auto binderPlayer = android::getRandomBinder(&dataProvider);
+ fakeServiceManager->addService(android::String16("media.extractor"), binderExtractor);
+ fakeServiceManager->addService(android::String16("media.player"), binderPlayer);
+#endif //__ANDROID__
+ });
+#endif // FUZZ_HEIF_FORMAT
/**
* Use maximum of 80% of buffer for creating decoder and save at least
* 20% buffer for fuzzing other APIs
diff --git a/packages/CompanionDeviceManager/res/values/strings.xml b/packages/CompanionDeviceManager/res/values/strings.xml
index 42d0cc403372..a57d6eb11927 100644
--- a/packages/CompanionDeviceManager/res/values/strings.xml
+++ b/packages/CompanionDeviceManager/res/values/strings.xml
@@ -34,7 +34,7 @@
<string name="chooser_title">Choose a <xliff:g id="profile_name" example="watch">%1$s</xliff:g> to set up</string>
<!-- Description of the privileges the application will get if associated with the companion device of WATCH profile [CHAR LIMIT=NONE] -->
- <string name="summary_watch">This app will be allowed to sync info, like the name of someone calling, and access these permissions on your <xliff:g id="device_name" example="phone">%1$s</xliff:g></string>
+ <string name="summary_watch">This app will be allowed to sync info, like the name of someone calling, and access these permissions on your <xliff:g id="device_type" example="phone">%1$s</xliff:g></string>
<!-- ================= DEVICE_PROFILE_GLASSES ================= -->
@@ -45,27 +45,18 @@
<string name="profile_name_glasses">device</string>
<!-- Description of the privileges the application will get if associated with the companion device of GLASSES profile [CHAR LIMIT=NONE] -->
- <string name="summary_glasses">This app will be allowed to access these permissions on your <xliff:g id="device_name" example="phone">%1$s</xliff:g></string>
+ <string name="summary_glasses">This app will be allowed to access these permissions on your <xliff:g id="device_type" example="phone">%1$s</xliff:g></string>
<!-- ================= DEVICE_PROFILE_APP_STREAMING ================= -->
<!-- Confirmation for associating an application with a companion device of APP_STREAMING profile (type) [CHAR LIMIT=NONE] -->
- <string name="title_app_streaming">Allow &lt;strong&gt;<xliff:g id="app_name" example="Exo">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone</string>
-
- <!-- Confirmation for associating an application with a companion device of APP_STREAMING profile (type) with mirroring enabled [CHAR LIMIT=NONE] -->
- <string name="title_app_streaming_with_mirroring">Allow &lt;strong&gt;<xliff:g id="app_name" example="Exo">%1$s</xliff:g>&lt;/strong&gt; to stream your phone\u2019s apps?</string>
+ <string name="title_app_streaming">Allow &lt;strong&gt;<xliff:g id="app_name" example="Exo">%1$s</xliff:g>&lt;/strong&gt; to stream your <xliff:g id="device_type" example="phone">%2$s</xliff:g>\u2019s apps to &lt;strong&gt;<xliff:g id="device_name" example="Chromebook">%3$s</xliff:g>&lt;/strong&gt;?</string>
<!-- Summary for associating an application with a companion device of APP_STREAMING profile [CHAR LIMIT=NONE] -->
- <string name="summary_app_streaming">%1$s will have access to anything that’s visible or played on the phone, including audio, photos, passwords, and messages.&lt;br/>&lt;br/>%1$s will be able to stream apps until you remove access to this permission.</string>
-
- <!-- Title of the helper dialog for APP_STREAMING profile [CHAR LIMIT=30]. -->
- <string name="helper_title_app_streaming">Cross-device services</string>
+ <string name="summary_app_streaming"><xliff:g id="app_name" example="Exo">%1$s</xliff:g> will have access to anything that’s visible or played on the <xliff:g id="device_type" example="phone">%2$s</xliff:g>, including audio, photos, passwords, and messages.&lt;br/>&lt;br/><xliff:g id="app_name" example="Exo">%1$s</xliff:g> will be able to stream apps to <xliff:g id="device_name" example="Chromebook">%3$s</xliff:g> until you remove access to this permission.</string>
<!-- Description of the helper dialog for APP_STREAMING profile. [CHAR LIMIT=NONE] -->
- <string name="helper_summary_app_streaming"><xliff:g id="app_name" example="GMS">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="display_name" example="Chromebook">%2$s</xliff:g> to stream apps between your devices</string>
-
- <!-- Description of the helper dialog for APP_STREAMING profile with mirroring enabled. [CHAR LIMIT=NONE] -->
- <string name="helper_summary_app_streaming_with_mirroring"><xliff:g id="app_name" example="GMS">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="display_name" example="Chromebook">%2$s</xliff:g> to display and stream apps between your devices</string>
+ <string name="helper_summary_app_streaming"><xliff:g id="app_name" example="GMS">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="device_name" example="Chromebook">%2$s</xliff:g> to display and stream apps between your devices</string>
<!-- ================= DEVICE_PROFILE_AUTOMOTIVE_PROJECTION ================= -->
@@ -78,30 +69,24 @@
<!-- ================= DEVICE_PROFILE_COMPUTER ================= -->
<!-- Confirmation for associating an application with a companion device of COMPUTER profile (type) [CHAR LIMIT=NONE] -->
- <string name="title_computer">Allow &lt;strong&gt;<xliff:g id="app_name" example="GMS">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone</string>
+ <string name="title_computer">Allow &lt;strong&gt;<xliff:g id="app_name" example="GMS">%1$s</xliff:g>&lt;/strong&gt; to access this information from your <xliff:g id="device_type" example="phone">%2$s</xliff:g></string>
<!-- Description of the privileges the application will get if associated with the companion device of COMPUTER profile (type) [CHAR LIMIT=NONE] -->
<string name="summary_computer"></string>
- <!-- Title of the helper dialog for COMPUTER profile [CHAR LIMIT=30]. -->
- <string name="helper_title_computer">Google Play services</string>
-
<!-- Description of the helper dialog for COMPUTER profile. [CHAR LIMIT=NONE] -->
- <string name="helper_summary_computer"><xliff:g id="app_name" example="GMS">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="display_name" example="Chromebook">%2$s</xliff:g> to access your phone\u2019s photos, media, and notifications</string>
+ <string name="helper_summary_computer"><xliff:g id="app_name" example="GMS">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="device_name" example="Chromebook">%2$s</xliff:g> to access your <xliff:g id="device_type" example="phone">%3$s</xliff:g>\u2019s photos, media, and notifications</string>
<!-- ================= DEVICE_PROFILE_NEARBY_DEVICE_STREAMING ================= -->
<!-- Confirmation for associating an application with a companion device of NEARBY_DEVICE_STREAMING profile (type) [CHAR LIMIT=NONE] -->
- <string name="title_nearby_device_streaming">Allow &lt;strong&gt;<xliff:g id="device_name" example="NearbyStreamer">%1$s</xliff:g>&lt;/strong&gt; to take this action?</string>
-
- <!-- Confirmation for associating an application with a companion device of NEARBY_DEVICE_STREAMING profile (type) with mirroring enabled [CHAR LIMIT=NONE] -->
- <string name="title_nearby_device_streaming_with_mirroring">Allow &lt;strong&gt;<xliff:g id="device_name" example="NearbyStreamer">%1$s</xliff:g>&lt;/strong&gt; to stream your phone\u2019s apps and system features?</string>
+ <string name="title_nearby_device_streaming">Allow &lt;strong&gt;<xliff:g id="device_name" example="NearbyStreamer">%1$s</xliff:g>&lt;/strong&gt; to stream your <xliff:g id="device_type" example="phone">%2$s</xliff:g>\u2019s apps and system features to &lt;strong&gt;<xliff:g id="device_name" example="Chromebook">%3$s</xliff:g>&lt;/strong&gt;?</string>
<!-- Summary for associating an application with a companion device of NEARBY_DEVICE_STREAMING profile [CHAR LIMIT=NONE] -->
- <string name="summary_nearby_device_streaming">%1$s will have access to anything that’s visible or played on your phone, including audio, photos, payment info, passwords, and messages.&lt;br/>&lt;br/>%1$s will be able to stream apps and system features until you remove access to this permission.</string>
+ <string name="summary_nearby_device_streaming"><xliff:g id="app_name" example="Exo">%1$s</xliff:g> will have access to anything that’s visible or played on your <xliff:g id="device_type" example="phone">%2$s</xliff:g>, including audio, photos, payment info, passwords, and messages.&lt;br/>&lt;br/><xliff:g id="app_name" example="Exo">%1$s</xliff:g> will be able to stream apps and system features to <xliff:g id="device_name" example="Chromebook">%3$s</xliff:g> until you remove access to this permission.</string>
<!-- Description of the helper dialog for NEARBY_DEVICE_STREAMING profile. [CHAR LIMIT=NONE] -->
- <string name="helper_summary_nearby_device_streaming"><xliff:g id="app_name" example="NearbyStreamerApp">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="device_name" example="NearbyDevice">%2$s</xliff:g> to stream apps and other system features to nearby devices</string>
+ <string name="helper_summary_nearby_device_streaming"><xliff:g id="app_name" example="NearbyStreamerApp">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="device_name" example="NearbyDevice">%2$s</xliff:g> to stream apps and other system features between your devices</string>
<!-- ================= null profile ================= -->
@@ -173,12 +158,6 @@
<!-- Notification permission will be granted of corresponding profile [CHAR LIMIT=30] -->
<string name="permission_notifications">Notifications</string>
- <!-- Apps permission will be granted of corresponding profile [CHAR LIMIT=30] -->
- <string name="permission_app_streaming">Apps</string>
-
- <!-- Nearby_device_streaming permission will be granted to the corresponding profile [CHAR LIMIT=45] -->
- <string name="permission_nearby_device_streaming">Streaming</string>
-
<!-- Description of phone permission of corresponding profile [CHAR LIMIT=NONE] -->
<string name="permission_phone_summary">Make and manage phone calls</string>
@@ -206,15 +185,9 @@
<!-- Description of NLA & POST_NOTIFICATION of corresponding profile [CHAR LIMIT=NONE] -->
<string name="permission_notifications_summary">\u2022 Read all notifications, including info like contacts, messages, and photos&lt;br/>\u2022 Send notifications&lt;br/>&lt;br/>You can manage this app\'s ability to read and send notifications anytime in Settings > Notifications.</string>
- <!-- Description of app streaming permission of corresponding profile [CHAR LIMIT=NONE] -->
- <string name="permission_app_streaming_summary">Stream your phone\u2019s apps</string>
-
<!-- Description of storage permission of corresponding profile [CHAR LIMIT=NONE] -->
<string name="permission_storage_summary"></string>
- <!-- Description of nearby_device_streaming permission of corresponding profile [CHAR LIMIT=NONE] -->
- <string name="permission_nearby_device_streaming_summary">Stream apps and other system features from your phone</string>
-
<!-- Description of change media output permission to be granted to the corresponding profile [CHAR LIMIT=NONE] -->
<string name="permission_media_routing_control_summary">Access a list of available devices and control which one streams or casts audio or video from other apps</string>
@@ -224,4 +197,10 @@
<!-- The type of the device for tablet [CHAR LIMIT=30] -->
<string name="device_type" product="tablet">tablet</string>
+ <!-- The type of the device for TV [CHAR LIMIT=30] -->
+ <string name="device_type" product="tv">tv</string>
+
+ <!-- The type of the device for other device [CHAR LIMIT=30] -->
+ <string name="device_type" product="device">device</string>
+
</resources>
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionAssociationActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionAssociationActivity.java
index e00533422072..61173306180e 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionAssociationActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionAssociationActivity.java
@@ -440,12 +440,13 @@ public class CompanionAssociationActivity extends FragmentActivity implements
return;
}
- title = getHtmlFromResources(this, PROFILE_TITLES.get(deviceProfile), deviceName);
+ title = getHtmlFromResources(this, PROFILE_TITLES.get(deviceProfile), mAppLabel,
+ getString(R.string.device_type), deviceName);
if (PROFILE_SUMMARIES.containsKey(deviceProfile)) {
final int summaryResourceId = PROFILE_SUMMARIES.get(deviceProfile);
final Spanned summary = getHtmlFromResources(this, summaryResourceId,
- deviceName);
+ mAppLabel, getString(R.string.device_type), deviceName);
mSummary.setText(summary);
} else {
mSummary.setVisibility(View.GONE);
@@ -646,6 +647,11 @@ public class CompanionAssociationActivity extends FragmentActivity implements
// and when mPermissionListRecyclerView is fully populated.
// Lastly, disable the Allow and Don't allow buttons.
private void setupPermissionList(String deviceProfile) {
+ if (!PROFILE_PERMISSIONS.containsKey(deviceProfile)) {
+ // Nothing to do if there are no permission types.
+ return;
+ }
+
final List<Integer> permissionTypes = new ArrayList<>(
PROFILE_PERMISSIONS.get(deviceProfile));
if (permissionTypes.isEmpty()) {
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceResources.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceResources.java
index dc68bccc8f0a..37b1f297f90b 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceResources.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceResources.java
@@ -27,13 +27,11 @@ import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
import static java.util.Collections.unmodifiableMap;
import static java.util.Collections.unmodifiableSet;
-import android.companion.virtual.flags.Flags;
import android.os.Build;
import android.util.ArrayMap;
import android.util.ArraySet;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -47,31 +45,27 @@ final class CompanionDeviceResources {
// Permission resources
private static final int PERMISSION_NOTIFICATION_LISTENER_ACCESS = 0;
private static final int PERMISSION_STORAGE = 1;
- private static final int PERMISSION_APP_STREAMING = 2;
- private static final int PERMISSION_PHONE = 3;
- private static final int PERMISSION_SMS = 4;
- private static final int PERMISSION_CONTACTS = 5;
- private static final int PERMISSION_CALENDAR = 6;
- private static final int PERMISSION_NEARBY_DEVICES = 7;
- private static final int PERMISSION_NEARBY_DEVICE_STREAMING = 8;
- private static final int PERMISSION_MICROPHONE = 9;
- private static final int PERMISSION_CALL_LOGS = 10;
+ private static final int PERMISSION_PHONE = 2;
+ private static final int PERMISSION_SMS = 3;
+ private static final int PERMISSION_CONTACTS = 4;
+ private static final int PERMISSION_CALENDAR = 5;
+ private static final int PERMISSION_NEARBY_DEVICES = 6;
+ private static final int PERMISSION_MICROPHONE = 7;
+ private static final int PERMISSION_CALL_LOGS = 8;
// Notification Listener Access & POST_NOTIFICATION permission
- private static final int PERMISSION_NOTIFICATIONS = 11;
- private static final int PERMISSION_CHANGE_MEDIA_OUTPUT = 12;
+ private static final int PERMISSION_NOTIFICATIONS = 9;
+ private static final int PERMISSION_CHANGE_MEDIA_OUTPUT = 10;
static final Map<Integer, Integer> PERMISSION_TITLES;
static {
final Map<Integer, Integer> map = new ArrayMap<>();
map.put(PERMISSION_NOTIFICATION_LISTENER_ACCESS, R.string.permission_notifications);
map.put(PERMISSION_STORAGE, R.string.permission_storage);
- map.put(PERMISSION_APP_STREAMING, R.string.permission_app_streaming);
map.put(PERMISSION_PHONE, R.string.permission_phone);
map.put(PERMISSION_SMS, R.string.permission_sms);
map.put(PERMISSION_CONTACTS, R.string.permission_contacts);
map.put(PERMISSION_CALENDAR, R.string.permission_calendar);
map.put(PERMISSION_NEARBY_DEVICES, R.string.permission_nearby_devices);
- map.put(PERMISSION_NEARBY_DEVICE_STREAMING, R.string.permission_nearby_device_streaming);
map.put(PERMISSION_MICROPHONE, R.string.permission_microphone);
map.put(PERMISSION_CALL_LOGS, R.string.permission_call_logs);
map.put(PERMISSION_NOTIFICATIONS, R.string.permission_notifications);
@@ -85,14 +79,11 @@ final class CompanionDeviceResources {
map.put(PERMISSION_NOTIFICATION_LISTENER_ACCESS,
R.string.permission_notification_listener_access_summary);
map.put(PERMISSION_STORAGE, R.string.permission_storage_summary);
- map.put(PERMISSION_APP_STREAMING, R.string.permission_app_streaming_summary);
map.put(PERMISSION_PHONE, R.string.permission_phone_summary);
map.put(PERMISSION_SMS, R.string.permission_sms_summary);
map.put(PERMISSION_CONTACTS, R.string.permission_contacts_summary);
map.put(PERMISSION_CALENDAR, R.string.permission_calendar_summary);
map.put(PERMISSION_NEARBY_DEVICES, R.string.permission_nearby_devices_summary);
- map.put(PERMISSION_NEARBY_DEVICE_STREAMING,
- R.string.permission_nearby_device_streaming_summary);
map.put(PERMISSION_MICROPHONE, R.string.permission_microphone_summary);
map.put(PERMISSION_CALL_LOGS, R.string.permission_call_logs_summary);
map.put(PERMISSION_NOTIFICATIONS, R.string.permission_notifications_summary);
@@ -105,14 +96,11 @@ final class CompanionDeviceResources {
final Map<Integer, Integer> map = new ArrayMap<>();
map.put(PERMISSION_NOTIFICATION_LISTENER_ACCESS, R.drawable.ic_permission_notifications);
map.put(PERMISSION_STORAGE, R.drawable.ic_permission_storage);
- map.put(PERMISSION_APP_STREAMING, R.drawable.ic_permission_app_streaming);
map.put(PERMISSION_PHONE, R.drawable.ic_permission_phone);
map.put(PERMISSION_SMS, R.drawable.ic_permission_sms);
map.put(PERMISSION_CONTACTS, R.drawable.ic_permission_contacts);
map.put(PERMISSION_CALENDAR, R.drawable.ic_permission_calendar);
map.put(PERMISSION_NEARBY_DEVICES, R.drawable.ic_permission_nearby_devices);
- map.put(PERMISSION_NEARBY_DEVICE_STREAMING,
- R.drawable.ic_permission_nearby_device_streaming);
map.put(PERMISSION_MICROPHONE, R.drawable.ic_permission_microphone);
map.put(PERMISSION_CALL_LOGS, R.drawable.ic_permission_call_logs);
map.put(PERMISSION_NOTIFICATIONS, R.drawable.ic_permission_notifications);
@@ -124,19 +112,10 @@ final class CompanionDeviceResources {
static final Map<String, Integer> PROFILE_TITLES;
static {
final Map<String, Integer> map = new ArrayMap<>();
- if (Flags.interactiveScreenMirror()) {
- map.put(DEVICE_PROFILE_APP_STREAMING, R.string.title_app_streaming_with_mirroring);
- } else {
- map.put(DEVICE_PROFILE_APP_STREAMING, R.string.title_app_streaming);
- }
+ map.put(DEVICE_PROFILE_APP_STREAMING, R.string.title_app_streaming);
map.put(DEVICE_PROFILE_AUTOMOTIVE_PROJECTION, R.string.title_automotive_projection);
map.put(DEVICE_PROFILE_COMPUTER, R.string.title_computer);
- if (Flags.interactiveScreenMirror()) {
- map.put(DEVICE_PROFILE_NEARBY_DEVICE_STREAMING,
- R.string.title_nearby_device_streaming_with_mirroring);
- } else {
- map.put(DEVICE_PROFILE_NEARBY_DEVICE_STREAMING, R.string.title_nearby_device_streaming);
- }
+ map.put(DEVICE_PROFILE_NEARBY_DEVICE_STREAMING, R.string.title_nearby_device_streaming);
map.put(DEVICE_PROFILE_WATCH, R.string.confirmation_title);
map.put(DEVICE_PROFILE_GLASSES, R.string.confirmation_title_glasses);
map.put(null, R.string.confirmation_title);
@@ -149,29 +128,29 @@ final class CompanionDeviceResources {
final Map<String, Integer> map = new ArrayMap<>();
map.put(DEVICE_PROFILE_WATCH, R.string.summary_watch);
map.put(DEVICE_PROFILE_GLASSES, R.string.summary_glasses);
- if (Flags.interactiveScreenMirror()) {
- map.put(DEVICE_PROFILE_APP_STREAMING, R.string.summary_app_streaming);
- map.put(DEVICE_PROFILE_NEARBY_DEVICE_STREAMING,
- R.string.summary_nearby_device_streaming);
- }
+ map.put(DEVICE_PROFILE_APP_STREAMING, R.string.summary_app_streaming);
+ map.put(DEVICE_PROFILE_NEARBY_DEVICE_STREAMING, R.string.summary_nearby_device_streaming);
map.put(null, R.string.summary_generic);
PROFILE_SUMMARIES = unmodifiableMap(map);
}
+ static final Map<String, Integer> PROFILE_HELPER_SUMMARIES;
+ static {
+ final Map<String, Integer> map = new ArrayMap<>();
+ map.put(DEVICE_PROFILE_APP_STREAMING, R.string.helper_summary_app_streaming);
+ map.put(DEVICE_PROFILE_NEARBY_DEVICE_STREAMING,
+ R.string.helper_summary_nearby_device_streaming);
+ map.put(DEVICE_PROFILE_COMPUTER, R.string.helper_summary_computer);
+
+ PROFILE_HELPER_SUMMARIES = unmodifiableMap(map);
+ }
+
static final Map<String, List<Integer>> PROFILE_PERMISSIONS;
static {
final Map<String, List<Integer>> map = new ArrayMap<>();
map.put(DEVICE_PROFILE_COMPUTER, Arrays.asList(
PERMISSION_NOTIFICATION_LISTENER_ACCESS, PERMISSION_STORAGE));
- if (Flags.interactiveScreenMirror()) {
- map.put(DEVICE_PROFILE_APP_STREAMING, Collections.emptyList());
- map.put(DEVICE_PROFILE_NEARBY_DEVICE_STREAMING, Collections.emptyList());
- } else {
- map.put(DEVICE_PROFILE_APP_STREAMING, Arrays.asList(PERMISSION_APP_STREAMING));
- map.put(DEVICE_PROFILE_NEARBY_DEVICE_STREAMING,
- Arrays.asList(PERMISSION_NEARBY_DEVICE_STREAMING));
- }
if (Build.VERSION.SDK_INT > UPSIDE_DOWN_CAKE) {
map.put(DEVICE_PROFILE_WATCH, Arrays.asList(PERMISSION_NOTIFICATIONS, PERMISSION_PHONE,
PERMISSION_CALL_LOGS, PERMISSION_SMS, PERMISSION_CONTACTS, PERMISSION_CALENDAR,
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionVendorHelperDialogFragment.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionVendorHelperDialogFragment.java
index fe0e021b363c..ec92987e7e87 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionVendorHelperDialogFragment.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionVendorHelperDialogFragment.java
@@ -16,17 +16,13 @@
package com.android.companiondevicemanager;
-import static android.companion.AssociationRequest.DEVICE_PROFILE_APP_STREAMING;
-import static android.companion.AssociationRequest.DEVICE_PROFILE_COMPUTER;
-import static android.companion.AssociationRequest.DEVICE_PROFILE_NEARBY_DEVICE_STREAMING;
-
+import static com.android.companiondevicemanager.CompanionDeviceResources.PROFILE_HELPER_SUMMARIES;
import static com.android.companiondevicemanager.Utils.getApplicationIcon;
import static com.android.companiondevicemanager.Utils.getApplicationLabel;
import static com.android.companiondevicemanager.Utils.getHtmlFromResources;
import android.annotation.Nullable;
import android.companion.AssociationRequest;
-import android.companion.virtual.flags.Flags;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
@@ -105,7 +101,7 @@ public class CompanionVendorHelperDialogFragment extends DialogFragment {
final String deviceProfile = request.getDeviceProfile();
final String packageName = request.getPackageName();
- final CharSequence displayName = request.getDisplayName();
+ final CharSequence deviceName = request.getDisplayName();
final int userId = request.getUserId();
final CharSequence appLabel;
@@ -123,37 +119,17 @@ public class CompanionVendorHelperDialogFragment extends DialogFragment {
mAppIcon = view.findViewById(R.id.app_icon);
mButton = view.findViewById(R.id.btn_back);
- final CharSequence title;
- final Spanned summary;
-
- switch (deviceProfile) {
- case DEVICE_PROFILE_APP_STREAMING:
- title = getHtmlFromResources(getContext(), R.string.helper_title_app_streaming);
- summary = getHtmlFromResources(
- getContext(), Flags.interactiveScreenMirror()
- ? R.string.helper_summary_app_streaming_with_mirroring
- : R.string.helper_summary_app_streaming, title, displayName);
- break;
-
- case DEVICE_PROFILE_COMPUTER:
- title = getHtmlFromResources(getContext(), R.string.helper_title_computer);
- summary = getHtmlFromResources(
- getContext(), R.string.helper_summary_computer, title, displayName);
- break;
-
- case DEVICE_PROFILE_NEARBY_DEVICE_STREAMING:
- title = appLabel;
- summary = getHtmlFromResources(
- getContext(), R.string.helper_summary_nearby_device_streaming, title,
- displayName);
- break;
-
- default:
- throw new RuntimeException("Unsupported profile " + deviceProfile);
+ if (PROFILE_HELPER_SUMMARIES.containsKey(deviceProfile)) {
+ final int summaryResourceId = PROFILE_HELPER_SUMMARIES.get(deviceProfile);
+ final Spanned summary = getHtmlFromResources(
+ getContext(), summaryResourceId, appLabel, deviceName,
+ getString(R.string.device_type));
+ mSummary.setText(summary);
+ } else {
+ throw new RuntimeException("Unsupported profile " + deviceProfile);
}
- mTitle.setText(title);
- mSummary.setText(summary);
+ mTitle.setText(appLabel);
mAppIcon.setImageDrawable(applicationIcon);
mButton.setOnClickListener(v -> {
diff --git a/packages/CredentialManager/wear/robotests/src/com/android/credentialmanager/CredentialSelectorUiStateGetMapperTest.kt b/packages/CredentialManager/wear/robotests/src/com/android/credentialmanager/CredentialSelectorUiStateGetMapperTest.kt
index c6013e2ffae6..ef4416e9841a 100644
--- a/packages/CredentialManager/wear/robotests/src/com/android/credentialmanager/CredentialSelectorUiStateGetMapperTest.kt
+++ b/packages/CredentialManager/wear/robotests/src/com/android/credentialmanager/CredentialSelectorUiStateGetMapperTest.kt
@@ -30,7 +30,7 @@ import com.android.credentialmanager.model.CredentialType
import com.google.common.truth.Truth.assertThat
import com.android.credentialmanager.ui.mappers.toGet
import com.android.credentialmanager.model.get.ProviderInfo
-import com.android.credentialmanager.CredentialSelectorUiState.Get.MultipleEntry.PerUserNameEntries
+import com.android.credentialmanager.CredentialSelectorUiState.Get.MultipleEntry.PerNameEntries
/** Unit tests for [CredentialSelectorUiStateGetMapper]. */
@SmallTest
@@ -108,7 +108,7 @@ class CredentialSelectorUiStateGetMapperTest {
}
@Test
- fun `On primary screen, multiple accounts returns SingleEntryPerAccount`() {
+ fun `On primary screen, multiple accounts returns MultipleEntryPrimaryScreen`() {
val getCredentialUiState = Request.Get(
token = null,
resultReceiver = null,
@@ -135,7 +135,7 @@ class CredentialSelectorUiStateGetMapperTest {
assertThat(getCredentialUiState).isEqualTo(
CredentialSelectorUiState.Get.MultipleEntry(
- listOf(PerUserNameEntries("userName", listOf(
+ listOf(PerNameEntries("userName", listOf(
passkeyCredentialEntryInfo,
passwordCredentialEntryInfo))
),
@@ -155,7 +155,7 @@ class CredentialSelectorUiStateGetMapperTest {
assertThat(getCredentialUiState).isEqualTo(
CredentialSelectorUiState.Get.MultipleEntry(
listOf(
- PerUserNameEntries("userName",
+ PerNameEntries("userName",
listOf(
recentlyUsedPasskeyCredential, // from provider 2
passkeyCredentialEntryInfo, // from provider 1 or 2
@@ -164,7 +164,7 @@ class CredentialSelectorUiStateGetMapperTest {
passwordCredentialEntryInfo, // from provider 1 or 2
passwordCredentialEntryInfo, // from provider 1 or 2
)),
- PerUserNameEntries("userName2", listOf(unknownCredentialEntryInfo)),
+ PerNameEntries("userName2", listOf(unknownCredentialEntryInfo)),
),
listOf(actionEntryInfo, actionEntryInfo),
listOf(authenticationEntryInfo, authenticationEntryInfo)
@@ -172,8 +172,44 @@ class CredentialSelectorUiStateGetMapperTest {
)
}
+ @Test
+ fun `Returned multiple entry is grouped by display name if present`() {
+ val testCred1 = createCredentialEntryInfo(displayName = "testDisplayName",
+ userName = "testUserName", credentialType = CredentialType.PASSWORD)
+ val testCred2 = createCredentialEntryInfo(displayName = "testDisplayName",
+ userName = "testUserName", credentialType = CredentialType.PASSKEY)
+ val getCredentialUiState = Request.Get(
+ token = null,
+ resultReceiver = null,
+ providerInfos = listOf(createProviderInfo(credentialList1),
+ createProviderInfo(credentialList2),
+ createProviderInfo(listOf(testCred1, testCred2))))
+ .toGet(isPrimary = false)
+
+ assertThat(getCredentialUiState).isEqualTo(
+ CredentialSelectorUiState.Get.MultipleEntry(
+ listOf(
+ PerNameEntries("userName",
+ listOf(
+ recentlyUsedPasskeyCredential, // from provider 2
+ passkeyCredentialEntryInfo, // from provider 1 or 2
+ passkeyCredentialEntryInfo, // from provider 1 or 2
+ recentlyUsedPasswordCredential, // from provider 2
+ passwordCredentialEntryInfo, // from provider 1 or 2
+ passwordCredentialEntryInfo, // from provider 1 or 2
+ )),
+ PerNameEntries("userName2", listOf(unknownCredentialEntryInfo)),
+ PerNameEntries("testDisplayName", listOf(testCred2, testCred1)),
+ ),
+ listOf(actionEntryInfo, actionEntryInfo, actionEntryInfo),
+ listOf(authenticationEntryInfo, authenticationEntryInfo, authenticationEntryInfo)
+ )
+ )
+ }
+
fun createCredentialEntryInfo(
userName: String,
+ displayName: String? = null,
credentialType: CredentialType = CredentialType.PASSKEY,
lastUsedTimeMillis: Long = 0L
): CredentialEntryInfo =
@@ -188,7 +224,7 @@ class CredentialSelectorUiStateGetMapperTest {
credentialTypeDisplayName = "",
providerDisplayName = "",
userName = userName,
- displayName = "",
+ displayName = displayName,
icon = mDrawable,
shouldTintIcon = false,
lastUsedTimeMillis = Instant.ofEpochMilli(lastUsedTimeMillis),
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/FlowEngine.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/FlowEngine.kt
index b2f55c108317..2f5ec72a20a8 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/FlowEngine.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/FlowEngine.kt
@@ -81,12 +81,12 @@ sealed class CredentialSelectorUiState {
) : Get()
/** Getting credential UI state on secondary screen when there are multiple accounts available. */
data class MultipleEntry(
- val accounts: List<PerUserNameEntries>,
+ val accounts: List<PerNameEntries>,
val actionEntryList: List<ActionEntryInfo>,
val authenticationEntryList: List<AuthenticationEntryInfo>,
) : Get() {
- data class PerUserNameEntries(
- val userName: String,
+ data class PerNameEntries(
+ val name: String,
val sortedCredentialEntryList: List<CredentialEntryInfo>,
)
}
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt
index 265627520cf7..7dfe742e4b5f 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt
@@ -19,15 +19,18 @@ package com.android.credentialmanager.ui.mappers
import android.graphics.drawable.Drawable
import com.android.credentialmanager.model.Request
import com.android.credentialmanager.CredentialSelectorUiState
-import com.android.credentialmanager.CredentialSelectorUiState.Get.MultipleEntry.PerUserNameEntries
+import com.android.credentialmanager.CredentialSelectorUiState.Get.MultipleEntry.PerNameEntries
import com.android.credentialmanager.model.CredentialType
import com.android.credentialmanager.model.get.CredentialEntryInfo
import java.time.Instant
fun Request.Get.toGet(isPrimary: Boolean): CredentialSelectorUiState.Get {
+
val accounts = providerInfos
.flatMap { it.credentialEntryList }
- .groupBy { it.userName}
+ .groupBy {
+ if (it.displayName.isNullOrBlank()) it.userName else checkNotNull(it.displayName)
+ }
.entries
.toList()
@@ -56,7 +59,7 @@ fun Request.Get.toGet(isPrimary: Boolean): CredentialSelectorUiState.Get {
}
} else {
CredentialSelectorUiState.Get.MultipleEntry(
- accounts = accounts.map { PerUserNameEntries(
+ accounts = accounts.map { PerNameEntries(
it.key,
it.value.sortedWith(comparator)
)
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFlattenScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFlattenScreen.kt
index 2af5be844af5..ef32c944d650 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFlattenScreen.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFlattenScreen.kt
@@ -79,7 +79,7 @@ fun MultiCredentialsFlattenScreen(
Row {
Spacer(Modifier.weight(0.0624f)) // 6.24% side margin
WearSecondaryLabel(
- text = userNameEntries.userName,
+ text = userNameEntries.name,
modifier = Modifier.padding(
top = 12.dp,
bottom = 4.dp,
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/signInWithProvider/SignInWithProviderScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/signInWithProvider/SignInWithProviderScreen.kt
index fd0fc8cce16c..14cc9bf25348 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/signInWithProvider/SignInWithProviderScreen.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/signInWithProvider/SignInWithProviderScreen.kt
@@ -55,15 +55,15 @@ fun SignInWithProviderScreen(
},
accountContent = {
val displayName = entry.displayName
- if (displayName == null ||
+ if (displayName.isNullOrBlank() ||
entry.displayName.equals(entry.userName, ignoreCase = true)) {
AccountRow(
primaryText = entry.userName,
)
} else {
AccountRow(
- primaryText = displayName,
- secondaryText = entry.userName,
+ primaryText = entry.userName,
+ secondaryText = displayName,
)
}
},
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 5c4cdb271a2f..687c72878bdb 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -881,6 +881,11 @@
<!-- UI debug setting: show physical key presses summary [CHAR LIMIT=150] -->
<string name="show_key_presses_summary">Show visual feedback for physical key presses</string>
+ <!-- UI debug setting: Title text for a debug setting that enables a visualization of touchpad input in a window on the screen [CHAR LIMIT=50] -->
+ <string name="touchpad_visualizer">Show touchpad input</string>
+ <!-- UI debug setting: Summary text for a debug setting that enables a visualization of touchpad input in a window on the screen [CHAR LIMIT=150] -->
+ <string name="touchpad_visualizer_summary">Screen overlay displaying touchpad input data and recognized gestures</string>
+
<!-- UI debug setting: show where surface updates happen? [CHAR LIMIT=25] -->
<string name="show_screen_updates">Show surface updates</string>
<!-- UI debug setting: show surface updates summary [CHAR LIMIT=50] -->
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
index 7b927d793c37..282327739fc6 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
@@ -200,6 +200,7 @@ public class SystemSettingsValidators {
VALIDATORS.put(System.POINTER_LOCATION, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.SHOW_TOUCHES, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.SHOW_KEY_PRESSES, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.TOUCHPAD_VISUALIZER, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.SHOW_ROTARY_INPUT, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.WINDOW_ORIENTATION_LISTENER_LOG, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.LOCKSCREEN_SOUNDS_ENABLED, BOOLEAN_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index cd37ad171fac..3c24f5c56603 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2831,6 +2831,9 @@ class SettingsProtoDumpUtil {
Settings.System.SHOW_KEY_PRESSES,
SystemSettingsProto.DevOptions.SHOW_KEY_PRESSES);
dumpSetting(s, p,
+ Settings.System.TOUCHPAD_VISUALIZER,
+ SystemSettingsProto.DevOptions.TOUCHPAD_VISUALIZER);
+ dumpSetting(s, p,
Settings.System.POINTER_LOCATION,
SystemSettingsProto.DevOptions.POINTER_LOCATION);
dumpSetting(s, p,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index e8ef620d6c0c..ba59ce81d362 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -3264,6 +3264,24 @@ public class SettingsProvider extends ContentProvider {
if (forceNotify || success) {
notifyForSettingsChange(key, name);
+
+ // If this is an aconfig flag, it will be written as a staged flag.
+ // Notify that its staged flag value will be updated.
+ if (Flags.notifyIndividualAconfigSyspropChanged() && type == SETTINGS_TYPE_CONFIG) {
+ int slashIndex = name.indexOf('/');
+ boolean validSlashIndex = slashIndex != -1
+ && slashIndex != 0
+ && slashIndex != name.length();
+ if (validSlashIndex) {
+ String namespace = name.substring(0, slashIndex);
+ String flagName = name.substring(slashIndex + 1);
+ if (settingsState.getAconfigDefaultFlags().containsKey(flagName)) {
+ String stagedName = "staged/" + namespace + "*" + flagName;
+ notifyForSettingsChange(key, stagedName);
+ }
+ }
+ }
+
if (wasUnsetNonPredefinedSetting) {
// Increment the generation number for all non-predefined, unset settings,
// because a new non-predefined setting has been inserted
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig b/packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig
index 4f5955b1c6ca..f53dec6dc713 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig
+++ b/packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig
@@ -52,3 +52,14 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "notify_individual_aconfig_sysprop_changed"
+ namespace: "core_experiments_team_internal"
+ description: "When enabled, propagate individual aconfig sys props on flag stage."
+ bug: "331963764"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 411decd8476a..8c9648437b17 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -918,6 +918,7 @@ public class SettingsBackupTest {
Settings.System.SHOW_GTALK_SERVICE_STATUS, // candidate for backup?
Settings.System.SHOW_TOUCHES,
Settings.System.SHOW_KEY_PRESSES,
+ Settings.System.TOUCHPAD_VISUALIZER,
Settings.System.SHOW_ROTARY_INPUT,
Settings.System.SIP_ADDRESS_ONLY, // value, not a setting
Settings.System.SIP_ALWAYS, // value, not a setting
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index cfd8f63590ea..c2e8c374bf5f 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -576,6 +576,7 @@ android_library {
"TraceurCommon",
"Traceur-res",
"//frameworks/libs/systemui:motion_tool_lib",
+ "//frameworks/libs/systemui:contextualeducationlib",
"notification_flags_lib",
"PlatformComposeCore",
"PlatformComposeSceneTransitionLayout",
@@ -736,6 +737,7 @@ android_library {
"WindowManager-Shell",
"LowLightDreamLib",
"//frameworks/libs/systemui:motion_tool_lib",
+ "//frameworks/libs/systemui:contextualeducationlib",
"androidx.core_core-animation-testing",
"androidx.compose.ui_ui",
"flag-junit",
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/Android.bp b/packages/SystemUI/accessibility/accessibilitymenu/Android.bp
index d674b6c96320..c881e07e554e 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/Android.bp
+++ b/packages/SystemUI/accessibility/accessibilitymenu/Android.bp
@@ -37,6 +37,7 @@ android_app {
"androidx.core_core",
"androidx.preference_preference",
"androidx.viewpager_viewpager",
+ "com_android_systemui_flags_lib",
"SettingsLibDisplayUtils",
"SettingsLibSettingsTheme",
"com_android_a11y_menu_flags_lib",
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/AndroidManifest.xml b/packages/SystemUI/accessibility/accessibilitymenu/AndroidManifest.xml
index a98625f0137c..a7b91c2b2f6a 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/AndroidManifest.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/AndroidManifest.xml
@@ -18,6 +18,7 @@
package="com.android.systemui.accessibility.accessibilitymenu">
<uses-permission android:name="android.permission.CONTROL_DISPLAY_BRIGHTNESS"/>
+ <uses-permission android:name="android.permission.MANAGE_USERS"/>
<application android:supportsRtl="true">
<service
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig b/packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig
index c1e43c9abb33..6d790114803a 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig
+++ b/packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig
@@ -29,3 +29,13 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "hide_restricted_actions"
+ namespace: "accessibility"
+ description: "Hides shortcut buttons for possibly restricted actions like brightness/volume adjustment"
+ bug: "347269196"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
index 7b43b72ee757..2e036e651d4e 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
@@ -16,6 +16,8 @@
package com.android.systemui.accessibility.accessibilitymenu.view;
+import static android.os.UserManager.DISALLOW_ADJUST_VOLUME;
+import static android.os.UserManager.DISALLOW_CONFIG_BRIGHTNESS;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.View.ACCESSIBILITY_LIVE_REGION_POLITE;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
@@ -24,6 +26,7 @@ import static java.lang.Math.max;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Insets;
@@ -32,6 +35,8 @@ import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.os.Handler;
import android.os.Looper;
+import android.os.UserHandle;
+import android.os.UserManager;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -48,6 +53,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService;
+import com.android.systemui.accessibility.accessibilitymenu.Flags;
import com.android.systemui.accessibility.accessibilitymenu.R;
import com.android.systemui.accessibility.accessibilitymenu.activity.A11yMenuSettingsActivity.A11yMenuPreferenceFragment;
import com.android.systemui.accessibility.accessibilitymenu.model.A11yMenuShortcut;
@@ -94,8 +100,6 @@ public class A11yMenuOverlayLayout {
A11yMenuShortcut.ShortcutId.ID_SCREENSHOT_VALUE.ordinal()
};
-
-
private final AccessibilityMenuService mService;
private final WindowManager mWindowManager;
private final DisplayManager mDisplayManager;
@@ -195,11 +199,43 @@ public class A11yMenuOverlayLayout {
for (int shortcutId :
(A11yMenuPreferenceFragment.isLargeButtonsEnabled(mService)
? LARGE_SHORTCUT_LIST_DEFAULT : SHORTCUT_LIST_DEFAULT)) {
- shortcutList.add(new A11yMenuShortcut(shortcutId));
+ if (!isShortcutRestricted(shortcutId)) {
+ shortcutList.add(new A11yMenuShortcut(shortcutId));
+ }
}
return shortcutList;
}
+ @SuppressLint("MissingPermission")
+ private boolean isShortcutRestricted(int shortcutId) {
+ if (!Flags.hideRestrictedActions()) {
+ return false;
+ }
+ final UserManager userManager = mService.getSystemService(UserManager.class);
+ if (userManager == null) {
+ return false;
+ }
+ final int userId = mService.getUserId();
+ final UserHandle userHandle = UserHandle.of(userId);
+ if (shortcutId == A11yMenuShortcut.ShortcutId.ID_BRIGHTNESS_DOWN_VALUE.ordinal()
+ || shortcutId == A11yMenuShortcut.ShortcutId.ID_BRIGHTNESS_UP_VALUE.ordinal()) {
+ if (userManager.hasUserRestriction(DISALLOW_CONFIG_BRIGHTNESS)
+ || (com.android.systemui.Flags.enforceBrightnessBaseUserRestriction()
+ && userManager.hasBaseUserRestriction(
+ DISALLOW_CONFIG_BRIGHTNESS, userHandle))) {
+ return true;
+ }
+ }
+ if (shortcutId == A11yMenuShortcut.ShortcutId.ID_VOLUME_DOWN_VALUE.ordinal()
+ || shortcutId == A11yMenuShortcut.ShortcutId.ID_VOLUME_UP_VALUE.ordinal()) {
+ if (userManager.hasUserRestriction(DISALLOW_ADJUST_VOLUME)
+ || userManager.hasBaseUserRestriction(DISALLOW_ADJUST_VOLUME, userHandle)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/** Updates a11y menu layout position by configuring layout params. */
private void updateLayoutPosition() {
final Display display = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
@@ -326,8 +362,7 @@ public class A11yMenuOverlayLayout {
return;
}
snackbar.setText(text);
- if (com.android.systemui.accessibility.accessibilitymenu
- .Flags.a11yMenuSnackbarLiveRegion()) {
+ if (Flags.a11yMenuSnackbarLiveRegion()) {
snackbar.setAccessibilityLiveRegion(ACCESSIBILITY_LIVE_REGION_POLITE);
}
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp b/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp
index 395354ef8f20..9d5a2e0dba4b 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp
+++ b/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp
@@ -31,6 +31,7 @@ android_test {
"androidx.test.core",
"androidx.test.runner",
"androidx.test.ext.junit",
+ "com_android_a11y_menu_flags_lib",
"compatibility-device-util-axt",
"platform-test-annotations",
"truth",
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/tests/AndroidManifest.xml b/packages/SystemUI/accessibility/accessibilitymenu/tests/AndroidManifest.xml
index 2be92450f207..40f71c53f53b 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/tests/AndroidManifest.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/tests/AndroidManifest.xml
@@ -20,6 +20,7 @@
<!-- Needed to write to Settings.Secure to enable and disable the service under test. -->
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<uses-permission android:name="android.permission.CONTROL_DISPLAY_BRIGHTNESS"/>
+ <uses-permission android:name="android.permission.MANAGE_USERS"/>
<application android:debuggable="true">
<uses-library android:name="android.test.runner" />
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java b/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java
index 991ce12df2e5..d16617fdc8e5 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java
@@ -45,6 +45,10 @@ import android.hardware.display.BrightnessInfo;
import android.hardware.display.DisplayManager;
import android.media.AudioManager;
import android.os.PowerManager;
+import android.os.UserManager;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.platform.uiautomator_helpers.WaitUtils;
import android.provider.Settings;
import android.util.Log;
@@ -59,6 +63,7 @@ import androidx.test.uiautomator.Configurator;
import androidx.test.uiautomator.UiDevice;
import com.android.compatibility.common.util.TestUtils;
+import com.android.systemui.accessibility.accessibilitymenu.Flags;
import com.android.systemui.accessibility.accessibilitymenu.model.A11yMenuShortcut.ShortcutId;
import org.junit.After;
@@ -66,6 +71,7 @@ import org.junit.AfterClass;
import org.junit.Assume;
import org.junit.Before;
import org.junit.BeforeClass;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -76,6 +82,9 @@ import java.util.concurrent.atomic.AtomicInteger;
@RunWith(AndroidJUnit4.class)
public class AccessibilityMenuServiceTest {
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
private static final String TAG = "A11yMenuServiceTest";
private static final int CLICK_ID = AccessibilityNodeInfo.ACTION_CLICK;
@@ -121,26 +130,8 @@ public class AccessibilityMenuServiceTest {
sDisplayManager = context.getSystemService(DisplayManager.class);
unlockSignal();
- // Disable all a11yServices if any are active.
- if (!sAccessibilityManager.getEnabledAccessibilityServiceList(
- AccessibilityServiceInfo.FEEDBACK_ALL_MASK).isEmpty()) {
- Settings.Secure.putString(context.getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "");
- TestUtils.waitUntil("Failed to disable all services",
- TIMEOUT_SERVICE_STATUS_CHANGE_S,
- () -> sAccessibilityManager.getEnabledAccessibilityServiceList(
- AccessibilityServiceInfo.FEEDBACK_ALL_MASK).isEmpty());
- }
-
- // Enable a11yMenu service.
- Settings.Secure.putString(context.getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, SERVICE_NAME);
+ enableA11yMenuService(context);
- TestUtils.waitUntil("Failed to enable service",
- TIMEOUT_SERVICE_STATUS_CHANGE_S,
- () -> sAccessibilityManager.getEnabledAccessibilityServiceList(
- AccessibilityServiceInfo.FEEDBACK_ALL_MASK).stream().filter(
- info -> info.getId().contains(SERVICE_NAME)).count() == 1);
context.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -184,6 +175,29 @@ public class AccessibilityMenuServiceTest {
sUiDevice.pressHome();
}
+ private static void enableA11yMenuService(Context context) throws Throwable {
+ // Disable all a11yServices if any are active.
+ if (!sAccessibilityManager.getEnabledAccessibilityServiceList(
+ AccessibilityServiceInfo.FEEDBACK_ALL_MASK).isEmpty()) {
+ Settings.Secure.putString(context.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "");
+ TestUtils.waitUntil("Failed to disable all services",
+ TIMEOUT_SERVICE_STATUS_CHANGE_S,
+ () -> sAccessibilityManager.getEnabledAccessibilityServiceList(
+ AccessibilityServiceInfo.FEEDBACK_ALL_MASK).isEmpty());
+ }
+
+ // Enable a11yMenu service.
+ Settings.Secure.putString(context.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, SERVICE_NAME);
+
+ TestUtils.waitUntil("Failed to enable service",
+ TIMEOUT_SERVICE_STATUS_CHANGE_S,
+ () -> sAccessibilityManager.getEnabledAccessibilityServiceList(
+ AccessibilityServiceInfo.FEEDBACK_ALL_MASK).stream().filter(
+ info -> info.getId().contains(SERVICE_NAME)).count() == 1);
+ }
+
private static boolean isMenuVisible() {
sUiDevice.waitForIdle();
AccessibilityNodeInfo root = sUiAutomation.getRootInActiveWindow();
@@ -484,6 +498,54 @@ public class AccessibilityMenuServiceTest {
sOpenBlocked::get);
}
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_HIDE_RESTRICTED_ACTIONS)
+ public void testRestrictedActions_BrightnessNotAvailable() throws Throwable {
+ try {
+ setUserRestriction(UserManager.DISALLOW_CONFIG_BRIGHTNESS, true);
+ openMenu();
+
+ List<AccessibilityNodeInfo> buttons = getGridButtonList();
+ AccessibilityNodeInfo brightnessUpButton = findGridButtonInfo(buttons,
+ String.valueOf(ShortcutId.ID_BRIGHTNESS_UP_VALUE.ordinal()));
+ AccessibilityNodeInfo brightnessDownButton = findGridButtonInfo(buttons,
+ String.valueOf(ShortcutId.ID_BRIGHTNESS_DOWN_VALUE.ordinal()));
+
+ assertThat(brightnessUpButton).isNull();
+ assertThat(brightnessDownButton).isNull();
+ } finally {
+ setUserRestriction(UserManager.DISALLOW_CONFIG_BRIGHTNESS, false);
+ }
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_HIDE_RESTRICTED_ACTIONS)
+ public void testRestrictedActions_VolumeNotAvailable() throws Throwable {
+ try {
+ setUserRestriction(UserManager.DISALLOW_ADJUST_VOLUME, true);
+ openMenu();
+
+ List<AccessibilityNodeInfo> buttons = getGridButtonList();
+ AccessibilityNodeInfo volumeUpButton = findGridButtonInfo(buttons,
+ String.valueOf(ShortcutId.ID_VOLUME_UP_VALUE.ordinal()));
+ AccessibilityNodeInfo volumeDownButton = findGridButtonInfo(buttons,
+ String.valueOf(ShortcutId.ID_VOLUME_DOWN_VALUE.ordinal()));
+
+ assertThat(volumeUpButton).isNull();
+ assertThat(volumeDownButton).isNull();
+ } finally {
+ setUserRestriction(UserManager.DISALLOW_ADJUST_VOLUME, false);
+ }
+ }
+
+ private void setUserRestriction(String restriction, boolean isRestricted) throws Throwable {
+ final Context context = sInstrumentation.getTargetContext();
+ final UserManager userManager = context.getSystemService(UserManager.class);
+ userManager.setUserRestriction(restriction, isRestricted);
+ // Re-enable the service for the restriction to take effect.
+ enableA11yMenuService(context);
+ }
+
private static void unlockSignal() throws IOException {
// go/adb-cheats#unlock-screen
wakeUpScreen();
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 0cbaf29773d2..23c6098e1114 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -227,17 +227,6 @@ flag {
}
flag {
- name: "notification_group_hun_removal_animation_fix"
- namespace: "systemui"
- description: "Fix the lack of hun removal animation for group notifications"
- "(not GROUP_ALERT_SUMMARY)"
- bug: "343475993"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
name: "scene_container"
namespace: "systemui"
description: "Enables the scene container framework go/flexiglass."
@@ -363,17 +352,6 @@ flag {
}
flag {
- name: "truncated_status_bar_icons_fix"
- namespace: "systemui"
- description: "Fixes the status bar icons being trunacted due to the status bar window height "
- "not being updated after certain rotations"
- bug: "323299264"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
name: "status_bar_monochrome_icons_fix"
namespace: "systemui"
description: "Fixes the status bar icon size when drawing InsetDrawables (ie. monochrome icons)"
@@ -403,6 +381,13 @@ flag {
}
flag {
+ name: "status_bar_call_chip_notification_icon"
+ namespace: "systemui"
+ description: "Use the small icon set on the notification for the status bar call chip"
+ bug: "354930838"
+}
+
+flag {
name: "compose_bouncer"
namespace: "systemui"
description: "Use the new compose bouncer in SystemUI"
@@ -582,16 +567,6 @@ flag {
}
flag {
- name: "screenshot_private_profile_accessibility_announcement_fix"
- namespace: "systemui"
- description: "Modified a11y announcement for private space screenshots"
- bug: "326941376"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
name: "screenshot_private_profile_behavior_fix"
namespace: "systemui"
description: "Private profile support for screenshots"
@@ -1073,16 +1048,6 @@ flag {
}
flag {
- namespace: "systemui"
- name: "privacy_dot_unfold_wrong_corner_fix"
- description: "Fixes an issue where the privacy dot is at the wrong corner after unfolding/folding."
- bug: "339335643"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
name: "validate_keyboard_shortcut_helper_icon_uri"
namespace: "systemui"
description: "Adds a check that the caller can access the content URI of an icon in the shortcut helper."
@@ -1301,3 +1266,20 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "compose_haptic_sliders"
+ namespace: "systemui"
+ description: "Adding haptic component infrastructure to sliders in Compose."
+ bug: "341968766"
+}
+
+flag {
+ namespace: "systemui"
+ name: "settings_ext_register_content_observer_on_bg_thread"
+ description: "Register content observer in callback flow APIs on background thread in SettingsProxyExt."
+ bug: "355389014"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
index d4bad23a1ee9..872bef256f3a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
@@ -27,7 +27,7 @@ import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.semantics.clearAndSetSemantics
-import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.disabled
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -243,7 +243,7 @@ private fun SceneScope.CommunalScene(
if (isFocusable) {
Modifier.focusable()
} else {
- Modifier.semantics { contentDescription = "" }.clearAndSetSemantics {}
+ Modifier.semantics { disabled() }.clearAndSetSemantics {}
}
)
) {
@@ -259,7 +259,7 @@ private fun SceneScope.CommunalScene(
modifier =
modifier.focusable(isFocusable).semantics {
if (!isFocusable) {
- contentDescription = ""
+ disabled()
}
}
)
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Key.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Key.kt
index 3cd5553bc963..acb436e4874b 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Key.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Key.kt
@@ -107,6 +107,7 @@ class MovableElementKey(
* The [StaticElementContentPicker] to use when deciding in which scene we should draw shared
* Elements or compose MovableElements.
*
+ * @see DefaultElementContentPicker
* @see MovableElementContentPicker
*/
override val contentPicker: StaticElementContentPicker,
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt
index fe16ef75118b..0105af3377fd 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt
@@ -127,7 +127,16 @@ private class PredictiveBackTransition(
return coroutineScope
.launch(start = CoroutineStart.ATOMIC) {
try {
- animatable.animateTo(targetProgress)
+ if (currentScene == toScene) {
+ animatable.animateTo(targetProgress, transformationSpec.progressSpec)
+ } else {
+ // If the back gesture is cancelled, the progress is animated back to 0f by
+ // the system. But we need this animate call anyways because
+ // PredictiveBackHandler doesn't guarantee that it ends at 0f. Since the
+ // remaining change in progress is usually very small, the progressSpec is
+ // omitted and the default spring spec used instead.
+ animatable.animateTo(targetProgress)
+ }
} finally {
state.finishTransition(this@PredictiveBackTransition, scene)
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt
index 38b83835ad29..a30b78049213 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt
@@ -305,6 +305,11 @@ interface ElementContentPicker {
* An element picker on which we can query the set of contents (scenes or overlays) that contain the
* element. This is needed by [MovableElement], that needs to know at composition time on which of
* the candidate contents an element should be composed.
+ *
+ * @see DefaultElementContentPicker(contents)
+ * @see HighestZIndexContentPicker(contents)
+ * @see LowestZIndexContentPicker(contents)
+ * @see MovableElementContentPicker
*/
interface StaticElementContentPicker : ElementContentPicker {
/** The exhaustive lists of contents that contain this element. */
@@ -434,6 +439,11 @@ class MovableElementContentPicker(
/** The default [ElementContentPicker]. */
val DefaultElementContentPicker = HighestZIndexContentPicker
+/** The [DefaultElementContentPicker] that can be used for [MovableElement]s. */
+fun DefaultElementContentPicker(contents: Set<ContentKey>): StaticElementContentPicker {
+ return HighestZIndexContentPicker(contents)
+}
+
@TransitionDsl
interface PropertyTransformationBuilder {
/**
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/PredictiveBackHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/PredictiveBackHandlerTest.kt
index 0eaecb09e97e..c414fbe1c2db 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/PredictiveBackHandlerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/PredictiveBackHandlerTest.kt
@@ -18,6 +18,8 @@ package com.android.compose.animation.scene
import androidx.activity.BackEventCompat
import androidx.activity.ComponentActivity
+import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.rememberCoroutineScope
@@ -59,7 +61,23 @@ class PredictiveBackHandlerTest {
@Test
fun testPredictiveBack() {
- val layoutState = rule.runOnUiThread { MutableSceneTransitionLayoutState(SceneA) }
+ val transitionFrames = 2
+ val layoutState =
+ rule.runOnUiThread {
+ MutableSceneTransitionLayoutState(
+ SceneA,
+ transitions =
+ transitions {
+ from(SceneA, to = SceneB) {
+ spec =
+ tween(
+ durationMillis = transitionFrames * 16,
+ easing = LinearEasing
+ )
+ }
+ }
+ )
+ }
rule.setContent {
SceneTransitionLayout(layoutState) {
scene(SceneA, mapOf(Back to SceneB)) { Box(Modifier.fillMaxSize()) }
@@ -88,12 +106,27 @@ class PredictiveBackHandlerTest {
assertThat(layoutState.transitionState).hasCurrentScene(SceneA)
assertThat(layoutState.transitionState).isIdle()
+ rule.mainClock.autoAdvance = false
+
// Start again and commit it.
rule.runOnUiThread {
dispatcher.dispatchOnBackStarted(backEvent())
dispatcher.dispatchOnBackProgressed(backEvent(progress = 0.4f))
dispatcher.onBackPressed()
}
+ rule.mainClock.advanceTimeByFrame()
+ rule.waitForIdle()
+ val transition2 = assertThat(layoutState.transitionState).isTransition()
+ // verify that transition picks up progress from preview
+ assertThat(transition2).hasProgress(0.4f, tolerance = 0.0001f)
+
+ rule.mainClock.advanceTimeByFrame()
+ rule.waitForIdle()
+ // verify that transition is half way between preview-end-state (0.4f) and target-state (1f)
+ // after one frame
+ assertThat(transition2).hasProgress(0.7f, tolerance = 0.0001f)
+
+ rule.mainClock.autoAdvance = true
rule.waitForIdle()
assertThat(layoutState.transitionState).hasCurrentScene(SceneB)
assertThat(layoutState.transitionState).isIdle()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
index 7a41bc6da176..12552489496d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
@@ -99,7 +99,9 @@ import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
import org.mockito.kotlin.spy
+import org.mockito.kotlin.times
import org.mockito.kotlin.whenever
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
import platform.test.runner.parameterized.Parameters
@@ -741,6 +743,18 @@ class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
}
@Test
+ fun communalContent_readTriggersUmoVisibilityUpdate() =
+ testScope.runTest {
+ verify(mediaHost, never()).updateViewVisibility()
+
+ val communalContent by collectLastValue(underTest.communalContent)
+
+ // updateViewVisibility is called when the flow is collected.
+ assertThat(communalContent).isNotNull()
+ verify(mediaHost).updateViewVisibility()
+ }
+
+ @Test
fun scrollPosition_persistedOnEditEntry() {
val index = 2
val offset = 30
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt
index 86c680a0b101..023de52b2460 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt
@@ -82,7 +82,7 @@ class WidgetInteractionHandlerTest : SysuiTestCase() {
assertFalse(launching!!)
val parent = FrameLayout(context)
- val view = CommunalAppWidgetHostView(context)
+ val view = CommunalAppWidgetHostView(context, underTest)
parent.addView(view)
val (fillInIntent, activityOptions) = testResponse.getLaunchOptions(view)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt
index 3a4b14b81e07..331db525c4ee 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt
@@ -22,10 +22,10 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.SysuiTestableContext
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.contextualeducation.GestureType.BACK
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
-import com.android.systemui.shared.education.GestureType.BACK_GESTURE
import com.google.common.truth.Truth.assertThat
import java.io.File
import java.time.Clock
@@ -70,8 +70,8 @@ class ContextualEducationRepositoryTest : SysuiTestCase() {
fun changeRetrievedValueForNewUser() =
testScope.runTest {
// Update data for old user.
- underTest.incrementSignalCount(BACK_GESTURE)
- val model by collectLastValue(underTest.readGestureEduModelFlow(BACK_GESTURE))
+ underTest.incrementSignalCount(BACK)
+ val model by collectLastValue(underTest.readGestureEduModelFlow(BACK))
assertThat(model?.signalCount).isEqualTo(1)
// User is changed.
@@ -83,17 +83,17 @@ class ContextualEducationRepositoryTest : SysuiTestCase() {
@Test
fun incrementSignalCount() =
testScope.runTest {
- underTest.incrementSignalCount(BACK_GESTURE)
- val model by collectLastValue(underTest.readGestureEduModelFlow(BACK_GESTURE))
+ underTest.incrementSignalCount(BACK)
+ val model by collectLastValue(underTest.readGestureEduModelFlow(BACK))
assertThat(model?.signalCount).isEqualTo(1)
}
@Test
fun dataAddedOnUpdateShortcutTriggerTime() =
testScope.runTest {
- val model by collectLastValue(underTest.readGestureEduModelFlow(BACK_GESTURE))
+ val model by collectLastValue(underTest.readGestureEduModelFlow(BACK))
assertThat(model?.lastShortcutTriggeredTime).isNull()
- underTest.updateShortcutTriggerTime(BACK_GESTURE)
+ underTest.updateShortcutTriggerTime(BACK)
assertThat(model?.lastShortcutTriggeredTime).isEqualTo(clock.instant())
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
index 01dbc6bf396c..ae3302ca658d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
@@ -20,10 +20,10 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.contextualeducation.GestureType
+import com.android.systemui.contextualeducation.GestureType.BACK
import com.android.systemui.education.data.repository.contextualEducationRepository
import com.android.systemui.kosmos.testScope
-import com.android.systemui.shared.education.GestureType
-import com.android.systemui.shared.education.GestureType.BACK_GESTURE
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
@@ -47,15 +47,15 @@ class KeyboardTouchpadEduInteractorTest : SysuiTestCase() {
@Test
fun newEducationInfoOnMaxSignalCountReached() =
testScope.runTest {
- tryTriggeringEducation(BACK_GESTURE)
+ tryTriggeringEducation(BACK)
val model by collectLastValue(underTest.educationTriggered)
- assertThat(model?.gestureType).isEqualTo(BACK_GESTURE)
+ assertThat(model?.gestureType).isEqualTo(BACK)
}
@Test
fun noEducationInfoBeforeMaxSignalCountReached() =
testScope.runTest {
- repository.incrementSignalCount(BACK_GESTURE)
+ repository.incrementSignalCount(BACK)
val model by collectLastValue(underTest.educationTriggered)
assertThat(model).isNull()
}
@@ -64,8 +64,8 @@ class KeyboardTouchpadEduInteractorTest : SysuiTestCase() {
fun noEducationInfoWhenShortcutTriggeredPreviously() =
testScope.runTest {
val model by collectLastValue(underTest.educationTriggered)
- repository.updateShortcutTriggerTime(BACK_GESTURE)
- tryTriggeringEducation(BACK_GESTURE)
+ repository.updateShortcutTriggerTime(BACK)
+ tryTriggeringEducation(BACK)
assertThat(model).isNull()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadStatsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadStatsInteractorTest.kt
index ee51e37faba7..cd0c58feebed 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadStatsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadStatsInteractorTest.kt
@@ -20,10 +20,10 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.contextualeducation.GestureType.BACK
import com.android.systemui.education.data.repository.contextualEducationRepository
import com.android.systemui.education.data.repository.fakeEduClock
import com.android.systemui.kosmos.testScope
-import com.android.systemui.shared.education.GestureType.BACK_GESTURE
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
@@ -41,11 +41,9 @@ class KeyboardTouchpadStatsInteractorTest : SysuiTestCase() {
fun dataUpdatedOnIncrementSignalCount() =
testScope.runTest {
val model by
- collectLastValue(
- kosmos.contextualEducationRepository.readGestureEduModelFlow(BACK_GESTURE)
- )
+ collectLastValue(kosmos.contextualEducationRepository.readGestureEduModelFlow(BACK))
val originalValue = model!!.signalCount
- underTest.incrementSignalCount(BACK_GESTURE)
+ underTest.incrementSignalCount(BACK)
assertThat(model?.signalCount).isEqualTo(originalValue + 1)
}
@@ -53,11 +51,9 @@ class KeyboardTouchpadStatsInteractorTest : SysuiTestCase() {
fun dataAddedOnUpdateShortcutTriggerTime() =
testScope.runTest {
val model by
- collectLastValue(
- kosmos.contextualEducationRepository.readGestureEduModelFlow(BACK_GESTURE)
- )
+ collectLastValue(kosmos.contextualEducationRepository.readGestureEduModelFlow(BACK))
assertThat(model?.lastShortcutTriggeredTime).isNull()
- underTest.updateShortcutTriggerTime(BACK_GESTURE)
+ underTest.updateShortcutTriggerTime(BACK)
assertThat(model?.lastShortcutTriggeredTime).isEqualTo(kosmos.fakeEduClock.instant())
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
index a8eccc5add1a..03647b9a3956 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
@@ -136,30 +136,6 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
}
@Test
- fun finishedKeyguardTransitionStepTests() =
- testScope.runTest {
- val finishedSteps by collectValues(underTest.finishedKeyguardTransitionStep)
- val steps = mutableListOf<TransitionStep>()
-
- steps.add(TransitionStep(LOCKSCREEN, AOD, 0f, STARTED))
- steps.add(TransitionStep(LOCKSCREEN, AOD, 0.9f, RUNNING))
- steps.add(TransitionStep(LOCKSCREEN, AOD, 1f, FINISHED))
- steps.add(TransitionStep(AOD, LOCKSCREEN, 0f, STARTED))
- steps.add(TransitionStep(AOD, LOCKSCREEN, 0.5f, RUNNING))
- steps.add(TransitionStep(AOD, LOCKSCREEN, 1f, FINISHED))
- steps.add(TransitionStep(AOD, GONE, 1f, STARTED))
-
- steps.forEach {
- repository.sendTransitionStep(it)
- runCurrent()
- }
-
- // Ignore the default state.
- assertThat(finishedSteps.subList(1, finishedSteps.size))
- .isEqualTo(listOf(steps[2], steps[5]))
- }
-
- @Test
fun startedKeyguardTransitionStepTests() =
testScope.runTest {
val startedSteps by collectValues(underTest.startedKeyguardTransitionStep)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
index 194f362d984c..6dbe94bf19c4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
@@ -19,11 +19,13 @@
package com.android.systemui.keyguard.ui.viewmodel
+import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.FlagsParameterization
import android.view.View
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
-import com.android.systemui.Flags as AConfigFlags
+import com.android.systemui.Flags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR
+import com.android.systemui.Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT
import com.android.systemui.Flags.FLAG_NEW_AOD_TRANSITION
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.data.repository.communalSceneRepository
@@ -68,6 +70,11 @@ import platform.test.runner.parameterized.Parameters
@SmallTest
@RunWith(ParameterizedAndroidJunit4::class)
+@EnableFlags(
+ FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT,
+ FLAG_NEW_AOD_TRANSITION,
+ FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR
+)
class KeyguardRootViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
private val kosmos = testKosmos()
private val testScope = kosmos.testScope
@@ -102,13 +109,6 @@ class KeyguardRootViewModelTest(flags: FlagsParameterization) : SysuiTestCase()
@Before
fun setUp() {
- mSetFlagsRule.enableFlags(FLAG_NEW_AOD_TRANSITION)
- if (!SceneContainerFlag.isEnabled) {
- mSetFlagsRule.enableFlags(AConfigFlags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR)
- mSetFlagsRule.disableFlags(
- AConfigFlags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT,
- )
- }
kosmos.sceneContainerRepository.setTransitionState(transitionState)
}
@@ -212,6 +212,11 @@ class KeyguardRootViewModelTest(flags: FlagsParameterization) : SysuiTestCase()
testScope.runTest {
val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
runCurrent()
+ keyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.DOZING,
+ testScope,
+ )
notificationsKeyguardInteractor.setPulseExpanding(false)
deviceEntryRepository.setBypassEnabled(false)
whenever(dozeParameters.alwaysOn).thenReturn(false)
@@ -227,6 +232,11 @@ class KeyguardRootViewModelTest(flags: FlagsParameterization) : SysuiTestCase()
testScope.runTest {
val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
runCurrent()
+ keyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.DOZING,
+ testScope,
+ )
notificationsKeyguardInteractor.setPulseExpanding(false)
deviceEntryRepository.setBypassEnabled(false)
whenever(dozeParameters.alwaysOn).thenReturn(true)
@@ -243,6 +253,11 @@ class KeyguardRootViewModelTest(flags: FlagsParameterization) : SysuiTestCase()
testScope.runTest {
val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
runCurrent()
+ keyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.DOZING,
+ testScope,
+ )
notificationsKeyguardInteractor.setPulseExpanding(false)
deviceEntryRepository.setBypassEnabled(false)
whenever(dozeParameters.alwaysOn).thenReturn(true)
@@ -255,6 +270,27 @@ class KeyguardRootViewModelTest(flags: FlagsParameterization) : SysuiTestCase()
}
@Test
+ fun iconContainer_isNotVisible_bypassDisabled_onLockscreen() =
+ testScope.runTest {
+ val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
+ runCurrent()
+ keyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.AOD,
+ to = KeyguardState.LOCKSCREEN,
+ testScope,
+ )
+ notificationsKeyguardInteractor.setPulseExpanding(false)
+ deviceEntryRepository.setBypassEnabled(false)
+ whenever(dozeParameters.alwaysOn).thenReturn(true)
+ whenever(dozeParameters.displayNeedsBlanking).thenReturn(false)
+ notificationsKeyguardInteractor.setNotificationsFullyHidden(true)
+ runCurrent()
+
+ assertThat(isVisible?.value).isFalse()
+ assertThat(isVisible?.isAnimating).isTrue()
+ }
+
+ @Test
fun isIconContainerVisible_stopAnimation() =
testScope.runTest {
val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/lifecycle/ActivatableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/lifecycle/ActivatableTest.kt
new file mode 100644
index 000000000000..67517a25ec87
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/lifecycle/ActivatableTest.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2024 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.lifecycle
+
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ActivatableTest : SysuiTestCase() {
+
+ @get:Rule val composeRule = createComposeRule()
+
+ @Test
+ fun rememberActivated() {
+ val keepAliveMutable = mutableStateOf(true)
+ var isActive = false
+ composeRule.setContent {
+ val keepAlive by keepAliveMutable
+ if (keepAlive) {
+ rememberActivated {
+ FakeActivatable(
+ onActivation = { isActive = true },
+ onDeactivation = { isActive = false },
+ )
+ }
+ }
+ }
+ assertThat(isActive).isTrue()
+ }
+
+ @Test
+ fun rememberActivated_leavingTheComposition() {
+ val keepAliveMutable = mutableStateOf(true)
+ var isActive = false
+ composeRule.setContent {
+ val keepAlive by keepAliveMutable
+ if (keepAlive) {
+ rememberActivated {
+ FakeActivatable(
+ onActivation = { isActive = true },
+ onDeactivation = { isActive = false },
+ )
+ }
+ }
+ }
+
+ // Tear down the composable.
+ composeRule.runOnUiThread { keepAliveMutable.value = false }
+ composeRule.waitForIdle()
+
+ assertThat(isActive).isFalse()
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/lifecycle/SafeActivatableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/lifecycle/SafeActivatableTest.kt
new file mode 100644
index 000000000000..9484821eb7e4
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/lifecycle/SafeActivatableTest.kt
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.lifecycle
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SafeActivatableTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+
+ private val underTest = FakeActivatable()
+
+ @Test
+ fun activate() =
+ testScope.runTest {
+ assertThat(underTest.isActive).isFalse()
+ assertThat(underTest.activationCount).isEqualTo(0)
+ assertThat(underTest.cancellationCount).isEqualTo(0)
+
+ underTest.activateIn(testScope)
+ runCurrent()
+ assertThat(underTest.isActive).isTrue()
+ assertThat(underTest.activationCount).isEqualTo(1)
+ assertThat(underTest.cancellationCount).isEqualTo(0)
+ }
+
+ @Test
+ fun activate_andCancel() =
+ testScope.runTest {
+ assertThat(underTest.isActive).isFalse()
+ assertThat(underTest.activationCount).isEqualTo(0)
+ assertThat(underTest.cancellationCount).isEqualTo(0)
+
+ val job = Job()
+ underTest.activateIn(testScope, context = job)
+ runCurrent()
+ assertThat(underTest.isActive).isTrue()
+ assertThat(underTest.activationCount).isEqualTo(1)
+ assertThat(underTest.cancellationCount).isEqualTo(0)
+
+ job.cancel()
+ runCurrent()
+ assertThat(underTest.isActive).isFalse()
+ assertThat(underTest.activationCount).isEqualTo(1)
+ assertThat(underTest.cancellationCount).isEqualTo(1)
+ }
+
+ @Test
+ fun activate_afterCancellation() =
+ testScope.runTest {
+ assertThat(underTest.isActive).isFalse()
+ assertThat(underTest.activationCount).isEqualTo(0)
+ assertThat(underTest.cancellationCount).isEqualTo(0)
+
+ val job = Job()
+ underTest.activateIn(testScope, context = job)
+ runCurrent()
+ assertThat(underTest.isActive).isTrue()
+ assertThat(underTest.activationCount).isEqualTo(1)
+ assertThat(underTest.cancellationCount).isEqualTo(0)
+
+ job.cancel()
+ runCurrent()
+ assertThat(underTest.isActive).isFalse()
+ assertThat(underTest.activationCount).isEqualTo(1)
+ assertThat(underTest.cancellationCount).isEqualTo(1)
+
+ underTest.activateIn(testScope)
+ runCurrent()
+ assertThat(underTest.isActive).isTrue()
+ assertThat(underTest.activationCount).isEqualTo(2)
+ assertThat(underTest.cancellationCount).isEqualTo(1)
+ }
+
+ @Test(expected = IllegalStateException::class)
+ fun activate_whileActive_throws() =
+ testScope.runTest {
+ assertThat(underTest.isActive).isFalse()
+ assertThat(underTest.activationCount).isEqualTo(0)
+ assertThat(underTest.cancellationCount).isEqualTo(0)
+
+ underTest.activateIn(testScope)
+ runCurrent()
+ assertThat(underTest.isActive).isTrue()
+ assertThat(underTest.activationCount).isEqualTo(1)
+ assertThat(underTest.cancellationCount).isEqualTo(0)
+
+ underTest.activateIn(testScope)
+ runCurrent()
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/lifecycle/SysUiViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/lifecycle/SysUiViewModelTest.kt
new file mode 100644
index 000000000000..d1f908dfc795
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/lifecycle/SysUiViewModelTest.kt
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2024 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.lifecycle
+
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SysUiViewModelTest : SysuiTestCase() {
+
+ @get:Rule val composeRule = createComposeRule()
+
+ @Test
+ fun rememberActivated() {
+ val keepAliveMutable = mutableStateOf(true)
+ var isActive = false
+ composeRule.setContent {
+ val keepAlive by keepAliveMutable
+ if (keepAlive) {
+ rememberViewModel {
+ FakeSysUiViewModel(
+ onActivation = { isActive = true },
+ onDeactivation = { isActive = false },
+ )
+ }
+ }
+ }
+ assertThat(isActive).isTrue()
+ }
+
+ @Test
+ fun rememberActivated_withKey() {
+ val keyMutable = mutableStateOf(1)
+ var isActive1 = false
+ var isActive2 = false
+ composeRule.setContent {
+ val key by keyMutable
+ rememberViewModel(key) {
+ when (key) {
+ 1 ->
+ FakeSysUiViewModel(
+ onActivation = { isActive1 = true },
+ onDeactivation = { isActive1 = false },
+ )
+ 2 ->
+ FakeSysUiViewModel(
+ onActivation = { isActive2 = true },
+ onDeactivation = { isActive2 = false },
+ )
+ else -> error("unsupported key $key")
+ }
+ }
+ }
+ assertThat(isActive1).isTrue()
+ assertThat(isActive2).isFalse()
+
+ composeRule.runOnUiThread { keyMutable.value = 2 }
+ composeRule.waitForIdle()
+ assertThat(isActive1).isFalse()
+ assertThat(isActive2).isTrue()
+
+ composeRule.runOnUiThread { keyMutable.value = 1 }
+ composeRule.waitForIdle()
+ assertThat(isActive1).isTrue()
+ assertThat(isActive2).isFalse()
+ }
+
+ @Test
+ fun rememberActivated_leavingTheComposition() {
+ val keepAliveMutable = mutableStateOf(true)
+ var isActive = false
+ composeRule.setContent {
+ val keepAlive by keepAliveMutable
+ if (keepAlive) {
+ rememberViewModel {
+ FakeSysUiViewModel(
+ onActivation = { isActive = true },
+ onDeactivation = { isActive = false },
+ )
+ }
+ }
+ }
+
+ // Tear down the composable.
+ composeRule.runOnUiThread { keepAliveMutable.value = false }
+ composeRule.waitForIdle()
+
+ assertThat(isActive).isFalse()
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorSceneContainerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorSceneContainerImplTest.kt
index aef9163a65ab..b917014d4798 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorSceneContainerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorSceneContainerImplTest.kt
@@ -124,4 +124,36 @@ class ShadeAnimationInteractorSceneContainerImplTest : SysuiTestCase() {
underTest.setIsLaunchingActivity(true)
Truth.assertThat(underTest.isLaunchingActivity.value).isEqualTo(true)
}
+
+ @Test
+ fun isAnyFlingAnimationRunning() =
+ testScope.runTest() {
+ val actual by collectLastValue(underTest.isAnyFlingAnimationRunning)
+
+ // WHEN transitioning from QS to Gone with user input ongoing
+ val userInputOngoing = MutableStateFlow(true)
+ val transitionState =
+ MutableStateFlow<ObservableTransitionState>(
+ ObservableTransitionState.Transition(
+ fromScene = Scenes.QuickSettings,
+ toScene = Scenes.Gone,
+ currentScene = flowOf(Scenes.QuickSettings),
+ progress = MutableStateFlow(.1f),
+ isInitiatedByUserInput = true,
+ isUserInputOngoing = userInputOngoing,
+ )
+ )
+ sceneInteractor.setTransitionState(transitionState)
+ runCurrent()
+
+ // THEN qs is not flinging
+ Truth.assertThat(actual).isFalse()
+
+ // WHEN user input ends
+ userInputOngoing.value = false
+ runCurrent()
+
+ // THEN qs is flinging
+ Truth.assertThat(actual).isTrue()
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
index 343b6bd3472c..3b2c9819c9b7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
@@ -25,7 +25,6 @@ import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.SwipeDirection
import com.android.systemui.SysuiTestCase
-import com.android.systemui.activatable.activateIn
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
@@ -37,6 +36,7 @@ import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintA
import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.kosmos.testScope
+import com.android.systemui.lifecycle.activateIn
import com.android.systemui.media.controls.data.repository.mediaFilterRepository
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.qs.ui.adapter.fakeQSSceneAdapter
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/PrivacyDotViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/PrivacyDotViewControllerTest.kt
index f12643280c26..663c3418b144 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/PrivacyDotViewControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/PrivacyDotViewControllerTest.kt
@@ -18,8 +18,6 @@ package com.android.systemui.statusbar.events
import android.graphics.Point
import android.graphics.Rect
-import android.platform.test.annotations.DisableFlags
-import android.platform.test.annotations.EnableFlags
import android.testing.TestableLooper.RunWithLooper
import android.view.Display
import android.view.DisplayAdjustments
@@ -28,7 +26,6 @@ import android.widget.FrameLayout
import android.widget.FrameLayout.LayoutParams.UNSPECIFIED_GRAVITY
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.res.R
import com.android.systemui.statusbar.FakeStatusBarStateController
@@ -297,8 +294,7 @@ class PrivacyDotViewControllerTest : SysuiTestCase() {
}
@Test
- @EnableFlags(Flags.FLAG_PRIVACY_DOT_UNFOLD_WRONG_CORNER_FIX)
- fun initialize_newViews_fixFlagEnabled_gravityIsUpdated() {
+ fun initialize_newViews_gravityIsUpdated() {
val newTopLeftView = initDotView()
val newTopRightView = initDotView()
val newBottomLeftView = initDotView()
@@ -318,28 +314,6 @@ class PrivacyDotViewControllerTest : SysuiTestCase() {
.isNotEqualTo(UNSPECIFIED_GRAVITY)
}
- @Test
- @DisableFlags(Flags.FLAG_PRIVACY_DOT_UNFOLD_WRONG_CORNER_FIX)
- fun initialize_newViews_fixFlagDisabled_gravityIsNotUpdated() {
- val newTopLeftView = initDotView()
- val newTopRightView = initDotView()
- val newBottomLeftView = initDotView()
- val newBottomRightView = initDotView()
- setRotation(ROTATION_LANDSCAPE) // Bottom right used in landscape
-
- val controller = createAndInitializeController()
- // Re-init with different views, but same rotation
- controller.initialize(
- newTopLeftView,
- newTopRightView,
- newBottomLeftView,
- newBottomRightView
- )
-
- assertThat((newBottomRightView.layoutParams as FrameLayout.LayoutParams).gravity)
- .isEqualTo(UNSPECIFIED_GRAVITY)
- }
-
private fun setRotation(rotation: Int) {
whenever(mockDisplay.rotation).thenReturn(rotation)
}
@@ -347,7 +321,7 @@ class PrivacyDotViewControllerTest : SysuiTestCase() {
private fun initDotView(): View {
val privacyDot = View(context).also { it.id = R.id.privacy_dot }
return FrameLayout(context).also {
- it.layoutParams = FrameLayout.LayoutParams(/* width = */ 0, /* height = */ 0)
+ it.layoutParams = FrameLayout.LayoutParams(/* width= */ 0, /* height= */ 0)
it.addView(privacyDot)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/SettingsProxyExtTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/SettingsProxyExtTest.kt
new file mode 100644
index 000000000000..e281894a93ab
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/SettingsProxyExtTest.kt
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.util.settings
+
+import android.database.ContentObserver
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.Flags
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+
+/** Tests for [SettingsProxyExt]. */
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
+class SettingsProxyExtTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+ @Mock lateinit var settingsProxy: SettingsProxy
+ @Mock lateinit var userSettingsProxy: UserSettingsProxy
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_SETTINGS_EXT_REGISTER_CONTENT_OBSERVER_ON_BG_THREAD)
+ fun observeFlow_bgFlagEnabled_settingsProxy_registerContentObserverInvoked() =
+ testScope.runTest {
+ val unused by collectLastValue(settingsProxy.observerFlow(SETTING_1, SETTING_2))
+ runCurrent()
+ verify(settingsProxy, times(2))
+ .registerContentObserver(any<String>(), any<ContentObserver>())
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_SETTINGS_EXT_REGISTER_CONTENT_OBSERVER_ON_BG_THREAD)
+ fun observeFlow_bgFlagDisabled_multipleSettings_SettingsProxy_registerContentObserverInvoked() =
+ testScope.runTest {
+ val unused by collectLastValue(settingsProxy.observerFlow(SETTING_1, SETTING_2))
+ runCurrent()
+ verify(settingsProxy, times(2))
+ .registerContentObserverSync(any<String>(), any<ContentObserver>())
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_SETTINGS_EXT_REGISTER_CONTENT_OBSERVER_ON_BG_THREAD)
+ fun observeFlow_bgFlagEnabled_channelClosed_settingsProxy_unregisterContentObserverInvoked() =
+ testScope.runTest {
+ val job = Job()
+ val unused by
+ collectLastValue(settingsProxy.observerFlow(SETTING_1, SETTING_2), context = job)
+ runCurrent()
+ job.cancel()
+ runCurrent()
+ verify(settingsProxy).unregisterContentObserverAsync(any<ContentObserver>())
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_SETTINGS_EXT_REGISTER_CONTENT_OBSERVER_ON_BG_THREAD)
+ fun observeFlow_bgFlagDisabled_channelClosed_settingsProxy_unregisterContentObserverInvoked() =
+ testScope.runTest {
+ val job = Job()
+ val unused by
+ collectLastValue(settingsProxy.observerFlow(SETTING_1, SETTING_2), context = job)
+ runCurrent()
+ job.cancel()
+ runCurrent()
+ verify(settingsProxy).unregisterContentObserverSync(any<ContentObserver>())
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_SETTINGS_EXT_REGISTER_CONTENT_OBSERVER_ON_BG_THREAD)
+ fun observeFlow_bgFlagEnabled_userSettingsProxy_registerContentObserverForUserInvoked() =
+ testScope.runTest {
+ val unused by
+ collectLastValue(userSettingsProxy.observerFlow(userId = 0, SETTING_1, SETTING_2))
+ runCurrent()
+ verify(userSettingsProxy, times(2))
+ .registerContentObserverForUser(any<String>(), any<ContentObserver>(), any<Int>())
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_SETTINGS_EXT_REGISTER_CONTENT_OBSERVER_ON_BG_THREAD)
+ fun observeFlow_bgFlagDisabled_userSettingsProxy_registerContentObserverForUserInvoked() =
+ testScope.runTest {
+ val unused by
+ collectLastValue(userSettingsProxy.observerFlow(userId = 0, SETTING_1, SETTING_2))
+ runCurrent()
+ verify(userSettingsProxy, times(2))
+ .registerContentObserverForUserSync(
+ any<String>(),
+ any<ContentObserver>(),
+ any<Int>()
+ )
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_SETTINGS_EXT_REGISTER_CONTENT_OBSERVER_ON_BG_THREAD)
+ fun observeFlow_bgFlagEnabled_channelClosed_userSettingsProxy_unregisterContentObserverInvoked() =
+ testScope.runTest {
+ val job = Job()
+ val unused by
+ collectLastValue(
+ userSettingsProxy.observerFlow(userId = 0, SETTING_1, SETTING_2),
+ context = job
+ )
+ runCurrent()
+ job.cancel()
+ runCurrent()
+ verify(userSettingsProxy).unregisterContentObserverAsync(any<ContentObserver>())
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_SETTINGS_EXT_REGISTER_CONTENT_OBSERVER_ON_BG_THREAD)
+ fun observeFlow_bgFlagDisabled_channelClosed_userSettingsProxy_unregisterContentObserverInvoked() =
+ testScope.runTest {
+ val job = Job()
+ val unused by
+ collectLastValue(
+ userSettingsProxy.observerFlow(userId = 0, SETTING_1, SETTING_2),
+ context = job
+ )
+ runCurrent()
+ job.cancel()
+ runCurrent()
+ verify(userSettingsProxy).unregisterContentObserverSync(any<ContentObserver>())
+ }
+
+ private companion object {
+ val SETTING_1 = "settings_1"
+ val SETTING_2 = "settings_2"
+ }
+}
diff --git a/packages/SystemUI/res/drawable/ic_redacted_notification_single_line_icon.xml b/packages/SystemUI/res/drawable/ic_redacted_notification_single_line_icon.xml
new file mode 100644
index 000000000000..8146c16e4aaf
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_redacted_notification_single_line_icon.xml
@@ -0,0 +1,27 @@
+<!--
+ ~ 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.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="32dp"
+ android:height="32dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="?android:attr/colorAccent"
+ android:pathData="M12,15m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"/>
+ <path
+ android:fillColor="?android:attr/colorAccent"
+ android:pathData="M18,8h-1.5V5.5C16.5,3.01 14.49,1 12,1S7.5,3.01 7.5,5.5V8H6c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V10C20,8.9 19.1,8 18,8zM9.5,5.5C9.5,4.12 10.62,3 12,3c1.38,0 2.5,1.12 2.5,2.5V8h-5V5.5zM18,20H6V10h1.5h9H18V20z"/>
+</vector>
diff --git a/packages/SystemUI/res/raw/biometricprompt_fingerprint_to_error_landscape.json b/packages/SystemUI/res/raw/biometricprompt_fingerprint_to_error_landscape.json
deleted file mode 100644
index 3d33b2afeaf1..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_fingerprint_to_error_landscape.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.9.0","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"BiometricPrompt_Symbol_Fingerprint_To_Error_Landscape","ddd":0,"assets":[{"id":"comp_0","nm":"Fingerprint_Animation_ForConfirm_Short","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"circle fill 5","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":249,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":388,"s":[100]},{"t":408,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":239,"op":1411,"st":239,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"t":249,"s":[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":239,"op":1139,"st":239,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".green400","cl":"green400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":249,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":388,"s":[100]},{"t":408,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.450980392157,0.709803921569,0.470588235294,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":239,"op":1411,"st":239,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"circle fill 3","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":80,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":90,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.8,"y":0},"t":108,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"t":118,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,35.389],[-0.111,50.111]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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.049,42.698],"ix":2},"a":{"a":0,"k":[0.049,42.698],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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 2","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":80,"op":980,"st":80,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".red400","cl":"red400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":7,"ty":3,"nm":"Null 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.833,"y":0.833},"o":{"x":0.333,"y":0.333},"t":85,"s":[209.333,136.333,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":440,"s":[209.333,136.333,0],"to":[1.944,2.278,0],"ti":[3.056,-2.278,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":450,"s":[221,150,0],"to":[-3.056,2.278,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":460,"s":[191,150,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":470,"s":[221,150,0],"to":[0,0,0],"ti":[2.5,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":480,"s":[191,150,0],"to":[-2.5,0,0],"ti":[-2.5,0,0]},{"t":490,"s":[206,150,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Fingerprint_Animation_ForConfirm_Short","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[170,77.667,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,0],"ix":1,"l":2},"s":{"a":0,"k":[30,30,100],"ix":6,"l":2}},"ao":0,"w":412,"h":300,"ip":0,"op":830,"st":-70,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_folded_base_bottomright.json b/packages/SystemUI/res/raw/biometricprompt_folded_base_bottomright.json
deleted file mode 100644
index 2797996c6ef2..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_folded_base_bottomright.json
+++ /dev/null
@@ -1 +0,0 @@
-{"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
deleted file mode 100644
index bf65b3418b61..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_folded_base_default.json
+++ /dev/null
@@ -1 +0,0 @@
-{"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
deleted file mode 100644
index 7351d7c38a39..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_folded_base_topleft.json
+++ /dev/null
@@ -1 +0,0 @@
-{"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/raw/biometricprompt_landscape_base.json b/packages/SystemUI/res/raw/biometricprompt_landscape_base.json
deleted file mode 100644
index 3781eeee231f..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_landscape_base.json
+++ /dev/null
@@ -1 +0,0 @@
-{"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}]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_portrait_base_bottomright.json b/packages/SystemUI/res/raw/biometricprompt_portrait_base_bottomright.json
deleted file mode 100644
index 495066638cf4..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_portrait_base_bottomright.json
+++ /dev/null
@@ -1 +0,0 @@
-{"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}]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_portrait_base_topleft.json b/packages/SystemUI/res/raw/biometricprompt_portrait_base_topleft.json
deleted file mode 100644
index 09ed22560885..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_portrait_base_topleft.json
+++ /dev/null
@@ -1 +0,0 @@
-{"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}]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_rear_landscape_base.json b/packages/SystemUI/res/raw/biometricprompt_rear_landscape_base.json
deleted file mode 100644
index 49c1c40f7f4f..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_rear_landscape_base.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.8.1","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"BiometricPrompt_Rear_Landscape_Base_Foldable","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 18","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[169.478,169.749,0],"ix":2,"l":2},"a":{"a":0,"k":[-48.123,-30.19,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".grey400","cl":"grey400","parent":13,"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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,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":[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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"black circle matte","parent":13,"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,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":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey904","cl":"grey904","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,35.536,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],[-2.552,0.087],[0,0]],"o":[[0,0],[0,-3.287],[0,0],[0,0]],"v":[[-2.301,8.869],[-2.301,-3.772],[2.301,-9.806],[2.301,9.806]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"black circle matte 2","parent":13,"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,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":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".blue401","cl":"blue401","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,-27.655,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,3.286],[0,0],[-2.552,0.086],[0,0]],"o":[[0,0],[0,-3.286],[0,0],[-2.552,-0.086]],"v":[[-2.301,16.282],[-2.301,-16.281],[2.301,-22.313],[2.301,22.313]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"black circle matte 3","parent":13,"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,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":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Finger 2","parent":1,"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":-129,"s":[-67]},{"t":-29,"s":[0]}],"ix":10},"p":{"a":0,"k":[-75.352,41.307,0],"ix":2,"l":2},"a":{"a":0,"k":[94.648,211.307,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.72,-5.642],[0,0],[-9.394,-0.562],[-0.298,-0.038]],"o":[[-5.153,4.329],[3.882,-16.05],[0.31,0.019],[-0.044,0.75]],"v":[[0.863,12.222],[-8.931,14.755],[8.005,-15.108],[8.931,-15.021]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[81.486,130.081],"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":"Layer 9","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.459,6.045],[-5.153,4.329],[-0.044,0.75],[3.116,-24.664],[5.23,-22.052],[8.666,11.92],[-2.9,9.135]],"o":[[0,0],[6.72,-5.642],[12.723,1.335],[-2.369,18.762],[-13.993,-5.333],[2.255,-5.502],[1.843,-5.815]],"v":[[-9.99,-18.348],[-0.196,-20.881],[7.872,-48.124],[21.578,-9.331],[12.104,48.124],[-22.574,21.555],[-14.791,-0.206]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[82.545,163.184],"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":"Layer 8","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"black circle matte 4","parent":13,"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,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":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".grey903","cl":"grey903","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-18.345,-92.442,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":[[24.07,0],[0,0],[-8.27,0],[0,0]],"o":[[0,0],[0,8.269],[0,0],[-14.024,-17.379]],"v":[[-29.778,-14.252],[-29.778,-0.721],[-14.805,14.252],[29.778,14.252]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"black circle matte 5","parent":13,"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,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":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".grey902","cl":"grey902","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-15.947,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[154.053,139.81,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.3,0.367],[0,0],[-2.364,0.157],[0,0]],"o":[[0,0],[2.3,-0.367],[0,0],[-2.364,-0.157]],"v":[[-3.5,75.533],[-3.5,-75.533],[3.5,-76.312],[3.5,76.312]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[113.225,139.81],"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":"Layer 7","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,8.269],[0,0],[2.181,-0.187],[0,0],[-2.23,0],[0,42.252],[10.593,13.127],[0,0]],"o":[[0,0],[-2.23,0],[0,0],[2.181,0.187],[42.252,0],[0,-18.182],[0,0],[-8.27,0]],"v":[[-34.946,-62.973],[-34.946,-76.504],[-41.558,-76.201],[-41.558,76.201],[-34.946,76.504],[41.558,0],[24.61,-48],[-19.973,-48]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[156.824,139.81],"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":"Layer 5","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".black 2","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-48.123,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,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":-129,"s":[0,0,100]},{"t":-79,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".grey700","cl":"grey700","parent":15,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-56.481,-59.936,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":[[3.767,0],[0,0],[0,-3.767],[0,0],[-3.767,0],[0,0],[0,3.767],[0,0]],"o":[[0,0],[-3.767,0],[0,0],[0,3.767],[0,0],[3.767,0],[0,0],[0,-3.767]],"v":[[46.055,-14.479],[-46.056,-14.479],[-52.876,-7.659],[-52.876,7.658],[-46.056,14.479],[46.055,14.479],[52.876,7.658],[52.876,-7.659]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".grey901","cl":"grey901","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[16.485,2.727,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[50,50,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.184,0],[0,0],[0,0],[0,0],[0,-4.375]],"o":[[0,4.184],[0,0],[0,0],[0,0],[4.375,0],[0,0]],"v":[[114.116,92.129],[106.54,99.705],[7.788,99.705],[7.788,-99.704],[106.161,-99.704],[114.116,-91.749]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[5.707,0],[0,0],[1.894,-1.05],[0.886,0.346],[0,0],[2.166,0],[0,0],[0,-5.707],[0,0],[0,-1.46],[0,0],[-1.133,-0.038],[0,0],[0,-1.459],[0,0],[-1.133,-0.038],[0,0],[-5.708,0],[0,0],[-1.894,1.05],[-0.846,-0.289],[0,0],[-2.166,0],[0,0],[0,5.706],[0,0]],"o":[[0,0],[-2.166,0],[-0.883,0.354],[0,0],[-1.895,-1.05],[0,0],[-5.708,0],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[0,5.707],[0,0],[2.165,0],[0.833,-0.334],[0,0],[1.894,1.05],[0,0],[5.707,0],[0,0],[0,-5.707]],"v":[[106.16,-102.082],[8.455,-102.082],[2.265,-100.48],[-0.488,-100.468],[-0.519,-100.48],[-6.71,-102.082],[-104.116,-102.082],[-114.45,-91.748],[-114.45,-36.119],[-116.494,-33.44],[-116.494,-18.979],[-114.45,-16.3],[-114.45,-0.877],[-116.494,1.802],[-116.494,28.704],[-114.45,31.383],[-114.45,91.749],[-104.116,102.083],[-6.495,102.083],[-0.305,100.481],[2.294,100.425],[2.395,100.481],[9.872,102.083],[106.161,102.083],[116.494,91.75],[116.494,-91.748]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.529411792755,0.54509806633,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":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_rear_portrait_base.json b/packages/SystemUI/res/raw/biometricprompt_rear_portrait_base.json
deleted file mode 100644
index 9ea0d35e1de2..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_rear_portrait_base.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.8.1","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"BiometricPrompt_Rear_Portrait_Base_Foldable","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 18","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[169.478,169.749,0],"ix":2,"l":2},"a":{"a":0,"k":[-48.123,-30.19,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".grey400","cl":"grey400","parent":14,"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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,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":[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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"black circle matte","parent":14,"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,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":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey904","cl":"grey904","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,35.536,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],[-2.552,0.087],[0,0]],"o":[[0,0],[0,-3.287],[0,0],[0,0]],"v":[[-2.301,8.869],[-2.301,-3.772],[2.301,-9.806],[2.301,9.806]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"black circle matte 2","parent":14,"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,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":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".blue401","cl":"blue401","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,-27.655,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,3.286],[0,0],[-2.552,0.086],[0,0]],"o":[[0,0],[0,-3.286],[0,0],[-2.552,-0.086]],"v":[[-2.301,16.282],[-2.301,-16.281],[2.301,-22.313],[2.301,22.313]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"black circle matte 3","parent":14,"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,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":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Finger 3","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-2,"ix":10},"p":{"a":0,"k":[260.134,83.782,0],"ix":2,"l":2},"a":{"a":0,"k":[302.634,38.782,0],"ix":1,"l":2},"s":{"a":0,"k":[178,178,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-4.262,5.076],[0,0],[-0.424,-7.095],[-0.028,-0.225]],"o":[[3.269,-3.892],[-12.123,2.932],[0.015,0.234],[0.567,-0.034]],"v":[[9.232,0.652],[11.145,-6.746],[-11.412,6.046],[-11.346,6.746]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[241.281,55.033],"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":"Layer 5","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.565,-1.102],[3.269,-3.892],[0.566,-0.033],[-18.63,2.353],[-16.656,3.951],[9.004,6.546],[6.9,-2.19]],"o":[[0,0],[-4.262,5.076],[1.008,9.61],[14.171,-1.79],[-4.028,-10.569],[-4.156,1.703],[-4.392,1.392]],"v":[[-13.858,-7.546],[-15.771,-0.148],[-36.349,5.946],[-7.047,16.299],[36.349,9.142],[16.281,-17.051],[-0.156,-11.172]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[266.285,55.833],"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":"Layer 4","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"black circle matte 4","parent":14,"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,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":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".grey903","cl":"grey903","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-18.345,-92.442,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":[[24.07,0],[0,0],[-8.27,0],[0,0]],"o":[[0,0],[0,8.269],[0,0],[-14.024,-17.379]],"v":[[-29.778,-14.252],[-29.778,-0.721],[-14.805,14.252],[29.778,14.252]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"black circle matte 5","parent":14,"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,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":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".grey902","cl":"grey902","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-15.947,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[154.053,139.81,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.3,0.367],[0,0],[-2.364,0.157],[0,0]],"o":[[0,0],[2.3,-0.367],[0,0],[-2.364,-0.157]],"v":[[-3.5,75.533],[-3.5,-75.533],[3.5,-76.312],[3.5,76.312]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[113.225,139.81],"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":"Layer 7","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,8.269],[0,0],[2.181,-0.187],[0,0],[-2.23,0],[0,42.252],[10.593,13.127],[0,0]],"o":[[0,0],[-2.23,0],[0,0],[2.181,0.187],[42.252,0],[0,-18.182],[0,0],[-8.27,0]],"v":[[-34.946,-62.973],[-34.946,-76.504],[-41.558,-76.201],[-41.558,76.201],[-34.946,76.504],[41.558,0],[24.61,-48],[-19.973,-48]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[156.824,139.81],"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":"Layer 5","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".black 2","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-48.123,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,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":-129,"s":[0,0,100]},{"t":-79,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".grey700","cl":"grey700","parent":16,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-56.481,-59.936,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":[[3.767,0],[0,0],[0,-3.767],[0,0],[-3.767,0],[0,0],[0,3.767],[0,0]],"o":[[0,0],[-3.767,0],[0,0],[0,3.767],[0,0],[3.767,0],[0,0],[0,-3.767]],"v":[[46.055,-14.479],[-46.056,-14.479],[-52.876,-7.659],[-52.876,7.658],[-46.056,14.479],[46.055,14.479],[52.876,7.658],[52.876,-7.659]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".grey901","cl":"grey901","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[16.485,2.727,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[50,50,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.184,0],[0,0],[0,0],[0,0],[0,-4.375]],"o":[[0,4.184],[0,0],[0,0],[0,0],[4.375,0],[0,0]],"v":[[114.116,92.129],[106.54,99.705],[7.788,99.705],[7.788,-99.704],[106.161,-99.704],[114.116,-91.749]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[5.707,0],[0,0],[1.894,-1.05],[0.886,0.346],[0,0],[2.166,0],[0,0],[0,-5.707],[0,0],[0,-1.46],[0,0],[-1.133,-0.038],[0,0],[0,-1.459],[0,0],[-1.133,-0.038],[0,0],[-5.708,0],[0,0],[-1.894,1.05],[-0.846,-0.289],[0,0],[-2.166,0],[0,0],[0,5.706],[0,0]],"o":[[0,0],[-2.166,0],[-0.883,0.354],[0,0],[-1.895,-1.05],[0,0],[-5.708,0],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[0,5.707],[0,0],[2.165,0],[0.833,-0.334],[0,0],[1.894,1.05],[0,0],[5.707,0],[0,0],[0,-5.707]],"v":[[106.16,-102.082],[8.455,-102.082],[2.265,-100.48],[-0.488,-100.468],[-0.519,-100.48],[-6.71,-102.082],[-104.116,-102.082],[-114.45,-91.748],[-114.45,-36.119],[-116.494,-33.44],[-116.494,-18.979],[-114.45,-16.3],[-114.45,-0.877],[-116.494,1.802],[-116.494,28.704],[-114.45,31.383],[-114.45,91.749],[-104.116,102.083],[-6.495,102.083],[-0.305,100.481],[2.294,100.425],[2.395,100.481],[9.872,102.083],[106.161,102.083],[116.494,91.75],[116.494,-91.748]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.529411792755,0.54509806633,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":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_rear_portrait_reverse_base.json b/packages/SystemUI/res/raw/biometricprompt_rear_portrait_reverse_base.json
deleted file mode 100644
index f2b259335034..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_rear_portrait_reverse_base.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.8.1","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"BiometricPrompt_Rear_Portrait_Reverse_Base_Foldable","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 18","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":270,"ix":10},"p":{"a":0,"k":[169.478,169.749,0],"ix":2,"l":2},"a":{"a":0,"k":[-48.123,-30.19,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".grey400","cl":"grey400","parent":13,"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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,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":[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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"black circle matte","parent":13,"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,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":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey904","cl":"grey904","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,35.536,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],[-2.552,0.087],[0,0]],"o":[[0,0],[0,-3.287],[0,0],[0,0]],"v":[[-2.301,8.869],[-2.301,-3.772],[2.301,-9.806],[2.301,9.806]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"black circle matte 2","parent":13,"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,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":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".blue401","cl":"blue401","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,-27.655,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,3.286],[0,0],[-2.552,0.086],[0,0]],"o":[[0,0],[0,-3.286],[0,0],[-2.552,-0.086]],"v":[[-2.301,16.282],[-2.301,-16.281],[2.301,-22.313],[2.301,22.313]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"black circle matte 3","parent":13,"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,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":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-75.352,41.307,0],"ix":2,"l":2},"a":{"a":0,"k":[94.648,211.307,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.72,-5.642],[0,0],[-9.394,-0.562],[-0.298,-0.038]],"o":[[-5.153,4.329],[3.882,-16.05],[0.31,0.019],[-0.044,0.75]],"v":[[0.863,12.222],[-8.931,14.755],[8.005,-15.108],[8.931,-15.021]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[81.486,130.081],"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":"Layer 9","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.459,6.045],[-5.153,4.329],[-0.044,0.75],[3.116,-24.664],[5.23,-22.052],[8.666,11.92],[-2.9,9.135]],"o":[[0,0],[6.72,-5.642],[12.723,1.335],[-2.369,18.762],[-13.993,-5.333],[2.255,-5.502],[1.843,-5.815]],"v":[[-9.99,-18.348],[-0.196,-20.881],[7.872,-48.124],[21.578,-9.331],[12.104,48.124],[-22.574,21.555],[-14.791,-0.206]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[82.545,163.184],"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":"Layer 8","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"black circle matte 4","parent":13,"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,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":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".grey903","cl":"grey903","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-18.345,-92.442,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":[[24.07,0],[0,0],[-8.27,0],[0,0]],"o":[[0,0],[0,8.269],[0,0],[-14.024,-17.379]],"v":[[-29.778,-14.252],[-29.778,-0.721],[-14.805,14.252],[29.778,14.252]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"black circle matte 5","parent":13,"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,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":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".grey902","cl":"grey902","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-15.947,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[154.053,139.81,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.3,0.367],[0,0],[-2.364,0.157],[0,0]],"o":[[0,0],[2.3,-0.367],[0,0],[-2.364,-0.157]],"v":[[-3.5,75.533],[-3.5,-75.533],[3.5,-76.312],[3.5,76.312]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[113.225,139.81],"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":"Layer 7","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,8.269],[0,0],[2.181,-0.187],[0,0],[-2.23,0],[0,42.252],[10.593,13.127],[0,0]],"o":[[0,0],[-2.23,0],[0,0],[2.181,0.187],[42.252,0],[0,-18.182],[0,0],[-8.27,0]],"v":[[-34.946,-62.973],[-34.946,-76.504],[-41.558,-76.201],[-41.558,76.201],[-34.946,76.504],[41.558,0],[24.61,-48],[-19.973,-48]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[156.824,139.81],"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":"Layer 5","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".black 2","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-48.123,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,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":-129,"s":[0,0,100]},{"t":-79,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".grey700","cl":"grey700","parent":15,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-56.481,-59.936,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":[[3.767,0],[0,0],[0,-3.767],[0,0],[-3.767,0],[0,0],[0,3.767],[0,0]],"o":[[0,0],[-3.767,0],[0,0],[0,3.767],[0,0],[3.767,0],[0,0],[0,-3.767]],"v":[[46.055,-14.479],[-46.056,-14.479],[-52.876,-7.659],[-52.876,7.658],[-46.056,14.479],[46.055,14.479],[52.876,7.658],[52.876,-7.659]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,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":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".grey901","cl":"grey901","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[16.485,2.727,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[50,50,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.184,0],[0,0],[0,0],[0,0],[0,-4.375]],"o":[[0,4.184],[0,0],[0,0],[0,0],[4.375,0],[0,0]],"v":[[114.116,92.129],[106.54,99.705],[7.788,99.705],[7.788,-99.704],[106.161,-99.704],[114.116,-91.749]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[5.707,0],[0,0],[1.894,-1.05],[0.886,0.346],[0,0],[2.166,0],[0,0],[0,-5.707],[0,0],[0,-1.46],[0,0],[-1.133,-0.038],[0,0],[0,-1.459],[0,0],[-1.133,-0.038],[0,0],[-5.708,0],[0,0],[-1.894,1.05],[-0.846,-0.289],[0,0],[-2.166,0],[0,0],[0,5.706],[0,0]],"o":[[0,0],[-2.166,0],[-0.883,0.354],[0,0],[-1.895,-1.05],[0,0],[-5.708,0],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[0,5.707],[0,0],[2.165,0],[0.833,-0.334],[0,0],[1.894,1.05],[0,0],[5.707,0],[0,0],[0,-5.707]],"v":[[106.16,-102.082],[8.455,-102.082],[2.265,-100.48],[-0.488,-100.468],[-0.519,-100.48],[-6.71,-102.082],[-104.116,-102.082],[-114.45,-91.748],[-114.45,-36.119],[-116.494,-33.44],[-116.494,-18.979],[-114.45,-16.3],[-114.45,-0.877],[-116.494,1.802],[-116.494,28.704],[-114.45,31.383],[-114.45,91.749],[-104.116,102.083],[-6.495,102.083],[-0.305,100.481],[2.294,100.425],[2.395,100.481],[9.872,102.083],[106.161,102.083],[116.494,91.75],[116.494,-91.748]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.529411792755,0.54509806633,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":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_error_to_fingerprint.json b/packages/SystemUI/res/raw/biometricprompt_sfps_error_to_fingerprint.json
new file mode 100644
index 000000000000..fa6fc07c3fe6
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_error_to_fingerprint.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":240,"op":421,"w":150,"h":150,"nm":"BM_Prompt_Error-to-FP_0and180","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":170,"s":[43.5,43.5,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":240,"s":[43.5,43.5,100]},{"t":260,"s":[64,64,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".red400","cl":"red400","parent":4,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.484,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.91,0.191,0],"ix":1,"l":2},"s":{"a":0,"k":[229.885,229.885,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[4,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,-7.079],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".red400","cl":"red400","parent":2,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-3.889,9.487,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.889,7.487,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":[4,4],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,7.491],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".red400","cl":"red400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933333333333,0.403921568627,0.360784313725,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Matte 3","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Nail 2","parent":11,"tt":1,"tp":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Matte 2","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"tp":10,"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":320,"s":[43]},{"t":365,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":320,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":365,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Nail","parent":15,"tt":1,"tp":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":14,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":320,"s":[50]},{"t":390,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":290,"s":[0,0,100]},{"t":380,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":290,"op":391,"st":290,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":290,"s":[50]},{"t":360,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":260,"s":[0,0,100]},{"t":350,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":391,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":131,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":131,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_error_to_fingerprint_180.json b/packages/SystemUI/res/raw/biometricprompt_sfps_error_to_fingerprint_180.json
new file mode 100755
index 000000000000..688ed7b3c57f
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_error_to_fingerprint_180.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":240,"op":421,"w":150,"h":150,"nm":"BM_Prompt_Error-to-FP_left","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[-64,64,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":170,"s":[-43.5,43.5,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":240,"s":[-43.5,43.5,100]},{"t":260,"s":[-64,64,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".red400","cl":"red400","parent":4,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.484,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.91,0.191,0],"ix":1,"l":2},"s":{"a":0,"k":[229.885,229.885,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[4,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,-7.079],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".red400","cl":"red400","parent":2,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-3.889,9.487,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.889,7.487,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":[4,4],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,7.491],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".red400","cl":"red400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933333333333,0.403921568627,0.360784313725,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Matte 3","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Nail 2","parent":11,"tt":1,"tp":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Matte 2","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"tp":10,"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":320,"s":[43]},{"t":365,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":320,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":365,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Nail","parent":15,"tt":1,"tp":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":14,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":320,"s":[50]},{"t":390,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":290,"s":[0,0,100]},{"t":380,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":290,"op":391,"st":290,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":290,"s":[50]},{"t":360,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":260,"s":[0,0,100]},{"t":350,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":391,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":131,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":131,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_error_to_fingerprint_270.json b/packages/SystemUI/res/raw/biometricprompt_sfps_error_to_fingerprint_270.json
new file mode 100644
index 000000000000..477c489ad086
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_error_to_fingerprint_270.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":240,"op":421,"w":150,"h":150,"nm":"BM_Prompt_Error-to-FP_270","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":170,"s":[43.5,43.5,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":240,"s":[43.5,43.5,100]},{"t":260,"s":[64,64,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".red400","cl":"red400","parent":4,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.484,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.91,0.191,0],"ix":1,"l":2},"s":{"a":0,"k":[229.885,229.885,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[4,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,-7.079],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".red400","cl":"red400","parent":2,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-3.889,9.487,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.889,7.487,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":[4,4],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,7.491],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".red400","cl":"red400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":270,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933333333333,0.403921568627,0.360784313725,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Matte 3","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Nail 2","parent":11,"tt":1,"tp":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Matte 2","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"tp":10,"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":320,"s":[43]},{"t":365,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":320,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":365,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Nail","parent":15,"tt":1,"tp":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":14,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":320,"s":[50]},{"t":390,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":290,"s":[0,0,100]},{"t":380,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":290,"op":391,"st":290,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":290,"s":[50]},{"t":360,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":260,"s":[0,0,100]},{"t":350,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":391,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":131,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":131,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_error_to_fingerprint_90.json b/packages/SystemUI/res/raw/biometricprompt_sfps_error_to_fingerprint_90.json
new file mode 100644
index 000000000000..9e6b4228c3e8
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_error_to_fingerprint_90.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":240,"op":421,"w":150,"h":150,"nm":"BM_Prompt_Error-to-FP_90","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":170,"s":[43.5,43.5,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":240,"s":[43.5,43.5,100]},{"t":260,"s":[64,64,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".red400","cl":"red400","parent":4,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.484,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.91,0.191,0],"ix":1,"l":2},"s":{"a":0,"k":[229.885,229.885,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[4,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,-7.079],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".red400","cl":"red400","parent":2,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-3.889,9.487,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.889,7.487,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":[4,4],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,7.491],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".red400","cl":"red400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":90,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933333333333,0.403921568627,0.360784313725,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Matte 3","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Nail 2","parent":11,"tt":1,"tp":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Matte 2","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"tp":10,"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":320,"s":[43]},{"t":365,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":320,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":365,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Nail","parent":15,"tt":1,"tp":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":14,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":320,"s":[50]},{"t":390,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":290,"s":[0,0,100]},{"t":380,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":290,"op":391,"st":290,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":290,"s":[50]},{"t":360,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":260,"s":[0,0,100]},{"t":350,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":391,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":131,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":131,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_error_to_success.json b/packages/SystemUI/res/raw/biometricprompt_sfps_error_to_success.json
new file mode 100644
index 000000000000..348e25df78c8
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_error_to_success.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":240,"op":421,"w":150,"h":150,"nm":"Error-to-success","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".red400","cl":"red400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.484,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.91,0.191,0],"ix":1,"l":2},"s":{"a":0,"k":[229.885,229.885,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[4,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,-7.079],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".red400","cl":"red400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-3.889,9.487,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.889,7.487,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":[4,4],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,7.491],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".red400","cl":"red400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[43.5,43.5,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933333333333,0.403921568627,0.360784313725,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"t":170,"s":[43.5,43.5,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"green400","parent":8,"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":[71.264,71.264,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":240,"s":[0]},{"t":270,"s":[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":240,"op":1131,"st":231,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".green400","cl":"green400","parent":6,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":240,"op":982,"st":82,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".grey400","cl":"grey400","parent":6,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"t":166,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".grey600","cl":"grey600","parent":6,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".grey600","cl":"grey600","parent":6,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Matte","parent":6,"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,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":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Nail","parent":17,"tt":1,"tp":14,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"Matte","parent":6,"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,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":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Finger","parent":6,"tt":1,"tp":16,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".black","cl":"black","parent":6,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".blue400","cl":"blue400","parent":6,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":".blue401","cl":"blue401","parent":6,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":930,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":".blue400","cl":"blue400","parent":6,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":".black","cl":"black","parent":6,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_error_to_unlock.json b/packages/SystemUI/res/raw/biometricprompt_sfps_error_to_unlock.json
new file mode 100644
index 000000000000..ab52490c5fb0
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_error_to_unlock.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":240,"op":421,"w":150,"h":150,"nm":"BM_Prompt_Error-to-Unlock_0","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".blue400","cl":"blue400","parent":4,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[74.259,78.552,0],"ix":2,"l":2},"a":{"a":0,"k":[-5.873,13.309,0],"ix":1,"l":2},"s":{"a":0,"k":[44,44,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.4,"y":0},"t":244,"s":[{"i":[[0,0],[0,0],[0.938,1.057],[1.355,0],[0.938,-1.057],[0,-1.527],[0,0],[-1.512,1.674],[-2.111,0],[-1.512,-1.703],[0,-2.408],[0,0]],"o":[[0,0],[0,-1.527],[-0.938,-1.057],[-1.329,0],[-0.938,1.057],[0,0],[0,-2.408],[1.486,-1.703],[2.137,0],[1.486,1.674],[0,0],[0,0]],"v":[[-0.17,-6.078],[-0.17,-9.822],[-1.577,-13.699],[-5.017,-15.284],[-8.419,-13.699],[-9.826,-9.822],[-12.68,-9.822],[-10.412,-15.945],[-5.017,-18.5],[0.456,-15.945],[2.684,-9.822],[2.684,-6.078]],"c":true}]},{"t":259,"s":[{"i":[[0,0],[0,0],[-1.069,1.057],[-1.545,0],[-1.069,-1.057],[0,-1.527],[0,0],[1.723,1.674],[2.406,0],[1.723,-1.703],[0,-2.408],[0,0]],"o":[[0,0],[0,-1.527],[1.069,-1.057],[1.515,0],[1.069,1.057],[0,0],[0,-2.408],[-1.693,-1.703],[-2.436,0],[-1.693,1.674],[0,0],[0,0]],"v":[[2.74,-6.079],[2.74,-9.823],[4.345,-13.699],[8.266,-15.285],[12.143,-13.699],[13.747,-9.823],[17,-9.823],[14.415,-15.945],[8.266,-18.5],[2.028,-15.945],[-0.512,-9.823],[-0.512,-6.079]],"c":true}]}],"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[214.286,214.286],"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":"icon","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":94,"op":994,"st":94,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[74.259,78.552,0],"ix":2,"l":2},"a":{"a":0,"k":[-5.873,13.309,0],"ix":1,"l":2},"s":{"a":0,"k":[44,44,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],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[8.266,15.285],[-13.747,15.285],[-13.747,-2.863],[8.266,-2.863]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.683,-0.675],[0.98,0],[0.683,0.675],[0,0.94],[-0.683,0.705],[-0.98,0],[-0.683,-0.705],[0,-0.94]],"o":[[-0.683,0.675],[-0.98,0],[-0.683,-0.675],[0,-0.94],[0.683,-0.705],[0.98,0],[0.683,0.705],[0,0.94]],"v":[[-0.245,8.677],[-2.74,9.69],[-5.236,8.677],[-6.261,6.255],[-5.236,3.788],[-2.74,2.731],[-0.245,3.788],[0.78,6.255]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[-0.624,-0.646],[-0.891,0],[0,0],[-0.624,0.617],[0,0.881],[0,0],[0.654,0.617],[0.891,0],[0,0],[0,0],[0,0],[0.654,-0.646],[0,-0.881],[0,0]],"o":[[0.654,0.617],[0,0],[0.891,0],[0.654,-0.646],[0,0],[0,-0.881],[-0.624,-0.646],[0,0],[0,0],[0,0],[-0.891,0],[-0.624,0.617],[0,0],[0,0.881]],"v":[[-16.064,17.575],[-13.747,18.5],[8.266,18.5],[10.539,17.575],[11.519,15.285],[11.519,-2.863],[10.539,-5.11],[8.266,-6.079],[2.74,-6.079],[-0.512,-6.079],[-13.747,-6.079],[-16.064,-5.11],[-17,-2.863],[-17,15.285]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[214.286,214.286],"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":"icon","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":94,"op":994,"st":94,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[43.5,43.5,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".red400","cl":"red400","parent":7,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.484,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.91,0.191,0],"ix":1,"l":2},"s":{"a":0,"k":[229.885,229.885,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[4,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,-7.079],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".red400","cl":"red400","parent":5,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-3.889,9.487,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.889,7.487,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":[4,4],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,7.491],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".red400","cl":"red400","parent":4,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933333333333,0.403921568627,0.360784313725,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[{"tm":248,"cm":"","dr":0},{"tm":256,"cm":"","dr":0}]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_authenticating.json b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_authenticating.json
new file mode 100644
index 000000000000..9db254353af1
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_authenticating.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":301,"w":150,"h":150,"nm":"BM_Prompt","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[64,64,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Nail","parent":8,"tt":1,"tp":5,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":7,"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":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".blue401","cl":"blue401","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":930,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".black","cl":"black","parent":1,"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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_error.json b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_error.json
new file mode 100644
index 000000000000..603760f1fbf8
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_error.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":181,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Error_0and180","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":170,"s":[43.5,43.5,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":240,"s":[43.5,43.5,100]},{"t":260,"s":[64,64,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".red400","cl":"red400","parent":4,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.484,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.91,0.191,0],"ix":1,"l":2},"s":{"a":0,"k":[229.885,229.885,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[4,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,-7.079],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".red400","cl":"red400","parent":2,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-3.889,9.487,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.889,7.487,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":[4,4],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,7.491],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".red400","cl":"red400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933333333333,0.403921568627,0.360784313725,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Matte 3","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Nail 2","parent":11,"tt":1,"tp":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Matte 2","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"tp":10,"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":320,"s":[43]},{"t":365,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":320,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":365,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Nail","parent":15,"tt":1,"tp":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":14,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":320,"s":[50]},{"t":390,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":290,"s":[0,0,100]},{"t":380,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":290,"op":391,"st":290,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":290,"s":[50]},{"t":360,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":260,"s":[0,0,100]},{"t":350,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":391,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":131,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":131,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_error_180.json b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_error_180.json
new file mode 100755
index 000000000000..4e66cfa2a40a
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_error_180.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":181,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Error_left","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[-64,64,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":170,"s":[-43.5,43.5,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":240,"s":[-43.5,43.5,100]},{"t":260,"s":[-64,64,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".red400","cl":"red400","parent":4,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.484,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.91,0.191,0],"ix":1,"l":2},"s":{"a":0,"k":[229.885,229.885,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[4,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,-7.079],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".red400","cl":"red400","parent":2,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-3.889,9.487,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.889,7.487,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":[4,4],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,7.491],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".red400","cl":"red400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933333333333,0.403921568627,0.360784313725,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Matte 3","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Nail 2","parent":11,"tt":1,"tp":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Matte 2","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"tp":10,"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":320,"s":[43]},{"t":365,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":320,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":365,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Nail","parent":15,"tt":1,"tp":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":14,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":320,"s":[50]},{"t":390,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":290,"s":[0,0,100]},{"t":380,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":290,"op":391,"st":290,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":290,"s":[50]},{"t":360,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":260,"s":[0,0,100]},{"t":350,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":391,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":131,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":131,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_error_270.json b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_error_270.json
new file mode 100644
index 000000000000..a1d2251b8e7a
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_error_270.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":181,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Error_270","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":170,"s":[43.5,43.5,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":240,"s":[43.5,43.5,100]},{"t":260,"s":[64,64,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".red400","cl":"red400","parent":4,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.484,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.91,0.191,0],"ix":1,"l":2},"s":{"a":0,"k":[229.885,229.885,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[4,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,-7.079],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".red400","cl":"red400","parent":2,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-3.889,9.487,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.889,7.487,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":[4,4],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,7.491],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".red400","cl":"red400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":270,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933333333333,0.403921568627,0.360784313725,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Matte 3","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Nail 2","parent":11,"tt":1,"tp":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Matte 2","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"tp":10,"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":320,"s":[43]},{"t":365,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":320,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":365,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Nail","parent":15,"tt":1,"tp":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":14,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":320,"s":[50]},{"t":390,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":290,"s":[0,0,100]},{"t":380,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":290,"op":391,"st":290,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":290,"s":[50]},{"t":360,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":260,"s":[0,0,100]},{"t":350,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":391,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":131,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":131,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_error_90.json b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_error_90.json
new file mode 100644
index 000000000000..59dc0d4c4c85
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_error_90.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":181,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Error_90","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":170,"s":[43.5,43.5,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":240,"s":[43.5,43.5,100]},{"t":260,"s":[64,64,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".red400","cl":"red400","parent":4,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.484,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.91,0.191,0],"ix":1,"l":2},"s":{"a":0,"k":[229.885,229.885,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[4,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,-7.079],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".red400","cl":"red400","parent":2,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-3.889,9.487,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.889,7.487,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":[4,4],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,7.491],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".red400","cl":"red400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":90,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933333333333,0.403921568627,0.360784313725,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Matte 3","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Nail 2","parent":11,"tt":1,"tp":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Matte 2","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"tp":10,"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":320,"s":[43]},{"t":365,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":320,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":365,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Nail","parent":15,"tt":1,"tp":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":14,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":320,"s":[50]},{"t":390,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":290,"s":[0,0,100]},{"t":380,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":290,"op":391,"st":290,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":290,"s":[50]},{"t":360,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":260,"s":[0,0,100]},{"t":350,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":391,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":131,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":131,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_success.json b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_success.json
new file mode 100644
index 000000000000..e2c850062985
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_success.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":211,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Success_0and180","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"t":170,"s":[43.5,43.5,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"green400","parent":3,"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":[71.264,71.264,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":150,"s":[0]},{"t":180,"s":[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":150,"op":1041,"st":141,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".green400","cl":"green400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"t":166,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"t":166,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Nail","parent":10,"tt":1,"tp":7,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":9,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":930,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_success_180.json b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_success_180.json
new file mode 100755
index 000000000000..21ee20d02d78
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_success_180.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":211,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Success_left","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[-64,64,100]},{"t":170,"s":[-43.5,43.5,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"green400","parent":3,"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":[-71.264,71.264,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":150,"s":[0]},{"t":180,"s":[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":150,"op":1041,"st":141,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".green400","cl":"green400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"t":166,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"t":166,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Nail","parent":10,"tt":1,"tp":7,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":9,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":930,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_success_270.json b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_success_270.json
new file mode 100644
index 000000000000..4c1a80955906
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_success_270.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":211,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Success_270","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"t":170,"s":[43.5,43.5,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"green400","parent":3,"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":[71.264,71.264,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":150,"s":[0]},{"t":180,"s":[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":150,"op":1041,"st":141,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".green400","cl":"green400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"t":166,"s":[100]}],"ix":11},"r":{"a":0,"k":-90,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"t":166,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Nail","parent":10,"tt":1,"tp":7,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":9,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":930,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_success_90.json b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_success_90.json
new file mode 100644
index 000000000000..51e17f7c5fa3
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_success_90.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":211,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Success_90","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"t":170,"s":[43.5,43.5,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"green400","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"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":[71.264,71.264,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":150,"s":[0]},{"t":180,"s":[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":150,"op":1041,"st":141,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".green400","cl":"green400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"t":166,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"t":166,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Nail","parent":10,"tt":1,"tp":7,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":9,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":930,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_unlock.json b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_unlock.json
new file mode 100644
index 000000000000..c4db1e4b2ff6
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_unlock.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":181,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Unlock_0and180","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-1.704,8.166,0],"ix":2,"l":2},"a":{"a":0,"k":[-5.873,13.309,0],"ix":1,"l":2},"s":{"a":0,"k":[101.149,101.149,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.4,"y":0},"t":150,"s":[{"i":[[0,0],[0,0],[0.938,1.057],[1.355,0],[0.938,-1.057],[0,-1.527],[0,0],[-1.512,1.674],[-2.111,0],[-1.512,-1.703],[0,-2.408],[0,0]],"o":[[0,0],[0,-1.527],[-0.938,-1.057],[-1.329,0],[-0.938,1.057],[0,0],[0,-2.408],[1.486,-1.703],[2.137,0],[1.486,1.674],[0,0],[0,0]],"v":[[-0.17,-6.078],[-0.17,-9.822],[-1.577,-13.699],[-5.017,-15.284],[-8.419,-13.699],[-9.826,-9.822],[-12.68,-9.822],[-10.412,-15.945],[-5.017,-18.5],[0.456,-15.945],[2.684,-9.822],[2.684,-6.078]],"c":true}]},{"t":165,"s":[{"i":[[0,0],[0,0],[-1.069,1.057],[-1.545,0],[-1.069,-1.057],[0,-1.527],[0,0],[1.723,1.674],[2.406,0],[1.723,-1.703],[0,-2.408],[0,0]],"o":[[0,0],[0,-1.527],[1.069,-1.057],[1.515,0],[1.069,1.057],[0,0],[0,-2.408],[-1.693,-1.703],[-2.436,0],[-1.693,1.674],[0,0],[0,0]],"v":[[2.74,-6.079],[2.74,-9.823],[4.345,-13.699],[8.266,-15.285],[12.143,-13.699],[13.747,-9.823],[17,-9.823],[14.415,-15.945],[8.266,-18.5],[2.028,-15.945],[-0.512,-9.823],[-0.512,-6.079]],"c":true}]}],"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[214.286,214.286],"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":"icon","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-1.704,8.166,0],"ix":2,"l":2},"a":{"a":0,"k":[-5.873,13.309,0],"ix":1,"l":2},"s":{"a":0,"k":[101.149,101.149,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],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[8.266,15.285],[-13.747,15.285],[-13.747,-2.863],[8.266,-2.863]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.683,-0.675],[0.98,0],[0.683,0.675],[0,0.94],[-0.683,0.705],[-0.98,0],[-0.683,-0.705],[0,-0.94]],"o":[[-0.683,0.675],[-0.98,0],[-0.683,-0.675],[0,-0.94],[0.683,-0.705],[0.98,0],[0.683,0.705],[0,0.94]],"v":[[-0.245,8.677],[-2.74,9.69],[-5.236,8.677],[-6.261,6.255],[-5.236,3.788],[-2.74,2.731],[-0.245,3.788],[0.78,6.255]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[-0.624,-0.646],[-0.891,0],[0,0],[-0.624,0.617],[0,0.881],[0,0],[0.654,0.617],[0.891,0],[0,0],[0,0],[0,0],[0.654,-0.646],[0,-0.881],[0,0]],"o":[[0.654,0.617],[0,0],[0.891,0],[0.654,-0.646],[0,0],[0,-0.881],[-0.624,-0.646],[0,0],[0,0],[0,0],[-0.891,0],[-0.624,0.617],[0,0],[0,0.881]],"v":[[-16.064,17.575],[-13.747,18.5],[8.266,18.5],[10.539,17.575],[11.519,15.285],[11.519,-2.863],[10.539,-5.11],[8.266,-6.079],[2.74,-6.079],[-0.512,-6.079],[-13.747,-6.079],[-16.064,-5.11],[-17,-2.863],[-17,15.285]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[214.286,214.286],"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":"icon","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"t":170,"s":[43.5,43.5,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"green400","parent":5,"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":[71.264,71.264,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":240,"s":[0]},{"t":270,"s":[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":240,"op":1131,"st":231,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".green400","cl":"green400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":240,"op":982,"st":82,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".grey400","cl":"grey400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"t":166,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".grey600","cl":"grey600","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".grey600","cl":"grey600","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Matte","parent":3,"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,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":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Nail","parent":14,"tt":1,"tp":11,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Matte","parent":3,"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,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":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Finger","parent":3,"tt":1,"tp":13,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".black","cl":"black","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":930,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".black","cl":"black","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_unlock_180.json b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_unlock_180.json
new file mode 100755
index 000000000000..56cd2adc14e3
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_unlock_180.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":181,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Unlock_left","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1.704,8.166,0],"ix":2,"l":2},"a":{"a":0,"k":[-5.873,13.309,0],"ix":1,"l":2},"s":{"a":0,"k":[-101.149,101.149,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.4,"y":0},"t":150,"s":[{"i":[[0,0],[0,0],[0.938,1.057],[1.355,0],[0.938,-1.057],[0,-1.527],[0,0],[-1.512,1.674],[-2.111,0],[-1.512,-1.703],[0,-2.408],[0,0]],"o":[[0,0],[0,-1.527],[-0.938,-1.057],[-1.329,0],[-0.938,1.057],[0,0],[0,-2.408],[1.486,-1.703],[2.137,0],[1.486,1.674],[0,0],[0,0]],"v":[[-0.17,-6.078],[-0.17,-9.822],[-1.577,-13.699],[-5.017,-15.284],[-8.419,-13.699],[-9.826,-9.822],[-12.68,-9.822],[-10.412,-15.945],[-5.017,-18.5],[0.456,-15.945],[2.684,-9.822],[2.684,-6.078]],"c":true}]},{"t":165,"s":[{"i":[[0,0],[0,0],[-1.069,1.057],[-1.545,0],[-1.069,-1.057],[0,-1.527],[0,0],[1.723,1.674],[2.406,0],[1.723,-1.703],[0,-2.408],[0,0]],"o":[[0,0],[0,-1.527],[1.069,-1.057],[1.515,0],[1.069,1.057],[0,0],[0,-2.408],[-1.693,-1.703],[-2.436,0],[-1.693,1.674],[0,0],[0,0]],"v":[[2.74,-6.079],[2.74,-9.823],[4.345,-13.699],[8.266,-15.285],[12.143,-13.699],[13.747,-9.823],[17,-9.823],[14.415,-15.945],[8.266,-18.5],[2.028,-15.945],[-0.512,-9.823],[-0.512,-6.079]],"c":true}]}],"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[214.286,214.286],"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":"icon","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1.704,8.166,0],"ix":2,"l":2},"a":{"a":0,"k":[-5.873,13.309,0],"ix":1,"l":2},"s":{"a":0,"k":[-101.149,101.149,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],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[8.266,15.285],[-13.747,15.285],[-13.747,-2.863],[8.266,-2.863]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.683,-0.675],[0.98,0],[0.683,0.675],[0,0.94],[-0.683,0.705],[-0.98,0],[-0.683,-0.705],[0,-0.94]],"o":[[-0.683,0.675],[-0.98,0],[-0.683,-0.675],[0,-0.94],[0.683,-0.705],[0.98,0],[0.683,0.705],[0,0.94]],"v":[[-0.245,8.677],[-2.74,9.69],[-5.236,8.677],[-6.261,6.255],[-5.236,3.788],[-2.74,2.731],[-0.245,3.788],[0.78,6.255]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[-0.624,-0.646],[-0.891,0],[0,0],[-0.624,0.617],[0,0.881],[0,0],[0.654,0.617],[0.891,0],[0,0],[0,0],[0,0],[0.654,-0.646],[0,-0.881],[0,0]],"o":[[0.654,0.617],[0,0],[0.891,0],[0.654,-0.646],[0,0],[0,-0.881],[-0.624,-0.646],[0,0],[0,0],[0,0],[-0.891,0],[-0.624,0.617],[0,0],[0,0.881]],"v":[[-16.064,17.575],[-13.747,18.5],[8.266,18.5],[10.539,17.575],[11.519,15.285],[11.519,-2.863],[10.539,-5.11],[8.266,-6.079],[2.74,-6.079],[-0.512,-6.079],[-13.747,-6.079],[-16.064,-5.11],[-17,-2.863],[-17,15.285]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[214.286,214.286],"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":"icon","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[-64,64,100]},{"t":170,"s":[-43.5,43.5,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"green400","parent":5,"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":[71.264,71.264,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":240,"s":[0]},{"t":270,"s":[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":240,"op":1131,"st":231,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".green400","cl":"green400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":240,"op":982,"st":82,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".grey400","cl":"grey400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"t":166,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".grey600","cl":"grey600","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".grey600","cl":"grey600","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Matte","parent":3,"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,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":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Nail","parent":14,"tt":1,"tp":11,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Matte","parent":3,"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,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":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Finger","parent":3,"tt":1,"tp":13,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".black","cl":"black","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":930,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".black","cl":"black","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_unlock_270.json b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_unlock_270.json
new file mode 100644
index 000000000000..30bb2d9f4fa6
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_unlock_270.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":181,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Unlock_270","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[8.166,1.704,0],"ix":2,"l":2},"a":{"a":0,"k":[-5.873,13.309,0],"ix":1,"l":2},"s":{"a":0,"k":[101.149,101.149,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.4,"y":0},"t":150,"s":[{"i":[[0,0],[0,0],[0.938,1.057],[1.355,0],[0.938,-1.057],[0,-1.527],[0,0],[-1.512,1.674],[-2.111,0],[-1.512,-1.703],[0,-2.408],[0,0]],"o":[[0,0],[0,-1.527],[-0.938,-1.057],[-1.329,0],[-0.938,1.057],[0,0],[0,-2.408],[1.486,-1.703],[2.137,0],[1.486,1.674],[0,0],[0,0]],"v":[[-0.17,-6.078],[-0.17,-9.822],[-1.577,-13.699],[-5.017,-15.284],[-8.419,-13.699],[-9.826,-9.822],[-12.68,-9.822],[-10.412,-15.945],[-5.017,-18.5],[0.456,-15.945],[2.684,-9.822],[2.684,-6.078]],"c":true}]},{"t":165,"s":[{"i":[[0,0],[0,0],[-1.069,1.057],[-1.545,0],[-1.069,-1.057],[0,-1.527],[0,0],[1.723,1.674],[2.406,0],[1.723,-1.703],[0,-2.408],[0,0]],"o":[[0,0],[0,-1.527],[1.069,-1.057],[1.515,0],[1.069,1.057],[0,0],[0,-2.408],[-1.693,-1.703],[-2.436,0],[-1.693,1.674],[0,0],[0,0]],"v":[[2.74,-6.079],[2.74,-9.823],[4.345,-13.699],[8.266,-15.285],[12.143,-13.699],[13.747,-9.823],[17,-9.823],[14.415,-15.945],[8.266,-18.5],[2.028,-15.945],[-0.512,-9.823],[-0.512,-6.079]],"c":true}]}],"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[214.286,214.286],"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":"icon","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[8.166,1.704,0],"ix":2,"l":2},"a":{"a":0,"k":[-5.873,13.309,0],"ix":1,"l":2},"s":{"a":0,"k":[101.149,101.149,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],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[8.266,15.285],[-13.747,15.285],[-13.747,-2.863],[8.266,-2.863]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.683,-0.675],[0.98,0],[0.683,0.675],[0,0.94],[-0.683,0.705],[-0.98,0],[-0.683,-0.705],[0,-0.94]],"o":[[-0.683,0.675],[-0.98,0],[-0.683,-0.675],[0,-0.94],[0.683,-0.705],[0.98,0],[0.683,0.705],[0,0.94]],"v":[[-0.245,8.677],[-2.74,9.69],[-5.236,8.677],[-6.261,6.255],[-5.236,3.788],[-2.74,2.731],[-0.245,3.788],[0.78,6.255]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[-0.624,-0.646],[-0.891,0],[0,0],[-0.624,0.617],[0,0.881],[0,0],[0.654,0.617],[0.891,0],[0,0],[0,0],[0,0],[0.654,-0.646],[0,-0.881],[0,0]],"o":[[0.654,0.617],[0,0],[0.891,0],[0.654,-0.646],[0,0],[0,-0.881],[-0.624,-0.646],[0,0],[0,0],[0,0],[-0.891,0],[-0.624,0.617],[0,0],[0,0.881]],"v":[[-16.064,17.575],[-13.747,18.5],[8.266,18.5],[10.539,17.575],[11.519,15.285],[11.519,-2.863],[10.539,-5.11],[8.266,-6.079],[2.74,-6.079],[-0.512,-6.079],[-13.747,-6.079],[-16.064,-5.11],[-17,-2.863],[-17,15.285]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[214.286,214.286],"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":"icon","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"t":170,"s":[43.5,43.5,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"green400","parent":5,"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":[71.264,71.264,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":240,"s":[0]},{"t":270,"s":[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":240,"op":1131,"st":231,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".green400","cl":"green400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":240,"op":982,"st":82,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".grey400","cl":"grey400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"t":166,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".grey600","cl":"grey600","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".grey600","cl":"grey600","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Matte","parent":3,"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,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":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Nail","parent":14,"tt":1,"tp":11,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Matte","parent":3,"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,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":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Finger","parent":3,"tt":1,"tp":13,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".black","cl":"black","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":930,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".black","cl":"black","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_unlock_90.json b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_unlock_90.json
new file mode 100644
index 000000000000..f9d13a6c64c2
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_fingerprint_to_unlock_90.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":181,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Unlock_90","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[-8.166,-1.704,0],"ix":2,"l":2},"a":{"a":0,"k":[-5.873,13.309,0],"ix":1,"l":2},"s":{"a":0,"k":[101.149,101.149,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.4,"y":0},"t":150,"s":[{"i":[[0,0],[0,0],[0.938,1.057],[1.355,0],[0.938,-1.057],[0,-1.527],[0,0],[-1.512,1.674],[-2.111,0],[-1.512,-1.703],[0,-2.408],[0,0]],"o":[[0,0],[0,-1.527],[-0.938,-1.057],[-1.329,0],[-0.938,1.057],[0,0],[0,-2.408],[1.486,-1.703],[2.137,0],[1.486,1.674],[0,0],[0,0]],"v":[[-0.17,-6.078],[-0.17,-9.822],[-1.577,-13.699],[-5.017,-15.284],[-8.419,-13.699],[-9.826,-9.822],[-12.68,-9.822],[-10.412,-15.945],[-5.017,-18.5],[0.456,-15.945],[2.684,-9.822],[2.684,-6.078]],"c":true}]},{"t":165,"s":[{"i":[[0,0],[0,0],[-1.069,1.057],[-1.545,0],[-1.069,-1.057],[0,-1.527],[0,0],[1.723,1.674],[2.406,0],[1.723,-1.703],[0,-2.408],[0,0]],"o":[[0,0],[0,-1.527],[1.069,-1.057],[1.515,0],[1.069,1.057],[0,0],[0,-2.408],[-1.693,-1.703],[-2.436,0],[-1.693,1.674],[0,0],[0,0]],"v":[[2.74,-6.079],[2.74,-9.823],[4.345,-13.699],[8.266,-15.285],[12.143,-13.699],[13.747,-9.823],[17,-9.823],[14.415,-15.945],[8.266,-18.5],[2.028,-15.945],[-0.512,-9.823],[-0.512,-6.079]],"c":true}]}],"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[214.286,214.286],"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":"icon","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[-8.166,-1.704,0],"ix":2,"l":2},"a":{"a":0,"k":[-5.873,13.309,0],"ix":1,"l":2},"s":{"a":0,"k":[101.149,101.149,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],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[8.266,15.285],[-13.747,15.285],[-13.747,-2.863],[8.266,-2.863]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.683,-0.675],[0.98,0],[0.683,0.675],[0,0.94],[-0.683,0.705],[-0.98,0],[-0.683,-0.705],[0,-0.94]],"o":[[-0.683,0.675],[-0.98,0],[-0.683,-0.675],[0,-0.94],[0.683,-0.705],[0.98,0],[0.683,0.705],[0,0.94]],"v":[[-0.245,8.677],[-2.74,9.69],[-5.236,8.677],[-6.261,6.255],[-5.236,3.788],[-2.74,2.731],[-0.245,3.788],[0.78,6.255]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[-0.624,-0.646],[-0.891,0],[0,0],[-0.624,0.617],[0,0.881],[0,0],[0.654,0.617],[0.891,0],[0,0],[0,0],[0,0],[0.654,-0.646],[0,-0.881],[0,0]],"o":[[0.654,0.617],[0,0],[0.891,0],[0.654,-0.646],[0,0],[0,-0.881],[-0.624,-0.646],[0,0],[0,0],[0,0],[-0.891,0],[-0.624,0.617],[0,0],[0,0.881]],"v":[[-16.064,17.575],[-13.747,18.5],[8.266,18.5],[10.539,17.575],[11.519,15.285],[11.519,-2.863],[10.539,-5.11],[8.266,-6.079],[2.74,-6.079],[-0.512,-6.079],[-13.747,-6.079],[-16.064,-5.11],[-17,-2.863],[-17,15.285]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[214.286,214.286],"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":"icon","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"t":170,"s":[43.5,43.5,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"green400","parent":5,"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":[71.264,71.264,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":240,"s":[0]},{"t":270,"s":[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":240,"op":1131,"st":231,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".green400","cl":"green400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":240,"op":982,"st":82,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".grey400","cl":"grey400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"t":166,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".grey600","cl":"grey600","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".grey600","cl":"grey600","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Matte","parent":3,"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,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":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Nail","parent":14,"tt":1,"tp":11,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Matte","parent":3,"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,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":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Finger","parent":3,"tt":1,"tp":13,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".black","cl":"black","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":930,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".black","cl":"black","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_error_to_fingerprint.json b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_error_to_fingerprint.json
new file mode 100644
index 000000000000..688ed7b3c57f
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_error_to_fingerprint.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":240,"op":421,"w":150,"h":150,"nm":"BM_Prompt_Error-to-FP_left","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[-64,64,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":170,"s":[-43.5,43.5,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":240,"s":[-43.5,43.5,100]},{"t":260,"s":[-64,64,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".red400","cl":"red400","parent":4,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.484,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.91,0.191,0],"ix":1,"l":2},"s":{"a":0,"k":[229.885,229.885,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[4,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,-7.079],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".red400","cl":"red400","parent":2,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-3.889,9.487,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.889,7.487,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":[4,4],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,7.491],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".red400","cl":"red400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933333333333,0.403921568627,0.360784313725,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Matte 3","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Nail 2","parent":11,"tt":1,"tp":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Matte 2","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"tp":10,"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":320,"s":[43]},{"t":365,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":320,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":365,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Nail","parent":15,"tt":1,"tp":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":14,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":320,"s":[50]},{"t":390,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":290,"s":[0,0,100]},{"t":380,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":290,"op":391,"st":290,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":290,"s":[50]},{"t":360,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":260,"s":[0,0,100]},{"t":350,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":391,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":131,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":131,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_error_to_fingerprint_180.json b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_error_to_fingerprint_180.json
new file mode 100644
index 000000000000..fa6fc07c3fe6
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_error_to_fingerprint_180.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":240,"op":421,"w":150,"h":150,"nm":"BM_Prompt_Error-to-FP_0and180","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":170,"s":[43.5,43.5,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":240,"s":[43.5,43.5,100]},{"t":260,"s":[64,64,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".red400","cl":"red400","parent":4,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.484,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.91,0.191,0],"ix":1,"l":2},"s":{"a":0,"k":[229.885,229.885,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[4,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,-7.079],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".red400","cl":"red400","parent":2,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-3.889,9.487,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.889,7.487,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":[4,4],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,7.491],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".red400","cl":"red400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933333333333,0.403921568627,0.360784313725,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Matte 3","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Nail 2","parent":11,"tt":1,"tp":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Matte 2","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"tp":10,"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":320,"s":[43]},{"t":365,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":320,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":365,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Nail","parent":15,"tt":1,"tp":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":14,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":320,"s":[50]},{"t":390,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":290,"s":[0,0,100]},{"t":380,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":290,"op":391,"st":290,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":290,"s":[50]},{"t":360,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":260,"s":[0,0,100]},{"t":350,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":391,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":131,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":131,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_error_to_fingerprint_270.json b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_error_to_fingerprint_270.json
new file mode 100644
index 000000000000..9e6b4228c3e8
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_error_to_fingerprint_270.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":240,"op":421,"w":150,"h":150,"nm":"BM_Prompt_Error-to-FP_90","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":170,"s":[43.5,43.5,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":240,"s":[43.5,43.5,100]},{"t":260,"s":[64,64,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".red400","cl":"red400","parent":4,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.484,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.91,0.191,0],"ix":1,"l":2},"s":{"a":0,"k":[229.885,229.885,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[4,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,-7.079],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".red400","cl":"red400","parent":2,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-3.889,9.487,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.889,7.487,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":[4,4],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,7.491],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".red400","cl":"red400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":90,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933333333333,0.403921568627,0.360784313725,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Matte 3","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Nail 2","parent":11,"tt":1,"tp":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Matte 2","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"tp":10,"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":320,"s":[43]},{"t":365,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":320,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":365,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Nail","parent":15,"tt":1,"tp":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":14,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":320,"s":[50]},{"t":390,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":290,"s":[0,0,100]},{"t":380,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":290,"op":391,"st":290,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":290,"s":[50]},{"t":360,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":260,"s":[0,0,100]},{"t":350,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":391,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":131,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":131,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_error_to_fingerprint_90.json b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_error_to_fingerprint_90.json
new file mode 100644
index 000000000000..477c489ad086
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_error_to_fingerprint_90.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":240,"op":421,"w":150,"h":150,"nm":"BM_Prompt_Error-to-FP_270","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":170,"s":[43.5,43.5,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":240,"s":[43.5,43.5,100]},{"t":260,"s":[64,64,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".red400","cl":"red400","parent":4,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.484,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.91,0.191,0],"ix":1,"l":2},"s":{"a":0,"k":[229.885,229.885,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[4,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,-7.079],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".red400","cl":"red400","parent":2,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-3.889,9.487,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.889,7.487,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":[4,4],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,7.491],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".red400","cl":"red400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":270,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933333333333,0.403921568627,0.360784313725,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Matte 3","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Nail 2","parent":11,"tt":1,"tp":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Matte 2","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"tp":10,"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":320,"s":[43]},{"t":365,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":320,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":365,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Nail","parent":15,"tt":1,"tp":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":14,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":320,"s":[50]},{"t":390,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":290,"s":[0,0,100]},{"t":380,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":290,"op":391,"st":290,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":290,"s":[50]},{"t":360,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":260,"s":[0,0,100]},{"t":350,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":391,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":131,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":131,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_authenticating.json b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_authenticating.json
new file mode 100755
index 000000000000..c68803767266
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_authenticating.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":301,"w":150,"h":150,"nm":"BM_Prompt_180","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[-64,64,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Nail","parent":8,"tt":1,"tp":5,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":7,"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":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".blue401","cl":"blue401","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":930,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".black","cl":"black","parent":1,"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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_error.json b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_error.json
new file mode 100644
index 000000000000..4e66cfa2a40a
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_error.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":181,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Error_left","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[-64,64,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":170,"s":[-43.5,43.5,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":240,"s":[-43.5,43.5,100]},{"t":260,"s":[-64,64,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".red400","cl":"red400","parent":4,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.484,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.91,0.191,0],"ix":1,"l":2},"s":{"a":0,"k":[229.885,229.885,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[4,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,-7.079],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".red400","cl":"red400","parent":2,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-3.889,9.487,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.889,7.487,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":[4,4],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,7.491],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".red400","cl":"red400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933333333333,0.403921568627,0.360784313725,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Matte 3","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Nail 2","parent":11,"tt":1,"tp":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Matte 2","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"tp":10,"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":320,"s":[43]},{"t":365,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":320,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":365,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Nail","parent":15,"tt":1,"tp":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":14,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":320,"s":[50]},{"t":390,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":290,"s":[0,0,100]},{"t":380,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":290,"op":391,"st":290,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":290,"s":[50]},{"t":360,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":260,"s":[0,0,100]},{"t":350,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":391,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":131,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":131,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_error_180.json b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_error_180.json
new file mode 100644
index 000000000000..603760f1fbf8
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_error_180.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":181,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Error_0and180","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":170,"s":[43.5,43.5,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":240,"s":[43.5,43.5,100]},{"t":260,"s":[64,64,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".red400","cl":"red400","parent":4,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.484,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.91,0.191,0],"ix":1,"l":2},"s":{"a":0,"k":[229.885,229.885,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[4,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,-7.079],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".red400","cl":"red400","parent":2,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-3.889,9.487,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.889,7.487,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":[4,4],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,7.491],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".red400","cl":"red400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933333333333,0.403921568627,0.360784313725,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Matte 3","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Nail 2","parent":11,"tt":1,"tp":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Matte 2","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"tp":10,"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":320,"s":[43]},{"t":365,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":320,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":365,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Nail","parent":15,"tt":1,"tp":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":14,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":320,"s":[50]},{"t":390,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":290,"s":[0,0,100]},{"t":380,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":290,"op":391,"st":290,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":290,"s":[50]},{"t":360,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":260,"s":[0,0,100]},{"t":350,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":391,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":131,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":131,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_error_270.json b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_error_270.json
new file mode 100644
index 000000000000..59dc0d4c4c85
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_error_270.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":181,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Error_90","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":170,"s":[43.5,43.5,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":240,"s":[43.5,43.5,100]},{"t":260,"s":[64,64,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".red400","cl":"red400","parent":4,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.484,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.91,0.191,0],"ix":1,"l":2},"s":{"a":0,"k":[229.885,229.885,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[4,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,-7.079],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".red400","cl":"red400","parent":2,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-3.889,9.487,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.889,7.487,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":[4,4],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,7.491],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".red400","cl":"red400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":90,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933333333333,0.403921568627,0.360784313725,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Matte 3","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Nail 2","parent":11,"tt":1,"tp":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Matte 2","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"tp":10,"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":320,"s":[43]},{"t":365,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":320,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":365,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Nail","parent":15,"tt":1,"tp":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":14,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":320,"s":[50]},{"t":390,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":290,"s":[0,0,100]},{"t":380,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":290,"op":391,"st":290,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":290,"s":[50]},{"t":360,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":260,"s":[0,0,100]},{"t":350,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":391,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":131,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":131,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_error_90.json b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_error_90.json
new file mode 100644
index 000000000000..a1d2251b8e7a
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_error_90.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":181,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Error_270","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":170,"s":[43.5,43.5,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":240,"s":[43.5,43.5,100]},{"t":260,"s":[64,64,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".red400","cl":"red400","parent":4,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,8.484,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.91,0.191,0],"ix":1,"l":2},"s":{"a":0,"k":[229.885,229.885,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[4,20],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,-7.079],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".red400","cl":"red400","parent":2,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-3.889,9.487,0],"ix":2,"l":2},"a":{"a":0,"k":[-3.889,7.487,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":[4,4],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333396912,0.403921604156,0.360784322023,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":[-3.91,7.491],"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":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".red400","cl":"red400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":270,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933333333333,0.403921568627,0.360784313725,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":170,"s":[6]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":240,"s":[6]},{"t":260,"s":[4]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Matte 3","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Nail 2","parent":11,"tt":1,"tp":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Matte 2","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"tp":10,"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":320,"s":[43]},{"t":365,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":320,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":365,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":428,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Nail","parent":15,"tt":1,"tp":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":14,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":159,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":320,"s":[50]},{"t":390,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":290,"s":[0,0,100]},{"t":380,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":290,"op":391,"st":290,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":290,"s":[50]},{"t":360,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":260,"s":[0,0,100]},{"t":350,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":260,"op":391,"st":260,"ct":1,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":131,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":131,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":248,"s":[0]},{"t":256,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_success.json b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_success.json
new file mode 100644
index 000000000000..21ee20d02d78
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_success.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":211,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Success_left","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[-64,64,100]},{"t":170,"s":[-43.5,43.5,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"green400","parent":3,"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":[-71.264,71.264,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":150,"s":[0]},{"t":180,"s":[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":150,"op":1041,"st":141,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".green400","cl":"green400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"t":166,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"t":166,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Nail","parent":10,"tt":1,"tp":7,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":9,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":930,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_success_180.json b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_success_180.json
new file mode 100644
index 000000000000..e2c850062985
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_success_180.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":211,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Success_0and180","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"t":170,"s":[43.5,43.5,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"green400","parent":3,"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":[71.264,71.264,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":150,"s":[0]},{"t":180,"s":[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":150,"op":1041,"st":141,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".green400","cl":"green400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"t":166,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"t":166,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Nail","parent":10,"tt":1,"tp":7,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":9,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":930,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_success_270.json b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_success_270.json
new file mode 100644
index 000000000000..51e17f7c5fa3
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_success_270.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":211,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Success_90","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"t":170,"s":[43.5,43.5,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"green400","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"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":[71.264,71.264,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":150,"s":[0]},{"t":180,"s":[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":150,"op":1041,"st":141,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".green400","cl":"green400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"t":166,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"t":166,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Nail","parent":10,"tt":1,"tp":7,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":9,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":930,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_success_90.json b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_success_90.json
new file mode 100644
index 000000000000..4c1a80955906
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_success_90.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":211,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Success_270","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"t":170,"s":[43.5,43.5,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"green400","parent":3,"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":[71.264,71.264,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":150,"s":[0]},{"t":180,"s":[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":150,"op":1041,"st":141,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".green400","cl":"green400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"t":166,"s":[100]}],"ix":11},"r":{"a":0,"k":-90,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey400","cl":"grey400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"t":166,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".grey600","cl":"grey600","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Nail","parent":10,"tt":1,"tp":7,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Matte","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":[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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Finger","parent":1,"tt":1,"tp":9,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.833,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":930,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".blue400","cl":"blue400","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".black","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_unlock.json b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_unlock.json
new file mode 100644
index 000000000000..56cd2adc14e3
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_unlock.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":181,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Unlock_left","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1.704,8.166,0],"ix":2,"l":2},"a":{"a":0,"k":[-5.873,13.309,0],"ix":1,"l":2},"s":{"a":0,"k":[-101.149,101.149,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.4,"y":0},"t":150,"s":[{"i":[[0,0],[0,0],[0.938,1.057],[1.355,0],[0.938,-1.057],[0,-1.527],[0,0],[-1.512,1.674],[-2.111,0],[-1.512,-1.703],[0,-2.408],[0,0]],"o":[[0,0],[0,-1.527],[-0.938,-1.057],[-1.329,0],[-0.938,1.057],[0,0],[0,-2.408],[1.486,-1.703],[2.137,0],[1.486,1.674],[0,0],[0,0]],"v":[[-0.17,-6.078],[-0.17,-9.822],[-1.577,-13.699],[-5.017,-15.284],[-8.419,-13.699],[-9.826,-9.822],[-12.68,-9.822],[-10.412,-15.945],[-5.017,-18.5],[0.456,-15.945],[2.684,-9.822],[2.684,-6.078]],"c":true}]},{"t":165,"s":[{"i":[[0,0],[0,0],[-1.069,1.057],[-1.545,0],[-1.069,-1.057],[0,-1.527],[0,0],[1.723,1.674],[2.406,0],[1.723,-1.703],[0,-2.408],[0,0]],"o":[[0,0],[0,-1.527],[1.069,-1.057],[1.515,0],[1.069,1.057],[0,0],[0,-2.408],[-1.693,-1.703],[-2.436,0],[-1.693,1.674],[0,0],[0,0]],"v":[[2.74,-6.079],[2.74,-9.823],[4.345,-13.699],[8.266,-15.285],[12.143,-13.699],[13.747,-9.823],[17,-9.823],[14.415,-15.945],[8.266,-18.5],[2.028,-15.945],[-0.512,-9.823],[-0.512,-6.079]],"c":true}]}],"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[214.286,214.286],"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":"icon","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1.704,8.166,0],"ix":2,"l":2},"a":{"a":0,"k":[-5.873,13.309,0],"ix":1,"l":2},"s":{"a":0,"k":[-101.149,101.149,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],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[8.266,15.285],[-13.747,15.285],[-13.747,-2.863],[8.266,-2.863]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.683,-0.675],[0.98,0],[0.683,0.675],[0,0.94],[-0.683,0.705],[-0.98,0],[-0.683,-0.705],[0,-0.94]],"o":[[-0.683,0.675],[-0.98,0],[-0.683,-0.675],[0,-0.94],[0.683,-0.705],[0.98,0],[0.683,0.705],[0,0.94]],"v":[[-0.245,8.677],[-2.74,9.69],[-5.236,8.677],[-6.261,6.255],[-5.236,3.788],[-2.74,2.731],[-0.245,3.788],[0.78,6.255]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[-0.624,-0.646],[-0.891,0],[0,0],[-0.624,0.617],[0,0.881],[0,0],[0.654,0.617],[0.891,0],[0,0],[0,0],[0,0],[0.654,-0.646],[0,-0.881],[0,0]],"o":[[0.654,0.617],[0,0],[0.891,0],[0.654,-0.646],[0,0],[0,-0.881],[-0.624,-0.646],[0,0],[0,0],[0,0],[-0.891,0],[-0.624,0.617],[0,0],[0,0.881]],"v":[[-16.064,17.575],[-13.747,18.5],[8.266,18.5],[10.539,17.575],[11.519,15.285],[11.519,-2.863],[10.539,-5.11],[8.266,-6.079],[2.74,-6.079],[-0.512,-6.079],[-13.747,-6.079],[-16.064,-5.11],[-17,-2.863],[-17,15.285]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[214.286,214.286],"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":"icon","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[-64,64,100]},{"t":170,"s":[-43.5,43.5,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"green400","parent":5,"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":[71.264,71.264,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":240,"s":[0]},{"t":270,"s":[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":240,"op":1131,"st":231,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".green400","cl":"green400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":240,"op":982,"st":82,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".grey400","cl":"grey400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"t":166,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".grey600","cl":"grey600","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".grey600","cl":"grey600","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Matte","parent":3,"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,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":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Nail","parent":14,"tt":1,"tp":11,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Matte","parent":3,"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,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":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Finger","parent":3,"tt":1,"tp":13,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".black","cl":"black","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":930,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".black","cl":"black","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_unlock_180.json b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_unlock_180.json
new file mode 100644
index 000000000000..c4db1e4b2ff6
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_unlock_180.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":181,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Unlock_0and180","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-1.704,8.166,0],"ix":2,"l":2},"a":{"a":0,"k":[-5.873,13.309,0],"ix":1,"l":2},"s":{"a":0,"k":[101.149,101.149,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.4,"y":0},"t":150,"s":[{"i":[[0,0],[0,0],[0.938,1.057],[1.355,0],[0.938,-1.057],[0,-1.527],[0,0],[-1.512,1.674],[-2.111,0],[-1.512,-1.703],[0,-2.408],[0,0]],"o":[[0,0],[0,-1.527],[-0.938,-1.057],[-1.329,0],[-0.938,1.057],[0,0],[0,-2.408],[1.486,-1.703],[2.137,0],[1.486,1.674],[0,0],[0,0]],"v":[[-0.17,-6.078],[-0.17,-9.822],[-1.577,-13.699],[-5.017,-15.284],[-8.419,-13.699],[-9.826,-9.822],[-12.68,-9.822],[-10.412,-15.945],[-5.017,-18.5],[0.456,-15.945],[2.684,-9.822],[2.684,-6.078]],"c":true}]},{"t":165,"s":[{"i":[[0,0],[0,0],[-1.069,1.057],[-1.545,0],[-1.069,-1.057],[0,-1.527],[0,0],[1.723,1.674],[2.406,0],[1.723,-1.703],[0,-2.408],[0,0]],"o":[[0,0],[0,-1.527],[1.069,-1.057],[1.515,0],[1.069,1.057],[0,0],[0,-2.408],[-1.693,-1.703],[-2.436,0],[-1.693,1.674],[0,0],[0,0]],"v":[[2.74,-6.079],[2.74,-9.823],[4.345,-13.699],[8.266,-15.285],[12.143,-13.699],[13.747,-9.823],[17,-9.823],[14.415,-15.945],[8.266,-18.5],[2.028,-15.945],[-0.512,-9.823],[-0.512,-6.079]],"c":true}]}],"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[214.286,214.286],"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":"icon","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-1.704,8.166,0],"ix":2,"l":2},"a":{"a":0,"k":[-5.873,13.309,0],"ix":1,"l":2},"s":{"a":0,"k":[101.149,101.149,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],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[8.266,15.285],[-13.747,15.285],[-13.747,-2.863],[8.266,-2.863]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.683,-0.675],[0.98,0],[0.683,0.675],[0,0.94],[-0.683,0.705],[-0.98,0],[-0.683,-0.705],[0,-0.94]],"o":[[-0.683,0.675],[-0.98,0],[-0.683,-0.675],[0,-0.94],[0.683,-0.705],[0.98,0],[0.683,0.705],[0,0.94]],"v":[[-0.245,8.677],[-2.74,9.69],[-5.236,8.677],[-6.261,6.255],[-5.236,3.788],[-2.74,2.731],[-0.245,3.788],[0.78,6.255]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[-0.624,-0.646],[-0.891,0],[0,0],[-0.624,0.617],[0,0.881],[0,0],[0.654,0.617],[0.891,0],[0,0],[0,0],[0,0],[0.654,-0.646],[0,-0.881],[0,0]],"o":[[0.654,0.617],[0,0],[0.891,0],[0.654,-0.646],[0,0],[0,-0.881],[-0.624,-0.646],[0,0],[0,0],[0,0],[-0.891,0],[-0.624,0.617],[0,0],[0,0.881]],"v":[[-16.064,17.575],[-13.747,18.5],[8.266,18.5],[10.539,17.575],[11.519,15.285],[11.519,-2.863],[10.539,-5.11],[8.266,-6.079],[2.74,-6.079],[-0.512,-6.079],[-13.747,-6.079],[-16.064,-5.11],[-17,-2.863],[-17,15.285]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[214.286,214.286],"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":"icon","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"t":170,"s":[43.5,43.5,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"green400","parent":5,"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":[71.264,71.264,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":240,"s":[0]},{"t":270,"s":[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":240,"op":1131,"st":231,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".green400","cl":"green400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":240,"op":982,"st":82,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".grey400","cl":"grey400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"t":166,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".grey600","cl":"grey600","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".grey600","cl":"grey600","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Matte","parent":3,"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,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":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Nail","parent":14,"tt":1,"tp":11,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Matte","parent":3,"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,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":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Finger","parent":3,"tt":1,"tp":13,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".black","cl":"black","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":930,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".black","cl":"black","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_unlock_270.json b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_unlock_270.json
new file mode 100644
index 000000000000..f9d13a6c64c2
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_unlock_270.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":181,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Unlock_90","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[-8.166,-1.704,0],"ix":2,"l":2},"a":{"a":0,"k":[-5.873,13.309,0],"ix":1,"l":2},"s":{"a":0,"k":[101.149,101.149,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.4,"y":0},"t":150,"s":[{"i":[[0,0],[0,0],[0.938,1.057],[1.355,0],[0.938,-1.057],[0,-1.527],[0,0],[-1.512,1.674],[-2.111,0],[-1.512,-1.703],[0,-2.408],[0,0]],"o":[[0,0],[0,-1.527],[-0.938,-1.057],[-1.329,0],[-0.938,1.057],[0,0],[0,-2.408],[1.486,-1.703],[2.137,0],[1.486,1.674],[0,0],[0,0]],"v":[[-0.17,-6.078],[-0.17,-9.822],[-1.577,-13.699],[-5.017,-15.284],[-8.419,-13.699],[-9.826,-9.822],[-12.68,-9.822],[-10.412,-15.945],[-5.017,-18.5],[0.456,-15.945],[2.684,-9.822],[2.684,-6.078]],"c":true}]},{"t":165,"s":[{"i":[[0,0],[0,0],[-1.069,1.057],[-1.545,0],[-1.069,-1.057],[0,-1.527],[0,0],[1.723,1.674],[2.406,0],[1.723,-1.703],[0,-2.408],[0,0]],"o":[[0,0],[0,-1.527],[1.069,-1.057],[1.515,0],[1.069,1.057],[0,0],[0,-2.408],[-1.693,-1.703],[-2.436,0],[-1.693,1.674],[0,0],[0,0]],"v":[[2.74,-6.079],[2.74,-9.823],[4.345,-13.699],[8.266,-15.285],[12.143,-13.699],[13.747,-9.823],[17,-9.823],[14.415,-15.945],[8.266,-18.5],[2.028,-15.945],[-0.512,-9.823],[-0.512,-6.079]],"c":true}]}],"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[214.286,214.286],"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":"icon","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[-8.166,-1.704,0],"ix":2,"l":2},"a":{"a":0,"k":[-5.873,13.309,0],"ix":1,"l":2},"s":{"a":0,"k":[101.149,101.149,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],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[8.266,15.285],[-13.747,15.285],[-13.747,-2.863],[8.266,-2.863]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.683,-0.675],[0.98,0],[0.683,0.675],[0,0.94],[-0.683,0.705],[-0.98,0],[-0.683,-0.705],[0,-0.94]],"o":[[-0.683,0.675],[-0.98,0],[-0.683,-0.675],[0,-0.94],[0.683,-0.705],[0.98,0],[0.683,0.705],[0,0.94]],"v":[[-0.245,8.677],[-2.74,9.69],[-5.236,8.677],[-6.261,6.255],[-5.236,3.788],[-2.74,2.731],[-0.245,3.788],[0.78,6.255]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[-0.624,-0.646],[-0.891,0],[0,0],[-0.624,0.617],[0,0.881],[0,0],[0.654,0.617],[0.891,0],[0,0],[0,0],[0,0],[0.654,-0.646],[0,-0.881],[0,0]],"o":[[0.654,0.617],[0,0],[0.891,0],[0.654,-0.646],[0,0],[0,-0.881],[-0.624,-0.646],[0,0],[0,0],[0,0],[-0.891,0],[-0.624,0.617],[0,0],[0,0.881]],"v":[[-16.064,17.575],[-13.747,18.5],[8.266,18.5],[10.539,17.575],[11.519,15.285],[11.519,-2.863],[10.539,-5.11],[8.266,-6.079],[2.74,-6.079],[-0.512,-6.079],[-13.747,-6.079],[-16.064,-5.11],[-17,-2.863],[-17,15.285]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[214.286,214.286],"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":"icon","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"t":170,"s":[43.5,43.5,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"green400","parent":5,"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":[71.264,71.264,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":240,"s":[0]},{"t":270,"s":[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":240,"op":1131,"st":231,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".green400","cl":"green400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":240,"op":982,"st":82,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".grey400","cl":"grey400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"t":166,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".grey600","cl":"grey600","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".grey600","cl":"grey600","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Matte","parent":3,"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,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":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Nail","parent":14,"tt":1,"tp":11,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Matte","parent":3,"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,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":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Finger","parent":3,"tt":1,"tp":13,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".black","cl":"black","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":930,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".black","cl":"black","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_unlock_90.json b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_unlock_90.json
new file mode 100644
index 000000000000..30bb2d9f4fa6
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_rear_display_fingerprint_to_unlock_90.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":0,"op":181,"w":150,"h":150,"nm":"BM_Prompt_FP-to-Unlock_270","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[8.166,1.704,0],"ix":2,"l":2},"a":{"a":0,"k":[-5.873,13.309,0],"ix":1,"l":2},"s":{"a":0,"k":[101.149,101.149,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.4,"y":0},"t":150,"s":[{"i":[[0,0],[0,0],[0.938,1.057],[1.355,0],[0.938,-1.057],[0,-1.527],[0,0],[-1.512,1.674],[-2.111,0],[-1.512,-1.703],[0,-2.408],[0,0]],"o":[[0,0],[0,-1.527],[-0.938,-1.057],[-1.329,0],[-0.938,1.057],[0,0],[0,-2.408],[1.486,-1.703],[2.137,0],[1.486,1.674],[0,0],[0,0]],"v":[[-0.17,-6.078],[-0.17,-9.822],[-1.577,-13.699],[-5.017,-15.284],[-8.419,-13.699],[-9.826,-9.822],[-12.68,-9.822],[-10.412,-15.945],[-5.017,-18.5],[0.456,-15.945],[2.684,-9.822],[2.684,-6.078]],"c":true}]},{"t":165,"s":[{"i":[[0,0],[0,0],[-1.069,1.057],[-1.545,0],[-1.069,-1.057],[0,-1.527],[0,0],[1.723,1.674],[2.406,0],[1.723,-1.703],[0,-2.408],[0,0]],"o":[[0,0],[0,-1.527],[1.069,-1.057],[1.515,0],[1.069,1.057],[0,0],[0,-2.408],[-1.693,-1.703],[-2.436,0],[-1.693,1.674],[0,0],[0,0]],"v":[[2.74,-6.079],[2.74,-9.823],[4.345,-13.699],[8.266,-15.285],[12.143,-13.699],[13.747,-9.823],[17,-9.823],[14.415,-15.945],[8.266,-18.5],[2.028,-15.945],[-0.512,-9.823],[-0.512,-6.079]],"c":true}]}],"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[214.286,214.286],"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":"icon","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[8.166,1.704,0],"ix":2,"l":2},"a":{"a":0,"k":[-5.873,13.309,0],"ix":1,"l":2},"s":{"a":0,"k":[101.149,101.149,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],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[8.266,15.285],[-13.747,15.285],[-13.747,-2.863],[8.266,-2.863]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.683,-0.675],[0.98,0],[0.683,0.675],[0,0.94],[-0.683,0.705],[-0.98,0],[-0.683,-0.705],[0,-0.94]],"o":[[-0.683,0.675],[-0.98,0],[-0.683,-0.675],[0,-0.94],[0.683,-0.705],[0.98,0],[0.683,0.705],[0,0.94]],"v":[[-0.245,8.677],[-2.74,9.69],[-5.236,8.677],[-6.261,6.255],[-5.236,3.788],[-2.74,2.731],[-0.245,3.788],[0.78,6.255]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[-0.624,-0.646],[-0.891,0],[0,0],[-0.624,0.617],[0,0.881],[0,0],[0.654,0.617],[0.891,0],[0,0],[0,0],[0,0],[0.654,-0.646],[0,-0.881],[0,0]],"o":[[0.654,0.617],[0,0],[0.891,0],[0.654,-0.646],[0,0],[0,-0.881],[-0.624,-0.646],[0,0],[0,0],[0,0],[-0.891,0],[-0.624,0.617],[0,0],[0,0.881]],"v":[[-16.064,17.575],[-13.747,18.5],[8.266,18.5],[10.539,17.575],[11.519,15.285],[11.519,-2.863],[10.539,-5.11],[8.266,-6.079],[2.74,-6.079],[-0.512,-6.079],[-13.747,-6.079],[-16.064,-5.11],[-17,-2.863],[-17,15.285]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[214.286,214.286],"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":"icon","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"t":170,"s":[43.5,43.5,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"green400","parent":5,"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":[71.264,71.264,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":240,"s":[0]},{"t":270,"s":[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":240,"op":1131,"st":231,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".green400","cl":"green400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":240,"op":982,"st":82,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".grey400","cl":"grey400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"t":166,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".grey600","cl":"grey600","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".grey600","cl":"grey600","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Matte","parent":3,"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,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":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Nail","parent":14,"tt":1,"tp":11,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Matte","parent":3,"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,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":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Finger","parent":3,"tt":1,"tp":13,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".black","cl":"black","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":930,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".black","cl":"black","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_sfps_unlock_to_success.json b/packages/SystemUI/res/raw/biometricprompt_sfps_unlock_to_success.json
new file mode 100644
index 000000000000..141ebb763308
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_sfps_unlock_to_success.json
@@ -0,0 +1 @@
+{"v":"5.10.2","fr":60,"ip":240,"op":361,"w":150,"h":150,"nm":"BM_Prompt_FP_to_Unlock","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".blue403","cl":"blue403","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-1.704,8.166,0],"ix":2,"l":2},"a":{"a":0,"k":[-5.873,13.309,0],"ix":1,"l":2},"s":{"a":0,"k":[101.149,101.149,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.4,"y":0},"t":150,"s":[{"i":[[0,0],[0,0],[0.938,1.057],[1.355,0],[0.938,-1.057],[0,-1.527],[0,0],[-1.512,1.674],[-2.111,0],[-1.512,-1.703],[0,-2.408],[0,0]],"o":[[0,0],[0,-1.527],[-0.938,-1.057],[-1.329,0],[-0.938,1.057],[0,0],[0,-2.408],[1.486,-1.703],[2.137,0],[1.486,1.674],[0,0],[0,0]],"v":[[-0.17,-6.078],[-0.17,-9.822],[-1.577,-13.699],[-5.017,-15.284],[-8.419,-13.699],[-9.826,-9.822],[-12.68,-9.822],[-10.412,-15.945],[-5.017,-18.5],[0.456,-15.945],[2.684,-9.822],[2.684,-6.078]],"c":true}]},{"t":165,"s":[{"i":[[0,0],[0,0],[-1.069,1.057],[-1.545,0],[-1.069,-1.057],[0,-1.527],[0,0],[1.723,1.674],[2.406,0],[1.723,-1.703],[0,-2.408],[0,0]],"o":[[0,0],[0,-1.527],[1.069,-1.057],[1.515,0],[1.069,1.057],[0,0],[0,-2.408],[-1.693,-1.703],[-2.436,0],[-1.693,1.674],[0,0],[0,0]],"v":[[2.74,-6.079],[2.74,-9.823],[4.345,-13.699],[8.266,-15.285],[12.143,-13.699],[13.747,-9.823],[17,-9.823],[14.415,-15.945],[8.266,-18.5],[2.028,-15.945],[-0.512,-9.823],[-0.512,-6.079]],"c":true}]}],"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[214.286,214.286],"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":"icon","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".blue402","cl":"blue402","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":154,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":162,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-1.704,8.166,0],"ix":2,"l":2},"a":{"a":0,"k":[-5.873,13.309,0],"ix":1,"l":2},"s":{"a":0,"k":[101.149,101.149,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],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[8.266,15.285],[-13.747,15.285],[-13.747,-2.863],[8.266,-2.863]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.683,-0.675],[0.98,0],[0.683,0.675],[0,0.94],[-0.683,0.705],[-0.98,0],[-0.683,-0.705],[0,-0.94]],"o":[[-0.683,0.675],[-0.98,0],[-0.683,-0.675],[0,-0.94],[0.683,-0.705],[0.98,0],[0.683,0.705],[0,0.94]],"v":[[-0.245,8.677],[-2.74,9.69],[-5.236,8.677],[-6.261,6.255],[-5.236,3.788],[-2.74,2.731],[-0.245,3.788],[0.78,6.255]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[-0.624,-0.646],[-0.891,0],[0,0],[-0.624,0.617],[0,0.881],[0,0],[0.654,0.617],[0.891,0],[0,0],[0,0],[0,0],[0.654,-0.646],[0,-0.881],[0,0]],"o":[[0.654,0.617],[0,0],[0.891,0],[0.654,-0.646],[0,0],[0,-0.881],[-0.624,-0.646],[0,0],[0,0],[0,0],[-0.891,0],[-0.624,0.617],[0,0],[0,0.881]],"v":[[-16.064,17.575],[-13.747,18.5],[8.266,18.5],[10.539,17.575],[11.519,15.285],[11.519,-2.863],[10.539,-5.11],[8.266,-6.079],[2.74,-6.079],[-0.512,-6.079],[-13.747,-6.079],[-16.064,-5.11],[-17,-2.863],[-17,15.285]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[214.286,214.286],"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":"icon","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":3,"nm":"Null 29","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":150,"s":[64,64,100]},{"t":170,"s":[43.5,43.5,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"green400","parent":5,"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":[71.264,71.264,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":240,"s":[0]},{"t":270,"s":[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":240,"op":1131,"st":231,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".green400","cl":"green400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"t":248,"s":[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,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.356862745098,0.725490196078,0.454901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":240,"op":982,"st":82,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":166,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[100]},{"t":248,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.4,0.61568627451,0.964705882353,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".grey400","cl":"grey400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":158,"s":[100]},{"t":166,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":150,"s":[4]},{"t":170,"s":[6]}],"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".grey600","cl":"grey600","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.422,1.727,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,-2.148],[0,0],[2.171,0.019],[0,0]],"o":[[0,0],[0,2.148],[0,0],[2.171,0.084]],"v":[[1.504,-10.64],[1.504,10.641],[-2.285,14.585],[-2.285,-14.582]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".grey600","cl":"grey600","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.73,0.002,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":[[-1.503,-0.24],[0,0],[1.545,-0.103],[0,0]],"o":[[0,0],[-1.503,0.24],[0,0],[1.545,0.103]],"v":[[2.287,-49.365],[2.287,49.365],[-2.287,49.875],[-2.287,-49.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Matte","parent":3,"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,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":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Nail","parent":14,"tt":1,"tp":11,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.413,-32.45,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":[[-2.537,-10.49],[3.914,3.121],[0.029,0.49],[-0.203,0.012]],"o":[[0,0],[-5.309,-4.235],[0.195,-0.025],[6.139,-0.367]],"v":[[5.837,9.643],[-1.02,8.379],[-5.837,-9.817],[-5.232,-9.874]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Matte","parent":3,"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,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":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"o":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"v":[[0,50],[50,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Finger","parent":3,"tt":1,"tp":13,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[43]},{"t":105,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":60,"s":[53.57,92.052,0],"to":[-14.604,-5.758,0],"ti":[0.932,11.227,0]},{"t":105,"s":[29.227,68.052,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-0.948,45.138,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":[[-4.392,-3.688],[0,0],[-1.205,-3.8],[-1.473,-3.596],[9.145,-3.485],[1.549,12.262],[-8.315,0.872]],"o":[[3.368,2.829],[0.954,3.951],[1.895,5.97],[-5.664,7.791],[-3.418,-14.412],[-2.036,-16.119],[0.029,0.49]],"v":[[-0.286,-13.646],[6.116,-11.991],[9.253,-0.135],[15.167,17.416],[-8.324,31.452],[-14.517,-6.098],[-5.559,-31.452]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".black","cl":"black","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.782,1.408,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.716,3.431],[1.716,0],[-1.716,-3.431]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-13.268,1.408,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,8.054],[-8.054,0]],"o":[[-8.054,0],[0,-8.054],[0,0]],"v":[[7.292,14.583],[-7.292,0],[7.292,-14.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".blue401","cl":"blue401","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":60,"s":[50]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":30,"s":[0,0,100]},{"t":120,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":930,"st":30,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue400","cl":"blue400","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":30,"s":[50]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.33,1.408,0],"ix":2,"l":2},"a":{"a":0,"k":[22.5,-0.242,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.667],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":90,"s":[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,16.658],[-16.658,0]],"o":[[-16.658,0],[0,-16.658],[0,0]],"v":[[15.081,30.161],[-15.081,0],[15.081,-30.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,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":[150,150],"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":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":".black","cl":"black","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":150,"s":[100]},{"t":158,"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":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-31.25,-2.604],[0,27.614],[0,0],[0,-27.614]],"o":[[0,-0.13],[0,-27.614],[-27.344,-0.651],[0,27.614]],"v":[[0,50],[1.172,0],[0,-50],[-50,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[150,150],"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":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":900,"st":0,"ct":1,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_symbol_error_to_fingerprint_landscape.json b/packages/SystemUI/res/raw/biometricprompt_symbol_error_to_fingerprint_landscape.json
deleted file mode 100644
index 034ac87c0f94..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_symbol_error_to_fingerprint_landscape.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.9.0","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"biometricprompt_symbol_error_to_fingerprint_landscape","ddd":0,"assets":[{"id":"comp_0","nm":"Fingerprint_Animation_ForConfirm_Short_For_ErrorToFingerprint","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"circle fill 5","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":249,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":388,"s":[100]},{"t":408,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":239,"op":1411,"st":239,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"t":249,"s":[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":239,"op":1139,"st":239,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".green400","cl":"green400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":249,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":388,"s":[100]},{"t":408,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.450980392157,0.709803921569,0.470588235294,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":239,"op":1411,"st":239,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"circle fill 3","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":80,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":90,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.8,"y":0},"t":108,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"t":118,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,35.389],[-0.111,50.111]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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.049,42.698],"ix":2},"a":{"a":0,"k":[0.049,42.698],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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 2","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":80,"op":980,"st":80,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".red400","cl":"red400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":7,"ty":3,"nm":"Null 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.833,"y":0.833},"o":{"x":0.333,"y":0.333},"t":85,"s":[209.333,136.333,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":440,"s":[209.333,136.333,0],"to":[1.944,2.278,0],"ti":[3.056,-2.278,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":450,"s":[221,150,0],"to":[-3.056,2.278,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":460,"s":[191,150,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":470,"s":[221,150,0],"to":[0,0,0],"ti":[2.5,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":480,"s":[191,150,0],"to":[-2.5,0,0],"ti":[-2.5,0,0]},{"t":490,"s":[206,150,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Fingerprint_Animation_ForConfirm_Short_For_ErrorToFingerprint","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[170,77.667,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,0],"ix":1,"l":2},"s":{"a":0,"k":[30,30,100],"ix":6,"l":2}},"ao":0,"w":412,"h":300,"ip":0,"op":792,"st":-108,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_symbol_error_to_fingerprint_portrait_bottomright.json b/packages/SystemUI/res/raw/biometricprompt_symbol_error_to_fingerprint_portrait_bottomright.json
deleted file mode 100644
index e5cc565e31d8..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_symbol_error_to_fingerprint_portrait_bottomright.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.9.0","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"biometricprompt_symbol_error_to_fingerprint_portrait_bottomright","ddd":0,"assets":[{"id":"comp_0","nm":"Fingerprint_Animation_ForConfirm_Short_For_ErrorToFingerprint","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"circle fill 5","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":249,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":388,"s":[100]},{"t":408,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":239,"op":1411,"st":239,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"t":249,"s":[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":239,"op":1139,"st":239,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".green400","cl":"green400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":249,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":388,"s":[100]},{"t":408,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.450980392157,0.709803921569,0.470588235294,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":239,"op":1411,"st":239,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"circle fill 3","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":80,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":90,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.8,"y":0},"t":108,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"t":118,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,35.389],[-0.111,50.111]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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.049,42.698],"ix":2},"a":{"a":0,"k":[0.049,42.698],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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 2","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":80,"op":980,"st":80,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".red400","cl":"red400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":7,"ty":3,"nm":"Null 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.833,"y":0.833},"o":{"x":0.333,"y":0.333},"t":85,"s":[209.333,136.333,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":440,"s":[209.333,136.333,0],"to":[1.944,2.278,0],"ti":[3.056,-2.278,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":450,"s":[221,150,0],"to":[-3.056,2.278,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":460,"s":[191,150,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":470,"s":[221,150,0],"to":[0,0,0],"ti":[2.5,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":480,"s":[191,150,0],"to":[-2.5,0,0],"ti":[-2.5,0,0]},{"t":490,"s":[206,150,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 12","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":2,"ty":0,"nm":"Fingerprint_Animation_ForConfirm_Short_For_ErrorToFingerprint","parent":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[0,-92.333,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,0],"ix":1,"l":2},"s":{"a":0,"k":[30,30,100],"ix":6,"l":2}},"ao":0,"w":412,"h":300,"ip":0,"op":792,"st":-108,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_symbol_error_to_fingerprint_portrait_topleft.json b/packages/SystemUI/res/raw/biometricprompt_symbol_error_to_fingerprint_portrait_topleft.json
deleted file mode 100644
index b08226551a02..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_symbol_error_to_fingerprint_portrait_topleft.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.9.0","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"biometricprompt_symbol_error_to_fingerprint_portrait_topleft","ddd":0,"assets":[{"id":"comp_0","nm":"Fingerprint_Animation_ForConfirm_Short_For_ErrorToFingerprint","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"circle fill 5","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":249,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":388,"s":[100]},{"t":408,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":239,"op":1411,"st":239,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"t":249,"s":[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":239,"op":1139,"st":239,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".green400","cl":"green400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":249,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":388,"s":[100]},{"t":408,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.450980392157,0.709803921569,0.470588235294,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":239,"op":1411,"st":239,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"circle fill 3","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":80,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":90,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.8,"y":0},"t":108,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"t":118,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,35.389],[-0.111,50.111]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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.049,42.698],"ix":2},"a":{"a":0,"k":[0.049,42.698],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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 2","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":80,"op":980,"st":80,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".red400","cl":"red400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":7,"ty":3,"nm":"Null 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.833,"y":0.833},"o":{"x":0.333,"y":0.333},"t":85,"s":[209.333,136.333,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":440,"s":[209.333,136.333,0],"to":[1.944,2.278,0],"ti":[3.056,-2.278,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":450,"s":[221,150,0],"to":[-3.056,2.278,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":460,"s":[191,150,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":470,"s":[221,150,0],"to":[0,0,0],"ti":[2.5,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":480,"s":[191,150,0],"to":[-2.5,0,0],"ti":[-2.5,0,0]},{"t":490,"s":[206,150,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 12","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":2,"ty":0,"nm":"Fingerprint_Animation_ForConfirm_Short_For_ErrorToFingerprint","parent":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[0,-92.333,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,0],"ix":1,"l":2},"s":{"a":0,"k":[30,30,100],"ix":6,"l":2}},"ao":0,"w":412,"h":300,"ip":0,"op":792,"st":-108,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_symbol_error_to_success_landscape.json b/packages/SystemUI/res/raw/biometricprompt_symbol_error_to_success_landscape.json
deleted file mode 100644
index befe3bb61cca..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_symbol_error_to_success_landscape.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.9.0","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"biometricprompt_symbol_error_to_success_landscape","ddd":0,"assets":[{"id":"comp_0","nm":"Fingerprint_Animation_ForConfirm_ErrorToSuccess","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"circle fill 5","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":118,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":257,"s":[100]},{"t":277,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":108,"op":1280,"st":108,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":112,"s":[0]},{"t":122,"s":[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":112,"op":1012,"st":112,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".green400","cl":"green400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":118,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":257,"s":[100]},{"t":277,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.450980392157,0.709803921569,0.470588235294,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":108,"op":1280,"st":108,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"circle fill 3","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":80,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":90,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.8,"y":0},"t":108,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"t":118,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,35.389],[-0.111,50.111]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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.049,42.698],"ix":2},"a":{"a":0,"k":[0.049,42.698],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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 2","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":80,"op":980,"st":80,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".red400","cl":"red400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":7,"ty":3,"nm":"Null 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.833,"y":0.833},"o":{"x":0.333,"y":0.333},"t":85,"s":[209.333,136.333,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":440,"s":[209.333,136.333,0],"to":[1.944,2.278,0],"ti":[3.056,-2.278,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":450,"s":[221,150,0],"to":[-3.056,2.278,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":460,"s":[191,150,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":470,"s":[221,150,0],"to":[0,0,0],"ti":[2.5,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":480,"s":[191,150,0],"to":[-2.5,0,0],"ti":[-2.5,0,0]},{"t":490,"s":[206,150,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Fingerprint_Animation_ForConfirm_ErrorToSuccess","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[170,77.667,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,0],"ix":1,"l":2},"s":{"a":0,"k":[30,30,100],"ix":6,"l":2}},"ao":0,"w":412,"h":300,"ip":0,"op":792,"st":-108,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_symbol_error_to_success_portrait_bottomright.json b/packages/SystemUI/res/raw/biometricprompt_symbol_error_to_success_portrait_bottomright.json
deleted file mode 100644
index d75b335747ce..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_symbol_error_to_success_portrait_bottomright.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.9.0","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"biometricprompt_symbol_error_to_success_portrait_bottomright","ddd":0,"assets":[{"id":"comp_0","nm":"Fingerprint_Animation_ForConfirm_ErrorToSuccess","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"circle fill 5","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":118,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":257,"s":[100]},{"t":277,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":108,"op":1280,"st":108,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":112,"s":[0]},{"t":122,"s":[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":112,"op":1012,"st":112,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".green400","cl":"green400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":118,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":257,"s":[100]},{"t":277,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.450980392157,0.709803921569,0.470588235294,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":108,"op":1280,"st":108,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"circle fill 3","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":80,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":90,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.8,"y":0},"t":108,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"t":118,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,35.389],[-0.111,50.111]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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.049,42.698],"ix":2},"a":{"a":0,"k":[0.049,42.698],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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 2","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":80,"op":980,"st":80,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".red400","cl":"red400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":7,"ty":3,"nm":"Null 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.833,"y":0.833},"o":{"x":0.333,"y":0.333},"t":85,"s":[209.333,136.333,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":440,"s":[209.333,136.333,0],"to":[1.944,2.278,0],"ti":[3.056,-2.278,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":450,"s":[221,150,0],"to":[-3.056,2.278,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":460,"s":[191,150,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":470,"s":[221,150,0],"to":[0,0,0],"ti":[2.5,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":480,"s":[191,150,0],"to":[-2.5,0,0],"ti":[-2.5,0,0]},{"t":490,"s":[206,150,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 13","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":2,"ty":0,"nm":"Fingerprint_Animation_ForConfirm_ErrorToSuccess","parent":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[0,-92.333,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,0],"ix":1,"l":2},"s":{"a":0,"k":[30,30,100],"ix":6,"l":2}},"ao":0,"w":412,"h":300,"ip":0,"op":792,"st":-108,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_symbol_error_to_success_portrait_topleft.json b/packages/SystemUI/res/raw/biometricprompt_symbol_error_to_success_portrait_topleft.json
deleted file mode 100644
index e6b2db1fd537..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_symbol_error_to_success_portrait_topleft.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.9.0","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"biometricprompt_symbol_error_to_success_portrait_topleft","ddd":0,"assets":[{"id":"comp_0","nm":"Fingerprint_Animation_ForConfirm_ErrorToSuccess","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"circle fill 5","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":118,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":257,"s":[100]},{"t":277,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":108,"op":1280,"st":108,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":112,"s":[0]},{"t":122,"s":[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":112,"op":1012,"st":112,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".green400","cl":"green400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":118,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":257,"s":[100]},{"t":277,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.450980392157,0.709803921569,0.470588235294,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":108,"op":1280,"st":108,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"circle fill 3","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":80,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":90,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.8,"y":0},"t":108,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"t":118,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,35.389],[-0.111,50.111]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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.049,42.698],"ix":2},"a":{"a":0,"k":[0.049,42.698],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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 2","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":80,"op":980,"st":80,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".red400","cl":"red400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":7,"ty":3,"nm":"Null 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.833,"y":0.833},"o":{"x":0.333,"y":0.333},"t":85,"s":[209.333,136.333,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":440,"s":[209.333,136.333,0],"to":[1.944,2.278,0],"ti":[3.056,-2.278,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":450,"s":[221,150,0],"to":[-3.056,2.278,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":460,"s":[191,150,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":470,"s":[221,150,0],"to":[0,0,0],"ti":[2.5,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":480,"s":[191,150,0],"to":[-2.5,0,0],"ti":[-2.5,0,0]},{"t":490,"s":[206,150,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 13","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":2,"ty":0,"nm":"Fingerprint_Animation_ForConfirm_ErrorToSuccess","parent":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[0,-92.333,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,0],"ix":1,"l":2},"s":{"a":0,"k":[30,30,100],"ix":6,"l":2}},"ao":0,"w":412,"h":300,"ip":0,"op":792,"st":-108,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_symbol_fingerprint_to_error_portrait_bottomright.json b/packages/SystemUI/res/raw/biometricprompt_symbol_fingerprint_to_error_portrait_bottomright.json
deleted file mode 100644
index 0da143c9243a..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_symbol_fingerprint_to_error_portrait_bottomright.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.9.0","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"biometricprompt_symbol_fingerprint_to_error_portrait_bottomright","ddd":0,"assets":[{"id":"comp_0","nm":"Fingerprint_Animation_ForConfirm_Short","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"circle fill 5","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":249,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":388,"s":[100]},{"t":408,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":239,"op":1411,"st":239,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"t":249,"s":[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":239,"op":1139,"st":239,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".green400","cl":"green400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":249,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":388,"s":[100]},{"t":408,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.450980392157,0.709803921569,0.470588235294,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":239,"op":1411,"st":239,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"circle fill 3","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":80,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":90,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.8,"y":0},"t":108,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"t":118,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,35.389],[-0.111,50.111]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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.049,42.698],"ix":2},"a":{"a":0,"k":[0.049,42.698],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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 2","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":80,"op":980,"st":80,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".red400","cl":"red400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":7,"ty":3,"nm":"Null 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.833,"y":0.833},"o":{"x":0.333,"y":0.333},"t":85,"s":[209.333,136.333,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":440,"s":[209.333,136.333,0],"to":[1.944,2.278,0],"ti":[3.056,-2.278,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":450,"s":[221,150,0],"to":[-3.056,2.278,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":460,"s":[191,150,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":470,"s":[221,150,0],"to":[0,0,0],"ti":[2.5,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":480,"s":[191,150,0],"to":[-2.5,0,0],"ti":[-2.5,0,0]},{"t":490,"s":[206,150,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 14","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":2,"ty":0,"nm":"Fingerprint_Animation_ForConfirm_Short","parent":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[0,-92.333,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,0],"ix":1,"l":2},"s":{"a":0,"k":[30,30,100],"ix":6,"l":2}},"ao":0,"w":412,"h":300,"ip":0,"op":830,"st":-70,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_symbol_fingerprint_to_error_portrait_topleft.json b/packages/SystemUI/res/raw/biometricprompt_symbol_fingerprint_to_error_portrait_topleft.json
deleted file mode 100644
index 15457c7e19c8..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_symbol_fingerprint_to_error_portrait_topleft.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.9.0","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"biometricprompt_symbol_fingerprint_to_error_portrait_topleft","ddd":0,"assets":[{"id":"comp_0","nm":"Fingerprint_Animation_ForConfirm_Short","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"circle fill 5","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":249,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":388,"s":[100]},{"t":408,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":239,"op":1411,"st":239,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"t":249,"s":[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":239,"op":1139,"st":239,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".green400","cl":"green400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":249,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":388,"s":[100]},{"t":408,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.450980392157,0.709803921569,0.470588235294,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":239,"op":1411,"st":239,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"circle fill 3","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":80,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":90,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.8,"y":0},"t":108,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"t":118,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,35.389],[-0.111,50.111]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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.049,42.698],"ix":2},"a":{"a":0,"k":[0.049,42.698],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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 2","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":80,"op":980,"st":80,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".red400","cl":"red400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":7,"ty":3,"nm":"Null 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.833,"y":0.833},"o":{"x":0.333,"y":0.333},"t":85,"s":[209.333,136.333,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":440,"s":[209.333,136.333,0],"to":[1.944,2.278,0],"ti":[3.056,-2.278,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":450,"s":[221,150,0],"to":[-3.056,2.278,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":460,"s":[191,150,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":470,"s":[221,150,0],"to":[0,0,0],"ti":[2.5,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":480,"s":[191,150,0],"to":[-2.5,0,0],"ti":[-2.5,0,0]},{"t":490,"s":[206,150,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 14","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":2,"ty":0,"nm":"Fingerprint_Animation_ForConfirm_Short","parent":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[0,-92.333,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,0],"ix":1,"l":2},"s":{"a":0,"k":[30,30,100],"ix":6,"l":2}},"ao":0,"w":412,"h":300,"ip":0,"op":830,"st":-70,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_symbol_fingerprint_to_success_landscape.json b/packages/SystemUI/res/raw/biometricprompt_symbol_fingerprint_to_success_landscape.json
deleted file mode 100644
index f39894b0a300..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_symbol_fingerprint_to_success_landscape.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.9.0","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"biometricprompt_symbol_fingerprint_to_success_landscape","ddd":0,"assets":[{"id":"comp_0","nm":"Fingerprint_Animation_ForConfirm_Short","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"circle fill 5","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":249,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":388,"s":[100]},{"t":408,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":239,"op":1411,"st":239,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"t":249,"s":[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":239,"op":1139,"st":239,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".green400","cl":"green400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":249,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":388,"s":[100]},{"t":408,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.450980392157,0.709803921569,0.470588235294,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":239,"op":1411,"st":239,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"circle fill 3","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":80,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":90,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.8,"y":0},"t":108,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"t":118,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,35.389],[-0.111,50.111]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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.049,42.698],"ix":2},"a":{"a":0,"k":[0.049,42.698],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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 2","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":80,"op":980,"st":80,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".red400","cl":"red400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":7,"ty":3,"nm":"Null 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.833,"y":0.833},"o":{"x":0.333,"y":0.333},"t":85,"s":[209.333,136.333,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":440,"s":[209.333,136.333,0],"to":[1.944,2.278,0],"ti":[3.056,-2.278,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":450,"s":[221,150,0],"to":[-3.056,2.278,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":460,"s":[191,150,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":470,"s":[221,150,0],"to":[0,0,0],"ti":[2.5,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":480,"s":[191,150,0],"to":[-2.5,0,0],"ti":[-2.5,0,0]},{"t":490,"s":[206,150,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Fingerprint_Animation_ForConfirm_Short","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[170,77.667,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,0],"ix":1,"l":2},"s":{"a":0,"k":[30,30,100],"ix":6,"l":2}},"ao":0,"w":412,"h":300,"ip":0,"op":661,"st":-239,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_symbol_fingerprint_to_success_portrait_bottomright.json b/packages/SystemUI/res/raw/biometricprompt_symbol_fingerprint_to_success_portrait_bottomright.json
deleted file mode 100644
index 6d4f4e2e1d23..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_symbol_fingerprint_to_success_portrait_bottomright.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.9.0","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"biometricprompt_symbol_fingerprint_to_success_portrait_bottomright","ddd":0,"assets":[{"id":"comp_0","nm":"Fingerprint_Animation_ForConfirm_Short","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"circle fill 5","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":249,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":388,"s":[100]},{"t":408,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":239,"op":1411,"st":239,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"t":249,"s":[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":239,"op":1139,"st":239,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".green400","cl":"green400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":249,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":388,"s":[100]},{"t":408,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.450980392157,0.709803921569,0.470588235294,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":239,"op":1411,"st":239,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"circle fill 3","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":80,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":90,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.8,"y":0},"t":108,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"t":118,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,35.389],[-0.111,50.111]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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.049,42.698],"ix":2},"a":{"a":0,"k":[0.049,42.698],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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 2","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":80,"op":980,"st":80,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".red400","cl":"red400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":7,"ty":3,"nm":"Null 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.833,"y":0.833},"o":{"x":0.333,"y":0.333},"t":85,"s":[209.333,136.333,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":440,"s":[209.333,136.333,0],"to":[1.944,2.278,0],"ti":[3.056,-2.278,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":450,"s":[221,150,0],"to":[-3.056,2.278,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":460,"s":[191,150,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":470,"s":[221,150,0],"to":[0,0,0],"ti":[2.5,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":480,"s":[191,150,0],"to":[-2.5,0,0],"ti":[-2.5,0,0]},{"t":490,"s":[206,150,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 15","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":2,"ty":0,"nm":"Fingerprint_Animation_ForConfirm_Short","parent":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[0,-92.333,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,0],"ix":1,"l":2},"s":{"a":0,"k":[30,30,100],"ix":6,"l":2}},"ao":0,"w":412,"h":300,"ip":0,"op":661,"st":-239,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]} \ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_symbol_fingerprint_to_success_portrait_topleft.json b/packages/SystemUI/res/raw/biometricprompt_symbol_fingerprint_to_success_portrait_topleft.json
deleted file mode 100644
index b7bb0d5cbb26..000000000000
--- a/packages/SystemUI/res/raw/biometricprompt_symbol_fingerprint_to_success_portrait_topleft.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.9.0","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"biometricprompt_symbol_fingerprint_to_success_portrait_topleft","ddd":0,"assets":[{"id":"comp_0","nm":"Fingerprint_Animation_ForConfirm_Short","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"circle fill 5","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":249,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":388,"s":[100]},{"t":408,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":239,"op":1411,"st":239,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-52.056,-2.445],[-17.306,32.25],[52.194,-37.194]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"t":249,"s":[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":239,"op":1139,"st":239,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".green400","cl":"green400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":239,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":249,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":388,"s":[100]},{"t":408,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.450980392157,0.709803921569,0.470588235294,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":239,"op":1411,"st":239,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"circle fill 3","td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".white","cl":"white","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,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":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":80,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.7,"y":0},"t":90,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"i":{"x":0.2,"y":1},"o":{"x":0.8,"y":0},"t":108,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,-49.945],[-0.056,14.056]],"c":false}]},{"t":118,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.111,14.055],[-0.056,14.056]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.056,35.389],[-0.111,50.111]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"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.049,42.698],"ix":2},"a":{"a":0,"k":[0.049,42.698],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":80,"s":[0,0]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"t":90,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.8,0.8],"y":[0,0]},"t":108,"s":[100,100]},{"t":118,"s":[0,0]}],"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 2","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":80,"op":980,"st":80,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".red400","cl":"red400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":80,"s":[0]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":90,"s":[100]},{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":108,"s":[100]},{"t":118,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206,150,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,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,62.45],[-62.45,0],[0,-62.45],[62.45,0]],"o":[[0,-62.45],[62.45,0],[0,62.45],[-62.45,0]],"v":[[-113.08,0],[0,-113.08],[113.08,0],[0,113.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[206,150],"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 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.403921598547,0.360784313725,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":80,"op":1252,"st":80,"bm":0},{"ddd":0,"ind":7,"ty":3,"nm":"Null 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.833,"y":0.833},"o":{"x":0.333,"y":0.333},"t":85,"s":[209.333,136.333,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":440,"s":[209.333,136.333,0],"to":[1.944,2.278,0],"ti":[3.056,-2.278,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":450,"s":[221,150,0],"to":[-3.056,2.278,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":460,"s":[191,150,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":470,"s":[221,150,0],"to":[0,0,0],"ti":[2.5,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":480,"s":[191,150,0],"to":[-2.5,0,0],"ti":[-2.5,0,0]},{"t":490,"s":[206,150,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 15","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":2,"ty":0,"nm":"Fingerprint_Animation_ForConfirm_Short","parent":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[0,-92.333,0],"ix":2,"l":2},"a":{"a":0,"k":[206,150,0],"ix":1,"l":2},"s":{"a":0,"k":[30,30,100],"ix":6,"l":2}},"ao":0,"w":412,"h":300,"ip":0,"op":661,"st":-239,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]} \ No newline at end of file
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index eda7bb0e7f6d..e5750d278bfe 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1729,10 +1729,18 @@
<dimen name="wallet_button_vertical_padding">8dp</dimen>
<!-- Ongoing activity chip -->
+ <!-- The activity chip side padding, used with the default phone icon. -->
<dimen name="ongoing_activity_chip_side_padding">12dp</dimen>
+ <!-- The activity chip side padding, used with an icon that has embedded padding (e.g. if the icon comes from the notification's smallIcon field). If the icon has padding, the chip itself can have less padding. -->
+ <dimen name="ongoing_activity_chip_side_padding_for_embedded_padding_icon">6dp</dimen>
+ <!-- The icon size, used with the default phone icon. -->
<dimen name="ongoing_activity_chip_icon_size">16dp</dimen>
- <!-- The padding between the icon and the text. -->
+ <!-- The icon size, used with an icon that has embedded padding. (If the icon has embedded padding, we need to make the whole icon larger so the icon itself doesn't look small.) -->
+ <dimen name="ongoing_activity_chip_embedded_padding_icon_size">22dp</dimen>
+ <!-- The padding between the icon and the text. Only used if the default phone icon is used. -->
<dimen name="ongoing_activity_chip_icon_text_padding">4dp</dimen>
+ <!-- The end padding for the timer text view. Only used if an embedded padding icon is used. -->
+ <dimen name="ongoing_activity_chip_text_end_padding_for_embedded_padding_icon">6dp</dimen>
<dimen name="ongoing_activity_chip_corner_radius">28dp</dimen>
<!-- Status bar user chip -->
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 212dae279387..e4f900d3a31a 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -132,6 +132,7 @@
<!-- Status bar -->
<item type="id" name="status_bar_dot" />
+ <item type="id" name="ongoing_activity_chip_custom_icon" />
<!-- Default display cutout on the physical top of screen -->
<item type="id" name="display_cutout" />
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 0318458f8ed1..159fb2e50c43 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1379,11 +1379,15 @@
<!-- Casting that launched by SysUI (i.e. when there is no app name) -->
<!-- System casting media projection permission dialog title. [CHAR LIMIT=100] -->
- <string name="media_projection_entry_cast_permission_dialog_title">Start casting?</string>
+ <string name="media_projection_entry_cast_permission_dialog_title">Cast your screen?</string>
+ <!-- System casting media projection permission option for capturing just a single app [CHAR LIMIT=50] -->
+ <string name="media_projection_entry_cast_permission_dialog_option_text_single_app">Cast one app</string>
+ <!-- System casting media projection permission option for capturing the whole screen [CHAR LIMIT=50] -->
+ <string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen">Cast entire screen</string>
<!-- System casting media projection permission warning for capturing the whole screen when SysUI casting requests it. [CHAR LIMIT=350] -->
- <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen">When you’re casting, Android has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, and audio and video.</string>
+ <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen">When you’re casting your entire screen, anything on your screen is visible. So be careful with things like passwords, payment details, messages, photos, and audio and video.</string>
<!-- System casting media projection permission warning for capturing a single app when SysUI casting requests it. [CHAR LIMIT=350] -->
- <string name="media_projection_entry_cast_permission_dialog_warning_single_app">When you’re casting an app, Android has access to anything shown or played on that app. So be careful with things like passwords, payment details, messages, photos, and audio and video.</string>
+ <string name="media_projection_entry_cast_permission_dialog_warning_single_app">When you’re casting an app, anything shown or played in that app is visible. So be careful with things like passwords, payment details, messages, photos, and audio and video.</string>
<!-- System casting media projection permission button to continue for SysUI casting. [CHAR LIMIT=60] -->
<string name="media_projection_entry_cast_permission_dialog_continue">Start casting</string>
@@ -3647,6 +3651,8 @@
hasn't typed in anything in the search box yet. The helper is a component that shows the
user which keyboard shortcuts they can use. [CHAR LIMIT=NONE] -->
<string name="shortcut_helper_search_placeholder">Search shortcuts</string>
+ <!-- Text shown when a search query didn't produce any results. [CHAR LIMIT=NONE] -->
+ <string name="shortcut_helper_no_search_results">No search results</string>
<!-- Content description of the icon that allows to collapse a keyboard shortcut helper category
panel. The helper is a component that shows the user which keyboard shortcuts they can
use. The helper shows shortcuts in categories, which can be collapsed or expanded.
@@ -3707,6 +3713,11 @@ Action + ESC for this.</string>
<!-- Education toast text for All Apps [CHAR_LIMIT=100] -->
<string name="all_apps_edu_toast_content">To view all your apps, press the action key on your keyboard</string>
+ <!-- Title of the one line view of a redacted notification -->
+ <string name="redacted_notification_single_line_title">Redacted</string>
+ <!-- Main text of the one line view of a redacted notification -->
+ <string name="redacted_notification_single_line_text">Unlock to view</string>
+
<!-- Education notification title for Back [CHAR_LIMIT=100] -->
<string name="back_edu_notification_title">Use your touchpad to go back</string>
<!-- Education notification text for Back [CHAR_LIMIT=100] -->
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/BiometricStatusRepository.kt b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/BiometricStatusRepository.kt
index ca03a00cca0c..da270c08f281 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/BiometricStatusRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/BiometricStatusRepository.kt
@@ -39,7 +39,6 @@ import com.android.systemui.biometrics.shared.model.AuthenticationReason
import com.android.systemui.biometrics.shared.model.AuthenticationReason.SettingsOperations
import com.android.systemui.biometrics.shared.model.AuthenticationState
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
-import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.shared.model.AcquiredFingerprintAuthenticationStatus
@@ -49,6 +48,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterIsInstance
@@ -85,7 +85,7 @@ constructor(
* onAcquired in [FingerprintManager.EnrollmentCallback] and [FaceManager.EnrollmentCallback]
*/
private val authenticationState: Flow<AuthenticationState> =
- conflatedCallbackFlow {
+ callbackFlow {
val updateAuthenticationState = { state: AuthenticationState ->
Log.d(TAG, "authenticationState updated: $state")
trySendWithFailureLogging(state, TAG, "Error sending AuthenticationState state")
@@ -169,7 +169,9 @@ constructor(
}
}
- updateAuthenticationState(AuthenticationState.Idle(AuthenticationReason.NotRunning))
+ updateAuthenticationState(
+ AuthenticationState.Idle(requestReason = AuthenticationReason.NotRunning)
+ )
biometricManager?.registerAuthenticationStateListener(authenticationStateListener)
awaitClose {
biometricManager?.unregisterAuthenticationStateListener(
@@ -180,23 +182,32 @@ constructor(
.distinctUntilChanged()
.shareIn(applicationScope, started = SharingStarted.Eagerly, replay = 1)
- override val fingerprintAuthenticationReason: Flow<AuthenticationReason> =
+ private val fingerprintAuthenticationState: Flow<AuthenticationState> =
authenticationState
.filter {
+ it.biometricSourceType == null ||
+ it.biometricSourceType == BiometricSourceType.FINGERPRINT
+ }
+ .onEach { Log.d(TAG, "fingerprintAuthenticationState updated: $it") }
+
+ private val fingerprintRunningState: Flow<AuthenticationState> =
+ fingerprintAuthenticationState
+ .filter {
it is AuthenticationState.Idle ||
- (it is AuthenticationState.Started &&
- it.biometricSourceType == BiometricSourceType.FINGERPRINT) ||
- (it is AuthenticationState.Stopped &&
- it.biometricSourceType == BiometricSourceType.FINGERPRINT)
+ it is AuthenticationState.Started ||
+ it is AuthenticationState.Stopped
}
+ .onEach { Log.d(TAG, "fingerprintRunningState updated: $it") }
+
+ override val fingerprintAuthenticationReason: Flow<AuthenticationReason> =
+ fingerprintRunningState
.map { it.requestReason }
.onEach { Log.d(TAG, "fingerprintAuthenticationReason updated: $it") }
override val fingerprintAcquiredStatus: Flow<FingerprintAuthenticationStatus> =
- authenticationState
- .filterIsInstance<AuthenticationState.Acquired>()
- .filter { it.biometricSourceType == BiometricSourceType.FINGERPRINT }
- .map { AcquiredFingerprintAuthenticationStatus(it.requestReason, it.acquiredInfo) }
+ fingerprintAuthenticationState.filterIsInstance<AuthenticationState.Acquired>().map {
+ AcquiredFingerprintAuthenticationStatus(it.requestReason, it.acquiredInfo)
+ }
companion object {
private const val TAG = "BiometricStatusRepositoryImpl"
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/AuthenticationState.kt b/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/AuthenticationState.kt
index 5ceae36dadb6..81ea6a9c15b0 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/AuthenticationState.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/AuthenticationState.kt
@@ -27,6 +27,9 @@ import android.hardware.biometrics.BiometricSourceType
* authentication.
*/
sealed interface AuthenticationState {
+ /** Indicates [BiometricSourceType] of authentication state update, null in idle auth state. */
+ val biometricSourceType: BiometricSourceType?
+
/**
* Indicates [AuthenticationReason] from [BiometricRequestConstants.RequestReason] for
* requesting auth
@@ -43,7 +46,7 @@ sealed interface AuthenticationState {
* message.
*/
data class Acquired(
- val biometricSourceType: BiometricSourceType,
+ override val biometricSourceType: BiometricSourceType,
override val requestReason: AuthenticationReason,
val acquiredInfo: Int
) : AuthenticationState
@@ -59,7 +62,7 @@ sealed interface AuthenticationState {
* @param requestReason reason from [BiometricRequestConstants.RequestReason] for authentication
*/
data class Error(
- val biometricSourceType: BiometricSourceType,
+ override val biometricSourceType: BiometricSourceType,
val errString: String?,
val errCode: Int,
override val requestReason: AuthenticationReason,
@@ -73,7 +76,7 @@ sealed interface AuthenticationState {
* @param userId The user id for the requested authentication
*/
data class Failed(
- val biometricSourceType: BiometricSourceType,
+ override val biometricSourceType: BiometricSourceType,
override val requestReason: AuthenticationReason,
val userId: Int
) : AuthenticationState
@@ -87,7 +90,7 @@ sealed interface AuthenticationState {
* @param requestReason reason from [BiometricRequestConstants.RequestReason] for authentication
*/
data class Help(
- val biometricSourceType: BiometricSourceType,
+ override val biometricSourceType: BiometricSourceType,
val helpString: String?,
val helpCode: Int,
override val requestReason: AuthenticationReason,
@@ -96,9 +99,13 @@ sealed interface AuthenticationState {
/**
* Authentication state when no auth is running
*
+ * @param biometricSourceType null
* @param requestReason [AuthenticationReason.NotRunning]
*/
- data class Idle(override val requestReason: AuthenticationReason) : AuthenticationState
+ data class Idle(
+ override val biometricSourceType: BiometricSourceType? = null,
+ override val requestReason: AuthenticationReason
+ ) : AuthenticationState
/**
* AuthenticationState when auth is started
@@ -107,7 +114,7 @@ sealed interface AuthenticationState {
* @param requestReason reason from [BiometricRequestConstants.RequestReason] for authentication
*/
data class Started(
- val biometricSourceType: BiometricSourceType,
+ override val biometricSourceType: BiometricSourceType,
override val requestReason: AuthenticationReason
) : AuthenticationState
@@ -118,7 +125,7 @@ sealed interface AuthenticationState {
* @param requestReason [AuthenticationReason.NotRunning]
*/
data class Stopped(
- val biometricSourceType: BiometricSourceType,
+ override val biometricSourceType: BiometricSourceType,
override val requestReason: AuthenticationReason
) : AuthenticationState
@@ -131,7 +138,7 @@ sealed interface AuthenticationState {
* @param userId The user id for the requested authentication
*/
data class Succeeded(
- val biometricSourceType: BiometricSourceType,
+ override val biometricSourceType: BiometricSourceType,
val isStrongBiometric: Boolean,
override val requestReason: AuthenticationReason,
val userId: Int
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
index 3ef55727a585..2d525aa6fcba 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
@@ -129,7 +129,6 @@ object BiometricViewBinder {
subtitleView.isSelected =
!accessibilityManager.isEnabled || !accessibilityManager.isTouchExplorationEnabled
- val iconOverlayView = view.requireViewById<LottieAnimationView>(R.id.biometric_icon_overlay)
val iconView = view.requireViewById<LottieAnimationView>(R.id.biometric_icon)
val iconSizeOverride =
@@ -185,15 +184,23 @@ object BiometricViewBinder {
// these do not change and need to be set before any size transitions
val modalities = viewModel.modalities.first()
- if (modalities.hasFingerprint) {
- /**
- * Load the given [rawResources] immediately so they are cached for use in the
- * [context].
- */
- val rawResources = viewModel.iconViewModel.getRawAssets(modalities.hasSfps)
- for (res in rawResources) {
- LottieCompositionFactory.fromRawRes(view.context, res)
+ /**
+ * Load the given [rawResources] immediately so they are cached for use in the
+ * [context].
+ */
+ val rawResources =
+ if (modalities.hasFaceAndFingerprint) {
+ viewModel.iconViewModel.getCoexAssetsList(modalities.hasSfps)
+ } else if (modalities.hasFingerprintOnly) {
+ viewModel.iconViewModel.getFingerprintAssetsList(modalities.hasSfps)
+ } else if (modalities.hasFaceOnly) {
+ viewModel.iconViewModel.getFaceAssetsList()
+ } else {
+ listOf()
}
+
+ for (res in rawResources) {
+ LottieCompositionFactory.fromRawRes(view.context, res)
}
val logoInfo = viewModel.logoInfo.first()
@@ -268,7 +275,6 @@ object BiometricViewBinder {
if (!showWithoutIcon) {
PromptIconViewBinder.bind(
iconView,
- iconOverlayView,
iconSizeOverride,
viewModel,
)
@@ -392,10 +398,7 @@ object BiometricViewBinder {
else -> null
}
}
- .collect { onTouch ->
- iconOverlayView.setOnTouchListener(onTouch)
- iconView.setOnTouchListener(onTouch)
- }
+ .collect { onTouch -> iconView.setOnTouchListener(onTouch) }
}
// dismiss prompt when authenticated and confirmed
@@ -416,9 +419,6 @@ object BiometricViewBinder {
accessibilityManager.isTouchExplorationEnabled &&
modalities.hasUdfps
) {
- iconOverlayView.setOnClickListener {
- viewModel.confirmAuthenticated()
- }
iconView.setOnClickListener { viewModel.confirmAuthenticated() }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
index a87ee24da2f7..b9ec2de63269 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
@@ -167,16 +167,13 @@ object BiometricViewSizeBinder {
fun setVisibilities(hideSensorIcon: Boolean, size: PromptSize) {
viewsToHideWhenSmall.forEach { it.showContentOrHide(forceHide = size.isSmall) }
largeConstraintSet.setVisibility(iconHolderView.id, View.GONE)
- largeConstraintSet.setVisibility(R.id.biometric_icon_overlay, View.GONE)
largeConstraintSet.setVisibility(R.id.indicator, View.GONE)
largeConstraintSet.setVisibility(R.id.scrollView, View.GONE)
if (hideSensorIcon) {
smallConstraintSet.setVisibility(iconHolderView.id, View.GONE)
- smallConstraintSet.setVisibility(R.id.biometric_icon_overlay, View.GONE)
smallConstraintSet.setVisibility(R.id.indicator, View.GONE)
mediumConstraintSet.setVisibility(iconHolderView.id, View.GONE)
- mediumConstraintSet.setVisibility(R.id.biometric_icon_overlay, View.GONE)
mediumConstraintSet.setVisibility(R.id.indicator, View.GONE)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
index 5e0e2bb9556e..9e4aaaa44085 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
@@ -17,6 +17,7 @@
package com.android.systemui.biometrics.ui.binder
+import android.content.res.Resources
import android.util.Log
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
@@ -29,8 +30,8 @@ import com.android.systemui.biometrics.ui.viewmodel.PromptIconViewModel.AuthType
import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.res.R
-import com.android.systemui.util.kotlin.Utils.Companion.toQuad
-import com.android.systemui.util.kotlin.Utils.Companion.toTriple
+import com.android.systemui.util.kotlin.Quad
+import com.android.systemui.util.kotlin.Utils.Companion.toQuint
import com.android.systemui.util.kotlin.sample
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
@@ -39,14 +40,10 @@ private const val TAG = "PromptIconViewBinder"
/** Sub-binder for [BiometricPromptLayout.iconView]. */
object PromptIconViewBinder {
- /**
- * Binds [BiometricPromptLayout.iconView] and [BiometricPromptLayout.biometric_icon_overlay] to
- * [PromptIconViewModel].
- */
+ /** Binds [BiometricPromptLayout.iconView] to [PromptIconViewModel]. */
@JvmStatic
fun bind(
iconView: LottieAnimationView,
- iconOverlayView: LottieAnimationView,
iconViewLayoutParamSizeOverride: Pair<Int, Int>?,
promptViewModel: PromptViewModel
) {
@@ -57,9 +54,6 @@ object PromptIconViewBinder {
if (iconViewLayoutParamSizeOverride != null) {
iconView.layoutParams.width = iconViewLayoutParamSizeOverride.first
iconView.layoutParams.height = iconViewLayoutParamSizeOverride.second
-
- iconOverlayView.layoutParams.width = iconViewLayoutParamSizeOverride.first
- iconOverlayView.layoutParams.height = iconViewLayoutParamSizeOverride.second
}
if (!constraintBp()) {
@@ -95,9 +89,6 @@ object PromptIconViewBinder {
if (iconViewLayoutParamSizeOverride == null) {
iconView.layoutParams.width = iconSize.first
iconView.layoutParams.height = iconSize.second
-
- iconOverlayView.layoutParams.width = iconSize.first
- iconOverlayView.layoutParams.height = iconSize.second
}
}
}
@@ -109,18 +100,25 @@ object PromptIconViewBinder {
combine(
viewModel.activeAuthType,
viewModel.shouldAnimateIconView,
+ viewModel.shouldLoopIconView,
viewModel.showingError,
- ::Triple
+ ::Quad
),
- ::toQuad
+ ::toQuint
)
- .collect { (iconAsset, activeAuthType, shouldAnimateIconView, showingError)
- ->
+ .collect {
+ (
+ iconAsset,
+ activeAuthType,
+ shouldAnimateIconView,
+ shouldLoopIconView,
+ showingError) ->
if (iconAsset != -1) {
iconView.updateAsset(
"iconAsset",
iconAsset,
shouldAnimateIconView,
+ shouldLoopIconView,
activeAuthType
)
viewModel.setPreviousIconWasError(showingError)
@@ -129,34 +127,7 @@ object PromptIconViewBinder {
}
launch {
- viewModel.iconOverlayAsset
- .sample(
- combine(
- viewModel.shouldAnimateIconOverlay,
- viewModel.showingError,
- ::Pair
- ),
- ::toTriple
- )
- .collect { (iconOverlayAsset, shouldAnimateIconOverlay, showingError) ->
- if (iconOverlayAsset != -1) {
- iconOverlayView.updateAsset(
- "iconOverlayAsset",
- iconOverlayAsset,
- shouldAnimateIconOverlay,
- AuthType.Fingerprint
- )
- viewModel.setPreviousIconOverlayWasError(showingError)
- }
- }
- }
-
- launch {
- viewModel.shouldFlipIconView.collect { shouldFlipIconView ->
- if (shouldFlipIconView) {
- iconView.rotation = 180f
- }
- }
+ viewModel.iconViewRotation.collect { rotation -> iconView.rotation = rotation }
}
launch {
@@ -171,97 +142,83 @@ object PromptIconViewBinder {
}
}
-private val assetIdToString: Map<Int, String> =
- mapOf(
- // UDFPS assets
- R.raw.fingerprint_dialogue_error_to_fingerprint_lottie to
- "fingerprint_dialogue_error_to_fingerprint_lottie",
- R.raw.fingerprint_dialogue_error_to_success_lottie to
- "fingerprint_dialogue_error_to_success_lottie",
- R.raw.fingerprint_dialogue_fingerprint_to_error_lottie to
- "fingerprint_dialogue_fingerprint_to_error_lottie",
- R.raw.fingerprint_dialogue_fingerprint_to_success_lottie to
- "fingerprint_dialogue_fingerprint_to_success_lottie",
- // SFPS assets
- R.raw.biometricprompt_fingerprint_to_error_landscape to
- "biometricprompt_fingerprint_to_error_landscape",
- R.raw.biometricprompt_folded_base_bottomright to "biometricprompt_folded_base_bottomright",
- R.raw.biometricprompt_folded_base_default to "biometricprompt_folded_base_default",
- R.raw.biometricprompt_folded_base_topleft to "biometricprompt_folded_base_topleft",
- R.raw.biometricprompt_landscape_base to "biometricprompt_landscape_base",
- R.raw.biometricprompt_portrait_base_bottomright to
- "biometricprompt_portrait_base_bottomright",
- R.raw.biometricprompt_portrait_base_topleft to "biometricprompt_portrait_base_topleft",
- R.raw.biometricprompt_symbol_error_to_fingerprint_landscape to
- "biometricprompt_symbol_error_to_fingerprint_landscape",
- R.raw.biometricprompt_symbol_error_to_fingerprint_portrait_bottomright to
- "biometricprompt_symbol_error_to_fingerprint_portrait_bottomright",
- R.raw.biometricprompt_symbol_error_to_fingerprint_portrait_topleft to
- "biometricprompt_symbol_error_to_fingerprint_portrait_topleft",
- R.raw.biometricprompt_symbol_error_to_success_landscape to
- "biometricprompt_symbol_error_to_success_landscape",
- R.raw.biometricprompt_symbol_error_to_success_portrait_bottomright to
- "biometricprompt_symbol_error_to_success_portrait_bottomright",
- R.raw.biometricprompt_symbol_error_to_success_portrait_topleft to
- "biometricprompt_symbol_error_to_success_portrait_topleft",
- R.raw.biometricprompt_symbol_fingerprint_to_error_portrait_bottomright to
- "biometricprompt_symbol_fingerprint_to_error_portrait_bottomright",
- R.raw.biometricprompt_symbol_fingerprint_to_error_portrait_topleft to
- "biometricprompt_symbol_fingerprint_to_error_portrait_topleft",
- R.raw.biometricprompt_symbol_fingerprint_to_success_landscape to
- "biometricprompt_symbol_fingerprint_to_success_landscape",
- R.raw.biometricprompt_symbol_fingerprint_to_success_portrait_bottomright to
- "biometricprompt_symbol_fingerprint_to_success_portrait_bottomright",
- R.raw.biometricprompt_symbol_fingerprint_to_success_portrait_topleft to
- "biometricprompt_symbol_fingerprint_to_success_portrait_topleft",
- // Face assets
- R.raw.face_dialog_wink_from_dark to "face_dialog_wink_from_dark",
- R.raw.face_dialog_dark_to_checkmark to "face_dialog_dark_to_checkmark",
- R.raw.face_dialog_dark_to_error to "face_dialog_dark_to_error",
- R.raw.face_dialog_error_to_idle to "face_dialog_error_to_idle",
- R.raw.face_dialog_idle_static to "face_dialog_idle_static",
- R.raw.face_dialog_authenticating to "face_dialog_authenticating",
- // Co-ex assets
- R.raw.fingerprint_dialogue_unlocked_to_checkmark_success_lottie to
- "fingerprint_dialogue_unlocked_to_checkmark_success_lottie",
- R.raw.fingerprint_dialogue_error_to_unlock_lottie to
- "fingerprint_dialogue_error_to_unlock_lottie",
- R.raw.fingerprint_dialogue_fingerprint_to_unlock_lottie to
- "fingerprint_dialogue_fingerprint_to_unlock_lottie",
- )
-
-private fun getAssetNameFromId(id: Int): String {
- return assetIdToString.getOrDefault(id, "Asset $id not found")
-}
-
fun LottieAnimationView.updateAsset(
type: String,
asset: Int,
shouldAnimateIconView: Boolean,
+ shouldLoopIconView: Boolean,
activeAuthType: AuthType
) {
setFailureListener(type, asset, activeAuthType)
+ pauseAnimation()
setAnimation(asset)
- frame = 0
+ if (animatingFromSfpsAuthenticating(asset)) {
+ // Skipping to error / success / unlock segment of animation
+ setMinFrame(151)
+ } else {
+ frame = 0
+ }
if (shouldAnimateIconView) {
- if (asset == R.raw.face_dialog_authenticating) {
- loop(true)
- } else {
- loop(false)
- }
+ loop(shouldLoopIconView)
playAnimation()
}
LottieColorUtils.applyDynamicColors(context, this)
}
+private fun animatingFromSfpsAuthenticating(asset: Int): Boolean =
+ asset in sfpsFpToErrorAssets || asset in sfpsFpToUnlockAssets || asset in sfpsFpToSuccessAssets
+
+private val sfpsFpToErrorAssets: List<Int> =
+ listOf(
+ R.raw.biometricprompt_sfps_fingerprint_to_error,
+ R.raw.biometricprompt_sfps_fingerprint_to_error_90,
+ R.raw.biometricprompt_sfps_fingerprint_to_error_180,
+ R.raw.biometricprompt_sfps_fingerprint_to_error_270,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_error,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_error_90,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_error_180,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_error_270,
+ )
+
+private val sfpsFpToUnlockAssets: List<Int> =
+ listOf(
+ R.raw.biometricprompt_sfps_fingerprint_to_unlock,
+ R.raw.biometricprompt_sfps_fingerprint_to_unlock_90,
+ R.raw.biometricprompt_sfps_fingerprint_to_unlock_180,
+ R.raw.biometricprompt_sfps_fingerprint_to_unlock_270,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_unlock,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_unlock_90,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_unlock_180,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_unlock_270,
+ )
+
+private val sfpsFpToSuccessAssets: List<Int> =
+ listOf(
+ R.raw.biometricprompt_sfps_fingerprint_to_success,
+ R.raw.biometricprompt_sfps_fingerprint_to_success_90,
+ R.raw.biometricprompt_sfps_fingerprint_to_success_180,
+ R.raw.biometricprompt_sfps_fingerprint_to_success_270,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_success,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_success_90,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_success_180,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_success_270,
+ )
+
private fun LottieAnimationView.setFailureListener(type: String, asset: Int, authType: AuthType) {
+ val assetName =
+ try {
+ context.resources.getResourceEntryName(asset)
+ } catch (e: Resources.NotFoundException) {
+ "Asset $asset not found"
+ }
+
setFailureListener { result: Throwable? ->
Log.d(
TAG,
"Collecting $type | " +
"activeAuthType = $authType | " +
"Invalid resource id: $asset, " +
- "name ${getAssetNameFromId(asset)}",
+ "name $assetName",
result
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
index c08914380117..574c40da226f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
@@ -19,11 +19,8 @@ package com.android.systemui.biometrics.ui.viewmodel
import android.annotation.RawRes
import android.content.res.Configuration
-import android.graphics.Rect
-import android.util.RotationUtils
import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor
-import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor
import com.android.systemui.biometrics.shared.model.DisplayRotation
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
import com.android.systemui.res.R
@@ -35,15 +32,11 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
-/**
- * Models UI of [BiometricPromptLayout.iconView] and [BiometricPromptLayout.biometric_icon_overlay]
- */
-class PromptIconViewModel
-constructor(
+/** Models UI of [BiometricPromptLayout.iconView] */
+class PromptIconViewModel(
promptViewModel: PromptViewModel,
private val displayStateInteractor: DisplayStateInteractor,
promptSelectorInteractor: PromptSelectorInteractor,
- udfpsOverlayInteractor: UdfpsOverlayInteractor,
) {
/** Auth types for the UI to display. */
@@ -74,44 +67,16 @@ constructor(
}
}
- val udfpsSensorBounds: Flow<Rect> =
- combine(
- udfpsOverlayInteractor.udfpsOverlayParams,
- displayStateInteractor.currentRotation
- ) { params, rotation ->
- val rotatedBounds = Rect(params.sensorBounds)
- RotationUtils.rotateBounds(
- rotatedBounds,
- params.naturalDisplayWidth,
- params.naturalDisplayHeight,
- rotation.ordinal
- )
- Rect(
- rotatedBounds.left,
- rotatedBounds.top,
- params.logicalDisplayWidth - rotatedBounds.right,
- params.logicalDisplayHeight - rotatedBounds.bottom
- )
- }
- .distinctUntilChanged()
-
/** Whether an error message is currently being shown. */
val showingError = promptViewModel.showingError
/** Whether the previous icon shown displayed an error. */
private val _previousIconWasError: MutableStateFlow<Boolean> = MutableStateFlow(false)
- /** Whether the previous icon overlay shown displayed an error. */
- private val _previousIconOverlayWasError: MutableStateFlow<Boolean> = MutableStateFlow(false)
-
fun setPreviousIconWasError(previousIconWasError: Boolean) {
_previousIconWasError.value = previousIconWasError
}
- fun setPreviousIconOverlayWasError(previousIconOverlayWasError: Boolean) {
- _previousIconOverlayWasError.value = previousIconOverlayWasError
- }
-
val iconSize: Flow<Pair<Int, Int>> =
combine(
promptViewModel.position,
@@ -133,7 +98,6 @@ constructor(
AuthType.Fingerprint ->
combine(
displayStateInteractor.currentRotation,
- displayStateInteractor.isFolded,
displayStateInteractor.isInRearDisplayMode,
promptSelectorInteractor.fingerprintSensorType,
promptViewModel.isAuthenticated,
@@ -141,7 +105,6 @@ constructor(
promptViewModel.showingError
) {
rotation: DisplayRotation,
- isFolded: Boolean,
isInRearDisplayMode: Boolean,
sensorType: FingerprintSensorType,
authState: PromptAuthState,
@@ -149,7 +112,13 @@ constructor(
showingError: Boolean ->
when (sensorType) {
FingerprintSensorType.POWER_BUTTON ->
- getSfpsIconViewAsset(rotation, isFolded, isInRearDisplayMode)
+ getSfpsIconViewAsset(
+ rotation,
+ isInRearDisplayMode,
+ authState.isAuthenticated,
+ isAuthenticating,
+ showingError
+ )
else ->
getFingerprintIconViewAsset(
authState.isAuthenticated,
@@ -179,7 +148,6 @@ constructor(
AuthType.Coex ->
combine(
displayStateInteractor.currentRotation,
- displayStateInteractor.isFolded,
displayStateInteractor.isInRearDisplayMode,
promptSelectorInteractor.fingerprintSensorType,
promptViewModel.isAuthenticated,
@@ -188,7 +156,6 @@ constructor(
promptViewModel.showingError,
) {
rotation: DisplayRotation,
- isFolded: Boolean,
isInRearDisplayMode: Boolean,
sensorType: FingerprintSensorType,
authState: PromptAuthState,
@@ -197,7 +164,14 @@ constructor(
showingError: Boolean ->
when (sensorType) {
FingerprintSensorType.POWER_BUTTON ->
- getSfpsIconViewAsset(rotation, isFolded, isInRearDisplayMode)
+ getCoexSfpsIconViewAsset(
+ rotation,
+ isInRearDisplayMode,
+ authState,
+ isAuthenticating,
+ isPendingConfirmation,
+ showingError
+ )
else ->
getCoexIconViewAsset(
authState,
@@ -214,8 +188,8 @@ constructor(
isAuthenticated: Boolean,
isAuthenticating: Boolean,
showingError: Boolean
- ): Int =
- if (isAuthenticated) {
+ ): Int {
+ return if (isAuthenticated) {
if (_previousIconWasError.value) {
R.raw.fingerprint_dialogue_error_to_success_lottie
} else {
@@ -232,39 +206,34 @@ constructor(
} else {
-1
}
+ }
@RawRes
private fun getSfpsIconViewAsset(
rotation: DisplayRotation,
- isDeviceFolded: Boolean,
isInRearDisplayMode: Boolean,
- ): Int =
- when (rotation) {
- DisplayRotation.ROTATION_90 ->
- if (isInRearDisplayMode) {
- R.raw.biometricprompt_rear_portrait_reverse_base
- } else if (isDeviceFolded) {
- R.raw.biometricprompt_folded_base_topleft
- } else {
- R.raw.biometricprompt_portrait_base_topleft
- }
- DisplayRotation.ROTATION_270 ->
- if (isInRearDisplayMode) {
- R.raw.biometricprompt_rear_portrait_base
- } else if (isDeviceFolded) {
- R.raw.biometricprompt_folded_base_bottomright
- } else {
- R.raw.biometricprompt_portrait_base_bottomright
- }
- else ->
- if (isInRearDisplayMode) {
- R.raw.biometricprompt_rear_landscape_base
- } else if (isDeviceFolded) {
- R.raw.biometricprompt_folded_base_default
- } else {
- R.raw.biometricprompt_landscape_base
- }
+ isAuthenticated: Boolean,
+ isAuthenticating: Boolean,
+ showingError: Boolean
+ ): Int {
+ return if (isAuthenticated) {
+ if (_previousIconWasError.value) {
+ R.raw.biometricprompt_sfps_error_to_success
+ } else {
+ getSfpsAsset_fingerprintToSuccess(rotation, isInRearDisplayMode)
+ }
+ } else if (isAuthenticating) {
+ if (_previousIconWasError.value) {
+ getSfpsAsset_errorToFingerprint(rotation, isInRearDisplayMode)
+ } else {
+ getSfpsAsset_fingerprintAuthenticating(isInRearDisplayMode)
+ }
+ } else if (showingError) {
+ getSfpsAsset_fingerprintToError(rotation, isInRearDisplayMode)
+ } else {
+ -1
}
+ }
@RawRes
private fun getFaceIconViewAsset(
@@ -272,8 +241,8 @@ constructor(
isAuthenticating: Boolean,
isPendingConfirmation: Boolean,
showingError: Boolean
- ): Int =
- if (authState.isAuthenticated && isPendingConfirmation) {
+ ): Int {
+ return if (authState.isAuthenticated && isPendingConfirmation) {
R.raw.face_dialog_wink_from_dark
} else if (authState.isAuthenticated) {
R.raw.face_dialog_dark_to_checkmark
@@ -286,6 +255,7 @@ constructor(
} else {
R.raw.face_dialog_idle_static
}
+ }
@RawRes
private fun getCoexIconViewAsset(
@@ -293,8 +263,8 @@ constructor(
isAuthenticating: Boolean,
isPendingConfirmation: Boolean,
showingError: Boolean
- ): Int =
- if (authState.isAuthenticatedAndExplicitlyConfirmed) {
+ ): Int {
+ return if (authState.isAuthenticatedAndExplicitlyConfirmed) {
R.raw.fingerprint_dialogue_unlocked_to_checkmark_success_lottie
} else if (isPendingConfirmation) {
if (_previousIconWasError.value) {
@@ -319,107 +289,43 @@ constructor(
} else {
-1
}
-
- /** Current BiometricPromptLayout.biometric_icon_overlay asset. */
- var iconOverlayAsset: Flow<Int> =
- activeAuthType.flatMapLatest { activeAuthType: AuthType ->
- when (activeAuthType) {
- AuthType.Fingerprint,
- AuthType.Coex ->
- combine(
- displayStateInteractor.currentRotation,
- promptSelectorInteractor.fingerprintSensorType,
- promptViewModel.isAuthenticated,
- promptViewModel.isAuthenticating,
- promptViewModel.showingError
- ) {
- rotation: DisplayRotation,
- sensorType: FingerprintSensorType,
- authState: PromptAuthState,
- isAuthenticating: Boolean,
- showingError: Boolean ->
- when (sensorType) {
- FingerprintSensorType.POWER_BUTTON ->
- getSfpsIconOverlayAsset(
- rotation,
- authState.isAuthenticated,
- isAuthenticating,
- showingError
- )
- else -> -1
- }
- }
- AuthType.Face -> flowOf(-1)
- }
- }
+ }
@RawRes
- private fun getSfpsIconOverlayAsset(
+ private fun getCoexSfpsIconViewAsset(
rotation: DisplayRotation,
- isAuthenticated: Boolean,
+ isInRearDisplayMode: Boolean,
+ authState: PromptAuthState,
isAuthenticating: Boolean,
+ isPendingConfirmation: Boolean,
showingError: Boolean
- ): Int =
- if (isAuthenticated) {
- if (_previousIconOverlayWasError.value) {
- when (rotation) {
- DisplayRotation.ROTATION_0 ->
- R.raw.biometricprompt_symbol_error_to_success_landscape
- DisplayRotation.ROTATION_90 ->
- R.raw.biometricprompt_symbol_error_to_success_portrait_topleft
- DisplayRotation.ROTATION_180 ->
- R.raw.biometricprompt_symbol_error_to_success_landscape
- DisplayRotation.ROTATION_270 ->
- R.raw.biometricprompt_symbol_error_to_success_portrait_bottomright
- }
+ ): Int {
+ return if (authState.isAuthenticatedAndExplicitlyConfirmed) {
+ R.raw.biometricprompt_sfps_unlock_to_success
+ } else if (isPendingConfirmation) {
+ if (_previousIconWasError.value) {
+ R.raw.biometricprompt_sfps_error_to_unlock
} else {
- when (rotation) {
- DisplayRotation.ROTATION_0 ->
- R.raw.biometricprompt_symbol_fingerprint_to_success_landscape
- DisplayRotation.ROTATION_90 ->
- R.raw.biometricprompt_symbol_fingerprint_to_success_portrait_topleft
- DisplayRotation.ROTATION_180 ->
- R.raw.biometricprompt_symbol_fingerprint_to_success_landscape
- DisplayRotation.ROTATION_270 ->
- R.raw.biometricprompt_symbol_fingerprint_to_success_portrait_bottomright
- }
+ getSfpsAsset_fingerprintToUnlock(rotation, isInRearDisplayMode)
+ }
+ } else if (authState.isAuthenticated) {
+ if (_previousIconWasError.value) {
+ R.raw.biometricprompt_sfps_error_to_success
+ } else {
+ getSfpsAsset_fingerprintToSuccess(rotation, isInRearDisplayMode)
}
} else if (isAuthenticating) {
- if (_previousIconOverlayWasError.value) {
- when (rotation) {
- DisplayRotation.ROTATION_0 ->
- R.raw.biometricprompt_symbol_error_to_fingerprint_landscape
- DisplayRotation.ROTATION_90 ->
- R.raw.biometricprompt_symbol_error_to_fingerprint_portrait_topleft
- DisplayRotation.ROTATION_180 ->
- R.raw.biometricprompt_symbol_error_to_fingerprint_landscape
- DisplayRotation.ROTATION_270 ->
- R.raw.biometricprompt_symbol_error_to_fingerprint_portrait_bottomright
- }
+ if (_previousIconWasError.value) {
+ getSfpsAsset_errorToFingerprint(rotation, isInRearDisplayMode)
} else {
- when (rotation) {
- DisplayRotation.ROTATION_0 ->
- R.raw.biometricprompt_fingerprint_to_error_landscape
- DisplayRotation.ROTATION_90 ->
- R.raw.biometricprompt_symbol_fingerprint_to_error_portrait_topleft
- DisplayRotation.ROTATION_180 ->
- R.raw.biometricprompt_fingerprint_to_error_landscape
- DisplayRotation.ROTATION_270 ->
- R.raw.biometricprompt_symbol_fingerprint_to_error_portrait_bottomright
- }
+ getSfpsAsset_fingerprintAuthenticating(isInRearDisplayMode)
}
} else if (showingError) {
- when (rotation) {
- DisplayRotation.ROTATION_0 -> R.raw.biometricprompt_fingerprint_to_error_landscape
- DisplayRotation.ROTATION_90 ->
- R.raw.biometricprompt_symbol_fingerprint_to_error_portrait_topleft
- DisplayRotation.ROTATION_180 -> R.raw.biometricprompt_fingerprint_to_error_landscape
- DisplayRotation.ROTATION_270 ->
- R.raw.biometricprompt_symbol_fingerprint_to_error_portrait_bottomright
- }
+ getSfpsAsset_fingerprintToError(rotation, isInRearDisplayMode)
} else {
-1
}
+ }
/** Content description for iconView */
val contentDescriptionId: Flow<Int> =
@@ -516,12 +422,7 @@ constructor(
isAuthenticating: Boolean,
showingError: Boolean ->
when (sensorType) {
- FingerprintSensorType.POWER_BUTTON ->
- shouldAnimateSfpsIconView(
- authState.isAuthenticated,
- isAuthenticating,
- showingError
- )
+ FingerprintSensorType.POWER_BUTTON -> true
else ->
shouldAnimateFingerprintIconView(
authState.isAuthenticated,
@@ -556,12 +457,7 @@ constructor(
isPendingConfirmation: Boolean,
showingError: Boolean ->
when (sensorType) {
- FingerprintSensorType.POWER_BUTTON ->
- shouldAnimateSfpsIconView(
- authState.isAuthenticated,
- isAuthenticating,
- showingError
- )
+ FingerprintSensorType.POWER_BUTTON -> true
else ->
shouldAnimateCoexIconView(
authState.isAuthenticated,
@@ -574,18 +470,22 @@ constructor(
}
}
+ /** Whether the current BiometricPromptLayout.iconView asset animation should be looping. */
+ val shouldLoopIconView: Flow<Boolean> =
+ activeAuthType.flatMapLatest { activeAuthType: AuthType ->
+ when (activeAuthType) {
+ AuthType.Fingerprint,
+ AuthType.Coex -> flowOf(false)
+ AuthType.Face -> promptViewModel.isAuthenticating
+ }
+ }
+
private fun shouldAnimateFingerprintIconView(
isAuthenticated: Boolean,
isAuthenticating: Boolean,
showingError: Boolean
) = (isAuthenticating && _previousIconWasError.value) || isAuthenticated || showingError
- private fun shouldAnimateSfpsIconView(
- isAuthenticated: Boolean,
- isAuthenticating: Boolean,
- showingError: Boolean
- ) = isAuthenticated || isAuthenticating || showingError
-
private fun shouldAnimateCoexIconView(
isAuthenticated: Boolean,
isAuthenticating: Boolean,
@@ -597,89 +497,123 @@ constructor(
isAuthenticated ||
showingError
- /** Whether the current iconOverlayAsset animation should be playing. */
- val shouldAnimateIconOverlay: Flow<Boolean> =
- activeAuthType.flatMapLatest { activeAuthType: AuthType ->
- when (activeAuthType) {
- AuthType.Fingerprint,
- AuthType.Coex ->
- combine(
- promptSelectorInteractor.fingerprintSensorType,
- promptViewModel.isAuthenticated,
- promptViewModel.isAuthenticating,
- promptViewModel.showingError
- ) {
- sensorType: FingerprintSensorType,
- authState: PromptAuthState,
- isAuthenticating: Boolean,
- showingError: Boolean ->
- when (sensorType) {
- FingerprintSensorType.POWER_BUTTON ->
- shouldAnimateSfpsIconOverlay(
- authState.isAuthenticated,
- isAuthenticating,
- showingError
- )
- else -> false
- }
- }
- AuthType.Face -> flowOf(false)
+ /* Used to rotate the iconView for assets reused across rotations. */
+ val iconViewRotation: Flow<Float> =
+ combine(iconAsset, displayStateInteractor.currentRotation) {
+ icon: Int,
+ rotation: DisplayRotation ->
+ if (assetReusedAcrossRotations(icon)) {
+ when (rotation) {
+ DisplayRotation.ROTATION_0 -> 0f
+ DisplayRotation.ROTATION_90 -> 270f
+ DisplayRotation.ROTATION_180 -> 180f
+ DisplayRotation.ROTATION_270 -> 90f
+ }
+ } else {
+ 0f
}
}
- private fun shouldAnimateSfpsIconOverlay(
- isAuthenticated: Boolean,
- isAuthenticating: Boolean,
- showingError: Boolean
- ) = (isAuthenticating && _previousIconOverlayWasError.value) || isAuthenticated || showingError
+ private fun assetReusedAcrossRotations(asset: Int): Boolean {
+ return asset in assetsReusedAcrossRotations
+ }
- /** Whether the iconView should be flipped due to a device using reverse default rotation . */
- val shouldFlipIconView: Flow<Boolean> =
- activeAuthType.flatMapLatest { activeAuthType: AuthType ->
- when (activeAuthType) {
- AuthType.Fingerprint,
- AuthType.Coex ->
- combine(
- promptSelectorInteractor.fingerprintSensorType,
- displayStateInteractor.currentRotation
- ) { sensorType: FingerprintSensorType, rotation: DisplayRotation ->
- when (sensorType) {
- FingerprintSensorType.POWER_BUTTON ->
- (rotation == DisplayRotation.ROTATION_180)
- else -> false
- }
- }
- AuthType.Face -> flowOf(false)
- }
- }
+ private val assetsReusedAcrossRotations: List<Int> =
+ listOf(
+ R.raw.biometricprompt_sfps_fingerprint_authenticating,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_authenticating,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_authenticating
+ )
/** Called on configuration changes */
fun onConfigurationChanged(newConfig: Configuration) {
displayStateInteractor.onConfigurationChanged(newConfig)
}
- /** iconView assets for caching */
- fun getRawAssets(hasSfps: Boolean): List<Int> {
- return if (hasSfps) {
+ /** Coex iconView assets for caching */
+ fun getCoexAssetsList(hasSfps: Boolean): List<Int> =
+ if (hasSfps) {
listOf(
- R.raw.biometricprompt_fingerprint_to_error_landscape,
- R.raw.biometricprompt_folded_base_bottomright,
- R.raw.biometricprompt_folded_base_default,
- R.raw.biometricprompt_folded_base_topleft,
- R.raw.biometricprompt_landscape_base,
- R.raw.biometricprompt_portrait_base_bottomright,
- R.raw.biometricprompt_portrait_base_topleft,
- R.raw.biometricprompt_symbol_error_to_fingerprint_landscape,
- R.raw.biometricprompt_symbol_error_to_fingerprint_portrait_bottomright,
- R.raw.biometricprompt_symbol_error_to_fingerprint_portrait_topleft,
- R.raw.biometricprompt_symbol_error_to_success_landscape,
- R.raw.biometricprompt_symbol_error_to_success_portrait_bottomright,
- R.raw.biometricprompt_symbol_error_to_success_portrait_topleft,
- R.raw.biometricprompt_symbol_fingerprint_to_error_portrait_bottomright,
- R.raw.biometricprompt_symbol_fingerprint_to_error_portrait_topleft,
- R.raw.biometricprompt_symbol_fingerprint_to_success_landscape,
- R.raw.biometricprompt_symbol_fingerprint_to_success_portrait_bottomright,
- R.raw.biometricprompt_symbol_fingerprint_to_success_portrait_topleft
+ R.raw.biometricprompt_sfps_fingerprint_authenticating,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_authenticating,
+ R.raw.biometricprompt_sfps_error_to_unlock,
+ R.raw.biometricprompt_sfps_error_to_success,
+ R.raw.biometricprompt_sfps_fingerprint_to_error,
+ R.raw.biometricprompt_sfps_fingerprint_to_error_90,
+ R.raw.biometricprompt_sfps_fingerprint_to_error_180,
+ R.raw.biometricprompt_sfps_fingerprint_to_error_270,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_error,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_error_90,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_error_180,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_error_270,
+ R.raw.biometricprompt_sfps_error_to_fingerprint,
+ R.raw.biometricprompt_sfps_error_to_fingerprint_90,
+ R.raw.biometricprompt_sfps_error_to_fingerprint_180,
+ R.raw.biometricprompt_sfps_error_to_fingerprint_270,
+ R.raw.biometricprompt_sfps_rear_display_error_to_fingerprint,
+ R.raw.biometricprompt_sfps_rear_display_error_to_fingerprint_90,
+ R.raw.biometricprompt_sfps_rear_display_error_to_fingerprint_180,
+ R.raw.biometricprompt_sfps_rear_display_error_to_fingerprint_270,
+ R.raw.biometricprompt_sfps_fingerprint_to_unlock,
+ R.raw.biometricprompt_sfps_fingerprint_to_unlock_90,
+ R.raw.biometricprompt_sfps_fingerprint_to_unlock_180,
+ R.raw.biometricprompt_sfps_fingerprint_to_unlock_270,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_unlock,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_unlock_90,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_unlock_180,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_unlock_270,
+ R.raw.biometricprompt_sfps_fingerprint_to_success,
+ R.raw.biometricprompt_sfps_fingerprint_to_success_90,
+ R.raw.biometricprompt_sfps_fingerprint_to_success_180,
+ R.raw.biometricprompt_sfps_fingerprint_to_success_270,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_success,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_success_90,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_success_180,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_success_270,
+ )
+ } else {
+ listOf(
+ R.raw.fingerprint_dialogue_unlocked_to_checkmark_success_lottie,
+ R.raw.fingerprint_dialogue_error_to_unlock_lottie,
+ R.raw.fingerprint_dialogue_fingerprint_to_unlock_lottie,
+ R.raw.fingerprint_dialogue_error_to_success_lottie,
+ R.raw.fingerprint_dialogue_fingerprint_to_success_lottie,
+ R.raw.fingerprint_dialogue_error_to_fingerprint_lottie,
+ R.raw.fingerprint_dialogue_fingerprint_to_error_lottie
+ )
+ }
+
+ /** Fingerprint iconView assets for caching */
+ fun getFingerprintAssetsList(hasSfps: Boolean): List<Int> =
+ if (hasSfps) {
+ listOf(
+ R.raw.biometricprompt_sfps_fingerprint_authenticating,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_authenticating,
+ R.raw.biometricprompt_sfps_error_to_success,
+ R.raw.biometricprompt_sfps_fingerprint_to_error,
+ R.raw.biometricprompt_sfps_fingerprint_to_error_90,
+ R.raw.biometricprompt_sfps_fingerprint_to_error_180,
+ R.raw.biometricprompt_sfps_fingerprint_to_error_270,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_error,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_error_90,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_error_180,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_error_270,
+ R.raw.biometricprompt_sfps_error_to_fingerprint,
+ R.raw.biometricprompt_sfps_error_to_fingerprint_90,
+ R.raw.biometricprompt_sfps_error_to_fingerprint_180,
+ R.raw.biometricprompt_sfps_error_to_fingerprint_270,
+ R.raw.biometricprompt_sfps_rear_display_error_to_fingerprint,
+ R.raw.biometricprompt_sfps_rear_display_error_to_fingerprint_90,
+ R.raw.biometricprompt_sfps_rear_display_error_to_fingerprint_180,
+ R.raw.biometricprompt_sfps_rear_display_error_to_fingerprint_270,
+ R.raw.biometricprompt_sfps_fingerprint_to_success,
+ R.raw.biometricprompt_sfps_fingerprint_to_success_90,
+ R.raw.biometricprompt_sfps_fingerprint_to_success_180,
+ R.raw.biometricprompt_sfps_fingerprint_to_success_270,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_success,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_success_90,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_success_180,
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_success_270,
)
} else {
listOf(
@@ -689,5 +623,120 @@ constructor(
R.raw.fingerprint_dialogue_fingerprint_to_success_lottie
)
}
- }
+
+ /** Face iconView assets for caching */
+ fun getFaceAssetsList(): List<Int> =
+ listOf(
+ R.raw.face_dialog_wink_from_dark,
+ R.raw.face_dialog_dark_to_checkmark,
+ R.raw.face_dialog_dark_to_error,
+ R.raw.face_dialog_error_to_idle,
+ R.raw.face_dialog_idle_static,
+ R.raw.face_dialog_authenticating
+ )
+
+ private fun getSfpsAsset_fingerprintAuthenticating(isInRearDisplayMode: Boolean): Int =
+ if (isInRearDisplayMode) {
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_authenticating
+ } else {
+ R.raw.biometricprompt_sfps_fingerprint_authenticating
+ }
+
+ private fun getSfpsAsset_fingerprintToError(
+ rotation: DisplayRotation,
+ isInRearDisplayMode: Boolean
+ ): Int =
+ if (isInRearDisplayMode) {
+ when (rotation) {
+ DisplayRotation.ROTATION_0 ->
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_error
+ DisplayRotation.ROTATION_90 ->
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_error_90
+ DisplayRotation.ROTATION_180 ->
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_error_180
+ DisplayRotation.ROTATION_270 ->
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_error_270
+ }
+ } else {
+ when (rotation) {
+ DisplayRotation.ROTATION_0 -> R.raw.biometricprompt_sfps_fingerprint_to_error
+ DisplayRotation.ROTATION_90 -> R.raw.biometricprompt_sfps_fingerprint_to_error_90
+ DisplayRotation.ROTATION_180 -> R.raw.biometricprompt_sfps_fingerprint_to_error_180
+ DisplayRotation.ROTATION_270 -> R.raw.biometricprompt_sfps_fingerprint_to_error_270
+ }
+ }
+
+ private fun getSfpsAsset_errorToFingerprint(
+ rotation: DisplayRotation,
+ isInRearDisplayMode: Boolean
+ ): Int =
+ if (isInRearDisplayMode) {
+ when (rotation) {
+ DisplayRotation.ROTATION_0 ->
+ R.raw.biometricprompt_sfps_rear_display_error_to_fingerprint
+ DisplayRotation.ROTATION_90 ->
+ R.raw.biometricprompt_sfps_rear_display_error_to_fingerprint_90
+ DisplayRotation.ROTATION_180 ->
+ R.raw.biometricprompt_sfps_rear_display_error_to_fingerprint_180
+ DisplayRotation.ROTATION_270 ->
+ R.raw.biometricprompt_sfps_rear_display_error_to_fingerprint_270
+ }
+ } else {
+ when (rotation) {
+ DisplayRotation.ROTATION_0 -> R.raw.biometricprompt_sfps_error_to_fingerprint
+ DisplayRotation.ROTATION_90 -> R.raw.biometricprompt_sfps_error_to_fingerprint_90
+ DisplayRotation.ROTATION_180 -> R.raw.biometricprompt_sfps_error_to_fingerprint_180
+ DisplayRotation.ROTATION_270 -> R.raw.biometricprompt_sfps_error_to_fingerprint_270
+ }
+ }
+
+ private fun getSfpsAsset_fingerprintToUnlock(
+ rotation: DisplayRotation,
+ isInRearDisplayMode: Boolean
+ ): Int =
+ if (isInRearDisplayMode) {
+ when (rotation) {
+ DisplayRotation.ROTATION_0 ->
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_unlock
+ DisplayRotation.ROTATION_90 ->
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_unlock_90
+ DisplayRotation.ROTATION_180 ->
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_unlock_180
+ DisplayRotation.ROTATION_270 ->
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_unlock_270
+ }
+ } else {
+ when (rotation) {
+ DisplayRotation.ROTATION_0 -> R.raw.biometricprompt_sfps_fingerprint_to_unlock
+ DisplayRotation.ROTATION_90 -> R.raw.biometricprompt_sfps_fingerprint_to_unlock_90
+ DisplayRotation.ROTATION_180 -> R.raw.biometricprompt_sfps_fingerprint_to_unlock_180
+ DisplayRotation.ROTATION_270 -> R.raw.biometricprompt_sfps_fingerprint_to_unlock_270
+ }
+ }
+
+ private fun getSfpsAsset_fingerprintToSuccess(
+ rotation: DisplayRotation,
+ isInRearDisplayMode: Boolean
+ ): Int =
+ if (isInRearDisplayMode) {
+ when (rotation) {
+ DisplayRotation.ROTATION_0 ->
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_success
+ DisplayRotation.ROTATION_90 ->
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_success_90
+ DisplayRotation.ROTATION_180 ->
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_success_180
+ DisplayRotation.ROTATION_270 ->
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_success_270
+ }
+ } else {
+ when (rotation) {
+ DisplayRotation.ROTATION_0 -> R.raw.biometricprompt_sfps_fingerprint_to_success
+ DisplayRotation.ROTATION_90 -> R.raw.biometricprompt_sfps_fingerprint_to_success_90
+ DisplayRotation.ROTATION_180 ->
+ R.raw.biometricprompt_sfps_fingerprint_to_success_180
+ DisplayRotation.ROTATION_270 ->
+ R.raw.biometricprompt_sfps_fingerprint_to_success_270
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
index d1ac6814bef2..fbc64708c3af 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
@@ -409,12 +409,7 @@ constructor(
.distinctUntilChanged()
val iconViewModel: PromptIconViewModel =
- PromptIconViewModel(
- this,
- displayStateInteractor,
- promptSelectorInteractor,
- udfpsOverlayInteractor
- )
+ PromptIconViewModel(this, displayStateInteractor, promptSelectorInteractor)
private val _isIconViewLoaded = MutableStateFlow(false)
@@ -903,8 +898,8 @@ constructor(
): Boolean {
if (
modalities.first().hasUdfps &&
- touchExplorationEnabled &&
- !isAuthenticated.first().isAuthenticated
+ touchExplorationEnabled &&
+ !isAuthenticated.first().isAuthenticated
) {
// TODO(b/315184924): Remove uses of UdfpsUtils
val scaledTouch =
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/binder/IconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/common/ui/binder/IconViewBinder.kt
index 64dedea3e6d4..108e22bc392b 100644
--- a/packages/SystemUI/src/com/android/systemui/common/ui/binder/IconViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/binder/IconViewBinder.kt
@@ -16,7 +16,6 @@
package com.android.systemui.common.ui.binder
-import android.view.View
import android.widget.ImageView
import com.android.systemui.common.shared.model.Icon
@@ -31,13 +30,4 @@ object IconViewBinder {
is Icon.Resource -> view.setImageResource(icon.res)
}
}
-
- fun bindNullable(icon: Icon?, view: ImageView) {
- if (icon != null) {
- view.visibility = View.VISIBLE
- bind(icon, view)
- } else {
- view.visibility = View.GONE
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractor.kt
index 6a20610da3a6..c780aac5aaca 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractor.kt
@@ -175,7 +175,7 @@ constructor(
}
}
- private fun finishCurrentTransition() {
+ private suspend fun finishCurrentTransition() {
internalTransitionInteractor.updateTransition(
currentTransitionId!!,
1f,
@@ -285,7 +285,7 @@ constructor(
currentTransitionId = internalTransitionInteractor.startTransition(transitionInfo)
}
- private fun updateProgress(progress: Float) {
+ private suspend fun updateProgress(progress: Float) {
if (currentTransitionId == null) return
internalTransitionInteractor.updateTransition(
currentTransitionId!!,
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
index 3fc8b096a48b..b06cf3ffcf45 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
@@ -97,8 +97,10 @@ constructor(
private val metricsLogger: CommunalMetricsLogger,
) : BaseCommunalViewModel(communalSceneInteractor, communalInteractor, mediaHost) {
+ private val logger = Logger(logBuffer, "CommunalViewModel")
+
private val _isMediaHostVisible =
- conflatedCallbackFlow<Boolean> {
+ conflatedCallbackFlow {
val callback = { visible: Boolean ->
trySend(visible)
Unit
@@ -106,11 +108,18 @@ constructor(
mediaHost.addVisibilityChangeListener(callback)
awaitClose { mediaHost.removeVisibilityChangeListener(callback) }
}
- .onStart { emit(mediaHost.visible) }
+ .onStart {
+ // Ensure the visibility state is correct when the hub is opened and this flow is
+ // started so that the UMO is shown when needed. The visibility state in MediaHost
+ // is not updated once its view has been detached, aka the hub is closed, which can
+ // result in this getting stuck as False and never being updated as the UMO is not
+ // shown.
+ mediaHost.updateViewVisibility()
+ emit(mediaHost.visible)
+ }
+ .onEach { logger.d({ "_isMediaHostVisible: $bool1" }) { bool1 = it } }
.flowOn(mainDispatcher)
- private val logger = Logger(logBuffer, "CommunalViewModel")
-
/** Communal content saved from the previous emission when the flow is active (not "frozen"). */
private var frozenCommunalContent: List<CommunalContentModel>? = null
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHost.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHost.kt
index 058ca4d963a0..10a565f49a8f 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHost.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHost.kt
@@ -36,7 +36,7 @@ class CommunalAppWidgetHost(
context: Context,
private val backgroundScope: CoroutineScope,
hostId: Int,
- interactionHandler: RemoteViews.InteractionHandler,
+ private val interactionHandler: RemoteViews.InteractionHandler,
looper: Looper,
logBuffer: LogBuffer,
) : AppWidgetHost(context, hostId, interactionHandler, looper) {
@@ -55,7 +55,7 @@ class CommunalAppWidgetHost(
appWidgetId: Int,
appWidget: AppWidgetProviderInfo?
): AppWidgetHostView {
- return CommunalAppWidgetHostView(context)
+ return CommunalAppWidgetHostView(context, interactionHandler)
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostView.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostView.kt
index 25591378938e..d5497345dda5 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostView.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostView.kt
@@ -17,17 +17,25 @@
package com.android.systemui.communal.widgets
import android.appwidget.AppWidgetHostView
+import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProviderInfo
import android.content.Context
+import android.content.pm.LauncherActivityInfo
+import android.content.pm.LauncherApps
import android.graphics.Outline
import android.graphics.Rect
import android.view.View
import android.view.ViewOutlineProvider
+import android.widget.RemoteViews
+import android.widget.RemoteViews.RemoteResponse
import com.android.systemui.animation.LaunchableView
import com.android.systemui.animation.LaunchableViewDelegate
/** AppWidgetHostView that displays in communal hub with support for rounded corners. */
-class CommunalAppWidgetHostView(context: Context) : AppWidgetHostView(context), LaunchableView {
+class CommunalAppWidgetHostView(
+ context: Context,
+ private val interactionHandler: RemoteViews.InteractionHandler,
+) : AppWidgetHostView(context, interactionHandler), LaunchableView {
private val launchableViewDelegate =
LaunchableViewDelegate(
this,
@@ -92,4 +100,26 @@ class CommunalAppWidgetHostView(context: Context) : AppWidgetHostView(context),
launchableViewDelegate.setShouldBlockVisibilityChanges(block)
override fun setVisibility(visibility: Int) = launchableViewDelegate.setVisibility(visibility)
+
+ override fun onDefaultViewClicked(view: View) {
+ AppWidgetManager.getInstance(context)?.noteAppWidgetTapped(appWidgetId)
+ if (appWidgetInfo == null) {
+ return
+ }
+ val launcherApps = context.getSystemService(LauncherApps::class.java)
+ val activityInfo: LauncherActivityInfo =
+ launcherApps
+ .getActivityList(appWidgetInfo.provider.packageName, appWidgetInfo.profile)
+ ?.getOrNull(0) ?: return
+
+ val intent =
+ launcherApps.getMainActivityLaunchIntent(
+ activityInfo.componentName,
+ null,
+ activityInfo.user
+ )
+ if (intent != null) {
+ interactionHandler.onInteraction(view, intent, RemoteResponse.fromPendingIntent(intent))
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/education/dagger/ContextualEducationModule.kt b/packages/SystemUI/src/com/android/systemui/education/dagger/ContextualEducationModule.kt
index b8019ab9ce0c..532b123663ad 100644
--- a/packages/SystemUI/src/com/android/systemui/education/dagger/ContextualEducationModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/education/dagger/ContextualEducationModule.kt
@@ -19,13 +19,13 @@ package com.android.systemui.education.dagger
import com.android.systemui.CoreStartable
import com.android.systemui.Flags
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.contextualeducation.GestureType
import com.android.systemui.education.data.repository.ContextualEducationRepository
import com.android.systemui.education.data.repository.ContextualEducationRepositoryImpl
import com.android.systemui.education.domain.interactor.ContextualEducationInteractor
import com.android.systemui.education.domain.interactor.KeyboardTouchpadEduInteractor
import com.android.systemui.education.domain.interactor.KeyboardTouchpadEduStatsInteractor
import com.android.systemui.education.domain.interactor.KeyboardTouchpadEduStatsInteractorImpl
-import com.android.systemui.shared.education.GestureType
import dagger.Binds
import dagger.Lazy
import dagger.Module
diff --git a/packages/SystemUI/src/com/android/systemui/education/data/repository/ContextualEducationRepository.kt b/packages/SystemUI/src/com/android/systemui/education/data/repository/ContextualEducationRepository.kt
index 248b7a526256..52ccba4b65c7 100644
--- a/packages/SystemUI/src/com/android/systemui/education/data/repository/ContextualEducationRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/education/data/repository/ContextualEducationRepository.kt
@@ -17,9 +17,9 @@
package com.android.systemui.education.data.repository
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.contextualeducation.GestureType
import com.android.systemui.education.dagger.ContextualEducationModule.EduClock
import com.android.systemui.education.data.model.GestureEduModel
-import com.android.systemui.shared.education.GestureType
import java.time.Clock
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
diff --git a/packages/SystemUI/src/com/android/systemui/education/data/repository/UserContextualEducationRepository.kt b/packages/SystemUI/src/com/android/systemui/education/data/repository/UserContextualEducationRepository.kt
index b7fc7733f3e6..4b37b29e88a5 100644
--- a/packages/SystemUI/src/com/android/systemui/education/data/repository/UserContextualEducationRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/education/data/repository/UserContextualEducationRepository.kt
@@ -27,9 +27,9 @@ import androidx.datastore.preferences.core.longPreferencesKey
import androidx.datastore.preferences.preferencesDataStoreFile
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.contextualeducation.GestureType
import com.android.systemui.education.dagger.ContextualEducationModule.EduDataStoreScope
import com.android.systemui.education.data.model.GestureEduModel
-import com.android.systemui.shared.education.GestureType
import java.time.Instant
import javax.inject.Inject
import javax.inject.Provider
diff --git a/packages/SystemUI/src/com/android/systemui/education/domain/interactor/ContextualEducationInteractor.kt b/packages/SystemUI/src/com/android/systemui/education/domain/interactor/ContextualEducationInteractor.kt
index 3036d970e985..bee289d4b63a 100644
--- a/packages/SystemUI/src/com/android/systemui/education/domain/interactor/ContextualEducationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/education/domain/interactor/ContextualEducationInteractor.kt
@@ -19,9 +19,10 @@ package com.android.systemui.education.domain.interactor
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.contextualeducation.GestureType
+import com.android.systemui.contextualeducation.GestureType.BACK
import com.android.systemui.education.data.model.GestureEduModel
import com.android.systemui.education.data.repository.ContextualEducationRepository
-import com.android.systemui.shared.education.GestureType
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
@@ -46,7 +47,7 @@ constructor(
private val repository: ContextualEducationRepository,
) : CoreStartable {
- val backGestureModelFlow = readEduModelsOnSignalCountChanged(GestureType.BACK_GESTURE)
+ val backGestureModelFlow = readEduModelsOnSignalCountChanged(BACK)
override fun start() {
backgroundScope.launch {
diff --git a/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt b/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt
index 247abf1a7ecc..9016c7339c25 100644
--- a/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt
@@ -19,10 +19,10 @@ package com.android.systemui.education.domain.interactor
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.contextualeducation.GestureType.BACK
import com.android.systemui.education.data.model.GestureEduModel
import com.android.systemui.education.shared.model.EducationInfo
import com.android.systemui.education.shared.model.EducationUiType
-import com.android.systemui.shared.education.GestureType.BACK_GESTURE
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
@@ -50,7 +50,7 @@ constructor(
backgroundScope.launch {
contextualEducationInteractor.backGestureModelFlow
.mapNotNull { getEduType(it) }
- .collect { _educationTriggered.value = EducationInfo(BACK_GESTURE, it) }
+ .collect { _educationTriggered.value = EducationInfo(BACK, it) }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduStatsInteractor.kt b/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduStatsInteractor.kt
index 643e571d2927..3223433568b9 100644
--- a/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduStatsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduStatsInteractor.kt
@@ -18,7 +18,7 @@ package com.android.systemui.education.domain.interactor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.shared.education.GestureType
+import com.android.systemui.contextualeducation.GestureType
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
diff --git a/packages/SystemUI/src/com/android/systemui/education/shared/model/EducationInfo.kt b/packages/SystemUI/src/com/android/systemui/education/shared/model/EducationInfo.kt
index 85f4012ddbd2..d92fb9bff512 100644
--- a/packages/SystemUI/src/com/android/systemui/education/shared/model/EducationInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/education/shared/model/EducationInfo.kt
@@ -16,7 +16,7 @@
package com.android.systemui.education.shared.model
-import com.android.systemui.shared.education.GestureType
+import com.android.systemui.contextualeducation.GestureType
/**
* Model for education triggered. [gestureType] indicates what gesture it is trying to educate about
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt b/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt
index 6e4038d85e03..59de2032c4f1 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt
@@ -23,7 +23,13 @@ import com.android.server.notification.Flags.crossAppPoliteNotifications
import com.android.server.notification.Flags.politeNotifications
import com.android.server.notification.Flags.vibrateWhileUnlocked
import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
+import com.android.systemui.Flags.FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON
+import com.android.systemui.Flags.FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS
+import com.android.systemui.Flags.FLAG_STATUS_BAR_USE_REPOS_FOR_CALL_CHIP
import com.android.systemui.Flags.communalHub
+import com.android.systemui.Flags.statusBarCallChipNotificationIcon
+import com.android.systemui.Flags.statusBarScreenSharingChips
+import com.android.systemui.Flags.statusBarUseReposForCallChip
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.KeyguardBottomAreaRefactor
import com.android.systemui.keyguard.MigrateClocksToBlueprint
@@ -38,9 +44,9 @@ import com.android.systemui.statusbar.notification.interruption.VisualInterrupti
import com.android.systemui.statusbar.notification.shared.NotificationAvalancheSuppression
import com.android.systemui.statusbar.notification.shared.NotificationIconContainerRefactor
import com.android.systemui.statusbar.notification.shared.NotificationMinimalismPrototype
+import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun
import com.android.systemui.statusbar.notification.shared.NotificationsHeadsUpRefactor
import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor
-import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun
import com.android.systemui.statusbar.notification.shared.PriorityPeopleSection
import javax.inject.Inject
@@ -77,6 +83,10 @@ class FlagDependencies @Inject constructor(featureFlags: FeatureFlagsClassic, ha
// QS Fragment using Compose dependencies
QSComposeFragment.token dependsOn NewQsUI.token
+
+ // Status bar chip dependencies
+ statusBarCallChipNotificationIconToken dependsOn statusBarUseReposForCallChipToken
+ statusBarCallChipNotificationIconToken dependsOn statusBarScreenSharingChipsToken
}
private inline val politeNotifications
@@ -96,4 +106,17 @@ class FlagDependencies @Inject constructor(featureFlags: FeatureFlagsClassic, ha
private inline val communalHub
get() = FlagToken(FLAG_COMMUNAL_HUB, communalHub())
+
+ private inline val statusBarCallChipNotificationIconToken
+ get() =
+ FlagToken(
+ FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON,
+ statusBarCallChipNotificationIcon()
+ )
+
+ private inline val statusBarScreenSharingChipsToken
+ get() = FlagToken(FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, statusBarScreenSharingChips())
+
+ private inline val statusBarUseReposForCallChipToken
+ get() = FlagToken(FLAG_STATUS_BAR_USE_REPOS_FOR_CALL_CHIP, statusBarUseReposForCallChip())
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
index 67aeddefcb4a..63f3d52b2d2d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
@@ -36,6 +36,7 @@ import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.FlowRowScope
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
@@ -208,9 +209,24 @@ private fun ShortcutHelperSinglePane(
Spacer(modifier = Modifier.height(6.dp))
ShortcutsSearchBar(onSearchQueryChanged)
Spacer(modifier = Modifier.height(16.dp))
- CategoriesPanelSinglePane(searchQuery, categories, selectedCategoryType, onCategorySelected)
- Spacer(modifier = Modifier.weight(1f))
- KeyboardSettings(onClick = onKeyboardSettingsClicked)
+ if (categories.isEmpty()) {
+ Box(modifier = Modifier.weight(1f)) {
+ NoSearchResultsText(horizontalPadding = 16.dp, fillHeight = true)
+ }
+ } else {
+ CategoriesPanelSinglePane(
+ searchQuery,
+ categories,
+ selectedCategoryType,
+ onCategorySelected
+ )
+ Spacer(modifier = Modifier.weight(1f))
+ }
+ KeyboardSettings(
+ horizontalPadding = 16.dp,
+ verticalPadding = 32.dp,
+ onClick = onKeyboardSettingsClicked
+ )
}
}
@@ -429,7 +445,7 @@ private fun ShortcutHelperTwoPane(
@Composable
private fun EndSidePanel(searchQuery: String, modifier: Modifier, category: ShortcutCategory?) {
if (category == null) {
- // TODO(b/353953351) - Show a "no results" UI?
+ NoSearchResultsText(horizontalPadding = 24.dp, fillHeight = false)
return
}
LazyColumn(modifier.nestedScroll(rememberNestedScrollInteropConnection())) {
@@ -441,6 +457,24 @@ private fun EndSidePanel(searchQuery: String, modifier: Modifier, category: Shor
}
@Composable
+private fun NoSearchResultsText(horizontalPadding: Dp, fillHeight: Boolean) {
+ var modifier = Modifier.fillMaxWidth()
+ if (fillHeight) {
+ modifier = modifier.fillMaxHeight()
+ }
+ Text(
+ stringResource(R.string.shortcut_helper_no_search_results),
+ style = MaterialTheme.typography.bodyMedium,
+ color = MaterialTheme.colorScheme.onSurface,
+ modifier =
+ modifier
+ .padding(vertical = 8.dp)
+ .background(MaterialTheme.colorScheme.surfaceBright, RoundedCornerShape(28.dp))
+ .padding(horizontal = horizontalPadding, vertical = 24.dp)
+ )
+}
+
+@Composable
private fun SubCategoryContainerDualPane(searchQuery: String, subCategory: ShortcutSubCategory) {
Surface(
modifier = Modifier.fillMaxWidth(),
@@ -659,7 +693,11 @@ private fun StartSidePanel(
Spacer(modifier = Modifier.heightIn(8.dp))
CategoriesPanelTwoPane(categories, selectedCategory, onCategoryClicked)
Spacer(modifier = Modifier.weight(1f))
- KeyboardSettings(onKeyboardSettingsClicked)
+ KeyboardSettings(
+ horizontalPadding = 24.dp,
+ verticalPadding = 24.dp,
+ onKeyboardSettingsClicked
+ )
}
}
@@ -805,10 +843,9 @@ private fun ShortcutsSearchBar(onQueryChange: (String) -> Unit) {
}
@Composable
-private fun KeyboardSettings(onClick: () -> Unit) {
+private fun KeyboardSettings(horizontalPadding: Dp, verticalPadding: Dp, onClick: () -> Unit) {
val interactionSource = remember { MutableInteractionSource() }
val isFocused by interactionSource.collectIsFocusedAsState()
-
Surface(
onClick = onClick,
shape = RoundedCornerShape(24.dp),
@@ -834,7 +871,7 @@ private fun KeyboardSettings(onClick: () -> Unit) {
color = MaterialTheme.colorScheme.onSurfaceVariant,
fontSize = 16.sp
)
- Spacer(modifier = Modifier.width(8.dp))
+ Spacer(modifier = Modifier.weight(1f))
Icon(
imageVector = Icons.AutoMirrored.Default.OpenInNew,
contentDescription = null,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
index aaeeb3911797..de60c1117c19 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
@@ -105,7 +105,7 @@ interface KeyguardTransitionRepository {
* When the transition is over, TransitionState.FINISHED must be passed into the [state]
* parameter.
*/
- fun updateTransition(
+ suspend fun updateTransition(
transitionId: UUID,
@FloatRange(from = 0.0, to = 1.0) value: Float,
state: TransitionState
@@ -173,9 +173,9 @@ constructor(
Log.d(TAG, "(Internal) Setting current transition info: $info")
// There is no fairness guarantee with 'withContext', which means that transitions could
- // be processed out of order. Use a Mutex to guarantee ordering.
+ // be processed out of order. Use a Mutex to guarantee ordering. [updateTransition]
+ // requires the same lock
_currentTransitionMutex.lock()
-
// Only used in a test environment
if (forceDelayForRaceConditionTest) {
delay(50L)
@@ -184,7 +184,6 @@ constructor(
// Animators must be started on the main thread.
return withContext("$TAG#startTransition", mainDispatcher) {
_currentTransitionMutex.unlock()
-
if (lastStep.from == info.from && lastStep.to == info.to) {
Log.i(TAG, "Duplicate call to start the transition, rejecting: $info")
return@withContext null
@@ -206,7 +205,7 @@ constructor(
// Cancel any existing manual transitions
updateTransitionId?.let { uuid ->
- updateTransition(uuid, lastStep.value, TransitionState.CANCELED)
+ updateTransitionInternal(uuid, lastStep.value, TransitionState.CANCELED)
}
info.animator?.let { animator ->
@@ -264,7 +263,23 @@ constructor(
}
}
- override fun updateTransition(
+ override suspend fun updateTransition(
+ transitionId: UUID,
+ @FloatRange(from = 0.0, to = 1.0) value: Float,
+ state: TransitionState
+ ) {
+ // There is no fairness guarantee with 'withContext', which means that transitions could
+ // be processed out of order. Use a Mutex to guarantee ordering. [startTransition]
+ // requires the same lock
+ _currentTransitionMutex.lock()
+ withContext("$TAG#updateTransition", mainDispatcher) {
+ _currentTransitionMutex.unlock()
+
+ updateTransitionInternal(transitionId, value, state)
+ }
+ }
+
+ private suspend fun updateTransitionInternal(
transitionId: UUID,
@FloatRange(from = 0.0, to = 1.0) value: Float,
state: TransitionState
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/InternalKeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/InternalKeyguardTransitionInteractor.kt
index a51421c10309..2cc6afa2f407 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/InternalKeyguardTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/InternalKeyguardTransitionInteractor.kt
@@ -63,7 +63,7 @@ constructor(
suspend fun startTransition(info: TransitionInfo) = repository.startTransition(info)
- fun updateTransition(
+ suspend fun updateTransition(
transitionId: UUID,
@FloatRange(from = 0.0, to = 1.0) value: Float,
state: TransitionState
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
index 797d4667c56d..afbe3579315d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
@@ -47,6 +47,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
@@ -55,6 +56,7 @@ import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.transform
import kotlinx.coroutines.launch
/** Encapsulates business-logic related to the keyguard transitions. */
@@ -150,6 +152,12 @@ constructor(
startedStep.to != prevStep.from
) {
getTransitionValueFlow(prevStep.from).emit(0f)
+ } else if (prevStep.transitionState == TransitionState.RUNNING) {
+ Log.e(
+ TAG,
+ "STARTED step ($startedStep) was preceded by a RUNNING step " +
+ "($prevStep), which should never happen. Things could go badly here."
+ )
}
}
}
@@ -252,15 +260,12 @@ constructor(
val startedKeyguardTransitionStep: Flow<TransitionStep> =
repository.transitions.filter { step -> step.transitionState == TransitionState.STARTED }
- /** The last [TransitionStep] with a [TransitionState] of FINISHED */
- val finishedKeyguardTransitionStep: Flow<TransitionStep> =
- repository.transitions.filter { step -> step.transitionState == TransitionState.FINISHED }
-
/** The destination state of the last [TransitionState.STARTED] transition. */
@SuppressLint("SharedFlowCreation")
val startedKeyguardState: SharedFlow<KeyguardState> =
startedKeyguardTransitionStep
.map { step -> step.to }
+ .buffer(2, BufferOverflow.DROP_OLDEST)
.shareIn(scope, SharingStarted.Eagerly, replay = 1)
/** The from state of the last [TransitionState.STARTED] transition. */
@@ -269,6 +274,7 @@ constructor(
val startedKeyguardFromState: SharedFlow<KeyguardState> =
startedKeyguardTransitionStep
.map { step -> step.from }
+ .buffer(2, BufferOverflow.DROP_OLDEST)
.shareIn(scope, SharingStarted.Eagerly, replay = 1)
/** Which keyguard state to use when the device goes to sleep. */
@@ -310,8 +316,13 @@ constructor(
*/
@SuppressLint("SharedFlowCreation")
val finishedKeyguardState: SharedFlow<KeyguardState> =
- finishedKeyguardTransitionStep
- .map { step -> step.to }
+ repository.transitions
+ .transform { step ->
+ if (step.transitionState == TransitionState.FINISHED) {
+ emit(step.to)
+ }
+ }
+ .buffer(2, BufferOverflow.DROP_OLDEST)
.shareIn(scope, SharingStarted.Eagerly, replay = 1)
/**
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
index 324811443e9d..b8500952d90a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
@@ -124,7 +124,7 @@ constructor(
}
}
- private fun finishCurrentTransition() {
+ private suspend fun finishCurrentTransition() {
internalTransitionInteractor.updateTransition(currentTransitionId!!, 1f, FINISHED)
resetTransitionData()
}
@@ -223,7 +223,7 @@ constructor(
currentTransitionId = internalTransitionInteractor.startTransition(transitionInfo)
}
- private fun updateProgress(progress: Float) {
+ private suspend fun updateProgress(progress: Float) {
if (currentTransitionId == null) return
internalTransitionInteractor.updateTransition(
currentTransitionId!!,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
index f96f053b8da1..91b66c3c0a9b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
@@ -207,14 +207,12 @@ object KeyguardRootViewBinder {
launch {
viewModel.burnInLayerVisibility.collect { visibility ->
childViews[burnInLayerId]?.visibility = visibility
- childViews[aodNotificationIconContainerId]?.visibility = visibility
}
}
launch {
viewModel.burnInLayerAlpha.collect { alpha ->
childViews[statusViewId]?.alpha = alpha
- childViews[aodNotificationIconContainerId]?.alpha = alpha
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
index 11889c568275..38a2b1bad3bf 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
@@ -320,19 +320,24 @@ constructor(
val isNotifIconContainerVisible: StateFlow<AnimatedValue<Boolean>> =
combine(
goneToAodTransitionRunning,
+ keyguardTransitionInteractor
+ .transitionValue(LOCKSCREEN)
+ .map { it > 0f }
+ .onStart { emit(false) },
keyguardTransitionInteractor.finishedKeyguardState.map {
KeyguardState.lockscreenVisibleInState(it)
},
deviceEntryInteractor.isBypassEnabled,
areNotifsFullyHiddenAnimated(),
isPulseExpandingAnimated(),
- ) {
- goneToAodTransitionRunning: Boolean,
- onKeyguard: Boolean,
- isBypassEnabled: Boolean,
- notifsFullyHidden: AnimatedValue<Boolean>,
- pulseExpanding: AnimatedValue<Boolean>,
- ->
+ ) { flows ->
+ val goneToAodTransitionRunning = flows[0] as Boolean
+ val isOnLockscreen = flows[1] as Boolean
+ val onKeyguard = flows[2] as Boolean
+ val isBypassEnabled = flows[3] as Boolean
+ val notifsFullyHidden = flows[4] as AnimatedValue<Boolean>
+ val pulseExpanding = flows[5] as AnimatedValue<Boolean>
+
when {
// Hide the AOD icons if we're not in the KEYGUARD state unless the screen off
// animation is playing, in which case we want them to be visible if we're
@@ -351,6 +356,8 @@ constructor(
isBypassEnabled -> true
// If we are pulsing (and not bypassing), then we are hidden
isPulseExpanding -> false
+ // Besides bypass above, they should not be visible on lockscreen
+ isOnLockscreen -> false
// If notifs are fully gone, then we're visible
areNotifsFullyHidden -> true
// Otherwise, we're hidden
diff --git a/packages/SystemUI/src/com/android/systemui/activatable/Activatable.kt b/packages/SystemUI/src/com/android/systemui/lifecycle/Activatable.kt
index dc2d931aad41..ebb0ea62a10c 100644
--- a/packages/SystemUI/src/com/android/systemui/activatable/Activatable.kt
+++ b/packages/SystemUI/src/com/android/systemui/lifecycle/Activatable.kt
@@ -14,7 +14,11 @@
* limitations under the License.
*/
-package com.android.systemui.activatable
+package com.android.systemui.lifecycle
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.remember
/** Defines interface for classes that can be activated to do coroutine work. */
interface Activatable {
@@ -55,3 +59,20 @@ interface Activatable {
*/
suspend fun activate()
}
+
+/**
+ * Returns a remembered [Activatable] of the type [T] that's automatically kept active until this
+ * composable leaves the composition.
+ *
+ * If the [key] changes, the old [Activatable] is deactivated and a new one will be instantiated,
+ * activated, and returned.
+ */
+@Composable
+fun <T : Activatable> rememberActivated(
+ key: Any = Unit,
+ factory: () -> T,
+): T {
+ val instance = remember(key) { factory() }
+ LaunchedEffect(instance) { instance.activate() }
+ return instance
+}
diff --git a/packages/SystemUI/src/com/android/systemui/lifecycle/SafeActivatable.kt b/packages/SystemUI/src/com/android/systemui/lifecycle/SafeActivatable.kt
new file mode 100644
index 000000000000..f080a421d295
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/lifecycle/SafeActivatable.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2024 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.lifecycle
+
+import java.util.concurrent.atomic.AtomicBoolean
+
+/**
+ * An [Activatable] that can be concurrently activated by no more than one owner.
+ *
+ * A previous call to [activate] must be canceled before a new call to [activate] can be made.
+ * Trying to call [activate] while already active will fail with an error.
+ */
+abstract class SafeActivatable : Activatable {
+
+ private val _isActive = AtomicBoolean(false)
+
+ var isActive: Boolean
+ get() = _isActive.get()
+ private set(value) {
+ _isActive.set(value)
+ }
+
+ final override suspend fun activate() {
+ val allowed = _isActive.compareAndSet(false, true)
+ check(allowed) { "Cannot activate an already active activatable!" }
+
+ try {
+ onActivated()
+ } finally {
+ isActive = false
+ }
+ }
+
+ /**
+ * Notifies that the [Activatable] has been activated.
+ *
+ * Serves as an entrypoint to kick off coroutine work that the object requires in order to keep
+ * its state fresh and/or perform side-effects.
+ *
+ * The method suspends and doesn't return until all work required by the object is finished. In
+ * most cases, it's expected for the work to remain ongoing forever so this method will forever
+ * suspend its caller until the coroutine that called it is canceled.
+ *
+ * Implementations could follow this pattern:
+ * ```kotlin
+ * override suspend fun onActivated() {
+ * coroutineScope {
+ * launch { ... }
+ * launch { ... }
+ * launch { ... }
+ * }
+ * }
+ * ```
+ *
+ * @see activate
+ */
+ protected abstract suspend fun onActivated()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/lifecycle/SysUiViewModel.kt b/packages/SystemUI/src/com/android/systemui/lifecycle/SysUiViewModel.kt
new file mode 100644
index 000000000000..0af5feaff3b2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/lifecycle/SysUiViewModel.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 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.lifecycle
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.remember
+
+/** Base class for all System UI view-models. */
+abstract class SysUiViewModel : SafeActivatable() {
+
+ override suspend fun onActivated() = Unit
+}
+
+/**
+ * Returns a remembered [SysUiViewModel] of the type [T] that's automatically kept active until this
+ * composable leaves the composition.
+ *
+ * If the [key] changes, the old [SysUiViewModel] is deactivated and a new one will be instantiated,
+ * activated, and returned.
+ */
+@Composable
+fun <T : SysUiViewModel> rememberViewModel(
+ key: Any = Unit,
+ factory: () -> T,
+): T {
+ val instance = remember(key) { factory() }
+ LaunchedEffect(instance) { instance.activate() }
+ return instance
+}
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionUtils.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionUtils.kt
new file mode 100644
index 000000000000..723ff5a84b63
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/MediaProjectionUtils.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 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.mediaprojection
+
+import android.content.pm.PackageManager
+import com.android.systemui.util.Utils
+
+/** Various utility methods related to media projection. */
+object MediaProjectionUtils {
+ /**
+ * Returns true iff projecting to the given [packageName] means that we're casting media to a
+ * *different* device (as opposed to sharing media to some application on *this* device).
+ */
+ fun packageHasCastingCapabilities(
+ packageManager: PackageManager,
+ packageName: String
+ ): Boolean {
+ // The [isHeadlessRemoteDisplayProvider] check approximates whether a projection is to a
+ // different device or the same device, because headless remote display packages are the
+ // only kinds of packages that do cast-to-other-device. This isn't exactly perfect,
+ // because it means that any projection by those headless remote display packages will be
+ // marked as going to a different device, even if that isn't always true. See b/321078669.
+ return Utils.isHeadlessRemoteDisplayProvider(packageManager, packageName)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
index cc4a92cb516c..3c83db3f258d 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
@@ -41,7 +41,6 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.graphics.Typeface;
import android.media.projection.IMediaProjection;
import android.media.projection.MediaProjectionConfig;
import android.media.projection.MediaProjectionManager;
@@ -50,10 +49,8 @@ import android.os.Bundle;
import android.os.RemoteException;
import android.os.UserHandle;
import android.text.BidiFormatter;
-import android.text.SpannableString;
import android.text.TextPaint;
import android.text.TextUtils;
-import android.text.style.StyleSpan;
import android.util.Log;
import android.view.Window;
@@ -61,6 +58,7 @@ import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger;
import com.android.systemui.mediaprojection.MediaProjectionServiceHelper;
+import com.android.systemui.mediaprojection.MediaProjectionUtils;
import com.android.systemui.mediaprojection.SessionCreationSource;
import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorActivity;
import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver;
@@ -68,12 +66,13 @@ import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDisabledDi
import com.android.systemui.res.R;
import com.android.systemui.statusbar.phone.AlertDialogWithDelegate;
import com.android.systemui.statusbar.phone.SystemUIDialog;
-import com.android.systemui.util.Utils;
-import dagger.Lazy;
+import java.util.function.Consumer;
import javax.inject.Inject;
+import dagger.Lazy;
+
public class MediaProjectionPermissionActivity extends Activity
implements DialogInterface.OnClickListener {
private static final String TAG = "MediaProjectionPermissionActivity";
@@ -189,30 +188,14 @@ public class MediaProjectionPermissionActivity extends Activity
final String appName = extractAppName(aInfo, packageManager);
final boolean hasCastingCapabilities =
- Utils.isHeadlessRemoteDisplayProvider(packageManager, mPackageName);
+ MediaProjectionUtils.INSTANCE.packageHasCastingCapabilities(
+ packageManager, mPackageName);
// Using application context for the dialog, instead of the activity context, so we get
// the correct screen width when in split screen.
Context dialogContext = getApplicationContext();
- final boolean overrideDisableSingleAppOption =
- CompatChanges.isChangeEnabled(
- OVERRIDE_DISABLE_MEDIA_PROJECTION_SINGLE_APP_OPTION,
- mPackageName, getHostUserHandle());
- MediaProjectionPermissionDialogDelegate delegate =
- new MediaProjectionPermissionDialogDelegate(
- dialogContext,
- getMediaProjectionConfig(),
- dialog -> {
- ScreenShareOption selectedOption =
- dialog.getSelectedScreenShareOption();
- grantMediaProjectionPermission(selectedOption.getMode());
- },
- () -> finish(RECORD_CANCEL, /* projection= */ null),
- hasCastingCapabilities,
- appName,
- overrideDisableSingleAppOption,
- mUid,
- mMediaProjectionMetricsLogger);
+ BaseMediaProjectionPermissionDialogDelegate<AlertDialog> delegate =
+ createPermissionDialogDelegate(appName, hasCastingCapabilities, dialogContext);
mDialog =
new AlertDialogWithDelegate(
dialogContext, R.style.Theme_SystemUI_Dialog, delegate);
@@ -274,6 +257,44 @@ public class MediaProjectionPermissionActivity extends Activity
return appName;
}
+ private BaseMediaProjectionPermissionDialogDelegate<AlertDialog> createPermissionDialogDelegate(
+ String appName,
+ boolean hasCastingCapabilities,
+ Context dialogContext) {
+ final boolean overrideDisableSingleAppOption =
+ CompatChanges.isChangeEnabled(
+ OVERRIDE_DISABLE_MEDIA_PROJECTION_SINGLE_APP_OPTION,
+ mPackageName, getHostUserHandle());
+ MediaProjectionConfig mediaProjectionConfig = getMediaProjectionConfig();
+ Consumer<BaseMediaProjectionPermissionDialogDelegate<AlertDialog>> onStartRecordingClicked =
+ dialog -> {
+ ScreenShareOption selectedOption = dialog.getSelectedScreenShareOption();
+ grantMediaProjectionPermission(selectedOption.getMode());
+ };
+ Runnable onCancelClicked = () -> finish(RECORD_CANCEL, /* projection= */ null);
+ if (hasCastingCapabilities) {
+ return new SystemCastPermissionDialogDelegate(
+ dialogContext,
+ mediaProjectionConfig,
+ onStartRecordingClicked,
+ onCancelClicked,
+ appName,
+ overrideDisableSingleAppOption,
+ mUid,
+ mMediaProjectionMetricsLogger);
+ } else {
+ return new ShareToAppPermissionDialogDelegate(
+ dialogContext,
+ mediaProjectionConfig,
+ onStartRecordingClicked,
+ onCancelClicked,
+ appName,
+ overrideDisableSingleAppOption,
+ mUid,
+ mMediaProjectionMetricsLogger);
+ }
+ }
+
@Override
protected void onDestroy() {
super.onDestroy();
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionUtils.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionUtils.kt
new file mode 100644
index 000000000000..88cbc3867744
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionUtils.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2024 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.mediaprojection.permission
+
+import android.content.Context
+import android.media.projection.MediaProjectionConfig
+import com.android.systemui.res.R
+
+/** Various utility methods related to media projection permissions. */
+object MediaProjectionPermissionUtils {
+ fun getSingleAppDisabledText(
+ context: Context,
+ appName: String,
+ mediaProjectionConfig: MediaProjectionConfig?,
+ overrideDisableSingleAppOption: Boolean,
+ ): String? {
+ // The single app option should only be disabled if the client has setup a
+ // MediaProjection with MediaProjectionConfig#createConfigForDefaultDisplay AND
+ // it hasn't been overridden by the OVERRIDE_DISABLE_SINGLE_APP_OPTION per-app override.
+ val singleAppOptionDisabled =
+ !overrideDisableSingleAppOption &&
+ mediaProjectionConfig?.regionToCapture ==
+ MediaProjectionConfig.CAPTURE_REGION_FIXED_DISPLAY
+ return if (singleAppOptionDisabled) {
+ context.getString(
+ R.string.media_projection_entry_app_permission_dialog_single_app_disabled,
+ appName,
+ )
+ } else {
+ null
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/ShareToAppPermissionDialogDelegate.kt
index 6d1a4587d089..5a2d88cf1466 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/ShareToAppPermissionDialogDelegate.kt
@@ -23,13 +23,16 @@ import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger
import com.android.systemui.res.R
import java.util.function.Consumer
-/** Dialog to select screen recording options */
-class MediaProjectionPermissionDialogDelegate(
+/**
+ * Dialog to select screen recording options for sharing the screen to another app on the same
+ * device.
+ */
+class ShareToAppPermissionDialogDelegate(
context: Context,
mediaProjectionConfig: MediaProjectionConfig?,
- private val onStartRecordingClicked: Consumer<MediaProjectionPermissionDialogDelegate>,
+ private val onStartRecordingClicked:
+ Consumer<BaseMediaProjectionPermissionDialogDelegate<AlertDialog>>,
private val onCancelClicked: Runnable,
- private val hasCastingCapabilities: Boolean,
appName: String,
forceShowPartialScreenshare: Boolean,
hostUid: Int,
@@ -39,24 +42,18 @@ class MediaProjectionPermissionDialogDelegate(
createOptionList(
context,
appName,
- hasCastingCapabilities,
mediaProjectionConfig,
- forceShowPartialScreenshare
+ overrideDisableSingleAppOption = forceShowPartialScreenshare,
),
appName,
hostUid,
- mediaProjectionMetricsLogger
+ mediaProjectionMetricsLogger,
) {
override fun onCreate(dialog: AlertDialog, savedInstanceState: Bundle?) {
super.onCreate(dialog, savedInstanceState)
// TODO(b/270018943): Handle the case of System sharing (not recording nor casting)
- if (hasCastingCapabilities) {
- setDialogTitle(R.string.media_projection_entry_cast_permission_dialog_title)
- setStartButtonText(R.string.media_projection_entry_cast_permission_dialog_continue)
- } else {
- setDialogTitle(R.string.media_projection_entry_app_permission_dialog_title)
- setStartButtonText(R.string.media_projection_entry_app_permission_dialog_continue)
- }
+ setDialogTitle(R.string.media_projection_entry_app_permission_dialog_title)
+ setStartButtonText(R.string.media_projection_entry_app_permission_dialog_continue)
setStartButtonOnClickListener {
// Note that it is important to run this callback before dismissing, so that the
// callback can disable the dialog exit animation if it wants to.
@@ -73,55 +70,35 @@ class MediaProjectionPermissionDialogDelegate(
private fun createOptionList(
context: Context,
appName: String,
- hasCastingCapabilities: Boolean,
mediaProjectionConfig: MediaProjectionConfig?,
- overrideDisableSingleAppOption: Boolean = false,
+ overrideDisableSingleAppOption: Boolean,
): List<ScreenShareOption> {
- val singleAppWarningText =
- if (hasCastingCapabilities) {
- R.string.media_projection_entry_cast_permission_dialog_warning_single_app
- } else {
- R.string.media_projection_entry_app_permission_dialog_warning_single_app
- }
- val entireScreenWarningText =
- if (hasCastingCapabilities) {
- R.string.media_projection_entry_cast_permission_dialog_warning_entire_screen
- } else {
- R.string.media_projection_entry_app_permission_dialog_warning_entire_screen
- }
-
- // The single app option should only be disabled if the client has setup a
- // MediaProjection with MediaProjectionConfig#createConfigForDefaultDisplay AND
- // it hasn't been overridden by the OVERRIDE_DISABLE_SINGLE_APP_OPTION per-app override.
- val singleAppOptionDisabled =
- !overrideDisableSingleAppOption &&
- mediaProjectionConfig?.regionToCapture ==
- MediaProjectionConfig.CAPTURE_REGION_FIXED_DISPLAY
-
val singleAppDisabledText =
- if (singleAppOptionDisabled) {
- context.getString(
- R.string.media_projection_entry_app_permission_dialog_single_app_disabled,
- appName
- )
- } else {
- null
- }
+ MediaProjectionPermissionUtils.getSingleAppDisabledText(
+ context,
+ appName,
+ mediaProjectionConfig,
+ overrideDisableSingleAppOption,
+ )
val options =
listOf(
ScreenShareOption(
mode = SINGLE_APP,
spinnerText = R.string.screen_share_permission_dialog_option_single_app,
- warningText = singleAppWarningText,
+ warningText =
+ R.string
+ .media_projection_entry_app_permission_dialog_warning_single_app,
spinnerDisabledText = singleAppDisabledText,
),
ScreenShareOption(
mode = ENTIRE_SCREEN,
spinnerText = R.string.screen_share_permission_dialog_option_entire_screen,
- warningText = entireScreenWarningText
+ warningText =
+ R.string
+ .media_projection_entry_app_permission_dialog_warning_entire_screen,
)
)
- return if (singleAppOptionDisabled) {
+ return if (singleAppDisabledText != null) {
// Make sure "Entire screen" is the first option when "Single App" is disabled.
options.reversed()
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/SystemCastPermissionDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/SystemCastPermissionDialogDelegate.kt
new file mode 100644
index 000000000000..1ac3ccd19cf4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/SystemCastPermissionDialogDelegate.kt
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.mediaprojection.permission
+
+import android.app.AlertDialog
+import android.content.Context
+import android.media.projection.MediaProjectionConfig
+import android.os.Bundle
+import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger
+import com.android.systemui.mediaprojection.permission.MediaProjectionPermissionUtils.getSingleAppDisabledText
+import com.android.systemui.res.R
+import java.util.function.Consumer
+
+/** Dialog to select screen recording options for casting the screen to a different device. */
+class SystemCastPermissionDialogDelegate(
+ context: Context,
+ mediaProjectionConfig: MediaProjectionConfig?,
+ private val onStartRecordingClicked:
+ Consumer<BaseMediaProjectionPermissionDialogDelegate<AlertDialog>>,
+ private val onCancelClicked: Runnable,
+ appName: String,
+ forceShowPartialScreenshare: Boolean,
+ hostUid: Int,
+ mediaProjectionMetricsLogger: MediaProjectionMetricsLogger,
+) :
+ BaseMediaProjectionPermissionDialogDelegate<AlertDialog>(
+ createOptionList(
+ context,
+ appName,
+ mediaProjectionConfig,
+ overrideDisableSingleAppOption = forceShowPartialScreenshare,
+ ),
+ appName,
+ hostUid,
+ mediaProjectionMetricsLogger,
+ dialogIconDrawable = R.drawable.ic_cast_connected,
+ ) {
+ override fun onCreate(dialog: AlertDialog, savedInstanceState: Bundle?) {
+ super.onCreate(dialog, savedInstanceState)
+ // TODO(b/270018943): Handle the case of System sharing (not recording nor casting)
+ setDialogTitle(R.string.media_projection_entry_cast_permission_dialog_title)
+ setStartButtonText(R.string.media_projection_entry_cast_permission_dialog_continue)
+ setStartButtonOnClickListener {
+ // Note that it is important to run this callback before dismissing, so that the
+ // callback can disable the dialog exit animation if it wants to.
+ onStartRecordingClicked.accept(this)
+ dialog.dismiss()
+ }
+ setCancelButtonOnClickListener {
+ onCancelClicked.run()
+ dialog.dismiss()
+ }
+ }
+
+ companion object {
+ private fun createOptionList(
+ context: Context,
+ appName: String,
+ mediaProjectionConfig: MediaProjectionConfig?,
+ overrideDisableSingleAppOption: Boolean,
+ ): List<ScreenShareOption> {
+ val singleAppDisabledText =
+ getSingleAppDisabledText(
+ context,
+ appName,
+ mediaProjectionConfig,
+ overrideDisableSingleAppOption
+ )
+ val options =
+ listOf(
+ ScreenShareOption(
+ mode = SINGLE_APP,
+ spinnerText =
+ R.string
+ .media_projection_entry_cast_permission_dialog_option_text_single_app,
+ warningText =
+ R.string
+ .media_projection_entry_cast_permission_dialog_warning_single_app,
+ spinnerDisabledText = singleAppDisabledText,
+ ),
+ ScreenShareOption(
+ mode = ENTIRE_SCREEN,
+ spinnerText =
+ R.string
+ .media_projection_entry_cast_permission_dialog_option_text_entire_screen,
+ warningText =
+ R.string
+ .media_projection_entry_cast_permission_dialog_warning_entire_screen,
+ )
+ )
+ return if (singleAppDisabledText != null) {
+ // Make sure "Entire screen" is the first option when "Single App" is disabled.
+ options.reversed()
+ } else {
+ options
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 9eca34f88a78..0fe4d3620227 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -74,6 +74,7 @@ import androidx.annotation.DimenRes;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.policy.GestureNavigationSettingsObserver;
import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.contextualeducation.GestureType;
import com.android.systemui.model.SysUiState;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.navigationbar.gestural.domain.GestureInteractor;
@@ -1057,6 +1058,8 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
mEdgeBackPlugin.setIsLeftPanel(mIsOnLeftEdge);
mEdgeBackPlugin.onMotionEvent(ev);
dispatchToBackAnimation(ev);
+ mOverviewProxyService.updateContextualEduStats(mIsTrackpadThreeFingerSwipe,
+ GestureType.BACK);
}
if (mLogGesture || mIsTrackpadThreeFingerSwipe) {
mDownPoint.set(ev.getX(), ev.getY());
diff --git a/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java b/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java
index 1cd5d91ef69e..2ecca2d8c776 100644
--- a/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java
+++ b/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java
@@ -16,6 +16,8 @@
package com.android.systemui.power;
+import static com.android.systemui.Flags.enableViewCaptureTracing;
+
import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
@@ -29,21 +31,27 @@ import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
+import com.android.app.viewcapture.ViewCapture;
+import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
import com.android.systemui.res.R;
+import kotlin.Lazy;
+
/**
* View that shows a warning shortly before the device goes into sleep
* after prolonged user inactivity when bound to.
*/
public class InattentiveSleepWarningView extends FrameLayout {
private final IBinder mWindowToken = new Binder();
- private final WindowManager mWindowManager;
+ private final ViewCaptureAwareWindowManager mWindowManager;
private Animator mFadeOutAnimator;
private boolean mDismissing;
- InattentiveSleepWarningView(Context context) {
+ InattentiveSleepWarningView(Context context, Lazy<ViewCapture> lazyViewCapture) {
super(context);
- mWindowManager = mContext.getSystemService(WindowManager.class);
+ WindowManager wm = mContext.getSystemService(WindowManager.class);
+ mWindowManager = new ViewCaptureAwareWindowManager(wm, lazyViewCapture,
+ enableViewCaptureTracing());
final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
layoutInflater.inflate(R.layout.inattentive_sleep_warning, this, true /* attachToRoot */);
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 958ace358816..861a7ce282af 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -16,6 +16,8 @@
package com.android.systemui.power;
+import static com.android.systemui.util.ConvenienceExtensionsKt.toKotlinLazy;
+
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -44,6 +46,7 @@ import android.util.Slog;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.app.viewcapture.ViewCapture;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settingslib.fuelgauge.Estimate;
import com.android.settingslib.utils.ThreadUtils;
@@ -56,6 +59,8 @@ import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import kotlin.Lazy;
+
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.concurrent.Future;
@@ -117,6 +122,7 @@ public class PowerUI implements
private final Context mContext;
private final BroadcastDispatcher mBroadcastDispatcher;
private final CommandQueue mCommandQueue;
+ private final Lazy<ViewCapture> mLazyViewCapture;
@Nullable
private final IVrManager mVrManager;
private final WakefulnessLifecycle.Observer mWakefulnessObserver =
@@ -157,7 +163,8 @@ public class PowerUI implements
EnhancedEstimates enhancedEstimates,
WakefulnessLifecycle wakefulnessLifecycle,
PowerManager powerManager,
- UserTracker userTracker) {
+ UserTracker userTracker,
+ dagger.Lazy<ViewCapture> daggerLazyViewCapture) {
mContext = context;
mBroadcastDispatcher = broadcastDispatcher;
mCommandQueue = commandQueue;
@@ -167,6 +174,7 @@ public class PowerUI implements
mPowerManager = powerManager;
mWakefulnessLifecycle = wakefulnessLifecycle;
mUserTracker = userTracker;
+ mLazyViewCapture = toKotlinLazy(daggerLazyViewCapture);
}
public void start() {
@@ -641,7 +649,7 @@ public class PowerUI implements
@Override
public void showInattentiveSleepWarning() {
if (mOverlayView == null) {
- mOverlayView = new InattentiveSleepWarningView(mContext);
+ mOverlayView = new InattentiveSleepWarningView(mContext, mLazyViewCapture);
}
mOverlayView.show();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
index c6f9ae8f4463..ddd0c7607cdd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
@@ -39,10 +39,10 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collectIndexed
import kotlinx.coroutines.flow.filterNotNull
-import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.takeWhile
import kotlinx.coroutines.launch
// TODO(b/http://b/299909989): Use QSTileViewModel directly after the rollout
@@ -87,8 +87,9 @@ constructor(
}
}
}
- // Warm up tile with some initial state
- launch { qsTileViewModel.state.first() }
+ // Warm up tile with some initial state. Because `state` is a StateFlow with initial
+ // state `null`, we collect until it's not null.
+ launch { qsTileViewModel.state.takeWhile { it == null }.collect {} }
}
// QSTileHost doesn't call this when userId is initialized
@@ -160,8 +161,8 @@ constructor(
override fun setListening(client: Any?, listening: Boolean) {
client ?: return
if (listening) {
- listeningClients.add(client)
- if (listeningClients.size == 1) {
+ val clientWasNotAlreadyListening = listeningClients.add(client)
+ if (clientWasNotAlreadyListening && listeningClients.size == 1) {
stateJob =
qsTileViewModel.state
.filterNotNull()
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 371707d78500..15366d592adf 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -89,6 +89,8 @@ import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.contextualeducation.GestureType;
+import com.android.systemui.education.domain.interactor.KeyboardTouchpadEduStatsInteractor;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.KeyguardWmStateRefactor;
import com.android.systemui.keyguard.WakefulnessLifecycle;
@@ -160,6 +162,8 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
private final NotificationShadeWindowController mStatusBarWinController;
private final Provider<SceneInteractor> mSceneInteractor;
+ private final KeyboardTouchpadEduStatsInteractor mKeyboardTouchpadEduStatsInteractor;
+
private final Runnable mConnectionRunnable = () ->
internalConnectToCurrentUser("runnable: startConnectionToCurrentUser");
private final ComponentName mRecentsComponentName;
@@ -661,7 +665,8 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
AssistUtils assistUtils,
DumpManager dumpManager,
Optional<UnfoldTransitionProgressForwarder> unfoldTransitionProgressForwarder,
- BroadcastDispatcher broadcastDispatcher
+ BroadcastDispatcher broadcastDispatcher,
+ KeyboardTouchpadEduStatsInteractor keyboardTouchpadEduStatsInteractor
) {
// b/241601880: This component should only be running for primary users or
// secondaryUsers when visibleBackgroundUsers are supported.
@@ -698,6 +703,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
mDisplayTracker = displayTracker;
mUnfoldTransitionProgressForwarder = unfoldTransitionProgressForwarder;
mBroadcastDispatcher = broadcastDispatcher;
+ mKeyboardTouchpadEduStatsInteractor = keyboardTouchpadEduStatsInteractor;
if (!KeyguardWmStateRefactor.isEnabled()) {
mSysuiUnlockAnimationController = sysuiUnlockAnimationController;
@@ -929,6 +935,19 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
return isEnabled() && !QuickStepContract.isLegacyMode(mNavBarMode);
}
+ /**
+ * Updates contextual education stats when a gesture is triggered
+ * @param isTrackpadGesture indicates if the gesture is triggered by trackpad
+ * @param gestureType type of gesture triggered
+ */
+ public void updateContextualEduStats(boolean isTrackpadGesture, GestureType gestureType) {
+ if (isTrackpadGesture) {
+ mKeyboardTouchpadEduStatsInteractor.updateShortcutTriggerTime(gestureType);
+ } else {
+ mKeyboardTouchpadEduStatsInteractor.incrementSignalCount(gestureType);
+ }
+ }
+
public boolean isEnabled() {
return mIsEnabled;
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt
index c7190c3039a9..103b4a5ff7ef 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt
@@ -19,7 +19,7 @@ package com.android.systemui.scene.shared.model
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
-import com.android.systemui.activatable.Activatable
+import com.android.systemui.lifecycle.Activatable
import kotlinx.coroutines.flow.Flow
/**
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotController.java
index bc8642c67fb4..a77375c14f26 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotController.java
@@ -19,7 +19,6 @@ package com.android.systemui.screenshot;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
-import static com.android.systemui.Flags.screenshotPrivateProfileAccessibilityAnnouncementFix;
import static com.android.systemui.Flags.screenshotSaveImageExporter;
import static com.android.systemui.screenshot.LogConfig.DEBUG_ANIM;
import static com.android.systemui.screenshot.LogConfig.DEBUG_CALLBACK;
@@ -355,19 +354,9 @@ public class LegacyScreenshotController implements InteractiveScreenshotHandler
void prepareViewForNewScreenshot(@NonNull ScreenshotData screenshot, String oldPackageName) {
withWindowAttached(() -> {
- if (screenshotPrivateProfileAccessibilityAnnouncementFix()) {
- mAnnouncementResolver.getScreenshotAnnouncement(
- screenshot.getUserHandle().getIdentifier(),
- mViewProxy::announceForAccessibility);
- } else {
- if (mUserManager.isManagedProfile(screenshot.getUserHandle().getIdentifier())) {
- mViewProxy.announceForAccessibility(mContext.getResources().getString(
- R.string.screenshot_saving_work_profile_title));
- } else {
- mViewProxy.announceForAccessibility(
- mContext.getResources().getString(R.string.screenshot_saving_title));
- }
- }
+ mAnnouncementResolver.getScreenshotAnnouncement(
+ screenshot.getUserHandle().getIdentifier(),
+ mViewProxy::announceForAccessibility);
});
mViewProxy.reset();
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index ec529cd6fa52..540d4c43c58d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -19,7 +19,6 @@ package com.android.systemui.screenshot;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
-import static com.android.systemui.Flags.screenshotPrivateProfileAccessibilityAnnouncementFix;
import static com.android.systemui.Flags.screenshotSaveImageExporter;
import static com.android.systemui.screenshot.LogConfig.DEBUG_ANIM;
import static com.android.systemui.screenshot.LogConfig.DEBUG_CALLBACK;
@@ -355,19 +354,11 @@ public class ScreenshotController implements InteractiveScreenshotHandler {
void prepareViewForNewScreenshot(@NonNull ScreenshotData screenshot, String oldPackageName) {
withWindowAttached(() -> {
- if (screenshotPrivateProfileAccessibilityAnnouncementFix()) {
- mAnnouncementResolver.getScreenshotAnnouncement(
- screenshot.getUserHandle().getIdentifier(),
- mViewProxy::announceForAccessibility);
- } else {
- if (mUserManager.isManagedProfile(screenshot.getUserHandle().getIdentifier())) {
- mViewProxy.announceForAccessibility(mContext.getResources().getString(
- R.string.screenshot_saving_work_profile_title));
- } else {
- mViewProxy.announceForAccessibility(
- mContext.getResources().getString(R.string.screenshot_saving_title));
- }
- }
+ mAnnouncementResolver.getScreenshotAnnouncement(
+ screenshot.getUserHandle().getIdentifier(),
+ announcement -> {
+ mViewProxy.announceForAccessibility(announcement);
+ });
});
mViewProxy.reset();
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractor.kt
index 134c983f7b30..d1a0a6dd2e3c 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractor.kt
@@ -17,6 +17,7 @@
package com.android.systemui.shade.domain.interactor
import com.android.systemui.shade.data.repository.ShadeAnimationRepository
+import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
@@ -38,4 +39,7 @@ abstract class ShadeAnimationInteractor(
* that is not considered "closing".
*/
abstract val isAnyCloseAnimationRunning: StateFlow<Boolean>
+
+ /** Whether a short animation to expand or collapse is running after user input has ended. */
+ abstract val isAnyFlingAnimationRunning: Flow<Boolean>
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorEmptyImpl.kt
index f364d6ddf939..dbc1b3be4f92 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorEmptyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorEmptyImpl.kt
@@ -20,6 +20,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.shade.data.repository.ShadeAnimationRepository
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.flowOf
/** Implementation of ShadeAnimationInteractor for shadeless SysUI variants. */
@SysUISingleton
@@ -29,4 +30,5 @@ constructor(
shadeAnimationRepository: ShadeAnimationRepository,
) : ShadeAnimationInteractor(shadeAnimationRepository) {
override val isAnyCloseAnimationRunning = MutableStateFlow(false)
+ override val isAnyFlingAnimationRunning = flowOf(false)
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorLegacyImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorLegacyImpl.kt
index c4f41346eab7..32d8659e9180 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorLegacyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorLegacyImpl.kt
@@ -20,6 +20,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.shade.data.repository.ShadeAnimationRepository
import com.android.systemui.shade.data.repository.ShadeRepository
import javax.inject.Inject
+import kotlinx.coroutines.flow.map
/** Implementation of ShadeAnimationInteractor compatible with NPVC. */
@SysUISingleton
@@ -30,4 +31,5 @@ constructor(
shadeRepository: ShadeRepository,
) : ShadeAnimationInteractor(shadeAnimationRepository) {
override val isAnyCloseAnimationRunning = shadeRepository.legacyIsClosing
+ override val isAnyFlingAnimationRunning = shadeRepository.currentFling.map { it != null }
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorSceneContainerImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorSceneContainerImpl.kt
index d9982e39e958..79a94a51768c 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorSceneContainerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorSceneContainerImpl.kt
@@ -36,12 +36,12 @@ import kotlinx.coroutines.flow.stateIn
@SysUISingleton
class ShadeAnimationInteractorSceneContainerImpl
@Inject
+@OptIn(ExperimentalCoroutinesApi::class)
constructor(
@Background scope: CoroutineScope,
shadeAnimationRepository: ShadeAnimationRepository,
sceneInteractor: SceneInteractor,
) : ShadeAnimationInteractor(shadeAnimationRepository) {
- @OptIn(ExperimentalCoroutinesApi::class)
override val isAnyCloseAnimationRunning =
sceneInteractor.transitionState
.flatMapLatest { state ->
@@ -62,4 +62,26 @@ constructor(
}
.distinctUntilChanged()
.stateIn(scope, SharingStarted.Eagerly, false)
+
+ override val isAnyFlingAnimationRunning =
+ sceneInteractor.transitionState
+ .flatMapLatest { state ->
+ when (state) {
+ is ObservableTransitionState.Idle -> flowOf(false)
+ is ObservableTransitionState.Transition ->
+ if (
+ state.isInitiatedByUserInput &&
+ (state.fromScene == Scenes.Shade ||
+ state.toScene == Scenes.Shade ||
+ state.fromScene == Scenes.QuickSettings ||
+ state.toScene == Scenes.QuickSettings)
+ ) {
+ state.isUserInputOngoing.map { !it }
+ } else {
+ flowOf(false)
+ }
+ }
+ }
+ .distinctUntilChanged()
+ .stateIn(scope, SharingStarted.Eagerly, false)
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
index f90dd3c2936b..06298efc95a4 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.shade.ui.viewmodel
import androidx.lifecycle.LifecycleOwner
@@ -24,8 +22,8 @@ import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
-import com.android.systemui.activatable.Activatable
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.lifecycle.Activatable
import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor
import com.android.systemui.qs.FooterActionsController
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
@@ -41,7 +39,6 @@ import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor
import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index bb26f92e510d..7244f8a64c19 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -16,7 +16,6 @@
package com.android.systemui.statusbar;
import static android.app.Flags.keyguardPrivateNotifications;
-import static android.app.Flags.redactSensitiveContentNotificationsOnLockscreen;
import static android.app.StatusBarManager.ACTION_KEYGUARD_PRIVATE_NOTIFICATIONS_CHANGED;
import static android.app.StatusBarManager.EXTRA_KM_PRIVATE_NOTIFS_ALLOWED;
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
@@ -72,6 +71,7 @@ import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
+import com.android.systemui.statusbar.notification.row.shared.LockscreenOtpRedaction;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.ListenerSet;
@@ -655,7 +655,7 @@ public class NotificationLockscreenUserManagerImpl implements
!userAllowsPrivateNotificationsInPublic(mCurrentUserId);
boolean isNotifForManagedProfile = mCurrentManagedProfiles.contains(userId);
boolean isNotifUserRedacted = !userAllowsPrivateNotificationsInPublic(userId);
- boolean isNotifSensitive = redactSensitiveContentNotificationsOnLockscreen()
+ boolean isNotifSensitive = LockscreenOtpRedaction.isEnabled()
&& ent.getRanking() != null && ent.getRanking().hasSensitiveContent();
// redact notifications if the current user is redacting notifications or the notification
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
index 59fd0ca4513e..18ea0b445481 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.chips.call.ui.viewmodel
import android.view.View
import com.android.internal.jank.InteractionJankMonitor
+import com.android.systemui.Flags
import com.android.systemui.animation.ActivityTransitionAnimator
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
@@ -59,12 +60,24 @@ constructor(
when (state) {
is OngoingCallModel.NoCall -> OngoingActivityChipModel.Hidden()
is OngoingCallModel.InCall -> {
+ val icon =
+ if (
+ Flags.statusBarCallChipNotificationIcon() &&
+ state.notificationIconView != null
+ ) {
+ OngoingActivityChipModel.ChipIcon.StatusBarView(
+ state.notificationIconView
+ )
+ } else {
+ OngoingActivityChipModel.ChipIcon.Basic(phoneIcon)
+ }
+
// This block mimics OngoingCallController#updateChip.
if (state.startTimeMs <= 0L) {
// If the start time is invalid, don't show a timer and show just an
// icon. See b/192379214.
OngoingActivityChipModel.Shown.IconOnly(
- icon = phoneIcon,
+ icon = icon,
colors = ColorsModel.Themed,
getOnClickListener(state),
)
@@ -73,7 +86,7 @@ constructor(
state.startTimeMs - systemClock.currentTimeMillis() +
systemClock.elapsedRealtime()
OngoingActivityChipModel.Shown.Timer(
- icon = phoneIcon,
+ icon = icon,
colors = ColorsModel.Themed,
startTimeMs = startTimeInElapsedRealtime,
getOnClickListener(state),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt
index d9b0504308f8..cf4e7072a7d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt
@@ -190,12 +190,14 @@ constructor(
): OngoingActivityChipModel.Shown {
return OngoingActivityChipModel.Shown.Timer(
icon =
- Icon.Resource(
- CAST_TO_OTHER_DEVICE_ICON,
- // This string is "Casting screen"
- ContentDescription.Resource(
- R.string.cast_screen_to_other_device_chip_accessibility_label,
- ),
+ OngoingActivityChipModel.ChipIcon.Basic(
+ Icon.Resource(
+ CAST_TO_OTHER_DEVICE_ICON,
+ // This string is "Casting screen"
+ ContentDescription.Resource(
+ R.string.cast_screen_to_other_device_chip_accessibility_label,
+ ),
+ )
),
colors = ColorsModel.Red,
// TODO(b/332662551): Maybe use a MediaProjection API to fetch this time.
@@ -213,10 +215,12 @@ constructor(
private fun createIconOnlyCastChip(deviceName: String?): OngoingActivityChipModel.Shown {
return OngoingActivityChipModel.Shown.IconOnly(
icon =
- Icon.Resource(
- CAST_TO_OTHER_DEVICE_ICON,
- // This string is just "Casting"
- ContentDescription.Resource(R.string.accessibility_casting),
+ OngoingActivityChipModel.ChipIcon.Basic(
+ Icon.Resource(
+ CAST_TO_OTHER_DEVICE_ICON,
+ // This string is just "Casting"
+ ContentDescription.Resource(R.string.accessibility_casting),
+ )
),
colors = ColorsModel.Red,
createDialogLaunchOnClickListener(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt
index 191c221f43c6..c5f78d2e6dd4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt
@@ -21,11 +21,11 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.LogLevel
+import com.android.systemui.mediaprojection.MediaProjectionUtils.packageHasCastingCapabilities
import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.mediaprojection.data.repository.MediaProjectionRepository
import com.android.systemui.statusbar.chips.StatusBarChipsLog
import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
-import com.android.systemui.util.Utils
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
@@ -60,7 +60,7 @@ constructor(
}
is MediaProjectionState.Projecting -> {
val type =
- if (isProjectionToOtherDevice(state.hostPackage)) {
+ if (packageHasCastingCapabilities(packageManager, state.hostPackage)) {
ProjectionChipModel.Type.CAST_TO_OTHER_DEVICE
} else {
ProjectionChipModel.Type.SHARE_TO_APP
@@ -86,19 +86,6 @@ constructor(
scope.launch { mediaProjectionRepository.stopProjecting() }
}
- /**
- * Returns true iff projecting to the given [packageName] means that we're projecting to a
- * *different* device (as opposed to projecting to some application on *this* device).
- */
- private fun isProjectionToOtherDevice(packageName: String?): Boolean {
- // The [isHeadlessRemoteDisplayProvider] check approximates whether a projection is to a
- // different device or the same device, because headless remote display packages are the
- // only kinds of packages that do cast-to-other-device. This isn't exactly perfect,
- // because it means that any projection by those headless remote display packages will be
- // marked as going to a different device, even if that isn't always true. See b/321078669.
- return Utils.isHeadlessRemoteDisplayProvider(packageManager, packageName)
- }
-
companion object {
private const val TAG = "MediaProjection"
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
index fcf3de42eb32..6ba4fefd6f3c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
@@ -78,11 +78,13 @@ constructor(
is ScreenRecordChipModel.Recording -> {
OngoingActivityChipModel.Shown.Timer(
icon =
- Icon.Resource(
- ICON,
- ContentDescription.Resource(
- R.string.screenrecord_ongoing_screen_only,
- ),
+ OngoingActivityChipModel.ChipIcon.Basic(
+ Icon.Resource(
+ ICON,
+ ContentDescription.Resource(
+ R.string.screenrecord_ongoing_screen_only,
+ ),
+ )
),
colors = ColorsModel.Red,
startTimeMs = systemClock.elapsedRealtime(),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt
index 85973fca4326..7897f93b6496 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt
@@ -110,9 +110,11 @@ constructor(
): OngoingActivityChipModel.Shown {
return OngoingActivityChipModel.Shown.Timer(
icon =
- Icon.Resource(
- SHARE_TO_APP_ICON,
- ContentDescription.Resource(R.string.share_to_app_chip_accessibility_label),
+ OngoingActivityChipModel.ChipIcon.Basic(
+ Icon.Resource(
+ SHARE_TO_APP_ICON,
+ ContentDescription.Resource(R.string.share_to_app_chip_accessibility_label),
+ )
),
colors = ColorsModel.Red,
// TODO(b/332662551): Maybe use a MediaProjection API to fetch this time.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
index 17cf60bf2dc5..26a2f9139608 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
@@ -17,7 +17,9 @@
package com.android.systemui.statusbar.chips.ui.model
import android.view.View
+import com.android.systemui.Flags
import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.statusbar.StatusBarIconView
/** Model representing the display of an ongoing activity as a chip in the status bar. */
sealed class OngoingActivityChipModel {
@@ -38,7 +40,7 @@ sealed class OngoingActivityChipModel {
/** This chip should be shown with the given information. */
abstract class Shown(
/** The icon to show on the chip. If null, no icon will be shown. */
- open val icon: Icon?,
+ open val icon: ChipIcon?,
/** What colors to use for the chip. */
open val colors: ColorsModel,
/**
@@ -50,7 +52,7 @@ sealed class OngoingActivityChipModel {
/** This chip shows only an icon and nothing else. */
data class IconOnly(
- override val icon: Icon,
+ override val icon: ChipIcon,
override val colors: ColorsModel,
override val onClickListener: View.OnClickListener?,
) : Shown(icon, colors, onClickListener) {
@@ -59,7 +61,7 @@ sealed class OngoingActivityChipModel {
/** The chip shows a timer, counting up from [startTimeMs]. */
data class Timer(
- override val icon: Icon,
+ override val icon: ChipIcon,
override val colors: ColorsModel,
/**
* The time this event started, used to show the timer.
@@ -88,4 +90,23 @@ sealed class OngoingActivityChipModel {
override val logName = "Shown.Countdown"
}
}
+
+ /** Represents an icon to show on the chip. */
+ sealed interface ChipIcon {
+ /**
+ * The icon is a custom icon, which is set on [impl]. The icon was likely created by an
+ * external app.
+ */
+ data class StatusBarView(val impl: StatusBarIconView) : ChipIcon {
+ init {
+ check(Flags.statusBarCallChipNotificationIcon()) {
+ "OngoingActivityChipModel.ChipIcon.StatusBarView created even though " +
+ "Flags.statusBarCallChipNotificationIcon is not enabled"
+ }
+ }
+ }
+
+ /** The icon is a basic resource or drawable icon that System UI created internally. */
+ data class Basic(val impl: Icon) : ChipIcon
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
index 9eb9ed5f2063..2930de2fd9ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
@@ -26,7 +26,6 @@ import android.widget.FrameLayout
import androidx.core.animation.Animator
import com.android.app.animation.Interpolators
import com.android.internal.annotations.GuardedBy
-import com.android.systemui.Flags.privacyDotUnfoldWrongCornerFix
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Main
@@ -45,10 +44,10 @@ import com.android.systemui.util.leak.RotationUtils.ROTATION_NONE
import com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE
import com.android.systemui.util.leak.RotationUtils.ROTATION_UPSIDE_DOWN
import com.android.systemui.util.leak.RotationUtils.Rotation
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
import java.util.concurrent.Executor
import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
/**
* Understands how to keep the persistent privacy dot in the corner of the screen in
@@ -61,12 +60,13 @@ import javax.inject.Inject
* Views will match the status bar top padding and status bar height so that the dot can appear to
* reside directly after the status bar system contents (basically after the battery).
*
- * NOTE: any operation that modifies views directly must run on the provided executor, because
- * these views are owned by ScreenDecorations and it runs in its own thread
+ * NOTE: any operation that modifies views directly must run on the provided executor, because these
+ * views are owned by ScreenDecorations and it runs in its own thread
*/
-
@SysUISingleton
-open class PrivacyDotViewController @Inject constructor(
+open class PrivacyDotViewController
+@Inject
+constructor(
@Main private val mainExecutor: Executor,
@Application scope: CoroutineScope,
private val stateController: StatusBarStateController,
@@ -90,6 +90,7 @@ open class PrivacyDotViewController @Inject constructor(
field = value
scheduleUpdate()
}
+
private val lock = Object()
private var cancelRunnable: Runnable? = null
@@ -106,46 +107,48 @@ open class PrivacyDotViewController @Inject constructor(
get() = field
init {
- contentInsetsProvider.addCallback(object : StatusBarContentInsetsChangedListener {
- override fun onStatusBarContentInsetsChanged() {
- dlog("onStatusBarContentInsetsChanged: ")
- setNewLayoutRects()
+ contentInsetsProvider.addCallback(
+ object : StatusBarContentInsetsChangedListener {
+ override fun onStatusBarContentInsetsChanged() {
+ dlog("onStatusBarContentInsetsChanged: ")
+ setNewLayoutRects()
+ }
}
- })
-
- configurationController.addCallback(object : ConfigurationController.ConfigurationListener {
- override fun onLayoutDirectionChanged(isRtl: Boolean) {
- uiExecutor?.execute {
- // If rtl changed, hide all dotes until the next state resolves
- setCornerVisibilities(View.INVISIBLE)
-
- synchronized(this) {
- val corner = selectDesignatedCorner(nextViewState.rotation, isRtl)
- nextViewState = nextViewState.copy(
- layoutRtl = isRtl,
- designatedCorner = corner
- )
+ )
+
+ configurationController.addCallback(
+ object : ConfigurationController.ConfigurationListener {
+ override fun onLayoutDirectionChanged(isRtl: Boolean) {
+ uiExecutor?.execute {
+ // If rtl changed, hide all dotes until the next state resolves
+ setCornerVisibilities(View.INVISIBLE)
+
+ synchronized(this) {
+ val corner = selectDesignatedCorner(nextViewState.rotation, isRtl)
+ nextViewState =
+ nextViewState.copy(layoutRtl = isRtl, designatedCorner = corner)
+ }
}
}
}
- })
+ )
- stateController.addCallback(object : StatusBarStateController.StateListener {
- override fun onExpandedChanged(isExpanded: Boolean) {
- updateStatusBarState()
- }
+ stateController.addCallback(
+ object : StatusBarStateController.StateListener {
+ override fun onExpandedChanged(isExpanded: Boolean) {
+ updateStatusBarState()
+ }
- override fun onStateChanged(newState: Int) {
- updateStatusBarState()
+ override fun onStateChanged(newState: Int) {
+ updateStatusBarState()
+ }
}
- })
+ )
scope.launch {
shadeInteractor?.isQsExpanded?.collect { isQsExpanded ->
dlog("setQsExpanded $isQsExpanded")
- synchronized(lock) {
- nextViewState = nextViewState.copy(qsExpanded = isQsExpanded)
- }
+ synchronized(lock) { nextViewState = nextViewState.copy(qsExpanded = isQsExpanded) }
}
}
}
@@ -179,11 +182,13 @@ open class PrivacyDotViewController @Inject constructor(
val paddingTop = contentInsetsProvider.getStatusBarPaddingTop(rot)
synchronized(lock) {
- nextViewState = nextViewState.copy(
+ nextViewState =
+ nextViewState.copy(
rotation = rot,
paddingTop = paddingTop,
designatedCorner = newCorner,
- cornerIndex = index)
+ cornerIndex = index
+ )
}
}
@@ -192,14 +197,14 @@ open class PrivacyDotViewController @Inject constructor(
dot.clearAnimation()
if (animate) {
dot.animate()
- .setDuration(DURATION)
- .setInterpolator(Interpolators.ALPHA_OUT)
- .alpha(0f)
- .withEndAction {
- dot.visibility = View.INVISIBLE
- showingListener?.onPrivacyDotHidden(dot)
- }
- .start()
+ .setDuration(DURATION)
+ .setInterpolator(Interpolators.ALPHA_OUT)
+ .alpha(0f)
+ .withEndAction {
+ dot.visibility = View.INVISIBLE
+ showingListener?.onPrivacyDotHidden(dot)
+ }
+ .start()
} else {
dot.visibility = View.INVISIBLE
showingListener?.onPrivacyDotHidden(dot)
@@ -213,10 +218,10 @@ open class PrivacyDotViewController @Inject constructor(
dot.visibility = View.VISIBLE
dot.alpha = 0f
dot.animate()
- .alpha(1f)
- .setDuration(DURATION)
- .setInterpolator(Interpolators.ALPHA_IN)
- .start()
+ .alpha(1f)
+ .setDuration(DURATION)
+ .setInterpolator(Interpolators.ALPHA_IN)
+ .start()
} else {
dot.visibility = View.VISIBLE
dot.alpha = 1f
@@ -241,9 +246,9 @@ open class PrivacyDotViewController @Inject constructor(
}
// Set the dot's view gravity to hug the status bar
- (corner.requireViewById<View>(R.id.privacy_dot)
- .layoutParams as FrameLayout.LayoutParams)
- .gravity = rotatedCorner.innerGravity()
+ (corner.requireViewById<View>(R.id.privacy_dot).layoutParams
+ as FrameLayout.LayoutParams)
+ .gravity = rotatedCorner.innerGravity()
}
}
@@ -353,10 +358,7 @@ open class PrivacyDotViewController @Inject constructor(
clearAnimation()
visibility = View.VISIBLE
alpha = 0f
- animate()
- .alpha(1.0f)
- .setDuration(300)
- .start()
+ animate().alpha(1.0f).setDuration(300).start()
}
}
}
@@ -405,15 +407,21 @@ open class PrivacyDotViewController @Inject constructor(
private fun widthForCorner(corner: Int, left: Int, right: Int): Int {
return when (corner) {
- TOP_LEFT, BOTTOM_LEFT -> left
- TOP_RIGHT, BOTTOM_RIGHT -> right
+ TOP_LEFT,
+ BOTTOM_LEFT -> left
+ TOP_RIGHT,
+ BOTTOM_RIGHT -> right
else -> throw IllegalArgumentException("Unknown corner")
}
}
fun initialize(topLeft: View, topRight: View, bottomLeft: View, bottomRight: View) {
- if (this::tl.isInitialized && this::tr.isInitialized &&
- this::bl.isInitialized && this::br.isInitialized) {
+ if (
+ this::tl.isInitialized &&
+ this::tr.isInitialized &&
+ this::bl.isInitialized &&
+ this::br.isInitialized
+ ) {
if (tl == topLeft && tr == topRight && bl == bottomLeft && br == bottomRight) {
return
}
@@ -430,19 +438,17 @@ open class PrivacyDotViewController @Inject constructor(
val index = dc.cornerIndex()
- mainExecutor.execute {
- animationScheduler.addCallback(systemStatusAnimationCallback)
- }
+ mainExecutor.execute { animationScheduler.addCallback(systemStatusAnimationCallback) }
val left = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_SEASCAPE)
val top = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_NONE)
val right = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_LANDSCAPE)
- val bottom = contentInsetsProvider
- .getStatusBarContentAreaForRotation(ROTATION_UPSIDE_DOWN)
+ val bottom = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_UPSIDE_DOWN)
val paddingTop = contentInsetsProvider.getStatusBarPaddingTop()
synchronized(lock) {
- nextViewState = nextViewState.copy(
+ nextViewState =
+ nextViewState.copy(
viewInitialized = true,
designatedCorner = dc,
cornerIndex = index,
@@ -452,14 +458,12 @@ open class PrivacyDotViewController @Inject constructor(
upsideDownRect = bottom,
paddingTop = paddingTop,
layoutRtl = rtl
- )
+ )
}
}
private fun updateStatusBarState() {
- synchronized(lock) {
- nextViewState = nextViewState.copy(shadeExpanded = isShadeInQs())
- }
+ synchronized(lock) { nextViewState = nextViewState.copy(shadeExpanded = isShadeInQs()) }
}
/**
@@ -469,16 +473,14 @@ open class PrivacyDotViewController @Inject constructor(
@GuardedBy("lock")
private fun isShadeInQs(): Boolean {
return (stateController.isExpanded && stateController.state == SHADE) ||
- (stateController.state == SHADE_LOCKED)
+ (stateController.state == SHADE_LOCKED)
}
private fun scheduleUpdate() {
dlog("scheduleUpdate: ")
cancelRunnable?.run()
- cancelRunnable = uiExecutor?.executeDelayed({
- processNextViewState()
- }, 100)
+ cancelRunnable = uiExecutor?.executeDelayed({ processNextViewState() }, 100)
}
@UiThread
@@ -486,9 +488,7 @@ open class PrivacyDotViewController @Inject constructor(
dlog("processNextViewState: ")
val newState: ViewState
- synchronized(lock) {
- newState = nextViewState.copy()
- }
+ synchronized(lock) { newState = nextViewState.copy() }
resolveState(newState)
}
@@ -508,7 +508,7 @@ open class PrivacyDotViewController @Inject constructor(
val designatedCornerChanged = state.designatedCorner != currentViewState.designatedCorner
val rotationChanged = state.rotation != currentViewState.rotation
- if (rotationChanged || (designatedCornerChanged && privacyDotUnfoldWrongCornerFix())) {
+ if (rotationChanged || designatedCornerChanged) {
// A rotation has started, hide the views to avoid flicker
updateRotations(state.rotation, state.paddingTop)
}
@@ -545,27 +545,29 @@ open class PrivacyDotViewController @Inject constructor(
}
private val systemStatusAnimationCallback: SystemStatusAnimationCallback =
- object : SystemStatusAnimationCallback {
- override fun onSystemStatusAnimationTransitionToPersistentDot(
- contentDescr: String?
- ): Animator? {
- synchronized(lock) {
- nextViewState = nextViewState.copy(
- systemPrivacyEventIsActive = true,
- contentDescription = contentDescr)
+ object : SystemStatusAnimationCallback {
+ override fun onSystemStatusAnimationTransitionToPersistentDot(
+ contentDescr: String?
+ ): Animator? {
+ synchronized(lock) {
+ nextViewState =
+ nextViewState.copy(
+ systemPrivacyEventIsActive = true,
+ contentDescription = contentDescr
+ )
+ }
+
+ return null
}
- return null
- }
+ override fun onHidePersistentDot(): Animator? {
+ synchronized(lock) {
+ nextViewState = nextViewState.copy(systemPrivacyEventIsActive = false)
+ }
- override fun onHidePersistentDot(): Animator? {
- synchronized(lock) {
- nextViewState = nextViewState.copy(systemPrivacyEventIsActive = false)
+ return null
}
-
- return null
}
- }
private fun View?.cornerIndex(): Int {
if (this != null) {
@@ -579,8 +581,7 @@ open class PrivacyDotViewController @Inject constructor(
val left = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_SEASCAPE)
val top = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_NONE)
val right = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_LANDSCAPE)
- val bottom = contentInsetsProvider
- .getStatusBarContentAreaForRotation(ROTATION_UPSIDE_DOWN)
+ val bottom = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_UPSIDE_DOWN)
return listOf(left, top, right, bottom)
}
@@ -589,17 +590,19 @@ open class PrivacyDotViewController @Inject constructor(
val rects = getLayoutRects()
synchronized(lock) {
- nextViewState = nextViewState.copy(
+ nextViewState =
+ nextViewState.copy(
seascapeRect = rects[0],
portraitRect = rects[1],
landscapeRect = rects[2],
upsideDownRect = rects[3]
- )
+ )
}
}
interface ShowingListener {
fun onPrivacyDotShown(v: View?)
+
fun onPrivacyDotHidden(v: View?)
}
}
@@ -647,22 +650,18 @@ private fun Int.innerGravity(): Int {
data class ViewState(
val viewInitialized: Boolean = false,
-
val systemPrivacyEventIsActive: Boolean = false,
val shadeExpanded: Boolean = false,
val qsExpanded: Boolean = false,
-
val portraitRect: Rect? = null,
val landscapeRect: Rect? = null,
val upsideDownRect: Rect? = null,
val seascapeRect: Rect? = null,
val layoutRtl: Boolean = false,
-
val rotation: Int = 0,
val paddingTop: Int = 0,
val cornerIndex: Int = -1,
val designatedCorner: View? = null,
-
val contentDescription: String? = null
) {
fun shouldShowDot(): Boolean {
@@ -671,11 +670,11 @@ data class ViewState(
fun needsLayout(other: ViewState): Boolean {
return rotation != other.rotation ||
- layoutRtl != other.layoutRtl ||
- portraitRect != other.portraitRect ||
- landscapeRect != other.landscapeRect ||
- upsideDownRect != other.upsideDownRect ||
- seascapeRect != other.seascapeRect
+ layoutRtl != other.layoutRtl ||
+ portraitRect != other.portraitRect ||
+ landscapeRect != other.landscapeRect ||
+ upsideDownRect != other.upsideDownRect ||
+ seascapeRect != other.seascapeRect
}
fun contentRectForRotation(@Rotation rot: Int): Rect {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
index 4a895c0571d2..c52632e4382e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
@@ -20,6 +20,7 @@ import static com.android.server.notification.Flags.screenshareNotificationHidin
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC;
+import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_SINGLE_LINE;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_GROUP_SUMMARY_HEADER;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER;
@@ -54,6 +55,7 @@ import com.android.systemui.statusbar.notification.row.RowInflaterTask;
import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent;
import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation;
import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation;
+import com.android.systemui.statusbar.notification.row.shared.LockscreenOtpRedaction;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import javax.inject.Inject;
@@ -253,10 +255,11 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
params.requireContentViews(FLAG_CONTENT_VIEW_EXPANDED);
params.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight);
params.setUseMinimized(isMinimized);
-
- if (screenshareNotificationHiding()
+ boolean needsRedaction = screenshareNotificationHiding()
? inflaterParams.getNeedsRedaction()
- : mNotificationLockscreenUserManager.needsRedaction(entry)) {
+ : mNotificationLockscreenUserManager.needsRedaction(entry);
+
+ if (needsRedaction) {
params.requireContentViews(FLAG_CONTENT_VIEW_PUBLIC);
} else {
params.markContentViewsFreeable(FLAG_CONTENT_VIEW_PUBLIC);
@@ -272,6 +275,14 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
}
}
+ if (LockscreenOtpRedaction.isEnabled()) {
+ if (inflaterParams.isChildInGroup() && needsRedaction) {
+ params.requireContentViews(FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE);
+ } else {
+ params.markContentViewsFreeable(FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE);
+ }
+ }
+
if (AsyncGroupHeaderViewInflation.isEnabled()) {
if (inflaterParams.isGroupSummary()) {
params.requireContentViews(FLAG_GROUP_SUMMARY_HEADER);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
index 5d2d56acd0e4..10084517ec19 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
@@ -25,6 +25,8 @@ import android.graphics.drawable.Icon
import android.service.notification.StatusBarNotification
import android.util.ArrayMap
import com.android.app.tracing.traceSection
+import com.android.systemui.Flags
+import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.notification.collection.GroupEntry
import com.android.systemui.statusbar.notification.collection.ListEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntry
@@ -128,8 +130,14 @@ private class ActiveNotificationsStoreBuilder(
return result
}
- private fun NotificationEntry.toModel(): ActiveNotificationModel =
- existingModels.createOrReuse(
+ private fun NotificationEntry.toModel(): ActiveNotificationModel {
+ val statusBarChipIcon =
+ if (Flags.statusBarCallChipNotificationIcon()) {
+ icons.statusBarChipIcon
+ } else {
+ null
+ }
+ return existingModels.createOrReuse(
key = key,
groupKey = sbn.groupKey,
whenTime = sbn.notification.`when`,
@@ -142,6 +150,7 @@ private class ActiveNotificationsStoreBuilder(
aodIcon = icons.aodIcon?.sourceIcon,
shelfIcon = icons.shelfIcon?.sourceIcon,
statusBarIcon = icons.statusBarIcon?.sourceIcon,
+ statusBarChipIconView = statusBarChipIcon,
uid = sbn.uid,
packageName = sbn.packageName,
contentIntent = sbn.notification.contentIntent,
@@ -150,6 +159,7 @@ private class ActiveNotificationsStoreBuilder(
bucket = bucket,
callType = sbn.toCallType(),
)
+ }
}
private fun ActiveNotificationsStore.createOrReuse(
@@ -165,6 +175,7 @@ private fun ActiveNotificationsStore.createOrReuse(
aodIcon: Icon?,
shelfIcon: Icon?,
statusBarIcon: Icon?,
+ statusBarChipIconView: StatusBarIconView?,
uid: Int,
packageName: String,
contentIntent: PendingIntent?,
@@ -187,6 +198,7 @@ private fun ActiveNotificationsStore.createOrReuse(
aodIcon = aodIcon,
shelfIcon = shelfIcon,
statusBarIcon = statusBarIcon,
+ statusBarChipIconView = statusBarChipIconView,
uid = uid,
instanceId = instanceId,
isGroupSummary = isGroupSummary,
@@ -209,6 +221,7 @@ private fun ActiveNotificationsStore.createOrReuse(
aodIcon = aodIcon,
shelfIcon = shelfIcon,
statusBarIcon = statusBarIcon,
+ statusBarChipIconView = statusBarChipIconView,
uid = uid,
instanceId = instanceId,
isGroupSummary = isGroupSummary,
@@ -232,6 +245,7 @@ private fun ActiveNotificationModel.isCurrent(
aodIcon: Icon?,
shelfIcon: Icon?,
statusBarIcon: Icon?,
+ statusBarChipIconView: StatusBarIconView?,
uid: Int,
packageName: String,
contentIntent: PendingIntent?,
@@ -253,6 +267,7 @@ private fun ActiveNotificationModel.isCurrent(
aodIcon != this.aodIcon -> false
shelfIcon != this.shelfIcon -> false
statusBarIcon != this.statusBarIcon -> false
+ statusBarChipIconView != this.statusBarChipIconView -> false
uid != this.uid -> false
instanceId != this.instanceId -> false
isGroupSummary != this.isGroupSummary -> false
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
index 331d3cc4c21b..dc6ab4126337 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
@@ -123,6 +123,13 @@ constructor(
// Construct the status bar icon view.
val sbIcon = iconBuilder.createIconView(entry)
sbIcon.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ val sbChipIcon: StatusBarIconView?
+ if (Flags.statusBarCallChipNotificationIcon()) {
+ sbChipIcon = iconBuilder.createIconView(entry)
+ sbChipIcon.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ } else {
+ sbChipIcon = null
+ }
// Construct the shelf icon view.
val shelfIcon = iconBuilder.createIconView(entry)
@@ -139,9 +146,19 @@ constructor(
try {
setIcon(entry, normalIconDescriptor, sbIcon)
+ if (Flags.statusBarCallChipNotificationIcon() && sbChipIcon != null) {
+ setIcon(entry, normalIconDescriptor, sbChipIcon)
+ }
setIcon(entry, sensitiveIconDescriptor, shelfIcon)
setIcon(entry, sensitiveIconDescriptor, aodIcon)
- entry.icons = IconPack.buildPack(sbIcon, shelfIcon, aodIcon, entry.icons)
+ entry.icons =
+ IconPack.buildPack(
+ sbIcon,
+ sbChipIcon,
+ shelfIcon,
+ aodIcon,
+ entry.icons,
+ )
} catch (e: InflationException) {
entry.icons = IconPack.buildEmptyPack(entry.icons)
throw e
@@ -182,6 +199,11 @@ constructor(
setIcon(entry, normalIconDescriptor, it)
}
+ entry.icons.statusBarChipIcon?.let {
+ it.setNotification(entry.sbn, notificationContentDescription)
+ setIcon(entry, normalIconDescriptor, it)
+ }
+
entry.icons.shelfIcon?.let {
it.setNotification(entry.sbn, notificationContentDescription)
setIcon(entry, sensitiveIconDescriptor, it)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconPack.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconPack.java
index d029ce722af9..611cebcf6427 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconPack.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconPack.java
@@ -29,6 +29,7 @@ public final class IconPack {
private final boolean mAreIconsAvailable;
@Nullable private final StatusBarIconView mStatusBarIcon;
+ @Nullable private final StatusBarIconView mStatusBarChipIcon;
@Nullable private final StatusBarIconView mShelfIcon;
@Nullable private final StatusBarIconView mAodIcon;
@@ -43,7 +44,7 @@ public final class IconPack {
* haven't been inflated yet or there was an error while inflating them).
*/
public static IconPack buildEmptyPack(@Nullable IconPack fromSource) {
- return new IconPack(false, null, null, null, fromSource);
+ return new IconPack(false, null, null, null, null, fromSource);
}
/**
@@ -51,20 +52,23 @@ public final class IconPack {
*/
public static IconPack buildPack(
@NonNull StatusBarIconView statusBarIcon,
+ @Nullable StatusBarIconView statusBarChipIcon,
@NonNull StatusBarIconView shelfIcon,
@NonNull StatusBarIconView aodIcon,
@Nullable IconPack source) {
- return new IconPack(true, statusBarIcon, shelfIcon, aodIcon, source);
+ return new IconPack(true, statusBarIcon, statusBarChipIcon, shelfIcon, aodIcon, source);
}
private IconPack(
boolean areIconsAvailable,
@Nullable StatusBarIconView statusBarIcon,
+ @Nullable StatusBarIconView statusBarChipIcon,
@Nullable StatusBarIconView shelfIcon,
@Nullable StatusBarIconView aodIcon,
@Nullable IconPack source) {
mAreIconsAvailable = areIconsAvailable;
mStatusBarIcon = statusBarIcon;
+ mStatusBarChipIcon = statusBarChipIcon;
mShelfIcon = shelfIcon;
mAodIcon = aodIcon;
if (source != null) {
@@ -79,6 +83,17 @@ public final class IconPack {
}
/**
+ * The version of the notification icon that appears inside a chip within the status bar.
+ *
+ * Separate from {@link #getStatusBarIcon()} so that we don't have to worry about detaching and
+ * re-attaching the same view when the chip appears and hides.
+ */
+ @Nullable
+ public StatusBarIconView getStatusBarChipIcon() {
+ return mStatusBarChipIcon;
+ }
+
+ /**
* The version of the icon that appears in the "shelf" at the bottom of the notification shade.
* In general, this icon also appears somewhere on the notification and is "sucked" into the
* shelf as the scrolls beyond it.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt
index a6ca3ab8bce3..17f401ac0dde 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt
@@ -19,6 +19,9 @@ package com.android.systemui.statusbar.notification.interruption
import android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST
import android.app.Notification
import android.app.Notification.BubbleMetadata
+import android.app.Notification.CATEGORY_ALARM
+import android.app.Notification.CATEGORY_CAR_EMERGENCY
+import android.app.Notification.CATEGORY_CAR_WARNING
import android.app.Notification.CATEGORY_EVENT
import android.app.Notification.CATEGORY_REMINDER
import android.app.Notification.VISIBILITY_PRIVATE
@@ -42,6 +45,7 @@ import android.provider.Settings.Global.HEADS_UP_OFF
import android.service.notification.Flags
import com.android.internal.logging.UiEvent
import com.android.internal.logging.UiEventLogger
+import com.android.internal.logging.UiEventLogger.UiEventEnum.RESERVE_NEW_UI_EVENT_ID
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.statusbar.StatusBarStateController
@@ -307,6 +311,9 @@ class AvalancheSuppressor(
ALLOW_CALLSTYLE,
ALLOW_CATEGORY_REMINDER,
ALLOW_CATEGORY_EVENT,
+ ALLOW_CATEGORY_ALARM,
+ ALLOW_CATEGORY_CAR_EMERGENCY,
+ ALLOW_CATEGORY_CAR_WARNING,
ALLOW_FSI_WITH_PERMISSION_ON,
ALLOW_COLORIZED,
ALLOW_EMERGENCY,
@@ -333,8 +340,13 @@ class AvalancheSuppressor(
@UiEvent(doc = "HUN allowed during avalanche because it is colorized.")
AVALANCHE_SUPPRESSOR_HUN_ALLOWED_COLORIZED(1832),
@UiEvent(doc = "HUN allowed during avalanche because it is an emergency notification.")
- AVALANCHE_SUPPRESSOR_HUN_ALLOWED_EMERGENCY(1833);
-
+ AVALANCHE_SUPPRESSOR_HUN_ALLOWED_EMERGENCY(1833),
+ @UiEvent(doc = "HUN allowed during avalanche because it is an alarm.")
+ AVALANCHE_SUPPRESSOR_HUN_ALLOWED_CATEGORY_ALARM(1867),
+ @UiEvent(doc = "HUN allowed during avalanche because it is a car emergency.")
+ AVALANCHE_SUPPRESSOR_HUN_ALLOWED_CATEGORY_CAR_EMERGENCY(1868),
+ @UiEvent(doc = "HUN allowed during avalanche because it is a car warning")
+ AVALANCHE_SUPPRESSOR_HUN_ALLOWED_CATEGORY_CAR_WARNING(1869);
override fun getId(): Int {
return id
}
@@ -423,6 +435,22 @@ class AvalancheSuppressor(
return State.ALLOW_CATEGORY_REMINDER
}
+ if (entry.sbn.notification.category == CATEGORY_ALARM) {
+ uiEventLogger.log(AvalancheEvent.AVALANCHE_SUPPRESSOR_HUN_ALLOWED_CATEGORY_ALARM)
+ return State.ALLOW_CATEGORY_ALARM
+ }
+
+ if (entry.sbn.notification.category == CATEGORY_CAR_EMERGENCY) {
+ uiEventLogger.log(
+ AvalancheEvent.AVALANCHE_SUPPRESSOR_HUN_ALLOWED_CATEGORY_CAR_EMERGENCY)
+ return State.ALLOW_CATEGORY_CAR_EMERGENCY
+ }
+
+ if (entry.sbn.notification.category == CATEGORY_CAR_WARNING) {
+ uiEventLogger.log(AvalancheEvent.AVALANCHE_SUPPRESSOR_HUN_ALLOWED_CATEGORY_CAR_WARNING)
+ return State.ALLOW_CATEGORY_CAR_WARNING
+ }
+
if (entry.sbn.notification.category == CATEGORY_EVENT) {
uiEventLogger.log(AvalancheEvent.AVALANCHE_SUPPRESSOR_HUN_ALLOWED_CATEGORY_EVENT)
return State.ALLOW_CATEGORY_EVENT
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 06af980010be..9d13a17d8e02 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -102,6 +102,7 @@ import com.android.systemui.statusbar.notification.logging.NotificationCounters;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation;
+import com.android.systemui.statusbar.notification.row.shared.LockscreenOtpRedaction;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationCompactMessagingTemplateViewWrapper;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
import com.android.systemui.statusbar.notification.shared.NotificationContentAlphaOptimization;
@@ -997,6 +998,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
mNotificationParent = isChildInGroup ? parent : null;
mPrivateLayout.setIsChildInGroup(isChildInGroup);
+ if (LockscreenOtpRedaction.isEnabled()) {
+ mPublicLayout.setIsChildInGroup(isChildInGroup);
+ }
updateBackgroundForGroupState();
updateClickAndFocus();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java
index ba1cfcc425e8..0738a03f8237 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java
@@ -46,7 +46,7 @@ import com.android.systemui.statusbar.notification.row.ui.viewmodel.SingleIcon;
import java.util.Objects;
/**
- * A hybrid view which may contain information about one ore more conversations.
+ * A hybrid view which may contain information about one or more conversations.
*/
public class HybridConversationNotificationView extends HybridNotificationView {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index af5117e0b561..8c80fd400360 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -56,8 +56,8 @@ import com.android.systemui.statusbar.notification.InflationException;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation;
import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation;
+import com.android.systemui.statusbar.notification.row.shared.LockscreenOtpRedaction;
import com.android.systemui.statusbar.notification.row.shared.NotificationRowContentBinderRefactor;
-import com.android.systemui.statusbar.notification.row.ui.viewbinder.SingleLineConversationViewBinder;
import com.android.systemui.statusbar.notification.row.ui.viewbinder.SingleLineViewBinder;
import com.android.systemui.statusbar.notification.row.ui.viewmodel.SingleLineViewModel;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
@@ -196,8 +196,8 @@ public class NotificationContentInflater implements NotificationRowContentBinder
result = inflateSmartReplyViews(result, reInflateFlags, entry, row.getContext(),
packageContext, row.getExistingSmartReplyState(), smartRepliesInflater, mLogger);
+ boolean isConversation = entry.getRanking().isConversation();
if (AsyncHybridViewInflation.isEnabled()) {
- boolean isConversation = entry.getRanking().isConversation();
Notification.MessagingStyle messagingStyle = null;
if (isConversation) {
messagingStyle = mConversationProcessor
@@ -210,8 +210,22 @@ public class NotificationContentInflater implements NotificationRowContentBinder
builder,
row.getContext()
);
- result.mInflatedSingleLineViewHolder =
- SingleLineViewInflater.inflateSingleLineViewHolder(
+ result.mInflatedSingleLineView =
+ SingleLineViewInflater.inflatePrivateSingleLineView(
+ isConversation,
+ reInflateFlags,
+ entry,
+ row.getContext(),
+ mLogger
+ );
+ }
+
+ if (LockscreenOtpRedaction.isEnabled()) {
+ result.mPublicInflatedSingleLineViewModel =
+ SingleLineViewInflater.inflateRedactedSingleLineViewModel(row.getContext(),
+ isConversation);
+ result.mPublicInflatedSingleLineView =
+ SingleLineViewInflater.inflatePublicSingleLineView(
isConversation,
reInflateFlags,
entry,
@@ -291,6 +305,16 @@ public class NotificationContentInflater implements NotificationRowContentBinder
row.getPrivateLayout().setHeadsUpInflatedSmartReplies(null);
});
break;
+ case FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE:
+ if (LockscreenOtpRedaction.isEnabled()) {
+ row.getPublicLayout()
+ .performWhenContentInactive(VISIBLE_TYPE_SINGLELINE, () -> {
+ row.getPublicLayout().setSingleLineView(null);
+ mRemoteViewCache.removeCachedView(entry,
+ FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE);
+ });
+ }
+ break;
case FLAG_CONTENT_VIEW_PUBLIC:
row.getPublicLayout().performWhenContentInactive(VISIBLE_TYPE_CONTRACTED, () -> {
row.getPublicLayout().setContractedChild(null);
@@ -334,6 +358,10 @@ public class NotificationContentInflater implements NotificationRowContentBinder
row.getPublicLayout().removeContentInactiveRunnable(VISIBLE_TYPE_CONTRACTED);
}
if (AsyncHybridViewInflation.isEnabled()
+ && (contentViews & FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE) != 0) {
+ row.getPublicLayout().removeContentInactiveRunnable(VISIBLE_TYPE_SINGLELINE);
+ }
+ if (LockscreenOtpRedaction.isEnabled()
&& (contentViews & FLAG_CONTENT_VIEW_SINGLE_LINE) != 0) {
row.getPrivateLayout().removeContentInactiveRunnable(VISIBLE_TYPE_SINGLELINE);
}
@@ -935,19 +963,21 @@ public class NotificationContentInflater implements NotificationRowContentBinder
if (AsyncHybridViewInflation.isEnabled()
&& (reInflateFlags & FLAG_CONTENT_VIEW_SINGLE_LINE) != 0) {
- HybridNotificationView viewHolder = result.mInflatedSingleLineViewHolder;
+ HybridNotificationView view = result.mInflatedSingleLineView;
SingleLineViewModel viewModel = result.mInflatedSingleLineViewModel;
- if (viewHolder != null && viewModel != null) {
- if (viewModel.isConversation()) {
- SingleLineConversationViewBinder.bind(
- result.mInflatedSingleLineViewModel,
- result.mInflatedSingleLineViewHolder
- );
- } else {
- SingleLineViewBinder.bind(result.mInflatedSingleLineViewModel,
- result.mInflatedSingleLineViewHolder);
- }
- privateLayout.setSingleLineView(result.mInflatedSingleLineViewHolder);
+ if (view != null && viewModel != null) {
+ SingleLineViewBinder.bind(viewModel, view);
+ privateLayout.setSingleLineView(result.mInflatedSingleLineView);
+ }
+ }
+
+ if (LockscreenOtpRedaction.isEnabled()
+ && (reInflateFlags & FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE) != 0) {
+ HybridNotificationView view = result.mPublicInflatedSingleLineView;
+ SingleLineViewModel viewModel = result.mPublicInflatedSingleLineViewModel;
+ if (view != null && viewModel != null) {
+ SingleLineViewBinder.bind(viewModel, view);
+ publicLayout.setSingleLineView(result.mPublicInflatedSingleLineView);
}
}
@@ -1211,8 +1241,22 @@ public class NotificationContentInflater implements NotificationRowContentBinder
recoveredBuilder,
mContext
);
- result.mInflatedSingleLineViewHolder =
- SingleLineViewInflater.inflateSingleLineViewHolder(
+ result.mInflatedSingleLineView =
+ SingleLineViewInflater.inflatePrivateSingleLineView(
+ isConversation,
+ mReInflateFlags,
+ mEntry,
+ mContext,
+ mLogger
+ );
+ }
+
+ if (LockscreenOtpRedaction.isEnabled()) {
+ result.mPublicInflatedSingleLineViewModel =
+ SingleLineViewInflater.inflateRedactedSingleLineViewModel(mContext,
+ isConversation);
+ result.mPublicInflatedSingleLineView =
+ SingleLineViewInflater.inflatePublicSingleLineView(
isConversation,
mReInflateFlags,
mEntry,
@@ -1347,8 +1391,13 @@ public class NotificationContentInflater implements NotificationRowContentBinder
// ViewModel for SingleLineView, holds the UI State
SingleLineViewModel mInflatedSingleLineViewModel;
+ // ViewModel for public SingleLineView, holds the UI State
+ SingleLineViewModel mPublicInflatedSingleLineViewModel;
// Inflated SingleLineViewHolder, SingleLineView that lacks the UI State
- HybridNotificationView mInflatedSingleLineViewHolder;
+ HybridNotificationView mInflatedSingleLineView;
+ // Inflated SingleLineViewHolder, SingleLineView that lacks the UI State for the public
+ // single line view
+ HybridNotificationView mPublicInflatedSingleLineView;
}
@VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 3f4690282771..7119145a1fa8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -113,7 +113,8 @@ public class NotificationContentView extends FrameLayout implements Notification
private View mContractedChild;
private View mExpandedChild;
private View mHeadsUpChild;
- private HybridNotificationView mSingleLineView;
+ @VisibleForTesting
+ protected HybridNotificationView mSingleLineView;
@Nullable public DisposableHandle mContractedBinderHandle;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java
index fe0ee5235808..07384afe2d2e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java
@@ -89,6 +89,7 @@ public interface NotificationRowContentBinder {
FLAG_CONTENT_VIEW_SINGLE_LINE,
FLAG_GROUP_SUMMARY_HEADER,
FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER,
+ FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE,
FLAG_CONTENT_VIEW_ALL})
@interface InflationFlag {}
/**
@@ -105,7 +106,7 @@ public interface NotificationRowContentBinder {
*/
int FLAG_CONTENT_VIEW_HEADS_UP = 1 << 2;
/**
- * The public view. This is a version of the contracted view that hides sensitive
+ * The public view. This is a version of the contracted view that hides sensitive
* information and is used on the lock screen if we determine that the notification's
* content should be hidden.
*/
@@ -126,7 +127,14 @@ public interface NotificationRowContentBinder {
*/
int FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER = 1 << 6;
- int FLAG_CONTENT_VIEW_ALL = (1 << 7) - 1;
+ /**
+ * The public single line view. This is a version of the contracted view that hides sensitive
+ * information and is used on the lock screen if we determine that the notification's
+ * content should be hidden, and the notification is shown as a child in a group.
+ */
+ int FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE = 1 << 7;
+
+ int FLAG_CONTENT_VIEW_ALL = (1 << 8) - 1;
/**
* Parameters for content view binding
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
index 492d802c7cb2..a5cd2a2de085 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
@@ -55,6 +55,7 @@ import com.android.systemui.statusbar.notification.row.NotificationRowContentBin
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC
+import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_SINGLE_LINE
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_GROUP_SUMMARY_HEADER
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER
@@ -63,11 +64,11 @@ import com.android.systemui.statusbar.notification.row.NotificationRowContentBin
import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation
import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation
import com.android.systemui.statusbar.notification.row.shared.HeadsUpStatusBarModel
+import com.android.systemui.statusbar.notification.row.shared.LockscreenOtpRedaction
import com.android.systemui.statusbar.notification.row.shared.NewRemoteViews
import com.android.systemui.statusbar.notification.row.shared.NotificationContentModel
import com.android.systemui.statusbar.notification.row.shared.NotificationRowContentBinderRefactor
import com.android.systemui.statusbar.notification.row.shared.RichOngoingContentModel
-import com.android.systemui.statusbar.notification.row.ui.viewbinder.SingleLineConversationViewBinder
import com.android.systemui.statusbar.notification.row.ui.viewbinder.SingleLineViewBinder
import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer
@@ -202,7 +203,19 @@ constructor(
if (AsyncHybridViewInflation.isEnabled) {
result.inflatedSingleLineView =
result.contentModel.singleLineViewModel?.let { viewModel ->
- SingleLineViewInflater.inflateSingleLineViewHolder(
+ SingleLineViewInflater.inflatePrivateSingleLineView(
+ viewModel.isConversation(),
+ reInflateFlags,
+ entry,
+ systemUIContext,
+ logger,
+ )
+ }
+ }
+ if (LockscreenOtpRedaction.isEnabled) {
+ result.inflatedPublicSingleLineView =
+ result.contentModel.publicSingleLineViewModel?.let { viewModel ->
+ SingleLineViewInflater.inflatePublicSingleLineView(
viewModel.isConversation(),
reInflateFlags,
entry,
@@ -294,6 +307,13 @@ constructor(
}
}
}
+ FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE -> {
+ if (LockscreenOtpRedaction.isEnabled) {
+ row.publicLayout.performWhenContentInactive(VISIBLE_TYPE_SINGLELINE) {
+ row.publicLayout.setSingleLineView(null)
+ }
+ }
+ }
else -> {}
}
}
@@ -327,6 +347,12 @@ constructor(
) {
row.privateLayout.removeContentInactiveRunnable(VISIBLE_TYPE_SINGLELINE)
}
+ if (
+ LockscreenOtpRedaction.isEnabled &&
+ contentViews and FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE != 0
+ ) {
+ row.publicLayout.removeContentInactiveRunnable(VISIBLE_TYPE_SINGLELINE)
+ }
}
/**
@@ -449,7 +475,7 @@ constructor(
logger.logAsyncTaskProgress(entry, "inflating single line view")
inflationProgress.inflatedSingleLineView =
inflationProgress.contentModel.singleLineViewModel?.let {
- SingleLineViewInflater.inflateSingleLineViewHolder(
+ SingleLineViewInflater.inflatePrivateSingleLineView(
it.isConversation(),
reInflateFlags,
entry,
@@ -459,6 +485,20 @@ constructor(
}
}
+ if (LockscreenOtpRedaction.isEnabled) {
+ logger.logAsyncTaskProgress(entry, "inflating public single line view")
+ inflationProgress.inflatedPublicSingleLineView =
+ inflationProgress.contentModel.publicSingleLineViewModel?.let { viewModel ->
+ SingleLineViewInflater.inflatePublicSingleLineView(
+ viewModel.isConversation(),
+ reInflateFlags,
+ entry,
+ context,
+ logger
+ )
+ }
+ }
+
if (reInflateFlags and CONTENT_VIEWS_TO_CREATE_RICH_ONGOING != 0) {
logger.logAsyncTaskProgress(entry, "inflating RON view")
inflationProgress.richOngoingNotificationViewHolder =
@@ -582,6 +622,8 @@ constructor(
// Inflated SingleLineView that lacks the UI State
var inflatedSingleLineView: HybridNotificationView? = null
+ // Inflated public SingleLineView that lacks the UI State
+ var inflatedPublicSingleLineView: HybridNotificationView? = null
}
@VisibleForTesting
@@ -706,6 +748,18 @@ constructor(
)
} else null
+ val publicSingleLineViewModel =
+ if (
+ LockscreenOtpRedaction.isEnabled &&
+ reInflateFlags and FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE != 0
+ ) {
+ logger.logAsyncTaskProgress(entry, "inflating public single line view model")
+ SingleLineViewInflater.inflateRedactedSingleLineViewModel(
+ systemUIContext,
+ entry.ranking.isConversation
+ )
+ } else null
+
val headsUpStatusBarModel =
HeadsUpStatusBarModel(
privateText = builder.getHeadsUpStatusBarText(/* publicMode= */ false),
@@ -716,6 +770,7 @@ constructor(
NotificationContentModel(
headsUpStatusBarModel = headsUpStatusBarModel,
singleLineViewModel = singleLineViewModel,
+ publicSingleLineViewModel = publicSingleLineViewModel,
richOngoingContentModel = richOngoingContentModel,
)
@@ -1405,15 +1460,23 @@ constructor(
val singleLineView = result.inflatedSingleLineView
val viewModel = result.contentModel.singleLineViewModel
if (singleLineView != null && viewModel != null) {
- if (viewModel.isConversation()) {
- SingleLineConversationViewBinder.bind(viewModel, singleLineView)
- } else {
- SingleLineViewBinder.bind(viewModel, singleLineView)
- }
+ SingleLineViewBinder.bind(viewModel, singleLineView)
row.privateLayout.setSingleLineView(result.inflatedSingleLineView)
}
}
+ if (
+ LockscreenOtpRedaction.isEnabled &&
+ reInflateFlags and FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE != 0
+ ) {
+ val singleLineView = result.inflatedPublicSingleLineView
+ val viewModel = result.contentModel.publicSingleLineViewModel
+ if (singleLineView != null && viewModel != null) {
+ SingleLineViewBinder.bind(viewModel, singleLineView)
+ row.publicLayout.setSingleLineView(result.inflatedPublicSingleLineView)
+ }
+ }
+
// after updating the content model, set the view, then start the new binder
result.richOngoingNotificationViewHolder?.let { viewHolder ->
row.privateLayout.contractedChild = viewHolder.view
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt
index 463192cd7042..d67947d1fda8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt
@@ -30,6 +30,7 @@ import com.android.internal.widget.MessagingMessage
import com.android.internal.widget.PeopleHelper
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.logKey
+import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_SINGLE_LINE
import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation
import com.android.systemui.statusbar.notification.row.ui.viewmodel.ConversationAvatar
@@ -107,6 +108,36 @@ internal object SingleLineViewInflater {
)
}
+ @JvmStatic
+ fun inflateRedactedSingleLineViewModel(
+ context: Context,
+ isConversation: Boolean = false
+ ): SingleLineViewModel {
+ val conversationData =
+ if (isConversation) {
+ ConversationData(
+ null,
+ SingleIcon(
+ context.getDrawable(
+ com.android.systemui.res.R.drawable
+ .ic_redacted_notification_single_line_icon
+ )
+ )
+ )
+ } else {
+ null
+ }
+ return SingleLineViewModel(
+ context.getString(
+ com.android.systemui.res.R.string.redacted_notification_single_line_title
+ ),
+ context.getString(
+ com.android.systemui.res.R.string.redacted_notification_single_line_text
+ ),
+ conversationData
+ )
+ }
+
/** load conversation text data from the MessagingStyle of conversation notifications */
private fun MessagingStyle.loadConversationTextData(
systemUiContext: Context
@@ -137,8 +168,8 @@ internal object SingleLineViewInflater {
// We need to find back-up values for those texts if they are needed and empty
return ConversationTextData(
- conversationTitle = conversationTitle
- ?: findBackUpConversationTitle(senderName, systemUiContext),
+ conversationTitle =
+ conversationTitle ?: findBackUpConversationTitle(senderName, systemUiContext),
conversationText = conversationText,
senderName = senderName,
)
@@ -328,12 +359,27 @@ internal object SingleLineViewInflater {
return FacePile(
topIconDrawable = secondLastIcon.loadDrawable(systemUiContext),
bottomIconDrawable = lastIcon.loadDrawable(systemUiContext),
- bottomBackgroundColor = builder.getBackgroundColor(/* isHeader = */ false),
+ bottomBackgroundColor = builder.getBackgroundColor(/* isHeader= */ false),
)
}
@JvmStatic
- fun inflateSingleLineViewHolder(
+ fun inflatePublicSingleLineView(
+ isConversation: Boolean,
+ reinflateFlags: Int,
+ entry: NotificationEntry,
+ context: Context,
+ logger: NotificationRowContentBinderLogger,
+ ): HybridNotificationView? {
+ return if ((reinflateFlags and FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE) == 0) {
+ null
+ } else {
+ inflateSingleLineView(isConversation, reinflateFlags, entry, context, logger)
+ }
+ }
+
+ @JvmStatic
+ fun inflatePrivateSingleLineView(
isConversation: Boolean,
reinflateFlags: Int,
entry: NotificationEntry,
@@ -341,9 +387,21 @@ internal object SingleLineViewInflater {
logger: NotificationRowContentBinderLogger,
): HybridNotificationView? {
if (AsyncHybridViewInflation.isUnexpectedlyInLegacyMode()) return null
- if (reinflateFlags and FLAG_CONTENT_VIEW_SINGLE_LINE == 0) {
- return null
+ return if ((reinflateFlags and FLAG_CONTENT_VIEW_SINGLE_LINE) == 0) {
+ null
+ } else {
+ inflateSingleLineView(isConversation, reinflateFlags, entry, context, logger)
}
+ }
+
+ private fun inflateSingleLineView(
+ isConversation: Boolean,
+ reinflateFlags: Int,
+ entry: NotificationEntry,
+ context: Context,
+ logger: NotificationRowContentBinderLogger,
+ ): HybridNotificationView? {
+ if (AsyncHybridViewInflation.isUnexpectedlyInLegacyMode()) return null
logger.logInflateSingleLine(entry, reinflateFlags, isConversation)
logger.logAsyncTaskProgress(entry, "inflating single-line content view")
@@ -356,7 +414,7 @@ internal object SingleLineViewInflater {
if (isConversation)
com.android.systemui.res.R.layout.hybrid_conversation_notification
else com.android.systemui.res.R.layout.hybrid_notification
- view = inflater.inflate(layoutRes, /* root = */ null) as HybridNotificationView
+ view = inflater.inflate(layoutRes, /* root= */ null) as HybridNotificationView
if (view == null) {
Log.wtf(TAG, "Single-line view inflation result is null for entry: ${entry.logKey}")
}
@@ -368,7 +426,7 @@ internal object SingleLineViewInflater {
name: CharSequence?,
uniqueNames: PeopleHelper.NameToPrefixMap? = null
): Icon {
- val layoutColor = getSmallIconColor(/* isHeader = */ false)
+ val layoutColor = getSmallIconColor(/* isHeader= */ false)
if (!name.isNullOrEmpty()) {
val symbol = uniqueNames?.getPrefix(name) ?: ""
return peopleHelper.createAvatarSymbol(
@@ -379,7 +437,7 @@ internal object SingleLineViewInflater {
}
// If name is null, create default avatar with background color
// TODO(b/319829062): Investigate caching default icon for color
- return peopleHelper.createAvatarSymbol(/* name = */ "", /* symbol = */ "", layoutColor)
+ return peopleHelper.createAvatarSymbol(/* name= */ "", /* symbol= */ "", layoutColor)
}
private fun Person.getKeyOrName(): CharSequence? = if (key == null) name else key
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/LockscreenOtpRedaction.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/LockscreenOtpRedaction.kt
new file mode 100644
index 000000000000..078deb9f7c92
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/LockscreenOtpRedaction.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.row.shared
+
+import android.app.Flags
+import android.app.Flags.redactSensitiveContentNotificationsOnLockscreen
+import com.android.systemui.flags.FlagToken
+
+/** Helper for reading or using the async hybrid view inflation flag state. */
+object LockscreenOtpRedaction {
+ const val FLAG_NAME = Flags.FLAG_REDACT_SENSITIVE_CONTENT_NOTIFICATIONS_ON_LOCKSCREEN
+
+ /** A token used for dependency declaration */
+ val token: FlagToken
+ get() = FlagToken(FLAG_NAME, isEnabled)
+
+ @JvmStatic
+ inline val isEnabled
+ get() =
+ redactSensitiveContentNotificationsOnLockscreen() && AsyncHybridViewInflation.isEnabled
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/NotificationContentModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/NotificationContentModel.kt
index 46010a1ab43d..0f9a5a30cbe5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/NotificationContentModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/NotificationContentModel.kt
@@ -21,6 +21,7 @@ import com.android.systemui.statusbar.notification.row.ui.viewmodel.SingleLineVi
data class NotificationContentModel(
val headsUpStatusBarModel: HeadsUpStatusBarModel,
val singleLineViewModel: SingleLineViewModel? = null,
+ val publicSingleLineViewModel: SingleLineViewModel? = null,
val richOngoingContentModel: RichOngoingContentModel? = null,
)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineConversationViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineConversationViewBinder.kt
deleted file mode 100644
index 69284bd7ef48..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineConversationViewBinder.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification.row.ui.viewbinder
-
-import com.android.systemui.statusbar.notification.row.HybridConversationNotificationView
-import com.android.systemui.statusbar.notification.row.HybridNotificationView
-import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation
-import com.android.systemui.statusbar.notification.row.ui.viewmodel.SingleLineViewModel
-
-object SingleLineConversationViewBinder {
- @JvmStatic
- fun bind(viewModel: SingleLineViewModel, view: HybridNotificationView?) {
- if (AsyncHybridViewInflation.isUnexpectedlyInLegacyMode()) return
- if (view !is HybridConversationNotificationView || !viewModel.isConversation()) {
- SingleLineViewBinder.bind(viewModel, view)
- return
- }
-
- viewModel.conversationData?.avatar?.let { view.setAvatar(it) }
- view.setText(
- viewModel.titleText,
- viewModel.contentText,
- viewModel.conversationData?.conversationSenderName
- )
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineViewBinder.kt
index 22e10c165521..3b0f1ee22be3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineViewBinder.kt
@@ -16,19 +16,32 @@
package com.android.systemui.statusbar.notification.row.ui.viewbinder
+import com.android.systemui.statusbar.notification.row.HybridConversationNotificationView
import com.android.systemui.statusbar.notification.row.HybridNotificationView
+import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation
import com.android.systemui.statusbar.notification.row.ui.viewmodel.SingleLineViewModel
object SingleLineViewBinder {
@JvmStatic
fun bind(viewModel: SingleLineViewModel?, view: HybridNotificationView?) {
- // bind the title and content text views
- view?.apply {
- bind(
- /* title = */ viewModel?.titleText,
- /* text = */ viewModel?.contentText,
- /* contentView = */ null
+ if (viewModel?.isConversation() == true && view is HybridConversationNotificationView) {
+ if (AsyncHybridViewInflation.isUnexpectedlyInLegacyMode()) return
+
+ viewModel.conversationData?.avatar?.let { view.setAvatar(it) }
+ view.setText(
+ viewModel.titleText,
+ viewModel.contentText,
+ viewModel.conversationData?.conversationSenderName
)
+ } else {
+ // bind the title and content text views
+ view?.apply {
+ bind(
+ /* title = */ viewModel?.titleText,
+ /* text = */ viewModel?.contentText,
+ /* contentView = */ null
+ )
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt
index 6960791f7bcb..cf19938aa533 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt
@@ -17,6 +17,7 @@ package com.android.systemui.statusbar.notification.shared
import android.app.PendingIntent
import android.graphics.drawable.Icon
+import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.notification.stack.PriorityBucket
/**
@@ -59,6 +60,8 @@ data class ActiveNotificationModel(
val shelfIcon: Icon?,
/** Icon to display in the status bar. */
val statusBarIcon: Icon?,
+ /** Icon to display in the status bar chip. */
+ val statusBarChipIconView: StatusBarIconView?,
/** The notifying app's [packageName]'s uid. */
val uid: Int,
/** The notifying app's packageName. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/GroupHunAnimationFix.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/GroupHunAnimationFix.kt
index 3b30c8623491..1dac8b0224b9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/GroupHunAnimationFix.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/GroupHunAnimationFix.kt
@@ -20,10 +20,13 @@ import com.android.systemui.Flags
import com.android.systemui.flags.FlagToken
import com.android.systemui.flags.RefactorFlagUtils
-/** Helper for com.android.systemui.Flags.FLAG_NOTIFICATION_GROUP_HUN_REMOVAL_ANIMATION_FIX */
+/**
+ * Helper for com.android.systemui.Flags.FLAG_NOTIFICATION_GROUP_HUN_REMOVAL_ANIMATION_FIX, which
+ * now uses FLAG_NOTIFICATION_AVALANCHE_THROTTLE_HUN
+ */
@Suppress("NOTHING_TO_INLINE")
object GroupHunAnimationFix {
- const val FLAG_NAME = Flags.FLAG_NOTIFICATION_GROUP_HUN_REMOVAL_ANIMATION_FIX
+ const val FLAG_NAME = Flags.FLAG_NOTIFICATION_AVALANCHE_THROTTLE_HUN
/** A token used for dependency declaration */
val token: FlagToken
@@ -32,7 +35,7 @@ object GroupHunAnimationFix {
/** Return whether the fix is enabled */
@JvmStatic
inline val isEnabled
- get() = Flags.notificationGroupHunRemovalAnimationFix()
+ get() = Flags.notificationAvalancheThrottleHun()
/**
* Called to ensure code is only run when the flag is enabled. This protects users from the
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 37fdaebc7d6a..3a3b05bdd71d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -30,7 +30,6 @@ import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME;
import static com.android.systemui.Flags.keyboardShortcutHelperRewrite;
import static com.android.systemui.Flags.lightRevealMigration;
import static com.android.systemui.Flags.newAodTransition;
-import static com.android.systemui.Flags.truncatedStatusBarIconsFix;
import static com.android.systemui.charging.WirelessChargingAnimation.UNKNOWN_BATTERY_LEVEL;
import static com.android.systemui.flags.Flags.SHORTCUT_LIST_SEARCH_LAYOUT;
import static com.android.systemui.statusbar.NotificationLockscreenUserManager.PERMISSION_SELF;
@@ -1933,11 +1932,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
mQSPanelController.updateResources();
}
- if (!truncatedStatusBarIconsFix()) {
- if (mStatusBarWindowController != null) {
- mStatusBarWindowController.refreshStatusBarHeight();
- }
- }
if (mShadeSurface != null) {
mShadeSurface.updateResources();
}
@@ -2995,7 +2989,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
@Override
public void onFalse() {
// Hides quick settings, bouncer, and quick-quick settings.
- mStatusBarKeyguardViewManager.reset(true, /* isFalsingReset= */true);
+ mStatusBarKeyguardViewManager.reset(true);
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 6b47ac113928..8115c36c31e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.phone;
-import static com.android.systemui.Flags.truncatedStatusBarIconsFix;
import android.annotation.Nullable;
import android.content.Context;
@@ -108,9 +107,7 @@ public class PhoneStatusBarView extends FrameLayout {
Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mClock);
if (updateDisplayParameters()) {
updateLayoutForCutout();
- if (truncatedStatusBarIconsFix()) {
- updateWindowHeight();
- }
+ updateWindowHeight();
}
}
@@ -135,9 +132,7 @@ public class PhoneStatusBarView extends FrameLayout {
updateLayoutForCutout();
requestLayout();
}
- if (truncatedStatusBarIconsFix()) {
- updateWindowHeight();
- }
+ updateWindowHeight();
}
void onDensityOrFontScaleChanged() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 0b8f18e8f286..2d775b74eb32 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -708,7 +708,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
* Shows the notification keyguard or the bouncer depending on
* {@link #needsFullscreenBouncer()}.
*/
- protected void showBouncerOrKeyguard(boolean hideBouncerWhenShowing, boolean isFalsingReset) {
+ protected void showBouncerOrKeyguard(boolean hideBouncerWhenShowing) {
boolean isDozing = mDozing;
if (Flags.simPinRaceConditionOnRestart()) {
KeyguardState toState = mKeyguardTransitionInteractor.getTransitionState().getValue()
@@ -734,12 +734,8 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mPrimaryBouncerInteractor.show(/* isScrimmed= */ true);
}
}
- } else if (!isFalsingReset) {
- // Falsing resets can cause this to flicker, so don't reset in this case
- Log.i(TAG, "Sim bouncer is already showing, issuing a refresh");
- mPrimaryBouncerInteractor.hide();
- mPrimaryBouncerInteractor.show(/* isScrimmed= */ true);
-
+ } else {
+ Log.e(TAG, "Attempted to show the sim bouncer when it is already showing.");
}
} else {
mCentralSurfaces.showKeyguard();
@@ -961,10 +957,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
@Override
public void reset(boolean hideBouncerWhenShowing) {
- reset(hideBouncerWhenShowing, /* isFalsingReset= */false);
- }
-
- public void reset(boolean hideBouncerWhenShowing, boolean isFalsingReset) {
if (mKeyguardStateController.isShowing() && !bouncerIsAnimatingAway()) {
final boolean isOccluded = mKeyguardStateController.isOccluded();
// Hide quick settings.
@@ -976,7 +968,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
hideBouncer(false /* destroyView */);
}
} else {
- showBouncerOrKeyguard(hideBouncerWhenShowing, isFalsingReset);
+ showBouncerOrKeyguard(hideBouncerWhenShowing);
}
if (hideBouncerWhenShowing) {
hideAlternateBouncer(true);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
index 7af066646629..4368239c31f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
@@ -38,6 +38,7 @@ import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.LogLevel
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.res.R
+import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
import com.android.systemui.statusbar.chips.ui.view.ChipChronometer
import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore
@@ -114,6 +115,9 @@ constructor(
CallNotificationInfo(
entry.sbn.key,
entry.sbn.notification.getWhen(),
+ // In this old listener pattern, we don't have access to the
+ // notification icon.
+ notificationIconView = null,
entry.sbn.notification.contentIntent,
entry.sbn.uid,
entry.sbn.notification.extras.getInt(
@@ -223,8 +227,15 @@ constructor(
callNotificationInfo
// This shouldn't happen, but protect against it in case
?: return OngoingCallModel.NoCall
+ val icon =
+ if (Flags.statusBarCallChipNotificationIcon()) {
+ currentInfo.notificationIconView
+ } else {
+ null
+ }
return OngoingCallModel.InCall(
startTimeMs = currentInfo.callStartTime,
+ notificationIconView = icon,
intent = currentInfo.intent,
)
} else {
@@ -260,6 +271,7 @@ constructor(
CallNotificationInfo(
notifModel.key,
notifModel.whenTime,
+ notifModel.statusBarChipIconView,
notifModel.contentIntent,
notifModel.uid,
isOngoing = true,
@@ -407,6 +419,8 @@ constructor(
private data class CallNotificationInfo(
val key: String,
val callStartTime: Long,
+ /** The icon set as the [android.app.Notification.getSmallIcon] field. */
+ val notificationIconView: StatusBarIconView?,
val intent: PendingIntent?,
val uid: Int,
/** True if the call is currently ongoing (as opposed to incoming, screening, etc.). */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
index 2c4848776b66..34bff80ea919 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone.ongoingcall.shared.model
import android.app.PendingIntent
+import com.android.systemui.statusbar.StatusBarIconView
/** Represents the state of any ongoing calls. */
sealed interface OngoingCallModel {
@@ -31,7 +32,13 @@ sealed interface OngoingCallModel {
* [com.android.systemui.util.time.SystemClock.currentTimeMillis], **not**
* [com.android.systemui.util.time.SystemClock.elapsedRealtime]. This value can be 0 if the
* user has started an outgoing call that hasn't been answered yet - see b/192379214.
+ * @property notificationIconView the [android.app.Notification.getSmallIcon] that's set on the
+ * call notification. We may use this icon in the chip instead of the default phone icon.
* @property intent the intent associated with the call notification.
*/
- data class InCall(val startTimeMs: Long, val intent: PendingIntent?) : OngoingCallModel
+ data class InCall(
+ val startTimeMs: Long,
+ val notificationIconView: StatusBarIconView?,
+ val intent: PendingIntent?,
+ ) : OngoingCallModel
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt
index cd442cf4ec9c..99ed2d99c749 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt
@@ -21,7 +21,6 @@ import android.telephony.TelephonyManager.EXTRA_DATA_SPN
import android.telephony.TelephonyManager.EXTRA_PLMN
import android.telephony.TelephonyManager.EXTRA_SHOW_PLMN
import android.telephony.TelephonyManager.EXTRA_SHOW_SPN
-import android.telephony.TelephonyManager.EXTRA_SPN
import com.android.systemui.log.table.Diffable
import com.android.systemui.log.table.TableRowLogger
@@ -97,8 +96,7 @@ sealed interface NetworkNameModel : Diffable<NetworkNameModel> {
fun Intent.toNetworkNameModel(separator: String): NetworkNameModel? {
val showSpn = getBooleanExtra(EXTRA_SHOW_SPN, false)
- val spn = getStringExtra(EXTRA_SPN)
- val dataSpn = getStringExtra(EXTRA_DATA_SPN)
+ val spn = getStringExtra(EXTRA_DATA_SPN)
val showPlmn = getBooleanExtra(EXTRA_SHOW_PLMN, false)
val plmn = getStringExtra(EXTRA_PLMN)
@@ -114,12 +112,6 @@ fun Intent.toNetworkNameModel(separator: String): NetworkNameModel? {
}
str.append(spn)
}
- if (showSpn && dataSpn != null) {
- if (str.isNotEmpty()) {
- str.append(separator)
- }
- str.append(dataSpn)
- }
return if (str.isNotEmpty()) NetworkNameModel.IntentDerived(str.toString()) else null
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
index 16bd7f830c66..d46aaf45b1a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
@@ -18,9 +18,12 @@ package com.android.systemui.statusbar.pipeline.shared.ui.binder
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
+import android.annotation.IdRes
import android.content.res.ColorStateList
import android.graphics.drawable.GradientDrawable
import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.lifecycle.Lifecycle
@@ -31,6 +34,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.res.R
import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.chips.ui.binder.ChipChronometerBinder
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
@@ -90,7 +94,7 @@ class CollapsedStatusBarViewBinderImpl @Inject constructor() : CollapsedStatusBa
if (Flags.statusBarScreenSharingChips()) {
val chipView: View = view.requireViewById(R.id.ongoing_activity_chip)
val chipContext = chipView.context
- val chipIconView: ImageView =
+ val chipDefaultIconView: ImageView =
chipView.requireViewById(R.id.ongoing_activity_chip_icon)
val chipTimeView: ChipChronometer =
chipView.requireViewById(R.id.ongoing_activity_chip_time)
@@ -105,16 +109,25 @@ class CollapsedStatusBarViewBinderImpl @Inject constructor() : CollapsedStatusBa
when (chipModel) {
is OngoingActivityChipModel.Shown -> {
// Data
- IconViewBinder.bindNullable(chipModel.icon, chipIconView)
+ setChipIcon(chipModel, chipBackgroundView, chipDefaultIconView)
setChipMainContent(chipModel, chipTextView, chipTimeView)
chipView.setOnClickListener(chipModel.onClickListener)
+ updateChipPadding(
+ chipModel,
+ chipBackgroundView,
+ chipTextView,
+ chipTimeView,
+ )
// Accessibility
setChipAccessibility(chipModel, chipView, chipBackgroundView)
// Colors
val textColor = chipModel.colors.text(chipContext)
- chipIconView.imageTintList = ColorStateList.valueOf(textColor)
+ chipDefaultIconView.imageTintList =
+ ColorStateList.valueOf(textColor)
+ chipBackgroundView.getCustomIconView()?.imageTintList =
+ ColorStateList.valueOf(textColor)
chipTimeView.setTextColor(textColor)
chipTextView.setTextColor(textColor)
(chipBackgroundView.background as GradientDrawable).color =
@@ -151,6 +164,69 @@ class CollapsedStatusBarViewBinderImpl @Inject constructor() : CollapsedStatusBa
}
}
+ private fun setChipIcon(
+ chipModel: OngoingActivityChipModel.Shown,
+ backgroundView: ChipBackgroundContainer,
+ defaultIconView: ImageView,
+ ) {
+ // Always remove any previously set custom icon. If we have a new custom icon, we'll re-add
+ // it.
+ backgroundView.removeView(backgroundView.getCustomIconView())
+
+ when (val icon = chipModel.icon) {
+ null -> {
+ defaultIconView.visibility = View.GONE
+ }
+ is OngoingActivityChipModel.ChipIcon.Basic -> {
+ IconViewBinder.bind(icon.impl, defaultIconView)
+ defaultIconView.visibility = View.VISIBLE
+ }
+ is OngoingActivityChipModel.ChipIcon.StatusBarView -> {
+ // Hide the default icon since we'll show this custom icon instead.
+ defaultIconView.visibility = View.GONE
+
+ // Add the new custom icon:
+ // 1. Set up the right visual params.
+ val iconView = icon.impl
+ with(iconView) {
+ id = CUSTOM_ICON_VIEW_ID
+ // TODO(b/354930838): Update the content description to not include "phone" and
+ // maybe include the app name.
+ contentDescription =
+ context.resources.getString(R.string.ongoing_phone_call_content_description)
+ }
+
+ // 2. If we just reinflated the view, we may need to detach the icon view from the
+ // old chip before we reattach it to the new one.
+ // See also: NotificationIconContainerViewBinder#bindIcons.
+ val currentParent = iconView.parent as? ViewGroup
+ if (currentParent != null && currentParent != backgroundView) {
+ currentParent.removeView(iconView)
+ currentParent.removeTransientView(iconView)
+ }
+
+ // 3: Add the icon as the starting view.
+ backgroundView.addView(
+ iconView,
+ /* index= */ 0,
+ generateCustomIconLayoutParams(iconView),
+ )
+ }
+ }
+ }
+
+ private fun View.getCustomIconView(): StatusBarIconView? {
+ return this.findViewById(CUSTOM_ICON_VIEW_ID)
+ }
+
+ private fun generateCustomIconLayoutParams(iconView: ImageView): FrameLayout.LayoutParams {
+ val customIconSize =
+ iconView.context.resources.getDimensionPixelSize(
+ R.dimen.ongoing_activity_chip_embedded_padding_icon_size
+ )
+ return FrameLayout.LayoutParams(customIconSize, customIconSize)
+ }
+
private fun setChipMainContent(
chipModel: OngoingActivityChipModel.Shown,
chipTextView: TextView,
@@ -180,37 +256,93 @@ class CollapsedStatusBarViewBinderImpl @Inject constructor() : CollapsedStatusBa
chipTimeView.visibility = View.GONE
}
}
- updateChipTextPadding(chipModel, chipTextView, chipTimeView)
}
- private fun updateChipTextPadding(
+ private fun updateChipPadding(
chipModel: OngoingActivityChipModel.Shown,
+ backgroundView: View,
chipTextView: TextView,
chipTimeView: ChipChronometer,
) {
- val requiresPadding = chipModel.icon != null
- if (requiresPadding) {
- chipTextView.addChipTextPaddingStart()
- chipTimeView.addChipTextPaddingStart()
+ if (chipModel.icon != null) {
+ if (chipModel.icon is OngoingActivityChipModel.ChipIcon.StatusBarView) {
+ // If the icon is a custom [StatusBarIconView], then it should've come from
+ // `Notification.smallIcon`, which is required to embed its own paddings. We need to
+ // adjust the other paddings to make everything look good :)
+ backgroundView.setBackgroundPaddingForEmbeddedPaddingIcon()
+ chipTextView.setTextPaddingForEmbeddedPaddingIcon()
+ chipTimeView.setTextPaddingForEmbeddedPaddingIcon()
+ } else {
+ backgroundView.setBackgroundPaddingForNormalIcon()
+ chipTextView.setTextPaddingForNormalIcon()
+ chipTimeView.setTextPaddingForNormalIcon()
+ }
} else {
- chipTextView.removeChipTextPaddingStart()
- chipTimeView.removeChipTextPaddingStart()
+ backgroundView.setBackgroundPaddingForNoIcon()
+ chipTextView.setTextPaddingForNoIcon()
+ chipTimeView.setTextPaddingForNoIcon()
}
}
- private fun View.addChipTextPaddingStart() {
+ private fun View.setTextPaddingForEmbeddedPaddingIcon() {
+ val newPaddingEnd =
+ context.resources.getDimensionPixelSize(
+ R.dimen.ongoing_activity_chip_text_end_padding_for_embedded_padding_icon
+ )
+ setPaddingRelative(
+ // The icon should embed enough padding between the icon and time view.
+ /* start= */ 0,
+ this.paddingTop,
+ newPaddingEnd,
+ this.paddingBottom,
+ )
+ }
+
+ private fun View.setTextPaddingForNormalIcon() {
this.setPaddingRelative(
this.context.resources.getDimensionPixelSize(
R.dimen.ongoing_activity_chip_icon_text_padding
),
paddingTop,
- paddingEnd,
+ // The background view will contain the right end padding.
+ /* end= */ 0,
+ paddingBottom,
+ )
+ }
+
+ private fun View.setTextPaddingForNoIcon() {
+ // The background view will have even start & end paddings, so we don't want the text view
+ // to add any additional padding.
+ this.setPaddingRelative(/* start= */ 0, paddingTop, /* end= */ 0, paddingBottom)
+ }
+
+ private fun View.setBackgroundPaddingForEmbeddedPaddingIcon() {
+ val sidePadding =
+ context.resources.getDimensionPixelSize(
+ R.dimen.ongoing_activity_chip_side_padding_for_embedded_padding_icon
+ )
+ setPaddingRelative(
+ sidePadding,
+ paddingTop,
+ sidePadding,
+ paddingBottom,
+ )
+ }
+
+ private fun View.setBackgroundPaddingForNormalIcon() {
+ val sidePadding =
+ context.resources.getDimensionPixelSize(R.dimen.ongoing_activity_chip_side_padding)
+ setPaddingRelative(
+ sidePadding,
+ paddingTop,
+ sidePadding,
paddingBottom,
)
}
- private fun View.removeChipTextPaddingStart() {
- this.setPaddingRelative(/* start= */ 0, paddingTop, paddingEnd, paddingBottom)
+ private fun View.setBackgroundPaddingForNoIcon() {
+ // The padding for the normal icon is also appropriate for no icon.
+ setBackgroundPaddingForNormalIcon()
}
private fun setChipAccessibility(
@@ -269,6 +401,10 @@ class CollapsedStatusBarViewBinderImpl @Inject constructor() : CollapsedStatusBa
)
.start()
}
+
+ companion object {
+ @IdRes private val CUSTOM_ICON_VIEW_ID = R.id.ongoing_activity_chip_custom_icon
+ }
}
/** Listener for various events that may affect the status bar's visibility. */
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt
index 3dca6fc65034..1b00ae2103f0 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt
@@ -16,130 +16,51 @@
package com.android.systemui.touchpad.tutorial.ui.composable
-import android.graphics.ColorFilter
-import android.graphics.PorterDuff
-import android.graphics.PorterDuffColorFilter
-import androidx.activity.compose.BackHandler
-import androidx.annotation.RawRes
-import androidx.annotation.StringRes
-import androidx.compose.animation.AnimatedContent
-import androidx.compose.animation.EnterTransition
-import androidx.compose.animation.ExitTransition
-import androidx.compose.animation.animateColorAsState
-import androidx.compose.animation.core.LinearEasing
-import androidx.compose.animation.core.snap
-import androidx.compose.animation.core.tween
-import androidx.compose.animation.fadeIn
-import androidx.compose.animation.fadeOut
-import androidx.compose.animation.togetherWith
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.BoxScope
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.width
import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.drawBehind
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.toArgb
-import androidx.compose.ui.input.pointer.pointerInteropFilter
-import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.unit.dp
-import com.airbnb.lottie.LottieProperty
-import com.airbnb.lottie.compose.LottieAnimation
-import com.airbnb.lottie.compose.LottieCompositionSpec
-import com.airbnb.lottie.compose.LottieConstants
-import com.airbnb.lottie.compose.LottieDynamicProperties
-import com.airbnb.lottie.compose.LottieDynamicProperty
-import com.airbnb.lottie.compose.animateLottieCompositionAsState
-import com.airbnb.lottie.compose.rememberLottieComposition
import com.airbnb.lottie.compose.rememberLottieDynamicProperties
-import com.airbnb.lottie.compose.rememberLottieDynamicProperty
import com.android.compose.theme.LocalAndroidColorScheme
import com.android.systemui.res.R
import com.android.systemui.touchpad.tutorial.ui.gesture.BackGestureMonitor
import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState
-import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.FINISHED
-import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.IN_PROGRESS
-import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.NOT_STARTED
-import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGestureHandler
-
-data class TutorialScreenColors(
- val backgroundColor: Color,
- val successBackgroundColor: Color,
- val titleColor: Color,
- val animationProperties: LottieDynamicProperties
-)
+import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGestureMonitor
@Composable
fun BackGestureTutorialScreen(
onDoneButtonClicked: () -> Unit,
onBack: () -> Unit,
) {
- val screenColors = rememberScreenColors()
- BackHandler(onBack = onBack)
- var gestureState by remember { mutableStateOf(NOT_STARTED) }
- val swipeDistanceThresholdPx =
- LocalContext.current.resources.getDimensionPixelSize(
- com.android.internal.R.dimen.system_gestures_distance_threshold
- )
- val gestureHandler =
- remember(swipeDistanceThresholdPx) {
- TouchpadGestureHandler(
- BackGestureMonitor(
- swipeDistanceThresholdPx,
- gestureStateChangedCallback = { gestureState = it }
+ val screenConfig =
+ TutorialScreenConfig(
+ colors = rememberScreenColors(),
+ strings =
+ TutorialScreenConfig.Strings(
+ titleResId = R.string.touchpad_back_gesture_action_title,
+ bodyResId = R.string.touchpad_back_gesture_guidance,
+ titleSuccessResId = R.string.touchpad_tutorial_gesture_done,
+ bodySuccessResId = R.string.touchpad_back_gesture_finished
),
- )
- }
- TouchpadGesturesHandlingBox(gestureHandler, gestureState) {
- GestureTutorialContent(gestureState, onDoneButtonClicked, screenColors)
- }
-}
-
-@Composable
-private fun TouchpadGesturesHandlingBox(
- gestureHandler: TouchpadGestureHandler,
- gestureState: GestureState,
- modifier: Modifier = Modifier,
- content: @Composable BoxScope.() -> Unit
-) {
- Box(
- modifier =
- modifier
- .fillMaxSize()
- // we need to use pointerInteropFilter because some info about touchpad gestures is
- // only available in MotionEvent
- .pointerInteropFilter(
- onTouchEvent = { event ->
- // FINISHED is the final state so we don't need to process touches anymore
- if (gestureState != FINISHED) {
- gestureHandler.onMotionEvent(event)
- } else {
- false
- }
- }
+ animations =
+ TutorialScreenConfig.Animations(
+ educationResId = R.raw.trackpad_back_edu,
+ successResId = R.raw.trackpad_back_success
)
- ) {
- content()
- }
+ )
+ val gestureMonitorProvider =
+ object : GestureMonitorProvider {
+ override fun createGestureMonitor(
+ gestureDistanceThresholdPx: Int,
+ gestureStateChangedCallback: (GestureState) -> Unit
+ ): TouchpadGestureMonitor {
+ return BackGestureMonitor(gestureDistanceThresholdPx, gestureStateChangedCallback)
+ }
+ }
+ GestureTutorialScreen(screenConfig, gestureMonitorProvider, onDoneButtonClicked, onBack)
}
@Composable
-private fun rememberScreenColors(): TutorialScreenColors {
+private fun rememberScreenColors(): TutorialScreenConfig.Colors {
val onTertiary = LocalAndroidColorScheme.current.onTertiary
val onTertiaryFixed = LocalAndroidColorScheme.current.onTertiaryFixed
val onTertiaryFixedVariant = LocalAndroidColorScheme.current.onTertiaryFixedVariant
@@ -154,167 +75,12 @@ private fun rememberScreenColors(): TutorialScreenColors {
)
val screenColors =
remember(onTertiaryFixed, surfaceContainer, tertiaryFixedDim, dynamicProperties) {
- TutorialScreenColors(
- backgroundColor = onTertiaryFixed,
- successBackgroundColor = surfaceContainer,
- titleColor = tertiaryFixedDim,
- animationProperties = dynamicProperties,
+ TutorialScreenConfig.Colors(
+ background = onTertiaryFixed,
+ successBackground = surfaceContainer,
+ title = tertiaryFixedDim,
+ animationColors = dynamicProperties,
)
}
return screenColors
}
-
-@Composable
-private fun GestureTutorialContent(
- gestureState: GestureState,
- onDoneButtonClicked: () -> Unit,
- screenColors: TutorialScreenColors
-) {
- val animatedColor by
- animateColorAsState(
- targetValue =
- if (gestureState == FINISHED) screenColors.successBackgroundColor
- else screenColors.backgroundColor,
- animationSpec = tween(durationMillis = 150, easing = LinearEasing),
- label = "backgroundColor"
- )
- Column(
- verticalArrangement = Arrangement.Center,
- modifier =
- Modifier.fillMaxSize()
- .drawBehind { drawRect(animatedColor) }
- .padding(start = 48.dp, top = 124.dp, end = 48.dp, bottom = 48.dp)
- ) {
- Row(modifier = Modifier.fillMaxWidth().weight(1f)) {
- TutorialDescription(
- titleTextId =
- if (gestureState == FINISHED) R.string.touchpad_tutorial_gesture_done
- else R.string.touchpad_back_gesture_action_title,
- titleColor = screenColors.titleColor,
- bodyTextId =
- if (gestureState == FINISHED) R.string.touchpad_back_gesture_finished
- else R.string.touchpad_back_gesture_guidance,
- modifier = Modifier.weight(1f)
- )
- Spacer(modifier = Modifier.width(76.dp))
- TutorialAnimation(
- gestureState,
- screenColors.animationProperties,
- modifier = Modifier.weight(1f).padding(top = 8.dp)
- )
- }
- DoneButton(onDoneButtonClicked = onDoneButtonClicked)
- }
-}
-
-@Composable
-fun TutorialDescription(
- @StringRes titleTextId: Int,
- titleColor: Color,
- @StringRes bodyTextId: Int,
- modifier: Modifier = Modifier
-) {
- Column(verticalArrangement = Arrangement.Top, modifier = modifier) {
- Text(
- text = stringResource(id = titleTextId),
- style = MaterialTheme.typography.displayLarge,
- color = titleColor
- )
- Spacer(modifier = Modifier.height(16.dp))
- Text(
- text = stringResource(id = bodyTextId),
- style = MaterialTheme.typography.bodyLarge,
- color = Color.White
- )
- }
-}
-
-@Composable
-fun TutorialAnimation(
- gestureState: GestureState,
- animationProperties: LottieDynamicProperties,
- modifier: Modifier = Modifier
-) {
- Box(modifier = modifier.fillMaxWidth()) {
- AnimatedContent(
- targetState = gestureState,
- transitionSpec = {
- if (initialState == NOT_STARTED && targetState == IN_PROGRESS) {
- val transitionDurationMillis = 150
- fadeIn(
- animationSpec = tween(transitionDurationMillis, easing = LinearEasing)
- ) togetherWith
- fadeOut(animationSpec = snap(delayMillis = transitionDurationMillis))
- } else {
- // empty transition works because all remaining transitions are from IN_PROGRESS
- // state which shares initial animation frame with both FINISHED and NOT_STARTED
- EnterTransition.None togetherWith ExitTransition.None
- }
- }
- ) { gestureState ->
- @RawRes val successAnimationId = R.raw.trackpad_back_success
- @RawRes val educationAnimationId = R.raw.trackpad_back_edu
- when (gestureState) {
- NOT_STARTED -> EducationAnimation(educationAnimationId, animationProperties)
- IN_PROGRESS -> FrozenSuccessAnimation(successAnimationId, animationProperties)
- FINISHED -> SuccessAnimation(successAnimationId, animationProperties)
- }
- }
- }
-}
-
-@Composable
-private fun FrozenSuccessAnimation(
- @RawRes successAnimationId: Int,
- animationProperties: LottieDynamicProperties
-) {
- val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(successAnimationId))
- LottieAnimation(
- composition = composition,
- progress = { 0f }, // animation should freeze on 1st frame
- dynamicProperties = animationProperties,
- )
-}
-
-@Composable
-private fun EducationAnimation(
- @RawRes educationAnimationId: Int,
- animationProperties: LottieDynamicProperties
-) {
- val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(educationAnimationId))
- val progress by
- animateLottieCompositionAsState(composition, iterations = LottieConstants.IterateForever)
- LottieAnimation(
- composition = composition,
- progress = { progress },
- dynamicProperties = animationProperties,
- )
-}
-
-@Composable
-private fun SuccessAnimation(
- @RawRes successAnimationId: Int,
- animationProperties: LottieDynamicProperties
-) {
- val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(successAnimationId))
- val progress by animateLottieCompositionAsState(composition, iterations = 1)
- LottieAnimation(
- composition = composition,
- progress = { progress },
- dynamicProperties = animationProperties,
- )
-}
-
-@Composable
-fun rememberColorFilterProperty(
- layerName: String,
- color: Color
-): LottieDynamicProperty<ColorFilter> {
- return rememberLottieDynamicProperty(
- LottieProperty.COLOR_FILTER,
- value = PorterDuffColorFilter(color.toArgb(), PorterDuff.Mode.SRC_ATOP),
- // "**" below means match zero or more layers, so ** layerName ** means find layer with that
- // name at any depth
- keyPath = arrayOf("**", layerName, "**")
- )
-}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt
new file mode 100644
index 000000000000..416c562d212d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2024 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.touchpad.tutorial.ui.composable
+
+import android.graphics.ColorFilter
+import android.graphics.PorterDuff
+import android.graphics.PorterDuffColorFilter
+import androidx.activity.compose.BackHandler
+import androidx.annotation.RawRes
+import androidx.annotation.StringRes
+import androidx.compose.animation.AnimatedContent
+import androidx.compose.animation.EnterTransition
+import androidx.compose.animation.ExitTransition
+import androidx.compose.animation.animateColorAsState
+import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.snap
+import androidx.compose.animation.core.tween
+import androidx.compose.animation.fadeIn
+import androidx.compose.animation.fadeOut
+import androidx.compose.animation.togetherWith
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.BoxScope
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.drawBehind
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.toArgb
+import androidx.compose.ui.input.pointer.pointerInteropFilter
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import com.airbnb.lottie.LottieProperty
+import com.airbnb.lottie.compose.LottieAnimation
+import com.airbnb.lottie.compose.LottieCompositionSpec
+import com.airbnb.lottie.compose.LottieConstants
+import com.airbnb.lottie.compose.LottieDynamicProperties
+import com.airbnb.lottie.compose.LottieDynamicProperty
+import com.airbnb.lottie.compose.animateLottieCompositionAsState
+import com.airbnb.lottie.compose.rememberLottieComposition
+import com.airbnb.lottie.compose.rememberLottieDynamicProperty
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.FINISHED
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.IN_PROGRESS
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.NOT_STARTED
+import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGestureHandler
+import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGestureMonitor
+
+interface GestureMonitorProvider {
+ fun createGestureMonitor(
+ gestureDistanceThresholdPx: Int,
+ gestureStateChangedCallback: (GestureState) -> Unit
+ ): TouchpadGestureMonitor
+}
+
+@Composable
+fun GestureTutorialScreen(
+ screenConfig: TutorialScreenConfig,
+ gestureMonitorProvider: GestureMonitorProvider,
+ onDoneButtonClicked: () -> Unit,
+ onBack: () -> Unit,
+) {
+ BackHandler(onBack = onBack)
+ var gestureState by remember { mutableStateOf(NOT_STARTED) }
+ val swipeDistanceThresholdPx =
+ LocalContext.current.resources.getDimensionPixelSize(
+ com.android.internal.R.dimen.system_gestures_distance_threshold
+ )
+ val gestureHandler =
+ remember(swipeDistanceThresholdPx) {
+ TouchpadGestureHandler(
+ gestureMonitorProvider.createGestureMonitor(
+ swipeDistanceThresholdPx,
+ gestureStateChangedCallback = { gestureState = it }
+ )
+ )
+ }
+ TouchpadGesturesHandlingBox(gestureHandler, gestureState) {
+ GestureTutorialContent(gestureState, onDoneButtonClicked, screenConfig)
+ }
+}
+
+@Composable
+private fun TouchpadGesturesHandlingBox(
+ gestureHandler: TouchpadGestureHandler,
+ gestureState: GestureState,
+ modifier: Modifier = Modifier,
+ content: @Composable BoxScope.() -> Unit
+) {
+ Box(
+ modifier =
+ modifier
+ .fillMaxSize()
+ // we need to use pointerInteropFilter because some info about touchpad gestures is
+ // only available in MotionEvent
+ .pointerInteropFilter(
+ onTouchEvent = { event ->
+ // FINISHED is the final state so we don't need to process touches anymore
+ if (gestureState == FINISHED) {
+ false
+ } else {
+ gestureHandler.onMotionEvent(event)
+ }
+ }
+ )
+ ) {
+ content()
+ }
+}
+
+@Composable
+private fun GestureTutorialContent(
+ gestureState: GestureState,
+ onDoneButtonClicked: () -> Unit,
+ config: TutorialScreenConfig
+) {
+ val animatedColor by
+ animateColorAsState(
+ targetValue =
+ if (gestureState == FINISHED) config.colors.successBackground
+ else config.colors.background,
+ animationSpec = tween(durationMillis = 150, easing = LinearEasing),
+ label = "backgroundColor"
+ )
+ Column(
+ verticalArrangement = Arrangement.Center,
+ modifier =
+ Modifier.fillMaxSize()
+ .drawBehind { drawRect(animatedColor) }
+ .padding(start = 48.dp, top = 124.dp, end = 48.dp, bottom = 48.dp)
+ ) {
+ Row(modifier = Modifier.fillMaxWidth().weight(1f)) {
+ TutorialDescription(
+ titleTextId =
+ if (gestureState == FINISHED) config.strings.titleSuccessResId
+ else config.strings.titleResId,
+ titleColor = config.colors.title,
+ bodyTextId =
+ if (gestureState == FINISHED) config.strings.bodySuccessResId
+ else config.strings.bodyResId,
+ modifier = Modifier.weight(1f)
+ )
+ Spacer(modifier = Modifier.width(76.dp))
+ TutorialAnimation(
+ gestureState,
+ config,
+ modifier = Modifier.weight(1f).padding(top = 8.dp)
+ )
+ }
+ DoneButton(onDoneButtonClicked = onDoneButtonClicked)
+ }
+}
+
+@Composable
+fun TutorialDescription(
+ @StringRes titleTextId: Int,
+ titleColor: Color,
+ @StringRes bodyTextId: Int,
+ modifier: Modifier = Modifier
+) {
+ Column(verticalArrangement = Arrangement.Top, modifier = modifier) {
+ Text(
+ text = stringResource(id = titleTextId),
+ style = MaterialTheme.typography.displayLarge,
+ color = titleColor
+ )
+ Spacer(modifier = Modifier.height(16.dp))
+ Text(
+ text = stringResource(id = bodyTextId),
+ style = MaterialTheme.typography.bodyLarge,
+ color = Color.White
+ )
+ }
+}
+
+@Composable
+fun TutorialAnimation(
+ gestureState: GestureState,
+ config: TutorialScreenConfig,
+ modifier: Modifier = Modifier
+) {
+ Box(modifier = modifier.fillMaxWidth()) {
+ AnimatedContent(
+ targetState = gestureState,
+ transitionSpec = {
+ if (initialState == NOT_STARTED && targetState == IN_PROGRESS) {
+ val transitionDurationMillis = 150
+ fadeIn(
+ animationSpec = tween(transitionDurationMillis, easing = LinearEasing)
+ ) togetherWith
+ fadeOut(animationSpec = snap(delayMillis = transitionDurationMillis))
+ } else {
+ // empty transition works because all remaining transitions are from IN_PROGRESS
+ // state which shares initial animation frame with both FINISHED and NOT_STARTED
+ EnterTransition.None togetherWith ExitTransition.None
+ }
+ }
+ ) { gestureState ->
+ when (gestureState) {
+ NOT_STARTED ->
+ EducationAnimation(
+ config.animations.educationResId,
+ config.colors.animationColors
+ )
+ IN_PROGRESS ->
+ FrozenSuccessAnimation(
+ config.animations.successResId,
+ config.colors.animationColors
+ )
+ FINISHED ->
+ SuccessAnimation(config.animations.successResId, config.colors.animationColors)
+ }
+ }
+ }
+}
+
+@Composable
+private fun FrozenSuccessAnimation(
+ @RawRes successAnimationId: Int,
+ animationProperties: LottieDynamicProperties
+) {
+ val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(successAnimationId))
+ LottieAnimation(
+ composition = composition,
+ progress = { 0f }, // animation should freeze on 1st frame
+ dynamicProperties = animationProperties,
+ )
+}
+
+@Composable
+private fun EducationAnimation(
+ @RawRes educationAnimationId: Int,
+ animationProperties: LottieDynamicProperties
+) {
+ val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(educationAnimationId))
+ val progress by
+ animateLottieCompositionAsState(composition, iterations = LottieConstants.IterateForever)
+ LottieAnimation(
+ composition = composition,
+ progress = { progress },
+ dynamicProperties = animationProperties,
+ )
+}
+
+@Composable
+private fun SuccessAnimation(
+ @RawRes successAnimationId: Int,
+ animationProperties: LottieDynamicProperties
+) {
+ val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(successAnimationId))
+ val progress by animateLottieCompositionAsState(composition, iterations = 1)
+ LottieAnimation(
+ composition = composition,
+ progress = { progress },
+ dynamicProperties = animationProperties,
+ )
+}
+
+@Composable
+fun rememberColorFilterProperty(
+ layerName: String,
+ color: Color
+): LottieDynamicProperty<ColorFilter> {
+ return rememberLottieDynamicProperty(
+ LottieProperty.COLOR_FILTER,
+ value = PorterDuffColorFilter(color.toArgb(), PorterDuff.Mode.SRC_ATOP),
+ // "**" below means match zero or more layers, so ** layerName ** means find layer with that
+ // name at any depth
+ keyPath = arrayOf("**", layerName, "**")
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialScreenConfig.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialScreenConfig.kt
new file mode 100644
index 000000000000..d76ceb9380cd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialScreenConfig.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 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.touchpad.tutorial.ui.composable
+
+import androidx.annotation.RawRes
+import androidx.annotation.StringRes
+import androidx.compose.ui.graphics.Color
+import com.airbnb.lottie.compose.LottieDynamicProperties
+
+data class TutorialScreenConfig(
+ val colors: Colors,
+ val strings: Strings,
+ val animations: Animations
+) {
+
+ data class Colors(
+ val background: Color,
+ val successBackground: Color,
+ val title: Color,
+ val animationColors: LottieDynamicProperties
+ )
+
+ data class Strings(
+ @StringRes val titleResId: Int,
+ @StringRes val bodyResId: Int,
+ @StringRes val titleSuccessResId: Int,
+ @StringRes val bodySuccessResId: Int,
+ )
+
+ data class Animations(
+ @RawRes val educationResId: Int,
+ @RawRes val successResId: Int,
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitor.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitor.kt
index ed3355ebf0f4..e3666ce66d5c 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitor.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitor.kt
@@ -16,38 +16,26 @@
package com.android.systemui.touchpad.tutorial.ui.gesture
-import android.view.MotionEvent
-import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.FINISHED
-import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.IN_PROGRESS
-import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.NOT_STARTED
import kotlin.math.abs
+/** Monitors for touchpad back gesture, that is three fingers swiping left or right */
class BackGestureMonitor(
override val gestureDistanceThresholdPx: Int,
override val gestureStateChangedCallback: (GestureState) -> Unit
-) : TouchpadGestureMonitor {
-
- private var xStart = 0f
-
- override fun processTouchpadEvent(event: MotionEvent) {
- val action = event.actionMasked
- when (action) {
- MotionEvent.ACTION_DOWN -> {
- if (isThreeFingerTouchpadSwipe(event)) {
- xStart = event.x
- gestureStateChangedCallback(IN_PROGRESS)
- }
- }
- MotionEvent.ACTION_UP -> {
- if (isThreeFingerTouchpadSwipe(event)) {
- val distance = abs(event.x - xStart)
- if (distance >= gestureDistanceThresholdPx) {
- gestureStateChangedCallback(FINISHED)
- } else {
- gestureStateChangedCallback(NOT_STARTED)
- }
+) :
+ TouchpadGestureMonitor by ThreeFingerGestureMonitor(
+ gestureDistanceThresholdPx = gestureDistanceThresholdPx,
+ gestureStateChangedCallback = gestureStateChangedCallback,
+ donePredicate =
+ object : GestureDonePredicate {
+ override fun wasGestureDone(
+ startX: Float,
+ startY: Float,
+ endX: Float,
+ endY: Float
+ ): Boolean {
+ val distance = abs(endX - startX)
+ return distance >= gestureDistanceThresholdPx
}
}
- }
- }
-}
+ )
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureMonitor.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureMonitor.kt
new file mode 100644
index 000000000000..a410f991182e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureMonitor.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 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.touchpad.tutorial.ui.gesture
+
+/** Monitors for touchpad home gesture, that is three fingers swiping up */
+class HomeGestureMonitor(
+ override val gestureDistanceThresholdPx: Int,
+ override val gestureStateChangedCallback: (GestureState) -> Unit
+) :
+ TouchpadGestureMonitor by ThreeFingerGestureMonitor(
+ gestureDistanceThresholdPx = gestureDistanceThresholdPx,
+ gestureStateChangedCallback = gestureStateChangedCallback,
+ donePredicate =
+ object : GestureDonePredicate {
+ override fun wasGestureDone(
+ startX: Float,
+ startY: Float,
+ endX: Float,
+ endY: Float
+ ): Boolean {
+ val distance = startY - endY
+ return distance >= gestureDistanceThresholdPx
+ }
+ }
+ )
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/ThreeFingerGestureMonitor.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/ThreeFingerGestureMonitor.kt
new file mode 100644
index 000000000000..377977ce0d74
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/ThreeFingerGestureMonitor.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 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.touchpad.tutorial.ui.gesture
+
+import android.view.MotionEvent
+
+interface GestureDonePredicate {
+ /**
+ * Should return if gesture was finished. The only events this predicate receives are ACTION_UP.
+ */
+ fun wasGestureDone(startX: Float, startY: Float, endX: Float, endY: Float): Boolean
+}
+
+/** Common implementation for all three-finger gesture monitors */
+class ThreeFingerGestureMonitor(
+ override val gestureDistanceThresholdPx: Int,
+ override val gestureStateChangedCallback: (GestureState) -> Unit,
+ private val donePredicate: GestureDonePredicate
+) : TouchpadGestureMonitor {
+
+ private var xStart = 0f
+ private var yStart = 0f
+
+ override fun processTouchpadEvent(event: MotionEvent) {
+ val action = event.actionMasked
+ when (action) {
+ MotionEvent.ACTION_DOWN -> {
+ if (isThreeFingerTouchpadSwipe(event)) {
+ xStart = event.x
+ yStart = event.y
+ gestureStateChangedCallback(GestureState.IN_PROGRESS)
+ }
+ }
+ MotionEvent.ACTION_UP -> {
+ if (isThreeFingerTouchpadSwipe(event)) {
+ if (donePredicate.wasGestureDone(xStart, yStart, event.x, event.y)) {
+ gestureStateChangedCallback(GestureState.FINISHED)
+ } else {
+ gestureStateChangedCallback(GestureState.NOT_STARTED)
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximityCheck.java b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximityCheck.java
index c06a3a1e200c..373417b7bd68 100644
--- a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximityCheck.java
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximityCheck.java
@@ -86,11 +86,12 @@ public class ProximityCheck implements Runnable {
}
private void onProximityEvent(ThresholdSensorEvent proximityEvent) {
- mCallbacks.forEach(
+ List<Consumer<Boolean>> oldCallbacks = mCallbacks;
+ mCallbacks = new ArrayList<>();
+ oldCallbacks.forEach(
booleanConsumer ->
booleanConsumer.accept(
proximityEvent == null ? null : proximityEvent.getBelow()));
- mCallbacks.clear();
unregister();
mRegistered.set(false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxyExt.kt b/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxyExt.kt
index d757e33fcc29..364681444c1b 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxyExt.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxyExt.kt
@@ -19,6 +19,7 @@ package com.android.systemui.util.settings
import android.annotation.UserIdInt
import android.database.ContentObserver
+import com.android.systemui.Flags
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
@@ -39,9 +40,21 @@ object SettingsProxyExt {
}
}
- names.forEach { name -> registerContentObserverForUserSync(name, observer, userId) }
+ names.forEach { name ->
+ if (Flags.settingsExtRegisterContentObserverOnBgThread()) {
+ registerContentObserverForUser(name, observer, userId)
+ } else {
+ registerContentObserverForUserSync(name, observer, userId)
+ }
+ }
- awaitClose { unregisterContentObserverSync(observer) }
+ awaitClose {
+ if (Flags.settingsExtRegisterContentObserverOnBgThread()) {
+ unregisterContentObserverAsync(observer)
+ } else {
+ unregisterContentObserverSync(observer)
+ }
+ }
}
}
@@ -57,9 +70,21 @@ object SettingsProxyExt {
}
}
- names.forEach { name -> registerContentObserverSync(name, observer) }
+ names.forEach { name ->
+ if (Flags.settingsExtRegisterContentObserverOnBgThread()) {
+ registerContentObserver(name, observer)
+ } else {
+ registerContentObserverSync(name, observer)
+ }
+ }
- awaitClose { unregisterContentObserverSync(observer) }
+ awaitClose {
+ if (Flags.settingsExtRegisterContentObserverOnBgThread()) {
+ unregisterContentObserverAsync(observer)
+ } else {
+ unregisterContentObserverSync(observer)
+ }
+ }
}
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
index 6ba9b32dd4c7..512d946e92d5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
@@ -23,7 +23,6 @@ import android.content.packageManager
import android.content.pm.ActivityInfo
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager.NameNotFoundException
-import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.Point
import android.graphics.Rect
@@ -125,6 +124,8 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
private val defaultLogoDescriptionFromAppInfo = "Test Android App"
private val defaultLogoDescriptionFromActivityInfo = "Test Coke App"
private val logoDescriptionFromApp = "Test Cake App"
+ private val packageNameForLogoWithOverrides = "should.use.overridden.logo"
+
/** Prompt panel size padding */
private val smallHorizontalGuidelinePadding =
context.resources.getDimensionPixelSize(
@@ -169,7 +170,6 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
@Before
fun setup() {
-
// Set up default logo info and app customized info
whenever(kosmos.packageManager.getApplicationInfo(eq(OP_PACKAGE_NAME_NO_ICON), anyInt()))
.thenReturn(applicationInfoNoIconOrDescription)
@@ -246,15 +246,6 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_0)
testCase.fingerprint?.isAnySidefpsType.let {
kosmos.displayStateRepository.setIsInRearDisplayMode(testCase.isInRearDisplayMode)
- if (testCase.isDeviceFolded) {
- kosmos.promptViewModel.iconViewModel.onConfigurationChanged(
- getFoldedConfiguration()
- )
- } else {
- kosmos.promptViewModel.iconViewModel.onConfigurationChanged(
- getUnfoldedConfiguration()
- )
- }
}
promptContentView =
@@ -279,12 +270,8 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
val authenticated by collectLastValue(kosmos.promptViewModel.isAuthenticated)
val modalities by collectLastValue(kosmos.promptViewModel.modalities)
val iconAsset by collectLastValue(kosmos.promptViewModel.iconViewModel.iconAsset)
- val iconOverlayAsset by
- collectLastValue(kosmos.promptViewModel.iconViewModel.iconOverlayAsset)
val shouldAnimateIconView by
collectLastValue(kosmos.promptViewModel.iconViewModel.shouldAnimateIconView)
- val shouldAnimateIconOverlay by
- collectLastValue(kosmos.promptViewModel.iconViewModel.shouldAnimateIconOverlay)
val iconContentDescriptionId by
collectLastValue(kosmos.promptViewModel.iconViewModel.contentDescriptionId)
val message by collectLastValue(kosmos.promptViewModel.message)
@@ -307,9 +294,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
if ((testCase.isCoex && !forceExplicitFlow) || testCase.isFaceOnly) {
// Face-only or implicit co-ex auth
assertThat(iconAsset).isEqualTo(R.raw.face_dialog_idle_static)
- assertThat(iconOverlayAsset).isEqualTo(-1)
assertThat(shouldAnimateIconView).isEqualTo(false)
- assertThat(shouldAnimateIconOverlay).isEqualTo(false)
}
if (forceExplicitFlow) {
@@ -325,29 +310,22 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
if ((testCase.isCoex && !forceExplicitFlow) || testCase.isFaceOnly) {
// Face-only or implicit co-ex auth
assertThat(iconAsset).isEqualTo(R.raw.face_dialog_authenticating)
- assertThat(iconOverlayAsset).isEqualTo(-1)
assertThat(iconContentDescriptionId)
.isEqualTo(R.string.biometric_dialog_face_icon_description_authenticating)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldAnimateIconOverlay).isEqualTo(false)
} else if ((testCase.isCoex && forceExplicitFlow) || testCase.isFingerprintOnly) {
// Fingerprint-only or explicit co-ex auth
if (testCase.sensorType == FingerprintSensorProperties.TYPE_POWER_BUTTON) {
- assertThat(iconAsset).isEqualTo(getSfpsBaseIconAsset())
- assertThat(iconOverlayAsset)
- .isEqualTo(R.raw.biometricprompt_fingerprint_to_error_landscape)
+ assertThat(iconAsset).isEqualTo(getSfpsAsset_fingerprintAuthenticating())
assertThat(iconContentDescriptionId)
.isEqualTo(R.string.security_settings_sfps_enroll_find_sensor_message)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldAnimateIconOverlay).isEqualTo(false)
} else {
assertThat(iconAsset)
.isEqualTo(R.raw.fingerprint_dialogue_fingerprint_to_error_lottie)
- assertThat(iconOverlayAsset).isEqualTo(-1)
assertThat(iconContentDescriptionId)
.isEqualTo(R.string.fingerprint_dialog_touch_sensor)
assertThat(shouldAnimateIconView).isEqualTo(false)
- assertThat(shouldAnimateIconOverlay).isEqualTo(false)
}
}
@@ -361,14 +339,10 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
@Test
fun start_authenticating_show_and_clear_error() = runGenericTest {
val iconAsset by collectLastValue(kosmos.promptViewModel.iconViewModel.iconAsset)
- val iconOverlayAsset by
- collectLastValue(kosmos.promptViewModel.iconViewModel.iconOverlayAsset)
val iconContentDescriptionId by
collectLastValue(kosmos.promptViewModel.iconViewModel.contentDescriptionId)
val shouldAnimateIconView by
collectLastValue(kosmos.promptViewModel.iconViewModel.shouldAnimateIconView)
- val shouldAnimateIconOverlay by
- collectLastValue(kosmos.promptViewModel.iconViewModel.shouldAnimateIconOverlay)
val message by collectLastValue(kosmos.promptViewModel.message)
var forceExplicitFlow =
@@ -387,7 +361,6 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
forceExplicitFlow = true
// Usually done by binder
kosmos.promptViewModel.iconViewModel.setPreviousIconWasError(true)
- kosmos.promptViewModel.iconViewModel.setPreviousIconOverlayWasError(true)
}
assertThat(message?.isError).isEqualTo(true)
@@ -397,70 +370,47 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
if (testCase.isFaceOnly) {
// Face-only auth
assertThat(iconAsset).isEqualTo(R.raw.face_dialog_dark_to_error)
- assertThat(iconOverlayAsset).isEqualTo(-1)
assertThat(iconContentDescriptionId).isEqualTo(R.string.keyguard_face_failed)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldAnimateIconOverlay).isEqualTo(false)
// Clear error, go to idle
errorJob.join()
assertThat(iconAsset).isEqualTo(R.raw.face_dialog_error_to_idle)
- assertThat(iconOverlayAsset).isEqualTo(-1)
assertThat(iconContentDescriptionId)
.isEqualTo(R.string.biometric_dialog_face_icon_description_idle)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldAnimateIconOverlay).isEqualTo(false)
} else if ((testCase.isCoex && forceExplicitFlow) || testCase.isFingerprintOnly) {
// Fingerprint-only or explicit co-ex auth
if (testCase.sensorType == FingerprintSensorProperties.TYPE_POWER_BUTTON) {
- assertThat(iconAsset).isEqualTo(getSfpsBaseIconAsset())
- assertThat(iconOverlayAsset)
- .isEqualTo(R.raw.biometricprompt_fingerprint_to_error_landscape)
+ assertThat(iconAsset).isEqualTo(getSfpsAsset_fingerprintToError())
assertThat(iconContentDescriptionId).isEqualTo(R.string.biometric_dialog_try_again)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldAnimateIconOverlay).isEqualTo(true)
} else {
assertThat(iconAsset)
.isEqualTo(R.raw.fingerprint_dialogue_fingerprint_to_error_lottie)
- assertThat(iconOverlayAsset).isEqualTo(-1)
assertThat(iconContentDescriptionId).isEqualTo(R.string.biometric_dialog_try_again)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldAnimateIconOverlay).isEqualTo(false)
}
// Clear error, restart authenticating
errorJob.join()
if (testCase.sensorType == FingerprintSensorProperties.TYPE_POWER_BUTTON) {
- assertThat(iconAsset).isEqualTo(getSfpsBaseIconAsset())
- assertThat(iconOverlayAsset)
- .isEqualTo(R.raw.biometricprompt_symbol_error_to_fingerprint_landscape)
+ assertThat(iconAsset).isEqualTo(getSfpsAsset_errorToFingerprint())
assertThat(iconContentDescriptionId)
.isEqualTo(R.string.security_settings_sfps_enroll_find_sensor_message)
- assertThat(shouldAnimateIconOverlay).isEqualTo(true)
+ assertThat(shouldAnimateIconView).isEqualTo(true)
} else {
assertThat(iconAsset)
.isEqualTo(R.raw.fingerprint_dialogue_error_to_fingerprint_lottie)
- assertThat(iconOverlayAsset).isEqualTo(-1)
assertThat(iconContentDescriptionId)
.isEqualTo(R.string.fingerprint_dialog_touch_sensor)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldAnimateIconOverlay).isEqualTo(false)
}
}
}
- private fun getSfpsBaseIconAsset(): Int {
- return if (testCase.isInRearDisplayMode) {
- R.raw.biometricprompt_rear_landscape_base
- } else if (testCase.isDeviceFolded) {
- R.raw.biometricprompt_folded_base_default
- } else {
- R.raw.biometricprompt_landscape_base
- }
- }
-
@Test
fun shows_error_to_unlock_or_success() {
// Face-only auth does not use error -> unlock or error -> success assets
@@ -490,9 +440,30 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
dismissAfterDelay = DELAY
)
- // TODO(b/350121748): SFPS test cases to be added after SFPS assets update
- if (testCase.sensorType != FingerprintSensorProperties.TYPE_POWER_BUTTON) {
- // Non-SFPS (UDFPS / rear-FPS) test cases
+ // SFPS test cases
+ if (testCase.sensorType == FingerprintSensorProperties.TYPE_POWER_BUTTON) {
+ // Covers (1) fingerprint-only (2) co-ex, authenticated by fingerprint
+ if (testCase.authenticatedByFingerprint) {
+ assertThat(iconAsset).isEqualTo(R.raw.biometricprompt_sfps_error_to_success)
+ assertThat(iconContentDescriptionId)
+ .isEqualTo(R.string.security_settings_sfps_enroll_find_sensor_message)
+ assertThat(shouldAnimateIconView).isEqualTo(true)
+ } else { // Covers co-ex, authenticated by face
+ assertThat(iconAsset).isEqualTo(R.raw.biometricprompt_sfps_error_to_unlock)
+ assertThat(iconContentDescriptionId)
+ .isEqualTo(R.string.fingerprint_dialog_authenticated_confirmation)
+ assertThat(shouldAnimateIconView).isEqualTo(true)
+
+ // Confirm authentication
+ kosmos.promptViewModel.confirmAuthenticated()
+
+ assertThat(iconAsset)
+ .isEqualTo(R.raw.biometricprompt_sfps_unlock_to_success)
+ assertThat(iconContentDescriptionId)
+ .isEqualTo(R.string.fingerprint_dialog_touch_sensor)
+ assertThat(shouldAnimateIconView).isEqualTo(true)
+ }
+ } else { // Non-SFPS (UDFPS / rear-FPS) test cases
// Covers (1) fingerprint-only (2) co-ex, authenticated by fingerprint
if (testCase.authenticatedByFingerprint) {
assertThat(iconAsset)
@@ -528,14 +499,10 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
if (!testCase.confirmationRequested) {
runGenericTest {
val iconAsset by collectLastValue(kosmos.promptViewModel.iconViewModel.iconAsset)
- val iconOverlayAsset by
- collectLastValue(kosmos.promptViewModel.iconViewModel.iconOverlayAsset)
val iconContentDescriptionId by
collectLastValue(kosmos.promptViewModel.iconViewModel.contentDescriptionId)
val shouldAnimateIconView by
collectLastValue(kosmos.promptViewModel.iconViewModel.shouldAnimateIconView)
- val shouldAnimateIconOverlay by
- collectLastValue(kosmos.promptViewModel.iconViewModel.shouldAnimateIconOverlay)
verifyIconSize()
kosmos.promptViewModel.showAuthenticated(
@@ -546,33 +513,24 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
if (testCase.isFingerprintOnly) {
// Fingerprint icon asset assertions
if (testCase.sensorType == FingerprintSensorProperties.TYPE_POWER_BUTTON) {
- assertThat(iconAsset).isEqualTo(getSfpsBaseIconAsset())
- assertThat(iconOverlayAsset)
- .isEqualTo(
- R.raw.biometricprompt_symbol_fingerprint_to_success_landscape
- )
+ assertThat(iconAsset).isEqualTo(getSfpsAsset_fingerprintToSuccess())
assertThat(iconContentDescriptionId)
.isEqualTo(R.string.security_settings_sfps_enroll_find_sensor_message)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldAnimateIconOverlay).isEqualTo(true)
} else {
assertThat(iconAsset)
.isEqualTo(R.raw.fingerprint_dialogue_fingerprint_to_success_lottie)
- assertThat(iconOverlayAsset).isEqualTo(-1)
assertThat(iconContentDescriptionId)
.isEqualTo(R.string.fingerprint_dialog_touch_sensor)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldAnimateIconOverlay).isEqualTo(false)
}
} else if (testCase.isFaceOnly || testCase.isCoex) {
// Face icon asset assertions
// If co-ex, use implicit flow (explicit flow always requires confirmation)
assertThat(iconAsset).isEqualTo(R.raw.face_dialog_dark_to_checkmark)
- assertThat(iconOverlayAsset).isEqualTo(-1)
assertThat(iconContentDescriptionId)
.isEqualTo(R.string.biometric_dialog_face_icon_description_authenticated)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldAnimateIconOverlay).isEqualTo(false)
}
}
}
@@ -583,14 +541,10 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
if (testCase.authenticatedByFace && testCase.confirmationRequested) {
runGenericTest {
val iconAsset by collectLastValue(kosmos.promptViewModel.iconViewModel.iconAsset)
- val iconOverlayAsset by
- collectLastValue(kosmos.promptViewModel.iconViewModel.iconOverlayAsset)
val iconContentDescriptionId by
collectLastValue(kosmos.promptViewModel.iconViewModel.contentDescriptionId)
val shouldAnimateIconView by
collectLastValue(kosmos.promptViewModel.iconViewModel.shouldAnimateIconView)
- val shouldAnimateIconOverlay by
- collectLastValue(kosmos.promptViewModel.iconViewModel.shouldAnimateIconOverlay)
val forceExplicitFlow = testCase.isCoex && testCase.confirmationRequested
verifyIconSize(forceExplicitFlow = forceExplicitFlow)
@@ -602,21 +556,21 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
if (testCase.isFaceOnly) {
assertThat(iconAsset).isEqualTo(R.raw.face_dialog_wink_from_dark)
- assertThat(iconOverlayAsset).isEqualTo(-1)
assertThat(iconContentDescriptionId)
.isEqualTo(R.string.biometric_dialog_face_icon_description_authenticated)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldAnimateIconOverlay).isEqualTo(false)
} else if (testCase.isCoex) { // explicit flow, confirmation requested
- // TODO: Update when SFPS co-ex is implemented
- if (testCase.sensorType != FingerprintSensorProperties.TYPE_POWER_BUTTON) {
+ if (testCase.sensorType == FingerprintSensorProperties.TYPE_POWER_BUTTON) {
+ assertThat(iconAsset).isEqualTo(getSfpsAsset_fingerprintToUnlock())
+ assertThat(iconContentDescriptionId)
+ .isEqualTo(R.string.fingerprint_dialog_authenticated_confirmation)
+ assertThat(shouldAnimateIconView).isEqualTo(true)
+ } else {
assertThat(iconAsset)
.isEqualTo(R.raw.fingerprint_dialogue_fingerprint_to_unlock_lottie)
- assertThat(iconOverlayAsset).isEqualTo(-1)
assertThat(iconContentDescriptionId)
.isEqualTo(R.string.biometric_dialog_confirm)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldAnimateIconOverlay).isEqualTo(false)
}
}
}
@@ -628,14 +582,10 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
if (testCase.authenticatedByFace && testCase.confirmationRequested) {
runGenericTest {
val iconAsset by collectLastValue(kosmos.promptViewModel.iconViewModel.iconAsset)
- val iconOverlayAsset by
- collectLastValue(kosmos.promptViewModel.iconViewModel.iconOverlayAsset)
val iconContentDescriptionId by
collectLastValue(kosmos.promptViewModel.iconViewModel.contentDescriptionId)
val shouldAnimateIconView by
collectLastValue(kosmos.promptViewModel.iconViewModel.shouldAnimateIconView)
- val shouldAnimateIconOverlay by
- collectLastValue(kosmos.promptViewModel.iconViewModel.shouldAnimateIconOverlay)
val forceExplicitFlow = testCase.isCoex && testCase.confirmationRequested
verifyIconSize(forceExplicitFlow = forceExplicitFlow)
@@ -648,32 +598,66 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
if (testCase.isFaceOnly) {
assertThat(iconAsset).isEqualTo(R.raw.face_dialog_dark_to_checkmark)
- assertThat(iconOverlayAsset).isEqualTo(-1)
assertThat(iconContentDescriptionId)
.isEqualTo(R.string.biometric_dialog_face_icon_description_confirmed)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldAnimateIconOverlay).isEqualTo(false)
}
// explicit flow because confirmation requested
if (testCase.isCoex) {
- // TODO: Update when SFPS co-ex is implemented
- if (testCase.sensorType != FingerprintSensorProperties.TYPE_POWER_BUTTON) {
+ if (testCase.sensorType == FingerprintSensorProperties.TYPE_POWER_BUTTON) {
+ assertThat(iconAsset)
+ .isEqualTo(R.raw.biometricprompt_sfps_unlock_to_success)
+ assertThat(shouldAnimateIconView).isEqualTo(true)
+ } else {
assertThat(iconAsset)
.isEqualTo(
R.raw.fingerprint_dialogue_unlocked_to_checkmark_success_lottie
)
- assertThat(iconOverlayAsset).isEqualTo(-1)
assertThat(iconContentDescriptionId)
.isEqualTo(R.string.fingerprint_dialog_touch_sensor)
assertThat(shouldAnimateIconView).isEqualTo(true)
- assertThat(shouldAnimateIconOverlay).isEqualTo(false)
}
}
}
}
}
+ private fun getSfpsAsset_fingerprintAuthenticating(): Int =
+ if (testCase.isInRearDisplayMode) {
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_authenticating
+ } else {
+ R.raw.biometricprompt_sfps_fingerprint_authenticating
+ }
+
+ private fun getSfpsAsset_fingerprintToError(): Int =
+ if (testCase.isInRearDisplayMode) {
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_error
+ } else {
+ R.raw.biometricprompt_sfps_fingerprint_to_error
+ }
+
+ private fun getSfpsAsset_fingerprintToUnlock(): Int =
+ if (testCase.isInRearDisplayMode) {
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_unlock
+ } else {
+ R.raw.biometricprompt_sfps_fingerprint_to_unlock
+ }
+
+ private fun getSfpsAsset_errorToFingerprint(): Int =
+ if (testCase.isInRearDisplayMode) {
+ R.raw.biometricprompt_sfps_rear_display_error_to_fingerprint
+ } else {
+ R.raw.biometricprompt_sfps_error_to_fingerprint
+ }
+
+ private fun getSfpsAsset_fingerprintToSuccess(): Int =
+ if (testCase.isInRearDisplayMode) {
+ R.raw.biometricprompt_sfps_rear_display_fingerprint_to_success
+ } else {
+ R.raw.biometricprompt_sfps_fingerprint_to_success
+ }
+
@Test
fun shows_authenticated_with_no_errors() = runGenericTest {
// this case can't happen until fingerprint is started
@@ -776,35 +760,18 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
.isEqualTo(HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING)
}
+ // biometricprompt_sfps_fingerprint_authenticating reused across rotations
+ // Other SFPS assets change across rotations, testing authenticated asset
@Test
- fun sfpsIconUpdates_onFoldConfigurationChanged() {
- if (
- testCase.sensorType == FingerprintSensorProperties.TYPE_POWER_BUTTON &&
- !testCase.isInRearDisplayMode
- ) {
+ fun sfpsAuthenticatedIconUpdates_onRotation() {
+ if (testCase.sensorType == FingerprintSensorProperties.TYPE_POWER_BUTTON) {
runGenericTest {
val currentIcon by collectLastValue(kosmos.promptViewModel.iconViewModel.iconAsset)
- kosmos.promptViewModel.iconViewModel.onConfigurationChanged(
- getFoldedConfiguration()
- )
- val foldedIcon = currentIcon
-
- kosmos.promptViewModel.iconViewModel.onConfigurationChanged(
- getUnfoldedConfiguration()
+ kosmos.promptViewModel.showAuthenticated(
+ modality = testCase.authenticatedModality,
+ dismissAfterDelay = DELAY
)
- val unfoldedIcon = currentIcon
-
- assertThat(foldedIcon).isNotEqualTo(unfoldedIcon)
- }
- }
- }
-
- @Test
- fun sfpsIconUpdates_onRotation() {
- if (testCase.sensorType == FingerprintSensorProperties.TYPE_POWER_BUTTON) {
- runGenericTest {
- val currentIcon by collectLastValue(kosmos.promptViewModel.iconViewModel.iconAsset)
kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_0)
val iconRotation0 = currentIcon
@@ -818,9 +785,12 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_270)
val iconRotation270 = currentIcon
- assertThat(iconRotation0).isEqualTo(iconRotation180)
assertThat(iconRotation0).isNotEqualTo(iconRotation90)
+ assertThat(iconRotation0).isNotEqualTo(iconRotation180)
assertThat(iconRotation0).isNotEqualTo(iconRotation270)
+ assertThat(iconRotation90).isNotEqualTo(iconRotation180)
+ assertThat(iconRotation90).isNotEqualTo(iconRotation270)
+ assertThat(iconRotation180).isNotEqualTo(iconRotation270)
}
}
}
@@ -1818,18 +1788,6 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
.first(),
authenticatedModality = BiometricModality.Fingerprint,
isInRearDisplayMode = false,
- isDeviceFolded = false
- ),
- TestCase(
- fingerprint =
- fingerprintSensorPropertiesInternal(
- strong = true,
- sensorType = FingerprintSensorProperties.TYPE_POWER_BUTTON
- )
- .first(),
- authenticatedModality = BiometricModality.Fingerprint,
- isInRearDisplayMode = false,
- isDeviceFolded = true
),
TestCase(
fingerprint =
@@ -1840,7 +1798,6 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
.first(),
authenticatedModality = BiometricModality.Fingerprint,
isInRearDisplayMode = true,
- isDeviceFolded = false
),
TestCase(
fingerprint =
@@ -1915,7 +1872,6 @@ internal data class TestCase(
val fingerprint: FingerprintSensorPropertiesInternal? = null,
val face: FaceSensorPropertiesInternal? = null,
val isInRearDisplayMode: Boolean = false,
- val isDeviceFolded: Boolean = false,
val authenticatedModality: BiometricModality,
val confirmationRequested: Boolean = false,
) {
@@ -1931,9 +1887,8 @@ internal data class TestCase(
face != null -> "face only"
else -> "?"
}
- return "[$modality, isInRearDisplayMode: $isInRearDisplayMode, " +
- "isDeviceFolded: $isDeviceFolded, by: $authenticatedModality, " +
- "confirm: $confirmationRequested]"
+ return "[$modality, isInRearDisplayMode: $isInRearDisplayMode, by: " +
+ "$authenticatedModality, confirm: $confirmationRequested]"
}
fun expectConfirmation(atLeastOneFailure: Boolean): Boolean =
@@ -2013,21 +1968,3 @@ private fun AuthController.captureCallback() =
withArgCaptor<AuthController.Callback> {
Mockito.verify(this@captureCallback).addCallback(capture())
}
-
-/** Get folded device configuration */
-fun getFoldedConfiguration(): Configuration {
- val testConfig = Configuration()
- val folded = INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP - 1
- testConfig.smallestScreenWidthDp = folded
- return testConfig
-}
-
-/** Get unfolded device configuration */
-fun getUnfoldedConfiguration(): Configuration {
- val testConfig = Configuration()
- val unfolded = INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP + 1
- testConfig.smallestScreenWidthDp = unfolded
- return testConfig
-}
-
-internal const val INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP = 600
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt
index 0489d815b074..945f86c1b2c7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt
@@ -89,10 +89,7 @@ class DetailDialogTest : SysuiTestCase() {
verify(taskView).startActivity(any(), any(), capture(optionsCaptor), any())
assertThat(optionsCaptor.value.pendingIntentBackgroundActivityStartMode)
- .isAnyOf(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED,
- ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS)
- assertThat(optionsCaptor.value.isPendingIntentBackgroundActivityLaunchAllowedByPermission)
- .isTrue()
+ .isEqualTo(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS)
assertThat(optionsCaptor.value.taskAlwaysOnTop).isTrue()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
index 48a5df91d47c..2af4d872f6a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
@@ -45,6 +45,7 @@ import java.math.BigDecimal
import java.math.RoundingMode
import java.util.UUID
import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.dropWhile
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@@ -332,10 +333,11 @@ class KeyguardTransitionRepositoryTest : SysuiTestCase() {
}
@Test
- fun attemptTomanuallyUpdateTransitionWithInvalidUUIDthrowsException() {
- underTest.updateTransition(UUID.randomUUID(), 0f, TransitionState.RUNNING)
- assertThat(wtfHandler.failed).isTrue()
- }
+ fun attemptTomanuallyUpdateTransitionWithInvalidUUIDthrowsException() =
+ testScope.runTest {
+ underTest.updateTransition(UUID.randomUUID(), 0f, TransitionState.RUNNING)
+ assertThat(wtfHandler.failed).isTrue()
+ }
@Test
fun attemptToManuallyUpdateTransitionAfterFINISHEDstateThrowsException() =
@@ -414,6 +416,64 @@ class KeyguardTransitionRepositoryTest : SysuiTestCase() {
)
}
+ @Test
+ fun simulateRaceConditionIsProcessedInOrderUsingUpdateTransition() =
+ testScope.runTest {
+ val ktr = KeyguardTransitionRepositoryImpl(kosmos.testDispatcher)
+ val steps by collectValues(ktr.transitions.dropWhile { step -> step.from == OFF })
+
+ // Begin a manual transition
+ val info1 = TransitionInfo(OWNER_NAME, AOD, LOCKSCREEN, animator = null)
+ launch {
+ ktr.forceDelayForRaceConditionTest = false
+ val uuid = ktr.startTransition(info1)
+
+ // Pause here to allow another transition to start
+ delay(20)
+
+ // Attempt to send an update, which should fail
+ ktr.updateTransition(uuid!!, 0.5f, TransitionState.RUNNING)
+ }
+
+ // Now start another transition, which should acquire the preempt the first
+ val info2 = TransitionInfo(OWNER_NAME, LOCKSCREEN, OCCLUDED, animator = null)
+ launch {
+ delay(10)
+ ktr.forceDelayForRaceConditionTest = true
+ ktr.startTransition(info2)
+ }
+
+ runCurrent()
+
+ // Manual transition has started
+ assertThat(steps[0])
+ .isEqualTo(
+ TransitionStep(info1.from, info1.to, 0f, TransitionState.STARTED, OWNER_NAME)
+ )
+
+ // The second transition has requested to start, and grabbed the mutex. But it is
+ // delayed
+ advanceTimeBy(15L)
+
+ // Advancing another 10ms should now trigger the first transition to request an update,
+ // which should not happen as the second transition has the mutex
+ advanceTimeBy(10L)
+
+ // Finally, advance past the delay in the second transition so it can run
+ advanceTimeBy(50L)
+
+ assertThat(steps[1])
+ .isEqualTo(
+ TransitionStep(info1.from, info1.to, 0f, TransitionState.CANCELED, OWNER_NAME)
+ )
+ assertThat(steps[2])
+ .isEqualTo(
+ TransitionStep(info2.from, info2.to, 0f, TransitionState.STARTED, OWNER_NAME)
+ )
+
+ assertThat(steps.size).isEqualTo(3)
+ }
+
private fun listWithStep(
step: BigDecimal,
start: BigDecimal = BigDecimal.ZERO,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/ShareToAppPermissionDialogDelegateTest.kt
index f884b874cca8..c57aa369490b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/ShareToAppPermissionDialogDelegateTest.kt
@@ -29,16 +29,16 @@ import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger
import com.android.systemui.res.R
import com.android.systemui.statusbar.phone.AlertDialogWithDelegate
import com.android.systemui.statusbar.phone.SystemUIDialog
-import com.android.systemui.util.mockito.mock
-import junit.framework.Assert.assertEquals
+import kotlin.test.assertEquals
import org.junit.After
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
@SmallTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
-class MediaProjectionPermissionDialogDelegateTest : SysuiTestCase() {
+class ShareToAppPermissionDialogDelegateTest : SysuiTestCase() {
private lateinit var dialog: AlertDialog
@@ -115,39 +115,16 @@ class MediaProjectionPermissionDialogDelegateTest : SysuiTestCase() {
assertEquals(context.getString(resIdFullScreen), secondOptionText)
}
- @Test
- fun showDialog_disableSingleApp_hasCastingCapabilities() {
- setUpAndShowDialog(
- mediaProjectionConfig = MediaProjectionConfig.createConfigForDefaultDisplay(),
- hasCastingCapabilities = true
- )
-
- val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_options)
- val secondOptionWarningText =
- spinner.adapter
- .getDropDownView(1, null, spinner)
- .findViewById<TextView>(android.R.id.text2)
- ?.text
-
- // check that the first option is full screen and enabled
- assertEquals(context.getString(resIdFullScreen), spinner.selectedItem)
-
- // check that the second option is single app and disabled
- assertEquals(context.getString(resIdSingleAppDisabled, appName), secondOptionWarningText)
- }
-
private fun setUpAndShowDialog(
mediaProjectionConfig: MediaProjectionConfig? = null,
overrideDisableSingleAppOption: Boolean = false,
- hasCastingCapabilities: Boolean = false,
) {
val delegate =
- MediaProjectionPermissionDialogDelegate(
+ ShareToAppPermissionDialogDelegate(
context,
mediaProjectionConfig,
onStartRecordingClicked = {},
onCancelClicked = {},
- hasCastingCapabilities,
appName,
overrideDisableSingleAppOption,
hostUid = 12345,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/SystemCastPermissionDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/SystemCastPermissionDialogDelegateTest.kt
new file mode 100644
index 000000000000..59602dcca091
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/SystemCastPermissionDialogDelegateTest.kt
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.mediaprojection.permission
+
+import android.app.AlertDialog
+import android.media.projection.MediaProjectionConfig
+import android.testing.TestableLooper
+import android.view.WindowManager
+import android.widget.Spinner
+import android.widget.TextView
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.phone.AlertDialogWithDelegate
+import com.android.systemui.statusbar.phone.SystemUIDialog
+import kotlin.test.assertEquals
+import org.junit.After
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class SystemCastPermissionDialogDelegateTest : SysuiTestCase() {
+
+ private lateinit var dialog: AlertDialog
+
+ private val appName = "Test App"
+
+ private val resIdSingleApp =
+ R.string.media_projection_entry_cast_permission_dialog_option_text_single_app
+ private val resIdFullScreen =
+ R.string.media_projection_entry_cast_permission_dialog_option_text_entire_screen
+ private val resIdSingleAppDisabled =
+ R.string.media_projection_entry_app_permission_dialog_single_app_disabled
+
+ @After
+ fun teardown() {
+ if (::dialog.isInitialized) {
+ dialog.dismiss()
+ }
+ }
+
+ @Test
+ fun showDefaultDialog() {
+ setUpAndShowDialog()
+
+ val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_options)
+ val secondOptionText =
+ spinner.adapter
+ .getDropDownView(1, null, spinner)
+ .findViewById<TextView>(android.R.id.text1)
+ ?.text
+
+ // check that the first option is single app and enabled
+ assertEquals(context.getString(resIdSingleApp), spinner.selectedItem)
+
+ // check that the second option is full screen and enabled
+ assertEquals(context.getString(resIdFullScreen), secondOptionText)
+ }
+
+ @Test
+ fun showDialog_disableSingleApp() {
+ setUpAndShowDialog(
+ mediaProjectionConfig = MediaProjectionConfig.createConfigForDefaultDisplay()
+ )
+
+ val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_options)
+ val secondOptionWarningText =
+ spinner.adapter
+ .getDropDownView(1, null, spinner)
+ .findViewById<TextView>(android.R.id.text2)
+ ?.text
+
+ // check that the first option is full screen and enabled
+ assertEquals(context.getString(resIdFullScreen), spinner.selectedItem)
+
+ // check that the second option is single app and disabled
+ assertEquals(context.getString(resIdSingleAppDisabled, appName), secondOptionWarningText)
+ }
+
+ @Test
+ fun showDialog_disableSingleApp_forceShowPartialScreenShareTrue() {
+ setUpAndShowDialog(
+ mediaProjectionConfig = MediaProjectionConfig.createConfigForDefaultDisplay(),
+ overrideDisableSingleAppOption = true,
+ )
+
+ val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_options)
+ val secondOptionText =
+ spinner.adapter
+ .getDropDownView(1, null, spinner)
+ .findViewById<TextView>(android.R.id.text1)
+ ?.text
+
+ // check that the first option is single app and enabled
+ assertEquals(context.getString(resIdSingleApp), spinner.selectedItem)
+
+ // check that the second option is full screen and enabled
+ assertEquals(context.getString(resIdFullScreen), secondOptionText)
+ }
+
+ private fun setUpAndShowDialog(
+ mediaProjectionConfig: MediaProjectionConfig? = null,
+ overrideDisableSingleAppOption: Boolean = false,
+ ) {
+ val delegate =
+ SystemCastPermissionDialogDelegate(
+ context,
+ mediaProjectionConfig,
+ onStartRecordingClicked = {},
+ onCancelClicked = {},
+ appName,
+ overrideDisableSingleAppOption,
+ hostUid = 12345,
+ mediaProjectionMetricsLogger = mock<MediaProjectionMetricsLogger>(),
+ )
+
+ dialog = AlertDialogWithDelegate(context, R.style.Theme_SystemUI_Dialog, delegate)
+ SystemUIDialog.applyFlags(dialog)
+ SystemUIDialog.setDialogSize(dialog)
+
+ dialog.window?.addSystemFlags(
+ WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,
+ )
+
+ delegate.onCreate(dialog, savedInstanceState = null)
+ dialog.show()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
index 4f4f0d9f42cf..2f41ac17892d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
@@ -45,6 +45,7 @@ import android.testing.TestableResources;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import com.android.app.viewcapture.ViewCapture;
import com.android.settingslib.fuelgauge.Estimate;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -54,6 +55,8 @@ import com.android.systemui.res.R;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.CommandQueue;
+import dagger.Lazy;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -94,6 +97,7 @@ public class PowerUITest extends SysuiTestCase {
@Mock private BroadcastDispatcher mBroadcastDispatcher;
@Mock private CommandQueue mCommandQueue;
@Mock private IVrManager mVrManager;
+ @Mock private Lazy<ViewCapture> mLazyViewCapture;
@Before
public void setup() {
@@ -705,7 +709,8 @@ public class PowerUITest extends SysuiTestCase {
mEnhancedEstimates,
mWakefulnessLifecycle,
mPowerManager,
- mUserTracker);
+ mUserTracker,
+ mLazyViewCapture);
mPowerUI.mThermalService = mThermalServiceMock;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt
index e1c39117f6c8..b02cccc2bb8d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt
@@ -35,6 +35,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dump.DumpManager
+import com.android.systemui.education.domain.interactor.KeyboardTouchpadEduStatsInteractor
import com.android.systemui.keyguard.KeyguardUnlockAnimationController
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.keyguard.ui.view.InWindowLauncherUnlockAnimationManager
@@ -121,6 +122,9 @@ class OverviewProxyServiceTest : SysuiTestCase() {
Optional<UnfoldTransitionProgressForwarder>
@Mock private lateinit var broadcastDispatcher: BroadcastDispatcher
+ @Mock
+ private lateinit var keyboardTouchpadEduStatsInteractor: KeyboardTouchpadEduStatsInteractor
+
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
@@ -289,7 +293,8 @@ class OverviewProxyServiceTest : SysuiTestCase() {
assistUtils,
dumpManager,
unfoldTransitionProgressForwarder,
- broadcastDispatcher
+ broadcastDispatcher,
+ keyboardTouchpadEduStatsInteractor
)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorTest.kt
index cd8a7407970f..8f41caf54ec8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorTest.kt
@@ -23,6 +23,7 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
+import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
import kotlinx.coroutines.test.runTest
@@ -39,7 +40,7 @@ class CallChipInteractorTest : SysuiTestCase() {
kosmos.testScope.runTest {
val latest by collectLastValue(underTest.ongoingCallState)
- val inCall = OngoingCallModel.InCall(startTimeMs = 1000, intent = null)
+ val inCall = inCallModel(startTimeMs = 1000)
repo.setOngoingCallState(inCall)
assertThat(latest).isEqualTo(inCall)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
index 1a6b420dace5..ce79fbde77a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
@@ -17,8 +17,11 @@
package com.android.systemui.statusbar.chips.call.ui.viewmodel
import android.app.PendingIntent
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
import android.view.View
import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.coroutines.collectLastValue
@@ -26,11 +29,13 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.plugins.activityStarter
import com.android.systemui.res.R
+import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.chips.ui.model.ColorsModel
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
+import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel
import com.android.systemui.util.time.fakeSystemClock
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
@@ -73,7 +78,7 @@ class CallChipViewModelTest : SysuiTestCase() {
testScope.runTest {
val latest by collectLastValue(underTest.chip)
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 0, intent = null))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 0))
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
}
@@ -83,7 +88,7 @@ class CallChipViewModelTest : SysuiTestCase() {
testScope.runTest {
val latest by collectLastValue(underTest.chip)
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = -2, intent = null))
+ repo.setOngoingCallState(inCallModel(startTimeMs = -2))
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
}
@@ -93,7 +98,7 @@ class CallChipViewModelTest : SysuiTestCase() {
testScope.runTest {
val latest by collectLastValue(underTest.chip)
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 345, intent = null))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 345))
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
}
@@ -106,7 +111,7 @@ class CallChipViewModelTest : SysuiTestCase() {
kosmos.fakeSystemClock.setCurrentTimeMillis(3000)
kosmos.fakeSystemClock.setElapsedRealtime(400_000)
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 1000, intent = null))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 1000))
// The OngoingCallModel start time is relative to currentTimeMillis, so this call
// started 2000ms ago (1000 - 3000). The OngoingActivityChipModel start time needs to be
@@ -117,29 +122,97 @@ class CallChipViewModelTest : SysuiTestCase() {
}
@Test
- fun chip_positiveStartTime_iconIsPhone() =
+ @DisableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
+ fun chip_positiveStartTime_notifIconFlagOff_iconIsPhone() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 1000, intent = null))
+ repo.setOngoingCallState(
+ inCallModel(startTimeMs = 1000, notificationIcon = mock<StatusBarIconView>())
+ )
+
+ assertThat((latest as OngoingActivityChipModel.Shown).icon)
+ .isInstanceOf(OngoingActivityChipModel.ChipIcon.Basic::class.java)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(com.android.internal.R.drawable.ic_phone)
+ assertThat(icon.contentDescription).isNotNull()
+ }
+
+ @Test
+ @EnableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
+ fun chip_positiveStartTime_notifIconFlagOn_iconIsNotifIcon() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ val notifIcon = mock<StatusBarIconView>()
+ repo.setOngoingCallState(inCallModel(startTimeMs = 1000, notificationIcon = notifIcon))
+
+ assertThat((latest as OngoingActivityChipModel.Shown).icon)
+ .isInstanceOf(OngoingActivityChipModel.ChipIcon.StatusBarView::class.java)
+ val actualIcon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.StatusBarView)
+ .impl
+ assertThat(actualIcon).isEqualTo(notifIcon)
+ }
+
+ @Test
+ @DisableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
+ fun chip_zeroStartTime_notifIconFlagOff_iconIsPhone() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ repo.setOngoingCallState(
+ inCallModel(startTimeMs = 0, notificationIcon = mock<StatusBarIconView>())
+ )
+
+ assertThat((latest as OngoingActivityChipModel.Shown).icon)
+ .isInstanceOf(OngoingActivityChipModel.ChipIcon.Basic::class.java)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(com.android.internal.R.drawable.ic_phone)
+ assertThat(icon.contentDescription).isNotNull()
+ }
+
+ @Test
+ @EnableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
+ fun chip_zeroStartTime_notifIconFlagOn_iconIsNotifIcon() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ val notifIcon = mock<StatusBarIconView>()
+ repo.setOngoingCallState(inCallModel(startTimeMs = 0, notificationIcon = notifIcon))
- assertThat(((latest as OngoingActivityChipModel.Shown).icon as Icon.Resource).res)
- .isEqualTo(com.android.internal.R.drawable.ic_phone)
- assertThat((latest as OngoingActivityChipModel.Shown).icon!!.contentDescription)
- .isNotNull()
+ assertThat((latest as OngoingActivityChipModel.Shown).icon)
+ .isInstanceOf(OngoingActivityChipModel.ChipIcon.StatusBarView::class.java)
+ val actualIcon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.StatusBarView)
+ .impl
+ assertThat(actualIcon).isEqualTo(notifIcon)
}
@Test
- fun chip_zeroStartTime_iconIsPhone() =
+ @EnableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
+ fun chip_notifIconFlagOn_butNullNotifIcon_iconIsPhone() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 0, intent = null))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 1000, notificationIcon = null))
- assertThat(((latest as OngoingActivityChipModel.Shown).icon as Icon.Resource).res)
- .isEqualTo(com.android.internal.R.drawable.ic_phone)
- assertThat((latest as OngoingActivityChipModel.Shown).icon!!.contentDescription)
- .isNotNull()
+ assertThat((latest as OngoingActivityChipModel.Shown).icon)
+ .isInstanceOf(OngoingActivityChipModel.ChipIcon.Basic::class.java)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(com.android.internal.R.drawable.ic_phone)
+ assertThat(icon.contentDescription).isNotNull()
}
@Test
@@ -147,7 +220,7 @@ class CallChipViewModelTest : SysuiTestCase() {
testScope.runTest {
val latest by collectLastValue(underTest.chip)
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 1000, intent = null))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 1000))
assertThat((latest as OngoingActivityChipModel.Shown).colors)
.isEqualTo(ColorsModel.Themed)
@@ -158,7 +231,7 @@ class CallChipViewModelTest : SysuiTestCase() {
testScope.runTest {
val latest by collectLastValue(underTest.chip)
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 0, intent = null))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 0))
assertThat((latest as OngoingActivityChipModel.Shown).colors)
.isEqualTo(ColorsModel.Themed)
@@ -172,7 +245,7 @@ class CallChipViewModelTest : SysuiTestCase() {
kosmos.fakeSystemClock.setElapsedRealtime(400_000)
// Start a call
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 1000, intent = null))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 1000))
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
assertThat((latest as OngoingActivityChipModel.Shown.Timer).startTimeMs)
.isEqualTo(398_000)
@@ -186,7 +259,7 @@ class CallChipViewModelTest : SysuiTestCase() {
kosmos.fakeSystemClock.setElapsedRealtime(500_000)
// Start a new call, which started 1000ms ago
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 102_000, intent = null))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 102_000))
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
assertThat((latest as OngoingActivityChipModel.Shown.Timer).startTimeMs)
.isEqualTo(499_000)
@@ -197,7 +270,7 @@ class CallChipViewModelTest : SysuiTestCase() {
testScope.runTest {
val latest by collectLastValue(underTest.chip)
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 1000, intent = null))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 1000, intent = null))
assertThat((latest as OngoingActivityChipModel.Shown).onClickListener).isNull()
}
@@ -208,7 +281,7 @@ class CallChipViewModelTest : SysuiTestCase() {
val latest by collectLastValue(underTest.chip)
val intent = mock<PendingIntent>()
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 1000, intent = intent))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 1000, intent = intent))
val clickListener = (latest as OngoingActivityChipModel.Shown).onClickListener
assertThat(clickListener).isNotNull()
@@ -223,7 +296,7 @@ class CallChipViewModelTest : SysuiTestCase() {
val latest by collectLastValue(underTest.chip)
val intent = mock<PendingIntent>()
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 0, intent = intent))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 0, intent = intent))
val clickListener = (latest as OngoingActivityChipModel.Shown).onClickListener
assertThat(clickListener).isNotNull()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
index 02764f8a15fd..a8d2c5b4cdd7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
@@ -125,8 +125,11 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
)
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(R.drawable.ic_cast_connected)
assertThat((icon.contentDescription as ContentDescription.Resource).res)
.isEqualTo(R.string.cast_screen_to_other_device_chip_accessibility_label)
}
@@ -141,8 +144,11 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE)
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(R.drawable.ic_cast_connected)
assertThat((icon.contentDescription as ContentDescription.Resource).res)
.isEqualTo(R.string.cast_screen_to_other_device_chip_accessibility_label)
}
@@ -176,8 +182,11 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
)
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(R.drawable.ic_cast_connected)
// This content description is just generic "Casting", not "Casting screen"
assertThat((icon.contentDescription as ContentDescription.Resource).res)
.isEqualTo(R.string.accessibility_casting)
@@ -203,8 +212,11 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
// Only the projection info will show a timer
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(R.drawable.ic_cast_connected)
// MediaProjection == screen casting, so this content description reflects that we're
// using the MediaProjection information.
assertThat((icon.contentDescription as ContentDescription.Resource).res)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
index b4a37ee1a55e..e68fa0bc6eb3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
@@ -148,8 +148,11 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() {
screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_screenrecord)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(R.drawable.ic_screenrecord)
assertThat(icon.contentDescription).isNotNull()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
index 2658679dee08..a2ef59916ff6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
@@ -133,8 +133,11 @@ class ShareToAppChipViewModelTest : SysuiTestCase() {
)
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_present_to_all)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(R.drawable.ic_present_to_all)
assertThat(icon.contentDescription).isNotNull()
}
@@ -147,8 +150,11 @@ class ShareToAppChipViewModelTest : SysuiTestCase() {
MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_present_to_all)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(R.drawable.ic_present_to_all)
assertThat(icon.contentDescription).isNotNull()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt
index b9049e8f76b6..a724cfaa4798 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.chips.ui.viewmodel
+import androidx.annotation.DrawableRes
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.Icon
@@ -50,7 +51,7 @@ class ChipTransitionHelperTest : SysuiTestCase() {
val newChip =
OngoingActivityChipModel.Shown.Timer(
- icon = Icon.Resource(R.drawable.ic_cake, contentDescription = null),
+ icon = createIcon(R.drawable.ic_cake),
colors = ColorsModel.Themed,
startTimeMs = 100L,
onClickListener = null,
@@ -62,7 +63,7 @@ class ChipTransitionHelperTest : SysuiTestCase() {
val newerChip =
OngoingActivityChipModel.Shown.IconOnly(
- icon = Icon.Resource(R.drawable.ic_hotspot, contentDescription = null),
+ icon = createIcon(R.drawable.ic_hotspot),
colors = ColorsModel.Themed,
onClickListener = null,
)
@@ -82,7 +83,7 @@ class ChipTransitionHelperTest : SysuiTestCase() {
val shownChip =
OngoingActivityChipModel.Shown.Timer(
- icon = Icon.Resource(R.drawable.ic_cake, contentDescription = null),
+ icon = createIcon(R.drawable.ic_cake),
colors = ColorsModel.Themed,
startTimeMs = 100L,
onClickListener = null,
@@ -122,7 +123,7 @@ class ChipTransitionHelperTest : SysuiTestCase() {
val shownChip =
OngoingActivityChipModel.Shown.Timer(
- icon = Icon.Resource(R.drawable.ic_cake, contentDescription = null),
+ icon = createIcon(R.drawable.ic_cake),
colors = ColorsModel.Themed,
startTimeMs = 100L,
onClickListener = null,
@@ -151,4 +152,7 @@ class ChipTransitionHelperTest : SysuiTestCase() {
advanceTimeBy(2)
assertThat(latest).isEqualTo(shownChip)
}
+
+ private fun createIcon(@DrawableRes drawable: Int) =
+ OngoingActivityChipModel.ChipIcon.Basic(Icon.Resource(drawable, contentDescription = null))
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
index ee249f0f8a2c..556ec6a307ab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
@@ -42,6 +42,7 @@ import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory
import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
+import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel
import com.android.systemui.util.time.fakeSystemClock
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -120,7 +121,7 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() {
testScope.runTest {
screenRecordState.value = ScreenRecordModel.Recording
- callRepo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 34, intent = null))
+ callRepo.setOngoingCallState(inCallModel(startTimeMs = 34))
val latest by collectLastValue(underTest.chip)
@@ -146,7 +147,7 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() {
screenRecordState.value = ScreenRecordModel.DoingNothing
mediaProjectionState.value =
MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
- callRepo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 34, intent = null))
+ callRepo.setOngoingCallState(inCallModel(startTimeMs = 34))
val latest by collectLastValue(underTest.chip)
@@ -160,7 +161,7 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() {
// MediaProjection covers both share-to-app and cast-to-other-device
mediaProjectionState.value = MediaProjectionState.NotProjecting
- callRepo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 34, intent = null))
+ callRepo.setOngoingCallState(inCallModel(startTimeMs = 34))
val latest by collectLastValue(underTest.chip)
@@ -171,7 +172,7 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() {
fun chip_higherPriorityChipAdded_lowerPriorityChipReplaced() =
testScope.runTest {
// Start with just the lower priority call chip
- callRepo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 34, intent = null))
+ callRepo.setOngoingCallState(inCallModel(startTimeMs = 34))
mediaProjectionState.value = MediaProjectionState.NotProjecting
screenRecordState.value = ScreenRecordModel.DoingNothing
@@ -205,7 +206,7 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() {
mediaProjectionState.value =
MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
- callRepo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 34, intent = null))
+ callRepo.setOngoingCallState(inCallModel(startTimeMs = 34))
val latest by collectLastValue(underTest.chip)
@@ -335,21 +336,29 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() {
fun assertIsScreenRecordChip(latest: OngoingActivityChipModel?) {
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_screenrecord)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(R.drawable.ic_screenrecord)
}
fun assertIsShareToAppChip(latest: OngoingActivityChipModel?) {
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_present_to_all)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(R.drawable.ic_present_to_all)
}
fun assertIsCallChip(latest: OngoingActivityChipModel?) {
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res)
- .isEqualTo(com.android.internal.R.drawable.ic_phone)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(com.android.internal.R.drawable.ic_phone)
}
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt
index 6a5976eccd3a..48ae7a2aa260 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt
@@ -39,6 +39,7 @@ import com.android.systemui.statusbar.phone.StatusBarBoundsProvider
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent
import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
+import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.capture
@@ -396,9 +397,7 @@ class StatusBarModeRepositoryImplTest : SysuiTestCase() {
testScope.runTest {
val latest by collectLastValue(underTest.statusBarAppearance)
- ongoingCallRepository.setOngoingCallState(
- OngoingCallModel.InCall(startTimeMs = 34, intent = null)
- )
+ ongoingCallRepository.setOngoingCallState(inCallModel(startTimeMs = 34))
onSystemBarAttributesChanged(
requestedVisibleTypes = WindowInsets.Type.navigationBars(),
)
@@ -411,9 +410,8 @@ class StatusBarModeRepositoryImplTest : SysuiTestCase() {
testScope.runTest {
val latest by collectLastValue(underTest.statusBarAppearance)
- ongoingCallRepository.setOngoingCallState(
- OngoingCallModel.InCall(startTimeMs = 789, intent = null)
- )
+ ongoingCallRepository.setOngoingCallState(inCallModel(startTimeMs = 789))
+
onSystemBarAttributesChanged(
requestedVisibleTypes = WindowInsets.Type.statusBars(),
appearance = APPEARANCE_OPAQUE_STATUS_BARS,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt
index bfa816e65eb2..25138fd0ff83 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt
@@ -30,9 +30,12 @@ import android.graphics.drawable.Icon
import android.os.Bundle
import android.os.SystemClock
import android.os.UserHandle
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
import androidx.test.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON
import com.android.systemui.SysuiTestCase
import com.android.systemui.controls.controller.AuxiliaryPersistenceWrapperTest.Companion.any
import com.android.systemui.statusbar.notification.collection.NotificationEntry
@@ -108,6 +111,28 @@ class IconManagerTest : SysuiTestCase() {
}
@Test
+ @DisableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
+ fun testCreateIcons_chipNotifIconFlagDisabled_statusBarChipIconIsNull() {
+ val entry =
+ notificationEntry(hasShortcut = true, hasMessageSenderIcon = true, hasLargeIcon = true)
+ entry?.let { iconManager.createIcons(it) }
+ testScope.runCurrent()
+
+ assertThat(entry?.icons?.statusBarChipIcon).isNull()
+ }
+
+ @Test
+ @EnableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
+ fun testCreateIcons_chipNotifIconFlagEnabled_statusBarChipIconIsNull() {
+ val entry =
+ notificationEntry(hasShortcut = true, hasMessageSenderIcon = true, hasLargeIcon = true)
+ entry?.let { iconManager.createIcons(it) }
+ testScope.runCurrent()
+
+ assertThat(entry?.icons?.statusBarChipIcon).isNotNull()
+ }
+
+ @Test
fun testCreateIcons_importantConversation_shortcutIcon() {
val entry =
notificationEntry(hasShortcut = true, hasMessageSenderIcon = true, hasLargeIcon = true)
@@ -179,6 +204,7 @@ class IconManagerTest : SysuiTestCase() {
}
@Test
+ @EnableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
fun testCreateIcons_sensitiveImportantConversation() {
val entry =
notificationEntry(hasShortcut = true, hasMessageSenderIcon = true, hasLargeIcon = false)
@@ -187,11 +213,13 @@ class IconManagerTest : SysuiTestCase() {
entry?.let { iconManager.createIcons(it) }
testScope.runCurrent()
assertThat(entry?.icons?.statusBarIcon?.sourceIcon).isEqualTo(shortcutIc)
+ assertThat(entry?.icons?.statusBarChipIcon?.sourceIcon).isEqualTo(shortcutIc)
assertThat(entry?.icons?.shelfIcon?.sourceIcon).isEqualTo(smallIc)
assertThat(entry?.icons?.aodIcon?.sourceIcon).isEqualTo(smallIc)
}
@Test
+ @EnableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
fun testUpdateIcons_sensitiveImportantConversation() {
val entry =
notificationEntry(hasShortcut = true, hasMessageSenderIcon = true, hasLargeIcon = false)
@@ -202,6 +230,7 @@ class IconManagerTest : SysuiTestCase() {
entry?.let { iconManager.updateIcons(it) }
testScope.runCurrent()
assertThat(entry?.icons?.statusBarIcon?.sourceIcon).isEqualTo(shortcutIc)
+ assertThat(entry?.icons?.statusBarChipIcon?.sourceIcon).isEqualTo(shortcutIc)
assertThat(entry?.icons?.shelfIcon?.sourceIcon).isEqualTo(smallIc)
assertThat(entry?.icons?.aodIcon?.sourceIcon).isEqualTo(smallIc)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt
index f9509d2d394d..d1b1f466ef7a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt
@@ -17,6 +17,9 @@
package com.android.systemui.statusbar.notification.interruption
import android.Manifest.permission
+import android.app.Notification.CATEGORY_ALARM
+import android.app.Notification.CATEGORY_CAR_EMERGENCY
+import android.app.Notification.CATEGORY_CAR_WARNING
import android.app.Notification.CATEGORY_EVENT
import android.app.Notification.CATEGORY_REMINDER
import android.app.NotificationManager
@@ -256,6 +259,61 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro
}
@Test
+ fun testAvalancheFilter_duringAvalanche_allowCategoryAlarm() {
+ avalancheProvider.startTime = whenAgo(10)
+
+ withFilter(
+ AvalancheSuppressor(avalancheProvider, systemClock, settingsInteractor, packageManager,
+ uiEventLogger, context, notificationManager)
+ ) {
+ ensurePeekState()
+ assertShouldHeadsUp(
+ buildEntry {
+ importance = NotificationManager.IMPORTANCE_HIGH
+ category = CATEGORY_ALARM
+ }
+ )
+ }
+ }
+
+ @Test
+ fun testAvalancheFilter_duringAvalanche_allowCategoryCarEmergency() {
+ avalancheProvider.startTime = whenAgo(10)
+
+ withFilter(
+ AvalancheSuppressor(avalancheProvider, systemClock, settingsInteractor, packageManager,
+ uiEventLogger, context, notificationManager)
+ ) {
+ ensurePeekState()
+ assertShouldHeadsUp(
+ buildEntry {
+ importance = NotificationManager.IMPORTANCE_HIGH
+ category = CATEGORY_CAR_EMERGENCY
+
+ }
+ )
+ }
+ }
+
+ @Test
+ fun testAvalancheFilter_duringAvalanche_allowCategoryCarWarning() {
+ avalancheProvider.startTime = whenAgo(10)
+
+ withFilter(
+ AvalancheSuppressor(avalancheProvider, systemClock, settingsInteractor, packageManager,
+ uiEventLogger, context, notificationManager)
+ ) {
+ ensurePeekState()
+ assertShouldHeadsUp(
+ buildEntry {
+ importance = NotificationManager.IMPORTANCE_HIGH
+ category = CATEGORY_CAR_WARNING
+ }
+ )
+ }
+ }
+
+ @Test
fun testAvalancheFilter_duringAvalanche_allowFsi() {
avalancheProvider.startTime = whenAgo(10)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
index 54a26f722d7f..3f28164709fd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.notification.row
import android.app.Notification
+import android.app.Person
import android.content.Context
import android.os.AsyncTask
import android.os.Build
@@ -39,6 +40,7 @@ import com.android.systemui.statusbar.notification.row.NotificationRowContentBin
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP
+import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationCallback
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag
import com.android.systemui.statusbar.notification.row.shared.HeadsUpStatusBarModel
@@ -561,6 +563,40 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
verify(row, times(0)).onNotificationUpdated()
}
+ // TODO b/356709333: Add screenshot tests for these views
+ @Test
+ fun testInflatePublicSingleLineView() {
+ row.publicLayout.removeAllViews()
+ inflateAndWait(false, notificationInflater, FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE, row)
+ Assert.assertNotNull(row.publicLayout.mSingleLineView)
+ Assert.assertTrue(row.publicLayout.mSingleLineView is HybridNotificationView)
+ }
+
+ @Test
+ fun testInflatePublicSingleLineConversationView() {
+ val testPerson = Person.Builder().setName("Person").build()
+ val messagingBuilder =
+ Notification.Builder(mContext, "no-id")
+ .setSmallIcon(R.drawable.ic_person)
+ .setContentTitle("Title")
+ .setContentText("Text")
+ .setStyle(Notification.MessagingStyle(testPerson))
+
+ val messagingRow = spy(testHelper.createRow(messagingBuilder.build()))
+ messagingRow.publicLayout.removeAllViews()
+ inflateAndWait(
+ false,
+ notificationInflater,
+ FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE,
+ messagingRow
+ )
+ Assert.assertNotNull(messagingRow.publicLayout.mSingleLineView)
+ // assert this is the conversation layout
+ Assert.assertTrue(
+ messagingRow.publicLayout.mSingleLineView is HybridConversationNotificationView
+ )
+ }
+
private class ExceptionHolder {
var exception: Exception? = null
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index d7fdce2958f7..75376e62f192 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -620,8 +620,12 @@ public class NotificationTestHelper {
.setUser(userHandle)
.setPostTime(System.currentTimeMillis())
.setChannel(channel)
+ .updateRanking(rankingBuilder -> rankingBuilder.setIsConversation(
+ notification.isStyle(Notification.MessagingStyle.class)
+ ))
.build();
+
return generateRow(entry, extraInflationFlags);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineConversationViewBinderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineConversationViewBinderTest.kt
deleted file mode 100644
index 53a11989cca0..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineConversationViewBinderTest.kt
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.statusbar.notification.row
-
-import android.app.Notification
-import android.app.Person
-import android.platform.test.annotations.EnableFlags
-import android.testing.TestableLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.internal.R
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_SINGLE_LINE
-import com.android.systemui.statusbar.notification.row.SingleLineViewInflater.inflateSingleLineViewHolder
-import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation
-import com.android.systemui.statusbar.notification.row.ui.viewbinder.SingleLineConversationViewBinder
-import com.android.systemui.util.mockito.mock
-import kotlin.test.assertEquals
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-@TestableLooper.RunWithLooper
-class SingleLineConversationViewBinderTest : SysuiTestCase() {
- private lateinit var notificationBuilder: Notification.Builder
- private lateinit var helper: NotificationTestHelper
-
- @Before
- fun setUp() {
- allowTestableLooperAsMainThread()
- helper = NotificationTestHelper(context, mDependency, TestableLooper.get(this))
- notificationBuilder = Notification.Builder(context, CHANNEL_ID)
- notificationBuilder
- .setSmallIcon(R.drawable.ic_corp_icon)
- .setContentTitle(CONTENT_TITLE)
- .setContentText(CONTENT_TEXT)
- }
-
- @Test
- @EnableFlags(AsyncHybridViewInflation.FLAG_NAME)
- fun bindGroupConversationSingleLineView() {
- // GIVEN a row with a group conversation notification
- val user =
- Person.Builder()
- // .setIcon(Icon.createWithResource(mContext,
- // R.drawable.ic_account_circle))
- .setName(USER_NAME)
- .build()
- val style =
- Notification.MessagingStyle(user)
- .addMessage(MESSAGE_TEXT, System.currentTimeMillis(), user)
- .addMessage(
- "How about lunch?",
- System.currentTimeMillis(),
- Person.Builder().setName("user2").build()
- )
- .setGroupConversation(true)
- notificationBuilder.setStyle(style).setShortcutId(SHORTCUT_ID)
- val notification = notificationBuilder.build()
- val row = helper.createRow(notification)
-
- val viewHolder =
- inflateSingleLineViewHolder(
- isConversation = true,
- reinflateFlags = FLAG_CONTENT_VIEW_SINGLE_LINE,
- entry = row.entry,
- context = context,
- logger = mock()
- )
- as HybridConversationNotificationView
- val viewModel =
- SingleLineViewInflater.inflateSingleLineViewModel(
- notification = notification,
- messagingStyle = style,
- builder = notificationBuilder,
- systemUiContext = context,
- )
- // WHEN: binds the viewHolder
- SingleLineConversationViewBinder.bind(
- viewModel,
- viewHolder,
- )
-
- // THEN: the single-line conversation view should be bind with view model's corresponding
- // fields
- assertEquals(viewModel.titleText, viewHolder.titleView.text)
- assertEquals(viewModel.contentText, viewHolder.textView.text)
- assertEquals(
- viewModel.conversationData?.conversationSenderName,
- viewHolder.conversationSenderNameView.text
- )
- }
-
- private companion object {
- const val CHANNEL_ID = "CHANNEL_ID"
- const val CONTENT_TITLE = "CONTENT_TITLE"
- const val CONTENT_TEXT = "CONTENT_TEXT"
- const val USER_NAME = "USER_NAME"
- const val MESSAGE_TEXT = "MESSAGE_TEXT"
- const val SHORTCUT_ID = "Shortcut"
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt
index ee819c4df0ef..6b3fb5b4a2eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt
@@ -16,18 +16,22 @@
package com.android.systemui.statusbar.notification.row
import android.app.Notification
+import android.app.Person
import android.platform.test.annotations.EnableFlags
import android.testing.TestableLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_SINGLE_LINE
-import com.android.systemui.statusbar.notification.row.SingleLineViewInflater.inflateSingleLineViewHolder
+import com.android.systemui.statusbar.notification.row.SingleLineViewInflater.inflatePrivateSingleLineView
+import com.android.systemui.statusbar.notification.row.SingleLineViewInflater.inflatePublicSingleLineView
import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation
import com.android.systemui.statusbar.notification.row.ui.viewbinder.SingleLineViewBinder
import com.android.systemui.util.mockito.mock
-import org.junit.Assert
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -59,14 +63,25 @@ class SingleLineViewBinderTest : SysuiTestCase() {
val notification = notificationBuilder.build()
val row: ExpandableNotificationRow = helper.createRow(notification)
- val viewHolder =
- inflateSingleLineViewHolder(
+ val view =
+ inflatePrivateSingleLineView(
isConversation = false,
reinflateFlags = FLAG_CONTENT_VIEW_SINGLE_LINE,
entry = row.entry,
context = context,
logger = mock()
)
+
+ val publicView =
+ inflatePublicSingleLineView(
+ isConversation = false,
+ reinflateFlags = FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE,
+ entry = row.entry,
+ context = context,
+ logger = mock()
+ )
+ assertNotNull(publicView)
+
val viewModel =
SingleLineViewInflater.inflateSingleLineViewModel(
notification = notification,
@@ -76,16 +91,86 @@ class SingleLineViewBinderTest : SysuiTestCase() {
)
// WHEN: binds the viewHolder
- SingleLineViewBinder.bind(viewModel, viewHolder)
+ SingleLineViewBinder.bind(viewModel, view)
// THEN: the single-line view should be bind with viewModel's title and content text
- Assert.assertEquals(viewModel.titleText, viewHolder?.titleView?.text)
- Assert.assertEquals(viewModel.contentText, viewHolder?.textView?.text)
+ assertEquals(viewModel.titleText, view?.titleView?.text)
+ assertEquals(viewModel.contentText, view?.textView?.text)
+ }
+
+ @Test
+ @EnableFlags(AsyncHybridViewInflation.FLAG_NAME)
+ fun bindGroupConversationSingleLineView() {
+ // GIVEN a row with a group conversation notification
+ val user =
+ Person.Builder()
+ // .setIcon(Icon.createWithResource(mContext,
+ // R.drawable.ic_account_circle))
+ .setName(USER_NAME)
+ .build()
+ val style =
+ Notification.MessagingStyle(user)
+ .addMessage(MESSAGE_TEXT, System.currentTimeMillis(), user)
+ .addMessage(
+ "How about lunch?",
+ System.currentTimeMillis(),
+ Person.Builder().setName("user2").build()
+ )
+ .setGroupConversation(true)
+ notificationBuilder.setStyle(style).setShortcutId(SHORTCUT_ID)
+ val notification = notificationBuilder.build()
+ val row = helper.createRow(notification)
+
+ val view =
+ inflatePrivateSingleLineView(
+ isConversation = true,
+ reinflateFlags = FLAG_CONTENT_VIEW_SINGLE_LINE,
+ entry = row.entry,
+ context = context,
+ logger = mock()
+ )
+ as HybridConversationNotificationView
+
+ val publicView =
+ inflatePublicSingleLineView(
+ isConversation = true,
+ reinflateFlags = FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE,
+ entry = row.entry,
+ context = context,
+ logger = mock()
+ )
+ as HybridConversationNotificationView
+ assertNotNull(publicView)
+
+ val viewModel =
+ SingleLineViewInflater.inflateSingleLineViewModel(
+ notification = notification,
+ messagingStyle = style,
+ builder = notificationBuilder,
+ systemUiContext = context,
+ )
+ // WHEN: binds the view
+ SingleLineViewBinder.bind(
+ viewModel,
+ view,
+ )
+
+ // THEN: the single-line conversation view should be bound with view model's corresponding
+ // fields
+ assertEquals(viewModel.titleText, view.titleView.text)
+ assertEquals(viewModel.contentText, view.textView.text)
+ assertEquals(
+ viewModel.conversationData?.conversationSenderName,
+ view.conversationSenderNameView.text
+ )
}
private companion object {
const val CHANNEL_ID = "CHANNEL_ID"
const val CONTENT_TITLE = "A Cool New Feature"
const val CONTENT_TEXT = "Checkout out new feature!"
+ const val USER_NAME = "USER_NAME"
+ const val MESSAGE_TEXT = "MESSAGE_TEXT"
+ const val SHORTCUT_ID = "Shortcut"
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index bd9cccd3458a..a6b27294546c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -1157,22 +1157,13 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
}
@Test
- @EnableFlags(com.android.systemui.Flags.FLAG_TRUNCATED_STATUS_BAR_ICONS_FIX)
- public void updateResources_flagEnabled_doesNotUpdateStatusBarWindowHeight() {
+ public void updateResources_doesNotUpdateStatusBarWindowHeight() {
mCentralSurfaces.updateResources();
verify(mStatusBarWindowController, never()).refreshStatusBarHeight();
}
@Test
- @DisableFlags(com.android.systemui.Flags.FLAG_TRUNCATED_STATUS_BAR_ICONS_FIX)
- public void updateResources_flagDisabled_updatesStatusBarWindowHeight() {
- mCentralSurfaces.updateResources();
-
- verify(mStatusBarWindowController).refreshStatusBarHeight();
- }
-
- @Test
@EnableSceneContainer
public void brightnesShowingChanged_flagEnabled_ScrimControllerNotified() {
mCentralSurfaces.registerCallbacks();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt
index e670884eff17..eae4f23c59d6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt
@@ -30,7 +30,6 @@ import android.view.View
import android.view.WindowInsets
import android.widget.FrameLayout
import androidx.test.filters.SmallTest
-import com.android.systemui.Flags
import com.android.systemui.Gefingerpoken
import com.android.systemui.SysuiTestCase
import com.android.systemui.plugins.DarkIconDispatcher
@@ -41,7 +40,6 @@ import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
-import org.mockito.Mockito.never
import org.mockito.Mockito.spy
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
@@ -123,36 +121,21 @@ class PhoneStatusBarViewTest : SysuiTestCase() {
}
@Test
- fun onAttachedToWindow_flagEnabled_updatesWindowHeight() {
- mSetFlagsRule.enableFlags(Flags.FLAG_TRUNCATED_STATUS_BAR_ICONS_FIX)
-
+ fun onAttachedToWindow_updatesWindowHeight() {
view.onAttachedToWindow()
verify(windowController).refreshStatusBarHeight()
}
@Test
- fun onAttachedToWindow_flagDisabled_doesNotUpdateWindowHeight() {
- mSetFlagsRule.disableFlags(Flags.FLAG_TRUNCATED_STATUS_BAR_ICONS_FIX)
-
- view.onAttachedToWindow()
-
- verify(windowController, never()).refreshStatusBarHeight()
- }
-
- @Test
- fun onConfigurationChanged_flagEnabled_updatesWindowHeight() {
- mSetFlagsRule.enableFlags(Flags.FLAG_TRUNCATED_STATUS_BAR_ICONS_FIX)
-
+ fun onConfigurationChanged_updatesWindowHeight() {
view.onConfigurationChanged(Configuration())
verify(windowController).refreshStatusBarHeight()
}
@Test
- fun onConfigurationChanged_multipleCalls_flagEnabled_updatesWindowHeightMultipleTimes() {
- mSetFlagsRule.enableFlags(Flags.FLAG_TRUNCATED_STATUS_BAR_ICONS_FIX)
-
+ fun onConfigurationChanged_multipleCalls_updatesWindowHeightMultipleTimes() {
view.onConfigurationChanged(Configuration())
view.onConfigurationChanged(Configuration())
view.onConfigurationChanged(Configuration())
@@ -162,29 +145,8 @@ class PhoneStatusBarViewTest : SysuiTestCase() {
}
@Test
- fun onConfigurationChanged_flagDisabled_doesNotUpdateWindowHeight() {
- mSetFlagsRule.disableFlags(Flags.FLAG_TRUNCATED_STATUS_BAR_ICONS_FIX)
-
- view.onConfigurationChanged(Configuration())
-
- verify(windowController, never()).refreshStatusBarHeight()
- }
-
- @Test
- fun onConfigurationChanged_multipleCalls_flagDisabled_doesNotUpdateWindowHeight() {
- mSetFlagsRule.disableFlags(Flags.FLAG_TRUNCATED_STATUS_BAR_ICONS_FIX)
-
- view.onConfigurationChanged(Configuration())
- view.onConfigurationChanged(Configuration())
- view.onConfigurationChanged(Configuration())
- view.onConfigurationChanged(Configuration())
-
- verify(windowController, never()).refreshStatusBarHeight()
- }
-
- @Test
fun onAttachedToWindow_updatesLeftTopRightPaddingsBasedOnInsets() {
- val insets = Insets.of(/* left = */ 10, /* top = */ 20, /* right = */ 30, /* bottom = */ 40)
+ val insets = Insets.of(/* left= */ 10, /* top= */ 20, /* right= */ 30, /* bottom= */ 40)
whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation())
.thenReturn(insets)
@@ -198,7 +160,7 @@ class PhoneStatusBarViewTest : SysuiTestCase() {
@Test
fun onConfigurationChanged_updatesLeftTopRightPaddingsBasedOnInsets() {
- val insets = Insets.of(/* left = */ 40, /* top = */ 30, /* right = */ 20, /* bottom = */ 10)
+ val insets = Insets.of(/* left= */ 40, /* top= */ 30, /* right= */ 20, /* bottom= */ 10)
whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation())
.thenReturn(insets)
@@ -213,7 +175,7 @@ class PhoneStatusBarViewTest : SysuiTestCase() {
@Test
fun onConfigurationChanged_noRelevantChange_doesNotUpdateInsets() {
val previousInsets =
- Insets.of(/* left = */ 40, /* top = */ 30, /* right = */ 20, /* bottom = */ 10)
+ Insets.of(/* left= */ 40, /* top= */ 30, /* right= */ 20, /* bottom= */ 10)
whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation())
.thenReturn(previousInsets)
context.orCreateTestableResources.overrideConfiguration(Configuration())
@@ -233,7 +195,7 @@ class PhoneStatusBarViewTest : SysuiTestCase() {
@Test
fun onConfigurationChanged_densityChanged_updatesInsets() {
val previousInsets =
- Insets.of(/* left = */ 40, /* top = */ 30, /* right = */ 20, /* bottom = */ 10)
+ Insets.of(/* left= */ 40, /* top= */ 30, /* right= */ 20, /* bottom= */ 10)
whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation())
.thenReturn(previousInsets)
val configuration = Configuration()
@@ -256,7 +218,7 @@ class PhoneStatusBarViewTest : SysuiTestCase() {
@Test
fun onConfigurationChanged_fontScaleChanged_updatesInsets() {
val previousInsets =
- Insets.of(/* left = */ 40, /* top = */ 30, /* right = */ 20, /* bottom = */ 10)
+ Insets.of(/* left= */ 40, /* top= */ 30, /* right= */ 20, /* bottom= */ 10)
whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation())
.thenReturn(previousInsets)
val configuration = Configuration()
@@ -291,7 +253,7 @@ class PhoneStatusBarViewTest : SysuiTestCase() {
@Test
fun onApplyWindowInsets_updatesLeftTopRightPaddingsBasedOnInsets() {
- val insets = Insets.of(/* left = */ 90, /* top = */ 10, /* right = */ 45, /* bottom = */ 50)
+ val insets = Insets.of(/* left= */ 90, /* top= */ 10, /* right= */ 45, /* bottom= */ 50)
whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation())
.thenReturn(insets)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 9b611057c059..af5e60e9cd01 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -1068,7 +1068,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
public void testShowBouncerOrKeyguard_needsFullScreen() {
when(mKeyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(
KeyguardSecurityModel.SecurityMode.SimPin);
- mStatusBarKeyguardViewManager.showBouncerOrKeyguard(false, false);
+ mStatusBarKeyguardViewManager.showBouncerOrKeyguard(false);
verify(mCentralSurfaces).hideKeyguard();
verify(mPrimaryBouncerInteractor).show(true);
}
@@ -1084,7 +1084,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
.thenReturn(KeyguardState.LOCKSCREEN);
reset(mCentralSurfaces);
- mStatusBarKeyguardViewManager.showBouncerOrKeyguard(false, false);
+ mStatusBarKeyguardViewManager.showBouncerOrKeyguard(false);
verify(mPrimaryBouncerInteractor).show(true);
verify(mCentralSurfaces).showKeyguard();
}
@@ -1092,26 +1092,11 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
@Test
@DisableSceneContainer
public void testShowBouncerOrKeyguard_needsFullScreen_bouncerAlreadyShowing() {
- boolean isFalsingReset = false;
when(mKeyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(
KeyguardSecurityModel.SecurityMode.SimPin);
when(mPrimaryBouncerInteractor.isFullyShowing()).thenReturn(true);
- mStatusBarKeyguardViewManager.showBouncerOrKeyguard(false, isFalsingReset);
+ mStatusBarKeyguardViewManager.showBouncerOrKeyguard(false);
verify(mCentralSurfaces, never()).hideKeyguard();
- verify(mPrimaryBouncerInteractor).show(true);
- }
-
- @Test
- @DisableSceneContainer
- public void testShowBouncerOrKeyguard_needsFullScreen_bouncerAlreadyShowing_onFalsing() {
- boolean isFalsingReset = true;
- when(mKeyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(
- KeyguardSecurityModel.SecurityMode.SimPin);
- when(mPrimaryBouncerInteractor.isFullyShowing()).thenReturn(true);
- mStatusBarKeyguardViewManager.showBouncerOrKeyguard(false, isFalsingReset);
- verify(mCentralSurfaces, never()).hideKeyguard();
-
- // Do not refresh the full screen bouncer if the call is from falsing
verify(mPrimaryBouncerInteractor, never()).show(true);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt
index 6c2e2c6ef47d..dfe01bf45f38 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt
@@ -28,7 +28,7 @@ import android.view.View
import android.widget.LinearLayout
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.Flags
+import com.android.systemui.Flags.FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON
import com.android.systemui.Flags.FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS
import com.android.systemui.Flags.FLAG_STATUS_BAR_USE_REPOS_FOR_CALL_CHIP
import com.android.systemui.SysuiTestCase
@@ -39,6 +39,7 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.plugins.activityStarter
import com.android.systemui.res.R
+import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.data.repository.fakeStatusBarModeRepository
import com.android.systemui.statusbar.gesture.SwipeStatusBarAwayGestureHandler
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
@@ -160,6 +161,47 @@ class OngoingCallControllerViaRepoTest : SysuiTestCase() {
}
@Test
+ @DisableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
+ fun interactorHasOngoingCallNotif_notifIconFlagOff_repoHasNoNotifIcon() =
+ testScope.runTest {
+ val icon = mock<StatusBarIconView>()
+ setNotifOnRepo(
+ activeNotificationModel(
+ key = "ongoingNotif",
+ callType = CallType.Ongoing,
+ uid = CALL_UID,
+ statusBarChipIcon = icon,
+ whenTime = 567,
+ )
+ )
+
+ val repoState = ongoingCallRepository.ongoingCallState.value
+ assertThat(repoState).isInstanceOf(OngoingCallModel.InCall::class.java)
+ assertThat((repoState as OngoingCallModel.InCall).notificationIconView).isNull()
+ }
+
+ @Test
+ @EnableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
+ fun interactorHasOngoingCallNotif_notifIconFlagOn_repoHasNotifIcon() =
+ testScope.runTest {
+ val icon = mock<StatusBarIconView>()
+
+ setNotifOnRepo(
+ activeNotificationModel(
+ key = "ongoingNotif",
+ callType = CallType.Ongoing,
+ uid = CALL_UID,
+ statusBarChipIcon = icon,
+ whenTime = 567,
+ )
+ )
+
+ val repoState = ongoingCallRepository.ongoingCallState.value
+ assertThat(repoState).isInstanceOf(OngoingCallModel.InCall::class.java)
+ assertThat((repoState as OngoingCallModel.InCall).notificationIconView).isEqualTo(icon)
+ }
+
+ @Test
fun notifRepoHasOngoingCallNotif_isOngoingCallNotif_windowControllerUpdated() {
setCallNotifOnRepo()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt
index cbb8fe82eff1..4c6eaa589e6a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt
@@ -21,6 +21,7 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
+import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
@@ -33,7 +34,7 @@ class OngoingCallRepositoryTest : SysuiTestCase() {
@Test
fun hasOngoingCall_matchesSet() {
- val inCallModel = OngoingCallModel.InCall(startTimeMs = 654, intent = null)
+ val inCallModel = inCallModel(startTimeMs = 654)
underTest.setOngoingCallState(inCallModel)
assertThat(underTest.ongoingCallState.value).isEqualTo(inCallModel)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
index 9d83d5fbaed9..8fd0b31b82f3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
@@ -59,7 +59,6 @@ import android.telephony.TelephonyManager.DATA_UNKNOWN
import android.telephony.TelephonyManager.ERI_OFF
import android.telephony.TelephonyManager.ERI_ON
import android.telephony.TelephonyManager.EXTRA_CARRIER_ID
-import android.telephony.TelephonyManager.EXTRA_DATA_SPN
import android.telephony.TelephonyManager.EXTRA_PLMN
import android.telephony.TelephonyManager.EXTRA_SHOW_PLMN
import android.telephony.TelephonyManager.EXTRA_SHOW_SPN
@@ -86,6 +85,7 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionMod
import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig
import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfigTest.Companion.configWithOverride
import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfigTest.Companion.createTestConfig
+import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileTelephonyHelpers.signalStrength
@@ -93,6 +93,8 @@ import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.Mobil
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.mockito.withArgCaptor
@@ -110,8 +112,6 @@ import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
-import org.mockito.kotlin.any
-import org.mockito.kotlin.argumentCaptor
@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
@OptIn(ExperimentalCoroutinesApi::class)
@@ -815,11 +815,9 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
val intent = spnIntent()
val captor = argumentCaptor<BroadcastReceiver>()
verify(context).registerReceiver(captor.capture(), any())
- captor.lastValue.onReceive(context, intent)
+ captor.value!!.onReceive(context, intent)
- // spnIntent() sets all values to true and test strings
- assertThat(latest)
- .isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN$SEP$DATA_SPN"))
+ assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP))
job.cancel()
}
@@ -833,19 +831,17 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
val intent = spnIntent()
val captor = argumentCaptor<BroadcastReceiver>()
verify(context).registerReceiver(captor.capture(), any())
- captor.lastValue.onReceive(context, intent)
+ captor.value!!.onReceive(context, intent)
- assertThat(latest)
- .isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN$SEP$DATA_SPN"))
+ assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP))
// WHEN an intent with a different subId is sent
val wrongSubIntent = spnIntent(subId = 101)
- captor.lastValue.onReceive(context, wrongSubIntent)
+ captor.value!!.onReceive(context, wrongSubIntent)
// THEN the previous intent's name is still used
- assertThat(latest)
- .isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN$SEP$DATA_SPN"))
+ assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP))
job.cancel()
}
@@ -859,10 +855,9 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
val intent = spnIntent()
val captor = argumentCaptor<BroadcastReceiver>()
verify(context).registerReceiver(captor.capture(), any())
- captor.lastValue.onReceive(context, intent)
+ captor.value!!.onReceive(context, intent)
- assertThat(latest)
- .isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN$SEP$DATA_SPN"))
+ assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP))
val intentWithoutInfo =
spnIntent(
@@ -870,7 +865,7 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
showPlmn = false,
)
- captor.lastValue.onReceive(context, intentWithoutInfo)
+ captor.value!!.onReceive(context, intentWithoutInfo)
assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL)
@@ -889,88 +884,10 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
val intent = spnIntent()
val captor = argumentCaptor<BroadcastReceiver>()
verify(context).registerReceiver(captor.capture(), any())
- captor.lastValue.onReceive(context, intent)
+ captor.value!!.onReceive(context, intent)
// The value is still there despite no active subscribers
- assertThat(underTest.networkName.value)
- .isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN$SEP$DATA_SPN"))
- }
-
- @Test
- fun networkName_allFieldsSet() =
- testScope.runTest {
- val latest by collectLastValue(underTest.networkName)
- val captor = argumentCaptor<BroadcastReceiver>()
- verify(context).registerReceiver(captor.capture(), any())
-
- val intent =
- spnIntent(
- subId = SUB_1_ID,
- showSpn = true,
- spn = SPN,
- dataSpn = null,
- showPlmn = true,
- plmn = PLMN,
- )
- captor.lastValue.onReceive(context, intent)
- assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN"))
- }
-
- @Test
- fun networkName_showPlmn_plmnNotNull_showSpn_spnNull_dataSpnNotNull() =
- testScope.runTest {
- val latest by collectLastValue(underTest.networkName)
- val captor = argumentCaptor<BroadcastReceiver>()
- verify(context).registerReceiver(captor.capture(), any())
- val intent =
- spnIntent(
- subId = SUB_1_ID,
- showSpn = true,
- spn = null,
- dataSpn = DATA_SPN,
- showPlmn = true,
- plmn = PLMN,
- )
- captor.lastValue.onReceive(context, intent)
- assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
- }
-
- @Test
- fun networkName_showPlmn_noShowSPN() =
- testScope.runTest {
- val latest by collectLastValue(underTest.networkName)
- val captor = argumentCaptor<BroadcastReceiver>()
- verify(context).registerReceiver(captor.capture(), any())
- val intent =
- spnIntent(
- subId = SUB_1_ID,
- showSpn = false,
- spn = SPN,
- dataSpn = DATA_SPN,
- showPlmn = true,
- plmn = PLMN,
- )
- captor.lastValue.onReceive(context, intent)
- assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN"))
- }
-
- @Test
- fun networkName_showPlmn_plmnNull_showSpn() =
- testScope.runTest {
- val latest by collectLastValue(underTest.networkName)
- val captor = argumentCaptor<BroadcastReceiver>()
- verify(context).registerReceiver(captor.capture(), any())
- val intent =
- spnIntent(
- subId = SUB_1_ID,
- showSpn = true,
- spn = SPN,
- dataSpn = DATA_SPN,
- showPlmn = true,
- plmn = null,
- )
- captor.lastValue.onReceive(context, intent)
- assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$SPN$SEP$DATA_SPN"))
+ assertThat(underTest.networkName.value).isEqualTo(intent.toNetworkNameModel(SEP))
}
@Test
@@ -1211,16 +1128,14 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
private fun spnIntent(
subId: Int = SUB_1_ID,
showSpn: Boolean = true,
- spn: String? = SPN,
- dataSpn: String? = DATA_SPN,
+ spn: String = SPN,
showPlmn: Boolean = true,
- plmn: String? = PLMN,
+ plmn: String = PLMN,
): Intent =
Intent(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED).apply {
putExtra(EXTRA_SUBSCRIPTION_INDEX, subId)
putExtra(EXTRA_SHOW_SPN, showSpn)
putExtra(EXTRA_SPN, spn)
- putExtra(EXTRA_DATA_SPN, dataSpn)
putExtra(EXTRA_SHOW_PLMN, showPlmn)
putExtra(EXTRA_PLMN, plmn)
}
@@ -1233,7 +1148,6 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
private const val SEP = "-"
private const val SPN = "testSpn"
- private const val DATA_SPN = "testDataSpn"
private const val PLMN = "testPlmn"
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureMonitorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureMonitorTest.kt
new file mode 100644
index 000000000000..6aefbe9bf059
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/HomeGestureMonitorTest.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2024 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.touchpad.tutorial.ui.gesture
+
+import android.view.MotionEvent
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.FINISHED
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.IN_PROGRESS
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.NOT_STARTED
+import com.android.systemui.touchpad.tutorial.ui.gesture.MultiFingerGesture.Companion.SWIPE_DISTANCE
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class HomeGestureMonitorTest : SysuiTestCase() {
+
+ private var gestureState = NOT_STARTED
+ private val gestureMonitor =
+ HomeGestureMonitor(
+ gestureDistanceThresholdPx = SWIPE_DISTANCE.toInt(),
+ gestureStateChangedCallback = { gestureState = it }
+ )
+
+ @Test
+ fun triggersGestureFinishedForThreeFingerGestureUp() {
+ assertStateAfterEvents(events = ThreeFingerGesture.swipeUp(), expectedState = FINISHED)
+ }
+
+ @Test
+ fun triggersGestureProgressForThreeFingerGestureStarted() {
+ assertStateAfterEvents(
+ events = ThreeFingerGesture.startEvents(x = 0f, y = 0f),
+ expectedState = IN_PROGRESS
+ )
+ }
+
+ @Test
+ fun doesntTriggerGestureFinished_onGestureDistanceTooShort() {
+ assertStateAfterEvents(
+ events = ThreeFingerGesture.swipeUp(distancePx = SWIPE_DISTANCE / 2),
+ expectedState = NOT_STARTED
+ )
+ }
+
+ @Test
+ fun doesntTriggerGestureFinished_onThreeFingersSwipeInOtherDirections() {
+ assertStateAfterEvents(events = ThreeFingerGesture.swipeDown(), expectedState = NOT_STARTED)
+ assertStateAfterEvents(events = ThreeFingerGesture.swipeLeft(), expectedState = NOT_STARTED)
+ assertStateAfterEvents(
+ events = ThreeFingerGesture.swipeRight(),
+ expectedState = NOT_STARTED
+ )
+ }
+
+ @Test
+ fun doesntTriggerGestureFinished_onTwoFingersSwipe() {
+ assertStateAfterEvents(events = TwoFingerGesture.swipeUp(), expectedState = NOT_STARTED)
+ }
+
+ @Test
+ fun doesntTriggerGestureFinished_onFourFingersSwipe() {
+ assertStateAfterEvents(events = FourFingerGesture.swipeUp(), expectedState = NOT_STARTED)
+ }
+
+ private fun assertStateAfterEvents(events: List<MotionEvent>, expectedState: GestureState) {
+ events.forEach { gestureMonitor.processTouchpadEvent(it) }
+ assertThat(gestureState).isEqualTo(expectedState)
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/FakeContextualEducationRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/FakeContextualEducationRepository.kt
index bade91a55534..3816e1b604ce 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/FakeContextualEducationRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/FakeContextualEducationRepository.kt
@@ -16,8 +16,8 @@
package com.android.systemui.education.data.repository
+import com.android.systemui.contextualeducation.GestureType
import com.android.systemui.education.data.model.GestureEduModel
-import com.android.systemui.shared.education.GestureType
import java.time.Clock
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt
index b5ea619cd57f..616f2b688746 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt
@@ -283,7 +283,7 @@ class FakeKeyguardTransitionRepository(
)
}
- override fun updateTransition(
+ override suspend fun updateTransition(
transitionId: UUID,
@FloatRange(from = 0.0, to = 1.0) value: Float,
state: TransitionState
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/activatable/ActivatableExt.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/lifecycle/ActivatableExt.kt
index 1f04a44f172b..d2655594abbf 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/activatable/ActivatableExt.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/lifecycle/ActivatableExt.kt
@@ -14,12 +14,17 @@
* limitations under the License.
*/
-package com.android.systemui.activatable
+package com.android.systemui.lifecycle
+import kotlin.coroutines.CoroutineContext
+import kotlin.coroutines.EmptyCoroutineContext
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.TestScope
/** Activates [activatable] for the duration of the test. */
-fun Activatable.activateIn(testScope: TestScope) {
- testScope.backgroundScope.launch { activate() }
+fun Activatable.activateIn(
+ testScope: TestScope,
+ context: CoroutineContext = EmptyCoroutineContext,
+) {
+ testScope.backgroundScope.launch(context) { activate() }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/lifecycle/FakeActivatable.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/lifecycle/FakeActivatable.kt
new file mode 100644
index 000000000000..e8b2dd232c1c
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/lifecycle/FakeActivatable.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 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.lifecycle
+
+import kotlinx.coroutines.awaitCancellation
+
+class FakeActivatable(
+ private val onActivation: () -> Unit = {},
+ private val onDeactivation: () -> Unit = {},
+) : SafeActivatable() {
+ var activationCount = 0
+ var cancellationCount = 0
+
+ override suspend fun onActivated() {
+ activationCount++
+ onActivation()
+ try {
+ awaitCancellation()
+ } finally {
+ cancellationCount++
+ onDeactivation()
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/lifecycle/FakeSysUiViewModel.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/lifecycle/FakeSysUiViewModel.kt
new file mode 100644
index 000000000000..9a56f2419669
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/lifecycle/FakeSysUiViewModel.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 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.lifecycle
+
+import kotlinx.coroutines.awaitCancellation
+
+class FakeSysUiViewModel(
+ private val onActivation: () -> Unit = {},
+ private val onDeactivation: () -> Unit = {},
+) : SysUiViewModel() {
+ var activationCount = 0
+ var cancellationCount = 0
+
+ override suspend fun onActivated() {
+ activationCount++
+ onActivation()
+ try {
+ awaitCancellation()
+ } finally {
+ cancellationCount++
+ onDeactivation()
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt
index 37f1f137094e..76bdc0de3d7b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.data.model
import android.app.PendingIntent
import android.graphics.drawable.Icon
+import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
import com.android.systemui.statusbar.notification.shared.CallType
import com.android.systemui.statusbar.notification.stack.BUCKET_UNKNOWN
@@ -36,6 +37,7 @@ fun activeNotificationModel(
aodIcon: Icon? = null,
shelfIcon: Icon? = null,
statusBarIcon: Icon? = null,
+ statusBarChipIcon: StatusBarIconView? = null,
uid: Int = 0,
instanceId: Int? = null,
isGroupSummary: Boolean = false,
@@ -57,6 +59,7 @@ fun activeNotificationModel(
aodIcon = aodIcon,
shelfIcon = shelfIcon,
statusBarIcon = statusBarIcon,
+ statusBarChipIconView = statusBarChipIcon,
uid = uid,
packageName = packageName,
contentIntent = contentIntent,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModelBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModelBuilder.kt
new file mode 100644
index 000000000000..3963d7c5be63
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModelBuilder.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone.ongoingcall.shared.model
+
+import android.app.PendingIntent
+import com.android.systemui.statusbar.StatusBarIconView
+
+/** Helper for building [OngoingCallModel.InCall] instances in tests. */
+fun inCallModel(
+ startTimeMs: Long,
+ notificationIcon: StatusBarIconView? = null,
+ intent: PendingIntent? = null
+) = OngoingCallModel.InCall(startTimeMs, notificationIcon, intent)
diff --git a/packages/overlays/HsumConfigOverlay/Android.bp b/packages/overlays/HsumConfigOverlay/Android.bp
new file mode 100644
index 000000000000..050b1f056038
--- /dev/null
+++ b/packages/overlays/HsumConfigOverlay/Android.bp
@@ -0,0 +1,16 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+runtime_resource_overlay {
+ name: "HsumConfigOverlay",
+ certificate: "platform",
+
+ product_specific: true,
+ sdk_version: "current",
+}
diff --git a/packages/overlays/HsumConfigOverlay/AndroidManifest.xml b/packages/overlays/HsumConfigOverlay/AndroidManifest.xml
new file mode 100644
index 000000000000..cd7a8796985e
--- /dev/null
+++ b/packages/overlays/HsumConfigOverlay/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.internal.overlay.hsumconfig"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay android:targetPackage="android" android:priority="2" android:isStatic="true" />
+</manifest>
diff --git a/packages/overlays/HsumConfigOverlay/OWNERS b/packages/overlays/HsumConfigOverlay/OWNERS
new file mode 100644
index 000000000000..79dd1c967829
--- /dev/null
+++ b/packages/overlays/HsumConfigOverlay/OWNERS
@@ -0,0 +1,2 @@
+# People who can approve submission
+include platform/frameworks/base:/MULTIUSER_OWNERS
diff --git a/packages/overlays/HsumConfigOverlay/res/values/config.xml b/packages/overlays/HsumConfigOverlay/res/values/config.xml
new file mode 100644
index 000000000000..7dbdfc71db93
--- /dev/null
+++ b/packages/overlays/HsumConfigOverlay/res/values/config.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 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.
+ -->
+
+<!-- Default configuration for Headless System User Mode (HSUM) builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- Whether multiple admins are allowed on the device. If set to true, new users can be created
+ with admin privileges and admin privileges can be granted/revoked from existing users. -->
+ <bool name="config_enableMultipleAdmins">true</bool>
+
+ <!-- Whether the device will automatically (at first boot) have a designated main user and treat
+ it as a permanent admin.
+ Since the main user is a permanent admin user it can't be deleted or downgraded to
+ non-admin status.
+ This is generally only relevant on headless system user mode (HSUM) devices; on other
+ devices, the main user is the system user which is always a permanent admin anyway.
+ Note that HSUM devices without this enabled will not automatically have a main user. -->
+ <bool name="config_isMainUserPermanentAdmin">true</bool>
+
+ <!-- Maximum number of users we allow to be running at a time.
+ Note that this includes the headless system user. -->
+ <integer name="config_multiuserMaxRunningUsers">4</integer>
+
+</resources>
diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp
index 7c8fd42cd540..2de3c5ef1967 100644
--- a/ravenwood/Android.bp
+++ b/ravenwood/Android.bp
@@ -181,13 +181,13 @@ java_library {
visibility: ["//visibility:public"],
}
-// Carefully compiles against only test_current to support tests that
+// Carefully compiles against only module_current to support tests that
// want to verify they're unbundled. The "impl" library above is what
// ships inside the Ravenwood environment to actually drive any API
// access to implementation details.
-// This library needs to be statically linked to mainline tests as well,
-// which need to be able to run on multiple API levels, so we can't use
-// test APIs in this module.
+// We can't use test_current here because this library needs to be statically
+// linked to mainline tests as well, which can't use test APIs because they
+// need to be able to run on multiple API levels.
java_library {
name: "ravenwood-junit",
srcs: [
diff --git a/ravenwood/runtime-common-src/com/android/ravenwood/common/JvmWorkaround.java b/ravenwood/runtime-common-src/com/android/ravenwood/common/JvmWorkaround.java
index ee280991216a..0238baa2dcbf 100644
--- a/ravenwood/runtime-common-src/com/android/ravenwood/common/JvmWorkaround.java
+++ b/ravenwood/runtime-common-src/com/android/ravenwood/common/JvmWorkaround.java
@@ -16,6 +16,7 @@
package com.android.ravenwood.common;
import java.io.FileDescriptor;
+import java.io.IOException;
/**
* Collection of methods to workaround limitation in the hostside JVM.
@@ -44,6 +45,11 @@ public abstract class JvmWorkaround {
public abstract int getFdInt(FileDescriptor fd);
/**
+ * Equivalent to Android's Os.close(fd).
+ */
+ public abstract void closeFd(FileDescriptor fd) throws IOException;
+
+ /**
* Placeholder implementation for the host side.
*
* Even on the host side, we don't want to throw just because the class is loaded,
@@ -64,5 +70,10 @@ public abstract class JvmWorkaround {
public int getFdInt(FileDescriptor fd) {
throw calledOnHostside();
}
+
+ @Override
+ public void closeFd(FileDescriptor fd) {
+ throw calledOnHostside();
+ }
}
}
diff --git a/ravenwood/runtime-common-src/com/android/ravenwood/common/OpenJdkWorkaround.java b/ravenwood/runtime-common-src/com/android/ravenwood/common/OpenJdkWorkaround.java
index 9aedaab5b911..a260147654cd 100644
--- a/ravenwood/runtime-common-src/com/android/ravenwood/common/OpenJdkWorkaround.java
+++ b/ravenwood/runtime-common-src/com/android/ravenwood/common/OpenJdkWorkaround.java
@@ -16,6 +16,8 @@
package com.android.ravenwood.common;
import java.io.FileDescriptor;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
class OpenJdkWorkaround extends JvmWorkaround {
@Override
@@ -43,4 +45,19 @@ class OpenJdkWorkaround extends JvmWorkaround {
+ " perhaps JRE has changed?", e);
}
}
+
+ @Override
+ public void closeFd(FileDescriptor fd) throws IOException {
+ try {
+ final Object obj = Class.forName("jdk.internal.access.SharedSecrets").getMethod(
+ "getJavaIOFileDescriptorAccess").invoke(null);
+ Class.forName("jdk.internal.access.JavaIOFileDescriptorAccess").getMethod(
+ "close", FileDescriptor.class).invoke(obj, fd);
+ } catch (InvocationTargetException e) {
+ SneakyThrow.sneakyThrow(e.getTargetException());
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException("Failed to interact with raw FileDescriptor internals;"
+ + " perhaps JRE has changed?", e);
+ }
+ }
}
diff --git a/ravenwood/runtime-common-src/com/android/ravenwood/common/SneakyThrow.java b/ravenwood/runtime-common-src/com/android/ravenwood/common/SneakyThrow.java
new file mode 100644
index 000000000000..0dbf7df12bce
--- /dev/null
+++ b/ravenwood/runtime-common-src/com/android/ravenwood/common/SneakyThrow.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 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.ravenwood.common;
+
+public class SneakyThrow {
+
+ private SneakyThrow() {
+ }
+
+ /**
+ * Throw checked exceptions without the need to declare in method signature
+ */
+ public static void sneakyThrow(Throwable t) {
+ SneakyThrow.<RuntimeException>sneakyThrow_(t);
+ }
+
+ private static <T extends Throwable> void sneakyThrow_(Throwable t) throws T {
+ throw (T) t;
+ }
+}
diff --git a/ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/nativesubstitution/ParcelFileDescriptor_host.java b/ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/nativesubstitution/ParcelFileDescriptor_host.java
index 1a15d7a8c19e..5a3589dae43a 100644
--- a/ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/nativesubstitution/ParcelFileDescriptor_host.java
+++ b/ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/nativesubstitution/ParcelFileDescriptor_host.java
@@ -16,105 +16,16 @@
package com.android.platform.test.ravenwood.nativesubstitution;
-import static android.os.ParcelFileDescriptor.MODE_APPEND;
-import static android.os.ParcelFileDescriptor.MODE_CREATE;
-import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
-import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
-import static android.os.ParcelFileDescriptor.MODE_TRUNCATE;
-import static android.os.ParcelFileDescriptor.MODE_WORLD_READABLE;
-import static android.os.ParcelFileDescriptor.MODE_WORLD_WRITEABLE;
-import static android.os.ParcelFileDescriptor.MODE_WRITE_ONLY;
-
-import android.system.ErrnoException;
-import android.system.Os;
-import android.util.Log;
-
-import com.android.internal.annotations.GuardedBy;
import com.android.ravenwood.common.JvmWorkaround;
-import java.io.File;
import java.io.FileDescriptor;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.util.HashMap;
-import java.util.Map;
public class ParcelFileDescriptor_host {
- private static final String TAG = "ParcelFileDescriptor_host";
-
- /**
- * Since we don't have a great way to keep an unmanaged {@code FileDescriptor} reference
- * alive, we keep a strong reference to the {@code RandomAccessFile} we used to open it. This
- * gives us a way to look up the original parent object when closing later.
- */
- @GuardedBy("sActive")
- private static final Map<FileDescriptor, RandomAccessFile> sActive = new HashMap<>();
-
- public static void native_setFdInt$ravenwood(FileDescriptor fd, int fdInt) {
+ public static void setFdInt(FileDescriptor fd, int fdInt) {
JvmWorkaround.getInstance().setFdInt(fd, fdInt);
}
- public static int native_getFdInt$ravenwood(FileDescriptor fd) {
+ public static int getFdInt(FileDescriptor fd) {
return JvmWorkaround.getInstance().getFdInt(fd);
}
-
- public static FileDescriptor native_open$ravenwood(File file, int pfdMode) throws IOException {
- if ((pfdMode & MODE_CREATE) != 0 && !file.exists()) {
- throw new FileNotFoundException();
- }
-
- final String modeString;
- if ((pfdMode & MODE_READ_WRITE) == MODE_READ_WRITE) {
- modeString = "rw";
- } else if ((pfdMode & MODE_WRITE_ONLY) == MODE_WRITE_ONLY) {
- modeString = "rw";
- } else if ((pfdMode & MODE_READ_ONLY) == MODE_READ_ONLY) {
- modeString = "r";
- } else {
- throw new IllegalArgumentException();
- }
-
- final RandomAccessFile raf = new RandomAccessFile(file, modeString);
-
- // Now that we have a real file on disk, match requested flags
- if ((pfdMode & MODE_TRUNCATE) != 0) {
- raf.setLength(0);
- }
- if ((pfdMode & MODE_APPEND) != 0) {
- raf.seek(raf.length());
- }
- if ((pfdMode & MODE_WORLD_READABLE) != 0) {
- file.setReadable(true, false);
- }
- if ((pfdMode & MODE_WORLD_WRITEABLE) != 0) {
- file.setWritable(true, false);
- }
-
- final FileDescriptor fd = raf.getFD();
- synchronized (sActive) {
- sActive.put(fd, raf);
- }
- return fd;
- }
-
- public static void native_close$ravenwood(FileDescriptor fd) {
- final RandomAccessFile raf;
- synchronized (sActive) {
- raf = sActive.remove(fd);
- }
- int fdInt = JvmWorkaround.getInstance().getFdInt(fd);
- try {
- if (raf != null) {
- raf.close();
- } else {
- // This FD wasn't created by native_open$ravenwood().
- // The FD was passed to the PFD ctor. Just close it.
- Os.close(fd);
- }
- } catch (IOException | ErrnoException e) {
- Log.w(TAG, "Exception thrown while closing fd " + fdInt, e);
- }
- }
}
-; \ No newline at end of file
diff --git a/ravenwood/runtime-helper-src/libcore-fake/android/system/Os.java b/ravenwood/runtime-helper-src/libcore-fake/android/system/Os.java
index 825ab72e773a..ecaa8161ee46 100644
--- a/ravenwood/runtime-helper-src/libcore-fake/android/system/Os.java
+++ b/ravenwood/runtime-helper-src/libcore-fake/android/system/Os.java
@@ -15,9 +15,11 @@
*/
package android.system;
+import com.android.ravenwood.common.JvmWorkaround;
import com.android.ravenwood.common.RavenwoodRuntimeNative;
import java.io.FileDescriptor;
+import java.io.IOException;
/**
* OS class replacement used on Ravenwood. For now, we just implement APIs as we need them...
@@ -56,6 +58,15 @@ public final class Os {
/** Ravenwood version of the OS API. */
public static void close(FileDescriptor fd) throws ErrnoException {
- RavenwoodRuntimeNative.close(fd);
+ try {
+ JvmWorkaround.getInstance().closeFd(fd);
+ } catch (IOException e) {
+ // The only valid error on Linux that can happen is EIO
+ throw new ErrnoException("close", OsConstants.EIO);
+ }
+ }
+
+ public static FileDescriptor open(String path, int flags, int mode) throws ErrnoException {
+ return RavenwoodRuntimeNative.open(path, flags, mode);
}
}
diff --git a/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/common/RavenwoodRuntimeNative.java b/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/common/RavenwoodRuntimeNative.java
index 2bc8e7123aad..beba83391652 100644
--- a/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/common/RavenwoodRuntimeNative.java
+++ b/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/common/RavenwoodRuntimeNative.java
@@ -48,7 +48,7 @@ public class RavenwoodRuntimeNative {
public static native StructStat stat(String path) throws ErrnoException;
- private static native void nClose(int fd) throws ErrnoException;
+ private static native int nOpen(String path, int flags, int mode) throws ErrnoException;
public static long lseek(FileDescriptor fd, long offset, int whence) throws ErrnoException {
return nLseek(JvmWorkaround.getInstance().getFdInt(fd), offset, whence);
@@ -69,7 +69,7 @@ public class RavenwoodRuntimeNative {
public static FileDescriptor dup(FileDescriptor fd) throws ErrnoException {
var fdInt = nDup(JvmWorkaround.getInstance().getFdInt(fd));
- var retFd = new java.io.FileDescriptor();
+ var retFd = new FileDescriptor();
JvmWorkaround.getInstance().setFdInt(retFd, fdInt);
return retFd;
}
@@ -86,10 +86,11 @@ public class RavenwoodRuntimeNative {
return nFstat(fdInt);
}
- /** See close(2) */
- public static void close(FileDescriptor fd) throws ErrnoException {
- var fdInt = JvmWorkaround.getInstance().getFdInt(fd);
-
- nClose(fdInt);
+ public static FileDescriptor open(String path, int flags, int mode) throws ErrnoException {
+ int fd = nOpen(path, flags, mode);
+ if (fd < 0) return null;
+ var retFd = new FileDescriptor();
+ JvmWorkaround.getInstance().setFdInt(retFd, fd);
+ return retFd;
}
}
diff --git a/ravenwood/runtime-jni/ravenwood_runtime.cpp b/ravenwood/runtime-jni/ravenwood_runtime.cpp
index ee84954a5c2a..c8049281bc53 100644
--- a/ravenwood/runtime-jni/ravenwood_runtime.cpp
+++ b/ravenwood/runtime-jni/ravenwood_runtime.cpp
@@ -18,9 +18,11 @@
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
+#include <string>
#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedLocalRef.h>
#include <nativehelper/ScopedUtfChars.h>
+#include <nativehelper/ScopedPrimitiveArray.h>
#include "jni.h"
#include "utils/Log.h"
@@ -49,6 +51,43 @@ static rc_t throwIfMinusOne(JNIEnv* env, const char* name, rc_t rc) {
static jclass g_StructStat;
static jclass g_StructTimespecClass;
+// We have to explicitly decode the string to real UTF-8, because when using GetStringUTFChars
+// we only get modified UTF-8, which is not the platform string type used in host JVM.
+struct ScopedRealUtf8Chars {
+ ScopedRealUtf8Chars(JNIEnv* env, jstring s) : valid_(false) {
+ if (s == nullptr) {
+ jniThrowNullPointerException(env);
+ return;
+ }
+ jclass clazz = env->GetObjectClass(s);
+ jmethodID getBytes = env->GetMethodID(clazz, "getBytes", "(Ljava/lang/String;)[B");
+
+ ScopedLocalRef<jstring> utf8(env, env->NewStringUTF("UTF-8"));
+ ScopedLocalRef<jbyteArray> jbytes(env,
+ (jbyteArray) env->CallObjectMethod(s, getBytes, utf8.get()));
+
+ ScopedByteArrayRO bytes(env, jbytes.get());
+ string_.append((const char *) bytes.get(), bytes.size());
+ valid_ = true;
+ }
+
+ const char* c_str() const {
+ return valid_ ? string_.c_str() : nullptr;
+ }
+
+ size_t size() const {
+ return string_.size();
+ }
+
+ const char& operator[](size_t n) const {
+ return string_[n];
+ }
+
+private:
+ std::string string_;
+ bool valid_;
+};
+
static jclass findClass(JNIEnv* env, const char* name) {
ScopedLocalRef<jclass> localClass(env, env->FindClass(name));
jclass result = reinterpret_cast<jclass>(env->NewGlobalRef(localClass.get()));
@@ -99,7 +138,7 @@ static jobject makeStructStat(JNIEnv* env, const struct stat64& sb) {
}
static jobject doStat(JNIEnv* env, jstring javaPath, bool isLstat) {
- ScopedUtfChars path(env, javaPath);
+ ScopedRealUtf8Chars path(env, javaPath);
if (path.c_str() == NULL) {
return NULL;
}
@@ -167,9 +206,12 @@ static jobject Linux_stat(JNIEnv* env, jobject, jstring javaPath) {
return doStat(env, javaPath, false);
}
-static void nClose(JNIEnv* env, jclass, jint fd) {
- // Don't use TEMP_FAILURE_RETRY() on close(): https://lkml.org/lkml/2005/9/10/129
- throwIfMinusOne(env, "close", close(fd));
+static jint Linux_open(JNIEnv* env, jobject, jstring javaPath, jint flags, jint mode) {
+ ScopedRealUtf8Chars path(env, javaPath);
+ if (path.c_str() == NULL) {
+ return -1;
+ }
+ return throwIfMinusOne(env, "open", TEMP_FAILURE_RETRY(open(path.c_str(), flags, mode)));
}
// ---- Registration ----
@@ -184,7 +226,7 @@ static const JNINativeMethod sMethods[] =
{ "nFstat", "(I)Landroid/system/StructStat;", (void*)nFstat },
{ "lstat", "(Ljava/lang/String;)Landroid/system/StructStat;", (void*)Linux_lstat },
{ "stat", "(Ljava/lang/String;)Landroid/system/StructStat;", (void*)Linux_stat },
- { "nClose", "(I)V", (void*)nClose },
+ { "nOpen", "(Ljava/lang/String;II)I", (void*)Linux_open },
};
extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
diff --git a/services/Android.bp b/services/Android.bp
index dce6aa71daea..ded7379ad487 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -108,6 +108,8 @@ filegroup {
filegroup {
name: "services-non-updatable-sources",
srcs: [
+ ":incremental_aidl",
+ ":services.core-aidl-sources",
":services.core-sources",
":services.core-sources-am-wm",
"core/java/com/android/server/am/package.html",
@@ -377,4 +379,8 @@ non_updatable_exportable_droidstubs {
},
},
api_surface: "system-server",
+ sdk_version: "module_current",
+ libs: [
+ "framework-annotations-lib",
+ ],
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 099cb2894515..d16a66522e51 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -45,9 +45,11 @@ import android.view.accessibility.AccessibilityEvent;
import com.android.server.LocalServices;
import com.android.server.accessibility.gestures.TouchExplorer;
+import com.android.server.accessibility.magnification.FullScreenMagnificationController;
import com.android.server.accessibility.magnification.FullScreenMagnificationGestureHandler;
import com.android.server.accessibility.magnification.FullScreenMagnificationVibrationHelper;
import com.android.server.accessibility.magnification.MagnificationGestureHandler;
+import com.android.server.accessibility.magnification.MouseEventHandler;
import com.android.server.accessibility.magnification.WindowMagnificationGestureHandler;
import com.android.server.accessibility.magnification.WindowMagnificationPromptController;
import com.android.server.policy.WindowManagerPolicy;
@@ -864,15 +866,21 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
TYPE_MAGNIFICATION_OVERLAY, null /* options */);
FullScreenMagnificationVibrationHelper fullScreenMagnificationVibrationHelper =
new FullScreenMagnificationVibrationHelper(uiContext);
- magnificationGestureHandler = new FullScreenMagnificationGestureHandler(uiContext,
- mAms.getMagnificationController().getFullScreenMagnificationController(),
- mAms.getTraceManager(),
- mAms.getMagnificationController(),
- detectControlGestures,
- detectTwoFingerTripleTap,
- triggerable,
- new WindowMagnificationPromptController(displayContext, mUserId), displayId,
- fullScreenMagnificationVibrationHelper);
+ FullScreenMagnificationController controller =
+ mAms.getMagnificationController().getFullScreenMagnificationController();
+ magnificationGestureHandler =
+ new FullScreenMagnificationGestureHandler(
+ uiContext,
+ controller,
+ mAms.getTraceManager(),
+ mAms.getMagnificationController(),
+ detectControlGestures,
+ detectTwoFingerTripleTap,
+ triggerable,
+ new WindowMagnificationPromptController(displayContext, mUserId),
+ displayId,
+ fullScreenMagnificationVibrationHelper,
+ new MouseEventHandler(controller));
}
return magnificationGestureHandler;
}
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
index b5b998f6cd5e..6b6b39df24d7 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
@@ -1131,7 +1131,10 @@ public class FullScreenMagnificationController implements
}
if (isAlwaysOnMagnificationEnabled()) {
- zoomOutFromService(displayId);
+ if (!mControllerCtx.getContext().getResources().getBoolean(
+ R.bool.config_magnification_keep_zoom_level_when_context_changed)) {
+ zoomOutFromService(displayId);
+ }
} else {
reset(displayId, true);
}
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
index 159022b4076d..b052d23971ab 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
@@ -16,6 +16,8 @@
package com.android.server.accessibility.magnification;
+import static android.view.InputDevice.SOURCE_MOUSE;
+import static android.view.InputDevice.SOURCE_STYLUS;
import static android.view.InputDevice.SOURCE_TOUCHSCREEN;
import static android.view.MotionEvent.ACTION_CANCEL;
import static android.view.MotionEvent.ACTION_DOWN;
@@ -183,7 +185,10 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
private final int mMinimumVelocity;
private final int mMaximumVelocity;
- public FullScreenMagnificationGestureHandler(@UiContext Context context,
+ private MouseEventHandler mMouseEventHandler;
+
+ public FullScreenMagnificationGestureHandler(
+ @UiContext Context context,
FullScreenMagnificationController fullScreenMagnificationController,
AccessibilityTraceManager trace,
Callback callback,
@@ -192,7 +197,8 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
boolean detectShortcutTrigger,
@NonNull WindowMagnificationPromptController promptController,
int displayId,
- FullScreenMagnificationVibrationHelper fullScreenMagnificationVibrationHelper) {
+ FullScreenMagnificationVibrationHelper fullScreenMagnificationVibrationHelper,
+ MouseEventHandler mouseEventHandler) {
this(
context,
fullScreenMagnificationController,
@@ -207,9 +213,8 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
/* magnificationLogger= */ null,
ViewConfiguration.get(context),
new OneFingerPanningSettingsProvider(
- context,
- Flags.enableMagnificationOneFingerPanningGesture()
- ));
+ context, Flags.enableMagnificationOneFingerPanningGesture()),
+ mouseEventHandler);
}
/** Constructor for tests. */
@@ -227,8 +232,8 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
FullScreenMagnificationVibrationHelper fullScreenMagnificationVibrationHelper,
MagnificationLogger magnificationLogger,
ViewConfiguration viewConfiguration,
- OneFingerPanningSettingsProvider oneFingerPanningSettingsProvider
- ) {
+ OneFingerPanningSettingsProvider oneFingerPanningSettingsProvider,
+ MouseEventHandler mouseEventHandler) {
super(displayId, detectSingleFingerTripleTap, detectTwoFingerTripleTap,
detectShortcutTrigger, trace, callback);
if (DEBUG_ALL) {
@@ -318,6 +323,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
mOverscrollEdgeSlop = context.getResources().getDimensionPixelSize(
R.dimen.accessibility_fullscreen_magnification_gesture_edge_slop);
mIsWatch = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
+ mMouseEventHandler = mouseEventHandler;
if (mDetectShortcutTrigger) {
mScreenStateReceiver = new ScreenStateReceiver(context, this);
@@ -331,15 +337,28 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
@Override
void onMotionEventInternal(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
- if (event.getActionMasked() == ACTION_DOWN) {
- cancelFling();
- }
+ if (event.getSource() == SOURCE_TOUCHSCREEN) {
+ if (event.getActionMasked() == ACTION_DOWN) {
+ cancelFling();
+ }
+ handleTouchEventWith(mCurrentState, event, rawEvent, policyFlags);
+ } else if (Flags.enableMagnificationFollowsMouse()
+ && (event.getSource() == SOURCE_MOUSE || event.getSource() == SOURCE_STYLUS)) {
+ if (mFullScreenMagnificationController.isActivated(mDisplayId)) {
+ // TODO(b/354696546): Allow mouse/stylus to activate whichever display they are
+ // over, rather than only interacting with the current display.
- handleEventWith(mCurrentState, event, rawEvent, policyFlags);
+ // Send through the mouse/stylus event handler.
+ mMouseEventHandler.onEvent(event, mDisplayId);
+ }
+ // Dispatch to normal event handling flow.
+ dispatchTransformedEvent(event, rawEvent, policyFlags);
+ }
}
- private void handleEventWith(State stateHandler,
- MotionEvent event, MotionEvent rawEvent, int policyFlags) {
+ private void handleTouchEventWith(
+ State stateHandler, MotionEvent event, MotionEvent rawEvent, int policyFlags) {
+
// To keep InputEventConsistencyVerifiers within GestureDetectors happy
mPanningScalingState.mScrollGestureDetector.onTouchEvent(event);
mPanningScalingState.mScaleGestureDetector.onTouchEvent(event);
@@ -1421,6 +1440,11 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
protected void cacheDelayedMotionEvent(MotionEvent event, MotionEvent rawEvent,
int policyFlags) {
+ if (Flags.enableMagnificationFollowsMouse()
+ && !event.isFromSource(SOURCE_TOUCHSCREEN)) {
+ // Only touch events need to be cached and sent later.
+ return;
+ }
if (event.getActionMasked() == ACTION_DOWN) {
mPreLastDown = mLastDown;
mLastDown = MotionEvent.obtain(event);
@@ -1458,7 +1482,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
mDelayedEventQueue = info.mNext;
info.event.setDownTime(info.event.getDownTime() + offset);
- handleEventWith(mDelegatingState, info.event, info.rawEvent, info.policyFlags);
+ handleTouchEventWith(mDelegatingState, info.event, info.rawEvent, info.policyFlags);
info.recycle();
} while (mDelayedEventQueue != null);
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java
index 11d071345457..08411c22b943 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java
@@ -16,6 +16,8 @@
package com.android.server.accessibility.magnification;
+import static android.view.InputDevice.SOURCE_MOUSE;
+import static android.view.InputDevice.SOURCE_STYLUS;
import static android.view.InputDevice.SOURCE_TOUCHSCREEN;
import static android.view.MotionEvent.ACTION_CANCEL;
import static android.view.MotionEvent.ACTION_UP;
@@ -139,12 +141,35 @@ public abstract class MagnificationGestureHandler extends BaseEventStreamTransfo
}
}
+ /**
+ * Some touchscreen, mouse and stylus events may modify magnifier state. Checks for whether the
+ * event should not be dispatched to the magnifier.
+ *
+ * @param event The event to check.
+ * @return `true` if the event should be sent through the normal event flow or `false` if it
+ * should be observed by magnifier.
+ */
private boolean shouldDispatchTransformedEvent(MotionEvent event) {
- if ((!mDetectSingleFingerTripleTap && !mDetectTwoFingerTripleTap && !mDetectShortcutTrigger)
- || !event.isFromSource(SOURCE_TOUCHSCREEN)) {
- return true;
+ if (event.getSource() == SOURCE_TOUCHSCREEN) {
+ if (mDetectSingleFingerTripleTap
+ || mDetectTwoFingerTripleTap
+ || mDetectShortcutTrigger) {
+ // Observe touchscreen events while magnification activation is detected.
+ return false;
+ }
+ }
+ if (Flags.enableMagnificationFollowsMouse()) {
+ if (event.isFromSource(SOURCE_MOUSE) || event.isFromSource(SOURCE_STYLUS)) {
+ // Note that mouse events include other mouse-like pointing devices
+ // such as touchpads and pointing sticks.
+ // Observe any mouse or stylus movement.
+ // We observe all movement to ensure that events continue to come in order,
+ // even though only some movement types actually move the viewport.
+ return false;
+ }
}
- return false;
+ // Magnification dispatches (ignores) all other events
+ return true;
}
final void dispatchTransformedEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MouseEventHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/MouseEventHandler.java
new file mode 100644
index 000000000000..845249e2c82f
--- /dev/null
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MouseEventHandler.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.accessibility.magnification;
+
+import static android.view.InputDevice.SOURCE_MOUSE;
+import static android.view.MotionEvent.ACTION_HOVER_MOVE;
+import static android.view.MotionEvent.ACTION_MOVE;
+
+import android.view.MotionEvent;
+
+import com.android.server.accessibility.AccessibilityManagerService;
+
+/** MouseEventHandler handles mouse and stylus events that should move the viewport. */
+public final class MouseEventHandler {
+ private final FullScreenMagnificationController mFullScreenMagnificationController;
+
+ public MouseEventHandler(FullScreenMagnificationController fullScreenMagnificationController) {
+ mFullScreenMagnificationController = fullScreenMagnificationController;
+ }
+
+ /**
+ * Handles a mouse or stylus event, moving the magnifier if needed.
+ *
+ * @param event The mouse or stylus MotionEvent to consume
+ * @param displayId The display that is being magnified
+ */
+ public void onEvent(MotionEvent event, int displayId) {
+ if (event.getAction() == ACTION_HOVER_MOVE
+ || (event.getAction() == ACTION_MOVE && event.getSource() == SOURCE_MOUSE)) {
+ final float eventX = event.getX();
+ final float eventY = event.getY();
+
+ // Only move the viewport when over a magnified region.
+ // TODO(b/354696546): Ensure this doesn't stop the viewport from reaching the
+ // corners and edges at high levels of magnification.
+ if (mFullScreenMagnificationController.magnificationRegionContains(
+ displayId, eventX, eventY)) {
+ mFullScreenMagnificationController.setCenter(
+ displayId,
+ eventX,
+ eventY,
+ /* animate= */ false,
+ AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
+ }
+ }
+ }
+}
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
index 6f1141ff76ec..1818cddbcf4c 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
@@ -148,6 +148,10 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
@Override
void onMotionEventInternal(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
+ if (event.getSource() != SOURCE_TOUCHSCREEN) {
+ // Window Magnification viewport doesn't move with mouse events (yet).
+ return;
+ }
// To keep InputEventConsistencyVerifiers within GestureDetectors happy.
mObservePanningScalingState.mPanningScalingHandler.onTouchEvent(event);
mCurrentState.onMotionEvent(event, rawEvent, policyFlags);
diff --git a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
index 0bf931ce2633..e57817f8e7ee 100644
--- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
+++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
@@ -28,12 +28,12 @@ import android.annotation.UserIdInt;
import android.app.WindowConfiguration;
import android.app.compat.CompatChanges;
import android.companion.virtual.VirtualDeviceManager.ActivityListener;
-import android.companion.virtual.flags.Flags;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.content.AttributionSource;
import android.content.ComponentName;
import android.content.Intent;
+import android.content.IntentSender;
import android.content.pm.ActivityInfo;
import android.os.Build;
import android.os.Handler;
@@ -52,6 +52,7 @@ import com.android.modules.expresslog.Counter;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import java.util.function.Supplier;
/**
* A controller to control the policies of the windows that can be displayed on the virtual display.
@@ -74,7 +75,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
*/
public interface ActivityBlockedCallback {
/** Called when an activity is blocked.*/
- void onActivityBlocked(int displayId, ActivityInfo activityInfo);
+ void onActivityBlocked(int displayId, ActivityInfo activityInfo, IntentSender intentSender);
}
private static final ComponentName BLOCKED_APP_STREAMING_COMPONENT =
new ComponentName("android", BlockedAppStreamingActivity.class.getName());
@@ -113,7 +114,6 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
@NonNull
private final ArraySet<ComponentName> mCrossTaskNavigationExemptions;
@Nullable
- private final ComponentName mPermissionDialogComponent;
private final Object mGenericWindowPolicyControllerLock = new Object();
@Nullable private final ActivityBlockedCallback mActivityBlockedCallback;
@@ -178,7 +178,6 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
@NonNull Set<ComponentName> activityPolicyExemptions,
boolean crossTaskNavigationAllowedByDefault,
@NonNull Set<ComponentName> crossTaskNavigationExemptions,
- @Nullable ComponentName permissionDialogComponent,
@Nullable ActivityListener activityListener,
@Nullable ActivityBlockedCallback activityBlockedCallback,
@Nullable SecureWindowCallback secureWindowCallback,
@@ -193,7 +192,6 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
mActivityPolicyExemptions = new ArraySet<>(activityPolicyExemptions);
mCrossTaskNavigationAllowedByDefault = crossTaskNavigationAllowedByDefault;
mCrossTaskNavigationExemptions = new ArraySet<>(crossTaskNavigationExemptions);
- mPermissionDialogComponent = permissionDialogComponent;
mActivityBlockedCallback = activityBlockedCallback;
setInterestedWindowFlags(windowFlags, systemWindowFlags);
mActivityListener = activityListener;
@@ -286,29 +284,20 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
@Override
public boolean canActivityBeLaunched(@NonNull ActivityInfo activityInfo,
@Nullable Intent intent, @WindowConfiguration.WindowingMode int windowingMode,
- int launchingFromDisplayId, boolean isNewTask) {
- if (Flags.interceptIntentsBeforeApplyingPolicy()) {
- if (mIntentListenerCallback != null && intent != null
- && mIntentListenerCallback.shouldInterceptIntent(intent)) {
- logActivityLaunchBlocked("Virtual device intercepting intent");
- return false;
- }
- if (!canContainActivity(activityInfo, windowingMode, launchingFromDisplayId,
- isNewTask)) {
- notifyActivityBlocked(activityInfo);
- return false;
- }
- } else {
- if (!canContainActivity(activityInfo, windowingMode, launchingFromDisplayId,
- isNewTask)) {
- notifyActivityBlocked(activityInfo);
- return false;
- }
- if (mIntentListenerCallback != null && intent != null
- && mIntentListenerCallback.shouldInterceptIntent(intent)) {
- logActivityLaunchBlocked("Virtual device intercepting intent");
- return false;
- }
+ int launchingFromDisplayId, boolean isNewTask, boolean isResultExpected,
+ @Nullable Supplier<IntentSender> intentSender) {
+ if (mIntentListenerCallback != null && intent != null
+ && mIntentListenerCallback.shouldInterceptIntent(intent)) {
+ logActivityLaunchBlocked("Virtual device intercepting intent");
+ return false;
+ }
+ if (!canContainActivity(activityInfo, windowingMode, launchingFromDisplayId,
+ isNewTask)) {
+ // If the sender of the original intent expects a result to be reported, do not pass the
+ // intent sender to the client callback. As the launch is blocked, the caller already
+ // received that activity result.
+ notifyActivityBlocked(activityInfo, isResultExpected ? null : intentSender);
+ return false;
}
return true;
}
@@ -370,14 +359,6 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
return false;
}
- // mPermissionDialogComponent being null means we don't want to block permission Dialogs
- // based on FLAG_STREAM_PERMISSIONS
- if (mPermissionDialogComponent != null
- && mPermissionDialogComponent.equals(activityComponent)) {
- logActivityLaunchBlocked("Permission dialog not allowed on virtual device");
- return false;
- }
-
return true;
}
@@ -406,7 +387,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
// TODO(b/201712607): Add checks for the apps that use SurfaceView#setSecure.
if ((windowFlags & FLAG_SECURE) != 0
|| (systemWindowFlags & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) {
- notifyActivityBlocked(activityInfo);
+ notifyActivityBlocked(activityInfo, /* intentSender= */ null);
return false;
}
}
@@ -479,19 +460,19 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
&& mDisplayCategories.contains(activityInfo.requiredDisplayCategory);
}
- private void notifyActivityBlocked(ActivityInfo activityInfo) {
+ private void notifyActivityBlocked(
+ ActivityInfo activityInfo, Supplier<IntentSender> intentSender) {
int displayId = waitAndGetDisplayId();
// Don't trigger activity blocked callback for mirror displays, because we can't show
// any activity or presentation on it anyway.
if (!waitAndGetIsMirrorDisplay() && mActivityBlockedCallback != null
&& displayId != INVALID_DISPLAY) {
- mActivityBlockedCallback.onActivityBlocked(displayId, activityInfo);
- }
- if (android.companion.virtualdevice.flags.Flags.metricsCollection()) {
- Counter.logIncrementWithUid(
- "virtual_devices.value_activity_blocked_count",
- mAttributionSource.getUid());
+ mActivityBlockedCallback.onActivityBlocked(displayId, activityInfo,
+ intentSender == null ? null : intentSender.get());
}
+ Counter.logIncrementWithUid(
+ "virtual_devices.value_activity_blocked_count",
+ mAttributionSource.getUid());
}
private static boolean isAllowedByPolicy(boolean allowedByDefault,
diff --git a/services/companion/java/com/android/server/companion/virtual/InputController.java b/services/companion/java/com/android/server/companion/virtual/InputController.java
index d091ce89e885..8da58cfd6b23 100644
--- a/services/companion/java/com/android/server/companion/virtual/InputController.java
+++ b/services/companion/java/com/android/server/companion/virtual/InputController.java
@@ -842,11 +842,9 @@ class InputController {
deviceName, inputDeviceId));
}
- if (android.companion.virtualdevice.flags.Flags.metricsCollection()) {
- String metricId = getMetricIdForInputType(type);
- if (metricId != null) {
- Counter.logIncrementWithUid(metricId, mAttributionSource.getUid());
- }
+ String metricId = getMetricIdForInputType(type);
+ if (metricId != null) {
+ Counter.logIncrementWithUid(metricId, mAttributionSource.getUid());
}
}
diff --git a/services/companion/java/com/android/server/companion/virtual/SensorController.java b/services/companion/java/com/android/server/companion/virtual/SensorController.java
index 065568573558..8d075db1c168 100644
--- a/services/companion/java/com/android/server/companion/virtual/SensorController.java
+++ b/services/companion/java/com/android/server/companion/virtual/SensorController.java
@@ -145,11 +145,9 @@ public class SensorController {
mSensorDescriptors.put(sensorToken, sensorDescriptor);
mVirtualSensors.put(handle, sensor);
}
- if (android.companion.virtualdevice.flags.Flags.metricsCollection()) {
- Counter.logIncrementWithUid(
- "virtual_devices.value_virtual_sensors_created_count",
- mAttributionSource.getUid());
- }
+ Counter.logIncrementWithUid(
+ "virtual_devices.value_virtual_sensors_created_count",
+ mAttributionSource.getUid());
}
boolean sendSensorEvent(@NonNull IBinder token, @NonNull VirtualSensorEvent event) {
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index 29ddf64486bb..2db54435199b 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -29,8 +29,6 @@ import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CAMERA;
import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CLIPBOARD;
import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_RECENTS;
import static android.companion.virtualdevice.flags.Flags.virtualCameraServiceDiscovery;
-import static android.companion.virtualdevice.flags.Flags.intentInterceptionActionMatchingFix;
-import static android.content.pm.PackageManager.ACTION_REQUEST_PERMISSIONS;
import android.annotation.EnforcePermission;
import android.annotation.NonNull;
@@ -62,6 +60,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.IntentSender;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.graphics.PointF;
@@ -208,7 +207,6 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
@GuardedBy("mVirtualDeviceLock")
@NonNull
private final Set<ComponentName> mActivityPolicyExemptions;
- private final ComponentName mPermissionDialogComponent;
private ActivityListener createListenerAdapter() {
return new ActivityListener() {
@@ -244,9 +242,11 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
@Override
public void onActivityLaunchBlocked(int displayId,
- @NonNull ComponentName componentName, @UserIdInt int userId) {
+ @NonNull ComponentName componentName, @UserIdInt int userId,
+ @Nullable IntentSender intentSender) {
try {
- mActivityListener.onActivityLaunchBlocked(displayId, componentName, userId);
+ mActivityListener.onActivityLaunchBlocked(
+ displayId, componentName, userId, intentSender);
} catch (RemoteException e) {
Slog.w(TAG, "Unable to call mActivityListener for display: " + displayId, e);
}
@@ -343,11 +343,6 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
if (mCameraAccessController != null) {
mCameraAccessController.startObservingIfNeeded();
}
- if (!Flags.streamPermissions()) {
- mPermissionDialogComponent = getPermissionDialogComponent();
- } else {
- mPermissionDialogComponent = null;
- }
mVirtualCameraController = virtualCameraController;
try {
token.linkToDeath(this, 0);
@@ -1298,7 +1293,6 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
/* crossTaskNavigationExemptions= */crossTaskNavigationAllowedByDefault
? mParams.getBlockedCrossTaskNavigations()
: mParams.getAllowedCrossTaskNavigations(),
- mPermissionDialogComponent,
mActivityListenerAdapter,
this::onActivityBlocked,
this::onSecureWindowShown,
@@ -1310,13 +1304,6 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
return gwpc;
}
- private ComponentName getPermissionDialogComponent() {
- Intent intent = new Intent(ACTION_REQUEST_PERMISSIONS);
- PackageManager packageManager = mContext.getPackageManager();
- intent.setPackage(packageManager.getPermissionControllerPackageName());
- return intent.resolveActivity(packageManager);
- }
-
int createVirtualDisplay(@NonNull VirtualDisplayConfig virtualDisplayConfig,
@NonNull IVirtualDisplayCallback callback, String packageName) {
GenericWindowPolicyController gwpc;
@@ -1328,7 +1315,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
this, gwpc, packageName);
gwpc.setDisplayId(displayId, /* isMirrorDisplay= */ Flags.interactiveScreenMirror()
&& mDisplayManagerInternal.getDisplayIdToMirror(displayId)
- != Display.INVALID_DISPLAY);
+ != Display.INVALID_DISPLAY);
boolean showPointer;
synchronized (mVirtualDeviceLock) {
@@ -1359,11 +1346,9 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
Binder.restoreCallingIdentity(token);
}
- if (android.companion.virtualdevice.flags.Flags.metricsCollection()) {
- Counter.logIncrementWithUid(
- "virtual_devices.value_virtual_display_created_count",
- mAttributionSource.getUid());
- }
+ Counter.logIncrementWithUid(
+ "virtual_devices.value_virtual_display_created_count",
+ mAttributionSource.getUid());
return displayId;
}
@@ -1382,7 +1367,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
}
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
- private void onActivityBlocked(int displayId, ActivityInfo activityInfo) {
+ private void onActivityBlocked(int displayId, ActivityInfo activityInfo,
+ IntentSender intentSender) {
Intent intent = BlockedAppStreamingActivity.createIntent(activityInfo, getDisplayName());
if (shouldShowBlockedActivityDialog(
activityInfo.getComponentName(), intent.getComponent())) {
@@ -1398,7 +1384,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
displayId,
activityInfo.getComponentName(),
UserHandle.getUserHandleForUid(
- activityInfo.applicationInfo.uid).getIdentifier());
+ activityInfo.applicationInfo.uid).getIdentifier(),
+ intentSender);
}
}
@@ -1431,11 +1418,9 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
showToastWhereUidIsRunning(uid, com.android.internal.R.string.vdm_secure_window,
Toast.LENGTH_LONG, mContext.getMainLooper());
- if (android.companion.virtualdevice.flags.Flags.metricsCollection()) {
- Counter.logIncrementWithUid(
- "virtual_devices.value_secure_window_blocked_count",
- mAttributionSource.getUid());
- }
+ Counter.logIncrementWithUid(
+ "virtual_devices.value_secure_window_blocked_count",
+ mAttributionSource.getUid());
}
}
@@ -1638,8 +1623,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
// Explicitly match the actions because the intent filter will match any intent
// without an explicit action. If the intent has no action, then require that there
// are no actions specified in the filter either.
- boolean explicitActionMatch = !intentInterceptionActionMatchingFix()
- || intent.getAction() != null || intentFilter.countActions() == 0;
+ boolean explicitActionMatch =
+ intent.getAction() != null || intentFilter.countActions() == 0;
if (explicitActionMatch && intentFilter.match(
intent.getAction(), intent.getType(), intent.getScheme(), intent.getData(),
intent.getCategories(), TAG) >= 0) {
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
index 1be1d2b1286b..3cd1ca4c6486 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
@@ -474,9 +474,7 @@ public class VirtualDeviceManagerService extends SystemService {
deviceId,
cameraAccessController, mPendingTrampolineCallback, activityListener,
soundEffectListener, runningAppsChangedCallback, params);
- if (Flags.expressMetrics()) {
- Counter.logIncrement("virtual_devices.value_virtual_devices_created_count");
- }
+ Counter.logIncrement("virtual_devices.value_virtual_devices_created_count");
synchronized (mVirtualDeviceManagerLock) {
if (!Flags.persistentDeviceIdApi() && mVirtualDevices.size() == 0) {
@@ -500,11 +498,9 @@ public class VirtualDeviceManagerService extends SystemService {
}
});
}
- if (android.companion.virtualdevice.flags.Flags.metricsCollection()) {
- Counter.logIncrementWithUid(
- "virtual_devices.value_virtual_devices_created_with_uid_count",
- attributionSource.getUid());
- }
+ Counter.logIncrementWithUid(
+ "virtual_devices.value_virtual_devices_created_with_uid_count",
+ attributionSource.getUid());
return virtualDevice;
}
diff --git a/services/companion/java/com/android/server/companion/virtual/audio/VirtualAudioController.java b/services/companion/java/com/android/server/companion/virtual/audio/VirtualAudioController.java
index 4bffb76e1701..d3b39452bf3c 100644
--- a/services/companion/java/com/android/server/companion/virtual/audio/VirtualAudioController.java
+++ b/services/companion/java/com/android/server/companion/virtual/audio/VirtualAudioController.java
@@ -77,11 +77,9 @@ public final class VirtualAudioController implements AudioPlaybackCallback,
mAudioPlaybackDetector = new AudioPlaybackDetector(context);
mAudioRecordingDetector = new AudioRecordingDetector(context);
- if (android.companion.virtualdevice.flags.Flags.metricsCollection()) {
- Counter.logIncrementWithUid(
- "virtual_devices.value_virtual_audio_created_count",
- attributionSource.getUid());
- }
+ Counter.logIncrementWithUid(
+ "virtual_devices.value_virtual_audio_created_count",
+ attributionSource.getUid());
}
/**
diff --git a/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraController.java b/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraController.java
index 62efafbe12c6..7b81ef3ef73f 100644
--- a/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraController.java
+++ b/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraController.java
@@ -102,11 +102,9 @@ public final class VirtualCameraController implements IBinder.DeathRecipient {
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
- if (android.companion.virtualdevice.flags.Flags.metricsCollection()) {
- Counter.logIncrementWithUid(
- "virtual_devices.value_virtual_camera_created_count",
- attributionSource.getUid());
- }
+ Counter.logIncrementWithUid(
+ "virtual_devices.value_virtual_camera_created_count",
+ attributionSource.getUid());
}
/**
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 363c1d8c5f04..89d796177da2 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -30,6 +30,18 @@ filegroup {
],
}
+filegroup {
+ name: "services.core-aidl-sources",
+ srcs: [
+ ":dumpstate_aidl",
+ ":framework_native_aidl",
+ ":gsiservice_aidl",
+ ":installd_aidl",
+ ":storaged_aidl",
+ ":vold_aidl",
+ ],
+}
+
java_library_static {
name: "services-config-update",
srcs: [
@@ -120,14 +132,9 @@ java_library_static {
":android.hardware.tv.hdmi.earc-V1-java-source",
":statslog-art-java-gen",
":statslog-contexthub-java-gen",
+ ":services.core-aidl-sources",
":services.core-sources",
":services.core.protologsrc",
- ":dumpstate_aidl",
- ":framework_native_aidl",
- ":gsiservice_aidl",
- ":installd_aidl",
- ":storaged_aidl",
- ":vold_aidl",
":platform-compat-config",
":platform-compat-overrides",
":display-device-config",
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 1ccc48d44f99..2de44820ec05 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -157,7 +157,7 @@ public final class BatteryService extends SystemService {
private int mLastMaxChargingVoltage;
private int mLastChargeCounter;
private int mLastBatteryCycleCount;
- private int mLastCharingState;
+ private int mLastChargingState;
/**
* The last seen charging policy. This requires the
* {@link android.Manifest.permission#BATTERY_STATS} permission and should therefore not be
@@ -555,7 +555,7 @@ public final class BatteryService extends SystemService {
|| mHealthInfo.batteryChargeCounterUah != mLastChargeCounter
|| mInvalidCharger != mLastInvalidCharger
|| mHealthInfo.batteryCycleCount != mLastBatteryCycleCount
- || mHealthInfo.chargingState != mLastCharingState)) {
+ || mHealthInfo.chargingState != mLastChargingState)) {
if (mPlugType != mLastPlugType) {
if (mLastPlugType == BATTERY_PLUGGED_NONE) {
@@ -738,7 +738,7 @@ public final class BatteryService extends SystemService {
mLastBatteryLevelCritical = mBatteryLevelCritical;
mLastInvalidCharger = mInvalidCharger;
mLastBatteryCycleCount = mHealthInfo.batteryCycleCount;
- mLastCharingState = mHealthInfo.chargingState;
+ mLastChargingState = mHealthInfo.chargingState;
}
}
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 33cf84220009..79e09d736b97 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -2229,7 +2229,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
for (Record r : mRecords) {
if (r.matchTelephonyCallbackEvent(
TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED)
- && idMatch(r, subId, phoneId)) {
+ && idMatchRelaxed(r, subId, phoneId)) {
try {
r.callback.onPreciseDataConnectionStateChanged(preciseState);
} catch (RemoteException ex) {
@@ -3535,6 +3535,10 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
synchronized (mRecords) {
int phoneId = getPhoneIdFromSubId(subId);
+ if (!validatePhoneId(phoneId)) {
+ loge("Invalid phone ID " + phoneId + " for " + subId);
+ return;
+ }
mCarrierRoamingNtnMode[phoneId] = active;
for (Record r : mRecords) {
if (r.matchTelephonyCallbackEvent(
@@ -3582,6 +3586,10 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
synchronized (mRecords) {
int phoneId = getPhoneIdFromSubId(subId);
+ if (!validatePhoneId(phoneId)) {
+ loge("Invalid phone ID " + phoneId + " for " + subId);
+ return;
+ }
mCarrierRoamingNtnEligible[phoneId] = eligible;
for (Record r : mRecords) {
if (r.matchTelephonyCallbackEvent(
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index cf0befaab98d..9d8f3374d6ad 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1716,6 +1716,12 @@ public class ActivityManagerService extends IActivityManager.Stub
*/
@Nullable volatile ContentCaptureManagerInternal mContentCaptureService;
+ /**
+ * The interface to the freezer.
+ */
+ @NonNull
+ private final Freezer mFreezer;
+
/*
* The default duration for the binder heavy hitter auto sampler
*/
@@ -2506,6 +2512,7 @@ public class ActivityManagerService extends IActivityManager.Stub
@Nullable UserController userController) {
mInjector = injector;
mContext = mInjector.getContext();
+ mFreezer = injector.getFreezer();
mUiContext = null;
mAppErrors = injector.getAppErrors();
mPackageWatchdog = null;
@@ -2555,6 +2562,7 @@ public class ActivityManagerService extends IActivityManager.Stub
LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
mInjector = new Injector(systemContext);
mContext = systemContext;
+ mFreezer = mInjector.getFreezer();
mFactoryTest = FactoryTest.getMode();
mSystemThread = ActivityThread.currentActivityThread();
@@ -18436,6 +18444,23 @@ public class ActivityManagerService extends IActivityManager.Stub
implements ActivityManagerLocal {
@Override
+ public void addFrozenProcessListener(int pid, @NonNull Executor executor,
+ @NonNull FrozenProcessListener listener) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(listener);
+ synchronized (mProcLock) {
+ final ProcessRecord app;
+ synchronized (mPidsSelfLocked) {
+ app = mPidsSelfLocked.get(pid);
+ }
+ if (app != null) {
+ mOomAdjuster.mCachedAppOptimizer.addFrozenProcessListener(app, executor,
+ listener);
+ }
+ }
+ }
+
+ @Override
public List<PendingIntentStats> getPendingIntentStats() {
return mPendingIntentController.dumpPendingIntentStatsForStatsd();
}
@@ -20919,6 +20944,11 @@ public class ActivityManagerService extends IActivityManager.Stub
public IntentFirewall getIntentFirewall() {
return null;
}
+
+ /** @return the default Freezer. */
+ public Freezer getFreezer() {
+ return new Freezer();
+ }
}
@Override
@@ -21022,7 +21052,7 @@ public class ActivityManagerService extends IActivityManager.Stub
final long token = Binder.clearCallingIdentity();
try {
- return CachedAppOptimizer.isFreezerSupported();
+ return mFreezer.isFreezerSupported();
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -21177,4 +21207,9 @@ public class ActivityManagerService extends IActivityManager.Stub
void clearPendingTopAppLocked() {
mPendingStartActivityUids.clear();
}
+
+ @NonNull
+ Freezer getFreezer() {
+ return mFreezer;
+ }
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index bbd432340e8f..0e19347163f1 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -1234,8 +1234,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
if (freeze) {
mInternal.mOomAdjuster.mCachedAppOptimizer.forceFreezeAppAsyncLSP(proc);
} else {
- mInternal.mOomAdjuster.mCachedAppOptimizer.unfreezeAppInternalLSP(proc, 0,
- true);
+ mInternal.mOomAdjuster.mCachedAppOptimizer.unfreezeAppLSP(proc, 0, true);
}
}
}
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index 1c4ffbb812a4..8f52f67ff7e0 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -49,6 +49,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import android.annotation.IntDef;
import android.annotation.UptimeMillisLong;
import android.app.ActivityManager;
+import android.app.ActivityManagerInternal.FrozenProcessListener;
import android.app.ActivityManagerInternal.OomAdjReason;
import android.app.ActivityThread;
import android.app.ApplicationExitInfo;
@@ -99,6 +100,7 @@ import java.util.LinkedList;
import java.util.Map;
import java.util.Random;
import java.util.Set;
+import java.util.concurrent.Executor;
public final class CachedAppOptimizer {
@@ -664,6 +666,8 @@ public final class CachedAppOptimizer {
private final ProcessDependencies mProcessDependencies;
private final ProcLocksReader mProcLocksReader;
+ private final Freezer mFreezer;
+
public CachedAppOptimizer(ActivityManagerService am) {
this(am, null, new DefaultProcessDependencies());
}
@@ -680,6 +684,7 @@ public final class CachedAppOptimizer {
mTestCallback = callback;
mSettingsObserver = new SettingsContentObserver();
mProcLocksReader = new ProcLocksReader();
+ mFreezer = mAm.getFreezer();
}
/**
@@ -1050,89 +1055,6 @@ public final class CachedAppOptimizer {
}
/**
- * Informs binder that a process is about to be frozen. If freezer is enabled on a process via
- * this method, this method will synchronously dispatch all pending transactions to the
- * specified pid. This method will not add significant latencies when unfreezing.
- * After freezing binder calls, binder will block all transaction to the frozen pid, and return
- * an error to the sending process.
- *
- * @param pid the target pid for which binder transactions are to be frozen
- * @param freeze specifies whether to flush transactions and then freeze (true) or unfreeze
- * binder for the specificed pid.
- * @param timeoutMs the timeout in milliseconds to wait for the binder interface to freeze
- * before giving up.
- *
- * @throws RuntimeException in case a flush/freeze operation could not complete successfully.
- * @return 0 if success, or -EAGAIN indicating there's pending transaction.
- */
- public static native int freezeBinder(int pid, boolean freeze, int timeoutMs);
-
- /**
- * Retrieves binder freeze info about a process.
- * @param pid the pid for which binder freeze info is to be retrieved.
- *
- * @throws RuntimeException if the operation could not complete successfully.
- * @return a bit field reporting the binder freeze info for the process.
- */
- private static native int getBinderFreezeInfo(int pid);
-
- /**
- * Returns the path to be checked to verify whether the freezer is supported by this system.
- * @return absolute path to the file
- */
- private static native String getFreezerCheckPath();
-
- /**
- * Check if task_profiles.json includes valid freezer profiles and actions
- * @return false if there are invalid profiles or actions
- */
- private static native boolean isFreezerProfileValid();
-
- /**
- * Determines whether the freezer is supported by this system
- */
- public static boolean isFreezerSupported() {
- boolean supported = false;
- FileReader fr = null;
-
- try {
- String path = getFreezerCheckPath();
- Slog.d(TAG_AM, "Checking cgroup freezer: " + path);
- fr = new FileReader(path);
- char state = (char) fr.read();
-
- if (state == '1' || state == '0') {
- // Also check freezer binder ioctl
- Slog.d(TAG_AM, "Checking binder freezer ioctl");
- getBinderFreezeInfo(Process.myPid());
-
- // Check if task_profiles.json contains invalid profiles
- Slog.d(TAG_AM, "Checking freezer profiles");
- supported = isFreezerProfileValid();
- } else {
- Slog.e(TAG_AM, "Unexpected value in cgroup.freeze");
- }
- } catch (java.io.FileNotFoundException e) {
- Slog.w(TAG_AM, "File cgroup.freeze not present");
- } catch (RuntimeException e) {
- Slog.w(TAG_AM, "Unable to read freezer info");
- } catch (Exception e) {
- Slog.w(TAG_AM, "Unable to read cgroup.freeze: " + e.toString());
- }
-
- if (fr != null) {
- try {
- fr.close();
- } catch (java.io.IOException e) {
- Slog.e(TAG_AM, "Exception closing cgroup.freeze: " + e.toString());
- }
- }
-
- Slog.d(TAG_AM, "Freezer supported: " + supported);
- return supported;
- }
-
- /**
* Reads the flag value from DeviceConfig to determine whether app freezer
* should be enabled, and starts the freeze/compaction thread if needed.
*/
@@ -1146,7 +1068,7 @@ public final class CachedAppOptimizer {
} else if ("enabled".equals(configOverride)
|| DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT,
KEY_USE_FREEZER, DEFAULT_USE_FREEZER)) {
- mUseFreezer = isFreezerSupported();
+ mUseFreezer = mFreezer.isFreezerSupported();
updateFreezerDebounceTimeout();
updateFreezerExemptInstPkg();
} else {
@@ -1486,8 +1408,15 @@ public final class CachedAppOptimizer {
}
}
+ /**
+ * Returns true if the app was frozen and became unfrozen, otherwise false.
+ *
+ * Do not call this directly. It will unfreeze a process but it will not send out any
+ * notifications. Instead call unfreezeAppLSP().
+ */
@GuardedBy({"mAm", "mProcLock", "mFreezerLock"})
- void unfreezeAppInternalLSP(ProcessRecord app, @UnfreezeReason int reason, boolean force) {
+ private boolean unfreezeAppInternalLSP(ProcessRecord app, @UnfreezeReason int reason,
+ boolean force) {
final int pid = app.getPid();
final ProcessCachedOptimizerRecord opt = app.mOptRecord;
boolean sticky = opt.isFreezeSticky();
@@ -1498,7 +1427,7 @@ public final class CachedAppOptimizer {
"Skip unfreezing because frozen state is sticky pid=" + pid + " "
+ app.processName);
}
- return;
+ return false;
}
boolean processFreezableChangeReported = false;
if (opt.isPendingFreeze()) {
@@ -1520,7 +1449,7 @@ public final class CachedAppOptimizer {
opt.setFreezerOverride(false);
if (pid == 0 || !opt.isFrozen()) {
- return;
+ return false;
}
// Unfreeze the binder interface first, to avoid transactions triggered by timers fired
@@ -1528,7 +1457,7 @@ public final class CachedAppOptimizer {
boolean processKilled = false;
try {
- int freezeInfo = getBinderFreezeInfo(pid);
+ int freezeInfo = mFreezer.getBinderFreezeInfo(pid);
if ((freezeInfo & SYNC_RECEIVED_WHILE_FROZEN) != 0) {
Slog.d(TAG_AM, "pid " + pid + " " + app.processName
@@ -1553,7 +1482,7 @@ public final class CachedAppOptimizer {
}
if (processKilled) {
- return;
+ return false;
}
if (!processFreezableChangeReported) {
reportProcessFreezableChangedLocked(app);
@@ -1562,19 +1491,19 @@ public final class CachedAppOptimizer {
long freezeTime = opt.getFreezeUnfreezeTime();
try {
- freezeBinder(pid, false, FREEZE_BINDER_TIMEOUT_MS);
+ mFreezer.freezeBinder(pid, false, FREEZE_BINDER_TIMEOUT_MS);
} catch (RuntimeException e) {
Slog.e(TAG_AM, "Unable to unfreeze binder for " + pid + " " + app.processName
+ ". Killing it");
app.killLocked("Unable to unfreeze",
ApplicationExitInfo.REASON_FREEZER,
ApplicationExitInfo.SUBREASON_FREEZER_BINDER_IOCTL, true);
- return;
+ return false;
}
try {
traceAppFreeze(app.processName, pid, reason);
- Process.setProcessFrozen(pid, app.uid, false);
+ mFreezer.setProcessFrozen(pid, app.uid, false);
opt.setFreezeUnfreezeTime(SystemClock.uptimeMillis());
opt.setFrozen(false);
@@ -1592,16 +1521,27 @@ public final class CachedAppOptimizer {
pid,
(int) Math.min(opt.getFreezeUnfreezeTime() - freezeTime, Integer.MAX_VALUE),
new Pair<ProcessRecord, Integer>(app, reason)));
+ return true;
}
+ return false;
}
@GuardedBy({"mAm", "mProcLock"})
- void unfreezeAppLSP(ProcessRecord app, @UnfreezeReason int reason) {
+ void unfreezeAppLSP(ProcessRecord app, @UnfreezeReason int reason, boolean force) {
+ final boolean shouldDispatch;
synchronized (mFreezerLock) {
- unfreezeAppInternalLSP(app, reason, false);
+ shouldDispatch = unfreezeAppInternalLSP(app, reason, force);
+ }
+ if (shouldDispatch) {
+ app.mOptRecord.dispatchUnfrozenEvent();
}
}
+ @GuardedBy({"mAm", "mProcLock"})
+ void unfreezeAppLSP(ProcessRecord app, @UnfreezeReason int reason) {
+ unfreezeAppLSP(app, reason, false);
+ }
+
/**
* This quick function works around the race condition between WM/ATMS and AMS, allowing
* the former to directly unfreeze a frozen process before the latter runs updateOomAdj.
@@ -1610,14 +1550,15 @@ public final class CachedAppOptimizer {
* @param pid pid of the process to be unfrozen
*/
void unfreezeProcess(int pid, @OomAdjReason int reason) {
+ final ProcessRecord app;
synchronized (mFreezerLock) {
- ProcessRecord app = mFrozenProcesses.get(pid);
+ app = mFrozenProcesses.get(pid);
if (app == null) {
return;
}
Slog.d(TAG_AM, "quick sync unfreeze " + pid + " for " + reason);
try {
- freezeBinder(pid, false, FREEZE_BINDER_TIMEOUT_MS);
+ mFreezer.freezeBinder(pid, false, FREEZE_BINDER_TIMEOUT_MS);
} catch (RuntimeException e) {
Slog.e(TAG_AM, "Unable to quick unfreeze binder for " + pid);
return;
@@ -1625,11 +1566,12 @@ public final class CachedAppOptimizer {
try {
traceAppFreeze(app.processName, pid, reason);
- Process.setProcessFrozen(pid, app.uid, false);
+ mFreezer.setProcessFrozen(pid, app.uid, false);
} catch (Exception e) {
Slog.e(TAG_AM, "Unable to quick unfreeze " + pid);
}
}
+ app.mOptRecord.dispatchUnfrozenEvent();
}
/**
@@ -2394,7 +2336,7 @@ public final class CachedAppOptimizer {
// Freeze binder interface before the process, to flush any
// transactions that might be pending.
try {
- if (freezeBinder(pid, true, FREEZE_BINDER_TIMEOUT_MS) != 0) {
+ if (mFreezer.freezeBinder(pid, true, FREEZE_BINDER_TIMEOUT_MS) != 0) {
handleBinderFreezerFailure(proc, "outstanding txns");
return;
}
@@ -2413,7 +2355,7 @@ public final class CachedAppOptimizer {
try {
traceAppFreeze(proc.processName, pid, -1);
- Process.setProcessFrozen(pid, proc.uid, true);
+ mFreezer.setProcessFrozen(pid, proc.uid, true);
opt.setFreezeUnfreezeTime(SystemClock.uptimeMillis());
opt.setFrozen(true);
opt.setHasCollectedFrozenPSS(false);
@@ -2452,7 +2394,7 @@ public final class CachedAppOptimizer {
try {
// post-check to prevent races
- int freezeInfo = getBinderFreezeInfo(pid);
+ int freezeInfo = mFreezer.getBinderFreezeInfo(pid);
if ((freezeInfo & TXNS_PENDING_WHILE_FROZEN) != 0) {
synchronized (mProcLock) {
@@ -2470,6 +2412,7 @@ public final class CachedAppOptimizer {
}
});
}
+ opt.dispatchFrozenEvent();
}
private void reportUnfreeze(ProcessRecord app, int pid, int frozenDuration,
@@ -2620,6 +2563,22 @@ public final class CachedAppOptimizer {
}
/**
+ * Freeze or unfreeze a process. This should only be used for testing.
+ */
+ @VisibleForTesting
+ void forceFreezeForTest(ProcessRecord proc, boolean freeze) {
+ synchronized (mAm) {
+ synchronized (mProcLock) {
+ if (freeze) {
+ forceFreezeAppAsyncLSP(proc);
+ } else {
+ unfreezeAppLSP(proc, UNFREEZE_REASON_NONE, true);
+ }
+ }
+ }
+ }
+
+ /**
* Sending binder transactions to frozen apps most likely indicates there's a bug. Log it and
* kill the frozen apps if they 1) receive sync binder transactions while frozen, or 2) miss
* async binder transactions due to kernel binder buffer running out.
@@ -2660,7 +2619,7 @@ public final class CachedAppOptimizer {
for (int i = 0; i < pids.size(); i++) {
int current = pids.get(i);
try {
- int freezeInfo = getBinderFreezeInfo(current);
+ int freezeInfo = mFreezer.getBinderFreezeInfo(current);
if ((freezeInfo & SYNC_RECEIVED_WHILE_FROZEN) != 0) {
killProcess(current, "Sync transaction while frozen",
@@ -2716,4 +2675,12 @@ public final class CachedAppOptimizer {
exception -> Slog.e(TAG_AM, "Unable to parse binderfs stats"));
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
+
+ /**
+ * Register a callback to notify when a process's frozen state changes.
+ */
+ public void addFrozenProcessListener(ProcessRecord app, Executor executor,
+ FrozenProcessListener listener) {
+ app.mOptRecord.addFrozenProcessListener(executor, listener);
+ }
}
diff --git a/services/core/java/com/android/server/am/ContentProviderHelper.java b/services/core/java/com/android/server/am/ContentProviderHelper.java
index afb7bb447be1..13145214c1c1 100644
--- a/services/core/java/com/android/server/am/ContentProviderHelper.java
+++ b/services/core/java/com/android/server/am/ContentProviderHelper.java
@@ -1806,10 +1806,12 @@ public class ContentProviderHelper {
ActivityManagerService.WAIT_FOR_CONTENT_PROVIDER_TIMEOUT_MSG, cpr);
}
final int userId = UserHandle.getUserId(cpr.uid);
+ boolean removed = false;
// Don't remove from provider map if it doesn't match
// could be a new content provider is starting
if (mProviderMap.getProviderByClass(cpr.name, userId) == cpr) {
mProviderMap.removeProviderByClass(cpr.name, userId);
+ removed = true;
}
String[] names = cpr.info.authority.split(";");
for (int j = 0; j < names.length; j++) {
@@ -1817,8 +1819,12 @@ public class ContentProviderHelper {
// could be a new content provider is starting
if (mProviderMap.getProviderByName(names[j], userId) == cpr) {
mProviderMap.removeProviderByName(names[j], userId);
+ removed = true;
}
}
+ if (removed && cpr.proc != null) {
+ cpr.proc.mProviders.removeProvider(cpr.info.name);
+ }
}
for (int i = cpr.connections.size() - 1; i >= 0; i--) {
diff --git a/services/core/java/com/android/server/am/Freezer.java b/services/core/java/com/android/server/am/Freezer.java
new file mode 100644
index 000000000000..3b3cf5509e10
--- /dev/null
+++ b/services/core/java/com/android/server/am/Freezer.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
+
+import android.os.Process;
+
+/**
+ * A collection of interfaces to manage the freezer. All access to the freezer goes through an
+ * instance of this class. The class can be overridden for testing.
+ *
+ * Methods may be called without external synchronization. Multiple instances of this class can be
+ * used concurrently.
+ */
+class Freezer {
+
+ /**
+ * Freeze or unfreeze the specified process.
+ *
+ * @param pid Identifier of the process to freeze or unfreeze.
+ * @param uid Identifier of the user the process is running under.
+ * @param frozen Specify whether to free (true) or unfreeze (false).
+ */
+ public void setProcessFrozen(int pid, int uid, boolean frozen) {
+ Process.setProcessFrozen(pid, uid, frozen);
+ }
+
+ /**
+ * Informs binder that a process is about to be frozen. If freezer is enabled on a process via
+ * this method, this method will synchronously dispatch all pending transactions to the
+ * specified pid. This method will not add significant latencies when unfreezing.
+ * After freezing binder calls, binder will block all transaction to the frozen pid, and return
+ * an error to the sending process.
+ *
+ * @param pid the target pid for which binder transactions are to be frozen
+ * @param freeze specifies whether to flush transactions and then freeze (true) or unfreeze
+ * binder for the specified pid.
+ * @param timeoutMs the timeout in milliseconds to wait for the binder interface to freeze
+ * before giving up.
+ *
+ * @throws RuntimeException in case a flush/freeze operation could not complete successfully.
+ * @return 0 if success, or -EAGAIN indicating there's pending transaction.
+ */
+ public int freezeBinder(int pid, boolean freeze, int timeoutMs) {
+ return nativeFreezeBinder(pid, freeze, timeoutMs);
+ }
+
+ /**
+ * Retrieves binder freeze info about a process.
+ * @param pid the pid for which binder freeze info is to be retrieved.
+ *
+ * @throws RuntimeException if the operation could not complete successfully.
+ * @return a bit field reporting the binder freeze info for the process.
+ */
+ public int getBinderFreezeInfo(int pid) {
+ return nativeGetBinderFreezeInfo(pid);
+ }
+
+ /**
+ * Determines whether the freezer is supported by this system.
+ * @return true if the freezer is supported.
+ */
+ public boolean isFreezerSupported() {
+ return nativeIsFreezerSupported();
+ }
+
+ // Native methods
+
+ /**
+ * Informs binder that a process is about to be frozen. If freezer is enabled on a process via
+ * this method, this method will synchronously dispatch all pending transactions to the
+ * specified pid. This method will not add significant latencies when unfreezing.
+ * After freezing binder calls, binder will block all transaction to the frozen pid, and return
+ * an error to the sending process.
+ *
+ * @param pid the target pid for which binder transactions are to be frozen
+ * @param freeze specifies whether to flush transactions and then freeze (true) or unfreeze
+ * binder for the specified pid.
+ * @param timeoutMs the timeout in milliseconds to wait for the binder interface to freeze
+ * before giving up.
+ *
+ * @throws RuntimeException in case a flush/freeze operation could not complete successfully.
+ * @return 0 if success, or -EAGAIN indicating there's pending transaction.
+ */
+ private static native int nativeFreezeBinder(int pid, boolean freeze, int timeoutMs);
+
+ /**
+ * Retrieves binder freeze info about a process.
+ * @param pid the pid for which binder freeze info is to be retrieved.
+ *
+ * @throws RuntimeException if the operation could not complete successfully.
+ * @return a bit field reporting the binder freeze info for the process.
+ */
+ private static native int nativeGetBinderFreezeInfo(int pid);
+
+ /**
+ * Return 0 if the freezer is supported on this platform and -1 otherwise.
+ */
+ private static native boolean nativeIsFreezerSupported();
+}
diff --git a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
index 53643b867b9e..57a5e3f0c302 100644
--- a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
+++ b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
@@ -19,6 +19,8 @@ package com.android.server.am;
import android.annotation.IntDef;
import android.annotation.UptimeMillisLong;
import android.app.ActivityManagerInternal.OomAdjReason;
+import android.app.ActivityManagerInternal.FrozenProcessListener;
+import android.util.Pair;
import android.util.TimeUtils;
import com.android.internal.annotations.GuardedBy;
@@ -29,6 +31,8 @@ import dalvik.annotation.optimization.NeverCompile;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executor;
/**
* The state info of app when it's cached, used by the optimizer.
@@ -165,6 +169,12 @@ final class ProcessCachedOptimizerRecord {
@GuardedBy("mProcLock")
private long mLastUsedTimeout;
+ /**
+ * The list of callbacks for this process whenever it is frozen or unfrozen.
+ */
+ final CopyOnWriteArrayList<Pair<Executor, FrozenProcessListener>> mFrozenProcessListeners =
+ new CopyOnWriteArrayList<>();
+
@GuardedBy("mProcLock")
long getLastCompactTime() {
return mLastCompactTime;
@@ -386,6 +396,22 @@ final class ProcessCachedOptimizerRecord {
mFreezeExempt = exempt;
}
+ void addFrozenProcessListener(Executor executor, FrozenProcessListener listener) {
+ mFrozenProcessListeners.add(new Pair<Executor, FrozenProcessListener>(executor, listener));
+ }
+
+ void dispatchFrozenEvent() {
+ mFrozenProcessListeners.forEach((pair) -> {
+ pair.first.execute(() -> pair.second.onProcessFrozen(mApp.mPid));
+ });
+ }
+
+ void dispatchUnfrozenEvent() {
+ mFrozenProcessListeners.forEach((pair) -> {
+ pair.first.execute(() -> pair.second.onProcessUnfrozen(mApp.mPid));
+ });
+ }
+
ProcessCachedOptimizerRecord(ProcessRecord app) {
mApp = app;
mProcLock = app.mService.mProcLock;
@@ -409,6 +435,10 @@ final class ProcessCachedOptimizerRecord {
pw.print(" " + IS_FROZEN + "="); pw.println(mFrozen);
pw.print(prefix); pw.print("earliestFreezableTimeMs=");
TimeUtils.formatDuration(mEarliestFreezableTimeMillis, nowUptime, pw);
+ if (!mFrozenProcessListeners.isEmpty()) {
+ pw.print(" mFrozenProcessListeners=");
+ mFrozenProcessListeners.forEach((pair) -> pw.print(pair.second + ", "));
+ }
pw.println();
}
}
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 726e8275ae2d..bb0c24b4f8c6 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -3005,7 +3005,7 @@ public final class ProcessList {
return freezePackageCgroup(packageUID, false);
}
- private static void freezeBinderAndPackageCgroup(List<Pair<ProcessRecord, Boolean>> procs,
+ private void freezeBinderAndPackageCgroup(List<Pair<ProcessRecord, Boolean>> procs,
int packageUID) {
// Freeze all binder processes under the target UID (whose cgroup is about to be frozen).
// Since we're going to kill these, we don't need to unfreze them later.
@@ -3019,7 +3019,7 @@ public final class ProcessList {
try {
int rc;
do {
- rc = CachedAppOptimizer.freezeBinder(pid, true, 10 /* timeout_ms */);
+ rc = mService.getFreezer().freezeBinder(pid, true, 10 /* timeout_ms */);
} while (rc == -EAGAIN && nRetries++ < 1);
if (rc != 0) Slog.e(TAG, "Unable to freeze binder for " + pid + ": " + rc);
} catch (RuntimeException e) {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index ac43e86a07c4..53b04df4652e 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -2032,8 +2032,11 @@ public class AudioService extends IAudioService.Stub
synchronized (mCachedAbsVolDrivingStreamsLock) {
mCachedAbsVolDrivingStreams.forEach((dev, stream) -> {
- mAudioSystem.setDeviceAbsoluteVolumeEnabled(dev, /*address=*/"", /*enabled=*/true,
- stream);
+ boolean enabled = true;
+ if (dev == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
+ enabled = mAvrcpAbsVolSupported;
+ }
+ mAudioSystem.setDeviceAbsoluteVolumeEnabled(dev, /*address=*/"", enabled, stream);
});
}
@@ -4831,6 +4834,20 @@ public class AudioService extends IAudioService.Stub
private void onUpdateContextualVolumes() {
final int streamType = getBluetoothContextualVolumeStream();
+ synchronized (mCachedAbsVolDrivingStreamsLock) {
+ mCachedAbsVolDrivingStreams.replaceAll((absDev, stream) -> {
+ boolean enabled = true;
+ if (absDev == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
+ enabled = mAvrcpAbsVolSupported;
+ }
+ if (stream != streamType) {
+ mAudioSystem.setDeviceAbsoluteVolumeEnabled(absDev, /*address=*/"",
+ enabled, streamType);
+ }
+ return streamType;
+ });
+ }
+
final Set<Integer> deviceTypes = getDeviceSetForStreamDirect(streamType);
final Set<Integer> absVolumeMultiModeCaseDevices =
AudioSystem.intersectionAudioDeviceTypes(
@@ -6450,17 +6467,6 @@ public class AudioService extends IAudioService.Stub
// change of mode may require volume to be re-applied on some devices
onUpdateContextualVolumes();
- synchronized (mCachedAbsVolDrivingStreamsLock) {
- mCachedAbsVolDrivingStreams.replaceAll((absDev, stream) -> {
- int streamToDriveAbs = getBluetoothContextualVolumeStream();
- if (stream != streamToDriveAbs) {
- mAudioSystem.setDeviceAbsoluteVolumeEnabled(absDev, /*address=*/
- "", /*enabled*/true, streamToDriveAbs);
- }
- return streamToDriveAbs;
- });
- }
-
// when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all SCO
// connections not started by the application changing the mode when pid changes
mDeviceBroker.postSetModeOwner(mode, pid, uid);
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 5b23364cf546..969a684f6ef5 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -2158,8 +2158,12 @@ public class SyncManager {
}
if (mBound) {
mBound = false;
- mLogger.log("unbindService for ", this);
- mContext.unbindService(this);
+ try {
+ mLogger.log("unbindService for ", this);
+ mContext.unbindService(this);
+ } catch (NoSuchElementException e) {
+ Slog.wtf(TAG, "Failed to unlink active sync adapter on close()", e);
+ }
try {
mBatteryStats.noteSyncFinish(mEventName, mSyncAdapterUid);
} catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionService.java b/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionService.java
index e24216433413..e0aa9bf3e0c3 100644
--- a/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionService.java
+++ b/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionService.java
@@ -21,11 +21,13 @@ import static android.app.Flags.systemTermsOfAddressEnabled;
import static com.android.server.grammaticalinflection.GrammaticalInflectionUtils.checkSystemGrammaticalGenderPermission;
import android.annotation.Nullable;
+import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.app.GrammaticalInflectionManager;
import android.app.IGrammaticalInflectionManager;
import android.content.AttributionSource;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.res.Configuration;
import android.os.Binder;
@@ -36,6 +38,7 @@ import android.os.ResultReceiver;
import android.os.ShellCallback;
import android.os.SystemProperties;
import android.os.Trace;
+import android.os.UserManager;
import android.permission.PermissionManager;
import android.util.AtomicFile;
import android.util.Log;
@@ -271,6 +274,31 @@ public class GrammaticalInflectionService extends SystemService {
throw new IllegalArgumentException("Unknown grammatical gender");
}
+ // TODO(b/356895553): Don't allow profiles and background user to change system
+ // grammaticalinflection
+ if (UserManager.isVisibleBackgroundUsersEnabled()
+ && mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_AUTOMOTIVE)) {
+ // The check is added only for automotive devices. On automotive devices, it is
+ // possible that multiple users are visible simultaneously using visible background
+ // users. In such cases, it is desired that only the current user (not the visible
+ // background user) can change the GrammaticalInflection of the device.
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ int currentUser = ActivityManager.getCurrentUser();
+ if (userId != currentUser) {
+ Log.w(TAG,
+ "Only current user is allowed to update GrammaticalInflection if "
+ + "visible background users are enabled. Current User"
+ + currentUser + ". Calling User: " + userId);
+ throw new SecurityException("Only current user is allowed to update "
+ + "GrammaticalInflection.");
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
final File file = getGrammaticalGenderFile(userId);
synchronized (mLock) {
final AtomicFile atomicFile = new AtomicFile(file);
diff --git a/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java b/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
index 42a99defcbee..b0dff22c6f03 100644
--- a/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
+++ b/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
@@ -28,7 +28,6 @@ import static android.view.WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVI
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED;
import static android.view.WindowManager.LayoutParams.SoftInputModeFlags;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static com.android.internal.inputmethod.InputMethodDebug.softInputModeToString;
import static com.android.internal.inputmethod.SoftInputShowHideReason.REMOVE_IME_SCREENSHOT_FROM_IMMS;
@@ -59,7 +58,6 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.server.LocalServices;
-import com.android.server.wm.ImeTargetChangeListener;
import com.android.server.wm.WindowManagerInternal;
import java.io.PrintWriter;
@@ -76,6 +74,9 @@ public final class ImeVisibilityStateComputer {
private static final boolean DEBUG = InputMethodManagerService.DEBUG;
+ @UserIdInt
+ private final int mUserId;
+
private final InputMethodManagerService mService;
private final WindowManagerInternal mWindowManagerInternal;
@@ -184,73 +185,64 @@ public final class ImeVisibilityStateComputer {
*/
private final ImeVisibilityPolicy mPolicy;
- public ImeVisibilityStateComputer(@NonNull InputMethodManagerService service) {
+ public ImeVisibilityStateComputer(@NonNull InputMethodManagerService service,
+ @UserIdInt int userId) {
this(service,
LocalServices.getService(WindowManagerInternal.class),
LocalServices.getService(WindowManagerInternal.class)::getDisplayImePolicy,
- new ImeVisibilityPolicy());
+ new ImeVisibilityPolicy(), userId);
}
@VisibleForTesting
public ImeVisibilityStateComputer(@NonNull InputMethodManagerService service,
@NonNull Injector injector) {
this(service, injector.getWmService(), injector.getImeValidator(),
- new ImeVisibilityPolicy());
+ new ImeVisibilityPolicy(), injector.getUserId());
}
interface Injector {
- default WindowManagerInternal getWmService() {
- return null;
- }
+ @NonNull
+ WindowManagerInternal getWmService();
- default InputMethodManagerService.ImeDisplayValidator getImeValidator() {
- return null;
- }
+ @NonNull
+ InputMethodManagerService.ImeDisplayValidator getImeValidator();
+
+ @UserIdInt
+ int getUserId();
}
private ImeVisibilityStateComputer(InputMethodManagerService service,
WindowManagerInternal wmService,
InputMethodManagerService.ImeDisplayValidator imeDisplayValidator,
- ImeVisibilityPolicy imePolicy) {
+ ImeVisibilityPolicy imePolicy, @UserIdInt int userId) {
+ mUserId = userId;
mService = service;
mWindowManagerInternal = wmService;
mImeDisplayValidator = imeDisplayValidator;
mPolicy = imePolicy;
- mWindowManagerInternal.setInputMethodTargetChangeListener(new ImeTargetChangeListener() {
- @Override
- public void onImeTargetOverlayVisibilityChanged(@NonNull IBinder overlayWindowToken,
- @WindowManager.LayoutParams.WindowType int windowType, boolean visible,
- boolean removed) {
- // Ignoring the starting window since it's ok to cover the IME target
- // window in temporary without affecting the IME visibility.
- final boolean hasOverlay = visible && !removed
- && windowType != TYPE_APPLICATION_STARTING;
- synchronized (ImfLock.class) {
- mHasVisibleImeLayeringOverlay = hasOverlay;
- }
- }
+ }
- @Override
- public void onImeInputTargetVisibilityChanged(IBinder imeInputTarget,
- boolean visibleRequested, boolean removed) {
- final boolean visibleAndNotRemoved = visibleRequested && !removed;
- synchronized (ImfLock.class) {
- if (visibleAndNotRemoved) {
- mCurVisibleImeInputTarget = imeInputTarget;
- return;
- }
- if (mHasVisibleImeLayeringOverlay
- && mCurVisibleImeInputTarget == imeInputTarget) {
- final int reason = SoftInputShowHideReason.HIDE_WHEN_INPUT_TARGET_INVISIBLE;
- final var statsToken = ImeTracker.forLogging().onStart(ImeTracker.TYPE_HIDE,
- ImeTracker.ORIGIN_SERVER, reason, false /* fromUser */);
- mService.onApplyImeVisibilityFromComputerLocked(imeInputTarget, statsToken,
- new ImeVisibilityResult(STATE_HIDE_IME_EXPLICIT, reason));
- }
- mCurVisibleImeInputTarget = null;
- }
- }
- });
+ @GuardedBy("ImfLock.class")
+ void setHasVisibleImeLayeringOverlay(boolean hasVisibleOverlay) {
+ mHasVisibleImeLayeringOverlay = hasVisibleOverlay;
+ }
+
+ @GuardedBy("ImfLock.class")
+ void onImeInputTargetVisibilityChanged(@NonNull IBinder imeInputTarget,
+ boolean visibleAndNotRemoved) {
+ if (visibleAndNotRemoved) {
+ mCurVisibleImeInputTarget = imeInputTarget;
+ return;
+ }
+ if (mHasVisibleImeLayeringOverlay
+ && mCurVisibleImeInputTarget == imeInputTarget) {
+ final int reason = SoftInputShowHideReason.HIDE_WHEN_INPUT_TARGET_INVISIBLE;
+ final var statsToken = ImeTracker.forLogging().onStart(ImeTracker.TYPE_HIDE,
+ ImeTracker.ORIGIN_SERVER, reason, false /* fromUser */);
+ mService.onApplyImeVisibilityFromComputerLocked(imeInputTarget, statsToken,
+ new ImeVisibilityResult(STATE_HIDE_IME_EXPLICIT, reason), mUserId);
+ }
+ mCurVisibleImeInputTarget = null;
}
/**
@@ -631,6 +623,12 @@ public final class ImeVisibilityStateComputer {
return mWindowManagerInternal.shouldRestoreImeVisibility(getWindowTokenFrom(state));
}
+ @UserIdInt
+ @VisibleForTesting
+ int getUserId() {
+ return mUserId;
+ }
+
@GuardedBy("ImfLock.class")
boolean isInputShown() {
return mInputShown;
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
index 03cbab53f1b8..94b14730bb07 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
@@ -463,7 +463,8 @@ final class InputMethodBindingController {
// should now try to restart the service for us.
mLastBindTime = SystemClock.uptimeMillis();
clearCurMethodAndSessions();
- mService.mVisibilityStateComputer.setInputShown(false);
+ final var userData = mService.getUserData(mUserId);
+ userData.mVisibilityStateComputer.setInputShown(false);
mService.unbindCurrentClientLocked(UnbindReason.DISCONNECT_IME, mUserId);
}
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 76380b75d98c..1c0a08288ff4 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -44,6 +44,7 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.DISPLAY_IME_POLICY_HIDE;
import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.inputmethod.ConnectionlessHandwritingCallback.CONNECTIONLESS_HANDWRITING_ERROR_OTHER;
import static android.view.inputmethod.ConnectionlessHandwritingCallback.CONNECTIONLESS_HANDWRITING_ERROR_UNSUPPORTED;
@@ -187,6 +188,7 @@ import com.android.server.inputmethod.InputMethodSubtypeSwitchingController.ImeS
import com.android.server.pm.UserManagerInternal;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.utils.PriorityDump;
+import com.android.server.wm.ImeTargetChangeListener;
import com.android.server.wm.WindowManagerInternal;
import java.io.FileDescriptor;
@@ -419,11 +421,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
private final InputMethodMenuControllerNew mMenuControllerNew;
@GuardedBy("ImfLock.class")
- @MultiUserUnawareField
- @NonNull
- final ImeVisibilityStateComputer mVisibilityStateComputer;
-
- @GuardedBy("ImfLock.class")
@SharedByAllUsersField
@NonNull
private final DefaultImeVisibilityApplier mVisibilityApplier;
@@ -628,10 +625,11 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
final int accessibilitySoftKeyboardSetting = Settings.Secure.getIntForUser(
mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0, userId);
- mVisibilityStateComputer.getImePolicy().setA11yRequestNoSoftKeyboard(
- accessibilitySoftKeyboardSetting);
final var userData = getUserData(userId);
- if (mVisibilityStateComputer.getImePolicy().isA11yRequestNoSoftKeyboard()) {
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
+ visibilityStateComputer.getImePolicy().setA11yRequestNoSoftKeyboard(
+ accessibilitySoftKeyboardSetting);
+ if (visibilityStateComputer.getImePolicy().isA11yRequestNoSoftKeyboard()) {
hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow,
0 /* flags */, SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE, userId);
} else if (isShowRequestedForCurrentWindow(userId)) {
@@ -678,22 +676,18 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
// sender userId can be a real user ID or USER_ALL.
final int senderUserId = pendingResult.getSendingUserId();
- if (senderUserId != UserHandle.USER_ALL) {
- synchronized (ImfLock.class) {
- if (senderUserId != mCurrentUserId) {
- // A background user is trying to hide the dialog. Ignore.
- return;
- }
+ synchronized (ImfLock.class) {
+ if (senderUserId != UserHandle.USER_ALL && senderUserId != mCurrentUserId) {
+ // A background user is trying to hide the dialog. Ignore.
+ return;
}
- }
- if (mNewInputMethodSwitcherMenuEnabled) {
- synchronized (ImfLock.class) {
- final var bindingController = getInputMethodBindingController(senderUserId);
- mMenuControllerNew.hide(bindingController.getCurTokenDisplayId(),
- senderUserId);
+ final int userId = mCurrentUserId;
+ if (mNewInputMethodSwitcherMenuEnabled) {
+ final var bindingController = getInputMethodBindingController(userId);
+ mMenuControllerNew.hide(bindingController.getCurTokenDisplayId(), userId);
+ } else {
+ mMenuController.hideInputMethodMenuLocked(userId);
}
- } else {
- mMenuController.hideInputMethodMenu(senderUserId);
}
} else {
Slog.w(TAG, "Unexpected intent " + intent);
@@ -970,6 +964,37 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
InputMethodDrawsNavBarResourceMonitor.registerCallback(context, mService.mIoHandler,
mService::onUpdateResourceOverlay);
+ // Also hook up ImeTargetChangeListener.
+ // TODO(b/356876005): Merge this into InputMethodManagerInternal.
+ final var windowManagerInternal = mService.mWindowManagerInternal;
+ windowManagerInternal.setInputMethodTargetChangeListener(new ImeTargetChangeListener() {
+ @Override
+ public void onImeTargetOverlayVisibilityChanged(@NonNull IBinder overlayWindowToken,
+ @WindowManager.LayoutParams.WindowType int windowType, boolean visible,
+ boolean removed, int displayId) {
+ // Ignoring the starting window since it's ok to cover the IME target
+ // window in temporary without affecting the IME visibility.
+ final boolean hasOverlay = visible && !removed
+ && windowType != TYPE_APPLICATION_STARTING;
+ synchronized (ImfLock.class) {
+ final var userId = mService.resolveImeUserIdFromDisplayIdLocked(displayId);
+ mService.getUserData(userId).mVisibilityStateComputer
+ .setHasVisibleImeLayeringOverlay(hasOverlay);
+ }
+ }
+
+ @Override
+ public void onImeInputTargetVisibilityChanged(IBinder imeInputTarget,
+ boolean visibleRequested, boolean removed, int displayId) {
+ final boolean visibleAndNotRemoved = visibleRequested && !removed;
+ synchronized (ImfLock.class) {
+ final var userId = mService.resolveImeUserIdFromDisplayIdLocked(displayId);
+ mService.getUserData(userId).mVisibilityStateComputer
+ .onImeInputTargetVisibilityChanged(imeInputTarget,
+ visibleAndNotRemoved);
+ }
+ }
+ });
// Also schedule user init tasks onto an I/O thread.
initializeUsersAsync(mService.mUserManagerInternal.getUserIds());
}
@@ -1001,6 +1026,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
Process.THREAD_PRIORITY_FOREGROUND, true /* allowIo */);
ioThread.start();
+ SecureSettingsWrapper.setContentResolver(context.getContentResolver());
+
return new InputMethodManagerService(context,
shouldEnableConcurrentMultiUserMode(context), thread.getLooper(),
Handler.createAsync(ioThread.getLooper()),
@@ -1059,6 +1086,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
public void onUserRemoved(UserInfo user) {
// Called directly from UserManagerService. Do not block the calling thread.
final int userId = user.id;
+ SecureSettingsWrapper.onUserRemoved(userId);
AdditionalSubtypeMapRepository.remove(userId);
InputMethodSettingsRepository.remove(userId);
mService.mUserDataRepository.remove(userId);
@@ -1185,7 +1213,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
mConcurrentMultiUserModeEnabled = concurrentMultiUserModeEnabled;
mContext = context;
mRes = context.getResources();
- SecureSettingsWrapper.onStart(mContext);
mHandler = Handler.createAsync(uiLooper, this);
mIoHandler = ioHandler;
@@ -1205,17 +1232,19 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
mShowOngoingImeSwitcherForPhones = false;
mCurrentUserId = mActivityManagerInternal.getCurrentUserId();
- @SuppressWarnings("GuardedBy") final IntFunction<InputMethodBindingController>
+ final IntFunction<InputMethodBindingController>
bindingControllerFactory = userId -> new InputMethodBindingController(userId,
InputMethodManagerService.this);
+ final IntFunction<ImeVisibilityStateComputer> visibilityStateComputerFactory =
+ userId -> new ImeVisibilityStateComputer(InputMethodManagerService.this,
+ userId);
mUserDataRepository = new UserDataRepository(
bindingControllerForTesting != null ? bindingControllerForTesting
- : bindingControllerFactory);
+ : bindingControllerFactory, visibilityStateComputerFactory);
mMenuController = new InputMethodMenuController(this);
mMenuControllerNew = mNewInputMethodSwitcherMenuEnabled
? new InputMethodMenuControllerNew() : null;
- mVisibilityStateComputer = new ImeVisibilityStateComputer(this);
mVisibilityApplier = new DefaultImeVisibilityApplier(this);
mClientController = new ClientController(mPackageManagerInternal);
@@ -1414,7 +1443,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
final int currentUserId = mCurrentUserId;
mStatusBarManagerInternal =
LocalServices.getService(StatusBarManagerInternal.class);
- hideStatusBarIconLocked();
+ hideStatusBarIconLocked(currentUserId);
final var bindingController = getInputMethodBindingController(currentUserId);
updateSystemUiLocked(bindingController.getImeWindowVis(),
bindingController.getBackDisposition(), currentUserId);
@@ -1840,10 +1869,11 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@GuardedBy("ImfLock.class")
void onUnbindCurrentMethodByReset(@UserIdInt int userId) {
final var userData = getUserData(userId);
- final ImeTargetWindowState winState = mVisibilityStateComputer.getWindowStateOrNull(
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
+ final ImeTargetWindowState winState = visibilityStateComputer.getWindowStateOrNull(
userData.mImeBindingState.mFocusedWindow);
if (winState != null && !winState.isRequestedImeVisible()
- && !mVisibilityStateComputer.isInputShown()) {
+ && !visibilityStateComputer.isInputShown()) {
// Normally, the focus window will apply the IME visibility state to
// WindowManager when the IME has applied it. But it would be too late when
// switching IMEs in between different users. (Since the focused IME will
@@ -1862,8 +1892,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@GuardedBy("ImfLock.class")
private boolean isShowRequestedForCurrentWindow(@UserIdInt int userId) {
final var userData = getUserData(userId);
- // TODO(b/349904272): Make mVisibilityStateComputer multi-user aware
- final ImeTargetWindowState state = mVisibilityStateComputer.getWindowStateOrNull(
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
+ final ImeTargetWindowState state = visibilityStateComputer.getWindowStateOrNull(
userData.mImeBindingState.mFocusedWindow);
return state != null && state.isRequestedImeVisible();
}
@@ -1927,8 +1957,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
: createStatsTokenForFocusedClient(true /* show */,
SoftInputShowHideReason.ATTACH_NEW_INPUT, userId);
userData.mCurStatsToken = null;
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
showCurrentInputLocked(userData.mImeBindingState.mFocusedWindow, statsToken,
- mVisibilityStateComputer.getShowFlags(), MotionEvent.TOOL_TYPE_UNKNOWN,
+ visibilityStateComputer.getShowFlags(), MotionEvent.TOOL_TYPE_UNKNOWN,
null /* resultReceiver */, SoftInputShowHideReason.ATTACH_NEW_INPUT,
userId);
}
@@ -2009,17 +2040,18 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
final int userId = bindingController.getUserId();
final var userData = getUserData(userId);
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
// Compute the final shown display ID with validated cs.selfReportedDisplayId for this
// session & other conditions.
- ImeTargetWindowState winState = mVisibilityStateComputer.getWindowStateOrNull(
+ ImeTargetWindowState winState = visibilityStateComputer.getWindowStateOrNull(
userData.mImeBindingState.mFocusedWindow);
if (winState == null) {
return InputBindResult.NOT_IME_TARGET_WINDOW;
}
final int csDisplayId = cs.mSelfReportedDisplayId;
bindingController.setDisplayIdToShowIme(
- mVisibilityStateComputer.computeImeDisplayId(winState, csDisplayId));
+ visibilityStateComputer.computeImeDisplayId(winState, csDisplayId));
// Potentially override the selected input method if the new display belongs to a virtual
// device with a custom IME.
@@ -2027,14 +2059,14 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
final String deviceMethodId = computeCurrentDeviceMethodIdLocked(
bindingController.getUserId(), selectedMethodId);
if (deviceMethodId == null) {
- mVisibilityStateComputer.getImePolicy().setImeHiddenByDisplayPolicy(true);
+ visibilityStateComputer.getImePolicy().setImeHiddenByDisplayPolicy(true);
} else if (!Objects.equals(deviceMethodId, selectedMethodId)) {
setInputMethodLocked(deviceMethodId, NOT_A_SUBTYPE_ID,
bindingController.getDeviceIdToShowIme(), userId);
selectedMethodId = deviceMethodId;
}
- if (mVisibilityStateComputer.getImePolicy().isImeHiddenByDisplayPolicy()) {
+ if (visibilityStateComputer.getImePolicy().isImeHiddenByDisplayPolicy()) {
hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow, 0 /* flags */,
SoftInputShowHideReason.HIDE_DISPLAY_IME_POLICY_HIDE, userId);
return InputBindResult.NO_IME;
@@ -2554,7 +2586,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
userData.mEnabledAccessibilitySessions.clear();
scheduleNotifyImeUidToAudioService(Process.INVALID_UID);
}
- hideStatusBarIconLocked();
+ hideStatusBarIconLocked(userId);
getUserData(userId).mInFullscreenMode = false;
mWindowManagerInternal.setDismissImeOnBackKeyPressed(false);
scheduleResetStylusHandwriting();
@@ -2565,6 +2597,11 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@DrawableRes int iconId, @NonNull UserData userData) {
final int userId = userData.mUserId;
synchronized (ImfLock.class) {
+ // To minimize app compat risk, ignore background users' request for single-user mode.
+ // TODO(b/357178609): generalize the logic and remove this special rule.
+ if (!mConcurrentMultiUserModeEnabled && userId != mCurrentUserId) {
+ return;
+ }
if (!calledWithValidTokenLocked(token, userData)) {
return;
}
@@ -2572,7 +2609,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
try {
if (iconId == 0) {
if (DEBUG) Slog.d(TAG, "hide the small icon for the input method");
- hideStatusBarIconLocked();
+ hideStatusBarIconLocked(userId);
} else if (packageName != null) {
if (DEBUG) Slog.d(TAG, "show a small icon for the input method");
final PackageManager userAwarePackageManager =
@@ -2600,7 +2637,12 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
@GuardedBy("ImfLock.class")
- private void hideStatusBarIconLocked() {
+ private void hideStatusBarIconLocked(@UserIdInt int userId) {
+ // To minimize app compat risk, ignore background users' request for single-user mode.
+ // TODO(b/357178609): generalize the logic and remove this special rule.
+ if (!mConcurrentMultiUserModeEnabled && userId != mCurrentUserId) {
+ return;
+ }
if (mStatusBarManagerInternal != null) {
mStatusBarManagerInternal.setIconVisibility(mSlotIme, false);
}
@@ -2781,7 +2823,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
if (targetWindow != null) {
mWindowManagerInternal.updateInputMethodTargetWindow(targetWindow);
}
- mVisibilityStateComputer.setLastImeTargetWindow(targetWindow);
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
+ visibilityStateComputer.setLastImeTargetWindow(targetWindow);
}
}
@@ -2806,6 +2849,11 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@GuardedBy("ImfLock.class")
private void updateSystemUiLocked(int vis, int backDisposition, @UserIdInt int userId) {
+ // To minimize app compat risk, ignore background users' request for single-user mode.
+ // TODO(b/357178609): generalize the logic and remove this special rule.
+ if (!mConcurrentMultiUserModeEnabled && userId != mCurrentUserId) {
+ return;
+ }
final var userData = getUserData(userId);
final var bindingController = userData.mBindingController;
final var curToken = bindingController.getCurToken();
@@ -3044,11 +3092,14 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
@GuardedBy("ImfLock.class")
- private void sendResultReceiverFailureLocked(@Nullable ResultReceiver resultReceiver) {
+ private void sendResultReceiverFailureLocked(@Nullable ResultReceiver resultReceiver,
+ @UserIdInt int userId) {
if (resultReceiver == null) {
return;
}
- final boolean isInputShown = mVisibilityStateComputer.isInputShown();
+ final var userData = getUserData(userId);
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
+ final boolean isInputShown = visibilityStateComputer.isInputShown();
resultReceiver.send(isInputShown
? InputMethodManager.RESULT_UNCHANGED_SHOWN
: InputMethodManager.RESULT_UNCHANGED_HIDDEN, null);
@@ -3063,12 +3114,15 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
ImeTracing.getInstance().triggerManagerServiceDump(
"InputMethodManagerService#showSoftInput", mDumper);
synchronized (ImfLock.class) {
+ final int uid = Binder.getCallingUid();
+ final int callingUserId = UserHandle.getUserId(uid);
+ final int userId = resolveImeUserIdLocked(callingUserId);
final boolean result = showSoftInputLocked(client, windowToken, statsToken, flags,
- lastClickToolType, resultReceiver, reason);
+ lastClickToolType, resultReceiver, reason, uid, userId);
// When ZeroJankProxy is enabled, the app has already received "true" as the return
// value, and expect "resultReceiver" to be notified later. See b/327751155.
if (!result && Flags.useZeroJankProxy()) {
- sendResultReceiverFailureLocked(resultReceiver);
+ sendResultReceiverFailureLocked(resultReceiver, userId);
}
return result; // ignored when ZeroJankProxy is enabled.
}
@@ -3078,10 +3132,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
private boolean showSoftInputLocked(IInputMethodClient client, IBinder windowToken,
@NonNull ImeTracker.Token statsToken, @InputMethodManager.ShowFlags int flags,
int lastClickToolType, ResultReceiver resultReceiver,
- @SoftInputShowHideReason int reason) {
- final int uid = Binder.getCallingUid();
- final int callingUserId = UserHandle.getUserId(uid);
- final int userId = resolveImeUserIdLocked(callingUserId);
+ @SoftInputShowHideReason int reason, int uid, @UserIdInt int userId) {
if (!canInteractWithImeLocked(uid, client, "showSoftInput", statsToken,
userId)) {
ImeTracker.forLogging().onFailed(
@@ -3094,7 +3145,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
try {
if (DEBUG) Slog.v(TAG, "Client requesting input be shown");
if (Flags.refactorInsetsController()) {
- boolean wasVisible = mVisibilityStateComputer.isInputShown();
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
+ boolean wasVisible = visibilityStateComputer.isInputShown();
if (userData.mImeBindingState != null
&& userData.mImeBindingState.mFocusedWindowClient != null
&& userData.mImeBindingState.mFocusedWindowClient.mClient != null) {
@@ -3432,7 +3484,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@NonNull ImeTracker.Token statsToken, @InputMethodManager.ShowFlags int flags,
@MotionEvent.ToolType int lastClickToolType, @Nullable ResultReceiver resultReceiver,
@SoftInputShowHideReason int reason, @UserIdInt int userId) {
- if (!mVisibilityStateComputer.onImeShowFlags(statsToken, flags)) {
+ final var userData = getUserData(userId);
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
+ if (!visibilityStateComputer.onImeShowFlags(statsToken, flags)) {
return false;
}
@@ -3442,10 +3496,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_SYSTEM_READY);
- mVisibilityStateComputer.requestImeVisibility(windowToken, true);
+ visibilityStateComputer.requestImeVisibility(windowToken, true);
// Ensure binding the connection when IME is going to show.
- final var userData = getUserData(userId);
final var bindingController = userData.mBindingController;
bindingController.setCurrentMethodVisible();
final IInputMethodInvoker curMethod = bindingController.getCurMethod();
@@ -3469,9 +3522,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
onUpdateEditorToolTypeLocked(lastClickToolType, userId);
}
mVisibilityApplier.performShowIme(windowToken, statsToken,
- mVisibilityStateComputer.getShowFlagsForInputMethodServiceOnly(),
+ visibilityStateComputer.getShowFlagsForInputMethodServiceOnly(),
resultReceiver, reason, userId);
- mVisibilityStateComputer.setInputShown(true);
+ visibilityStateComputer.setInputShown(true);
return true;
} else {
ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
@@ -3511,12 +3564,15 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
ImeTracing.getInstance().triggerManagerServiceDump(
"InputMethodManagerService#hideSoftInput", mDumper);
synchronized (ImfLock.class) {
+ final int uid = Binder.getCallingUid();
+ final int callingUserId = UserHandle.getUserId(uid);
+ final int userId = resolveImeUserIdLocked(callingUserId);
final boolean result = hideSoftInputLocked(client, windowToken, statsToken, flags,
- resultReceiver, reason);
+ resultReceiver, reason, uid, userId);
// When ZeroJankProxy is enabled, the app has already received "true" as the return
// value, and expect "resultReceiver" to be notified later. See b/327751155.
if (!result && Flags.useZeroJankProxy()) {
- sendResultReceiverFailureLocked(resultReceiver);
+ sendResultReceiverFailureLocked(resultReceiver, userId);
}
return result; // ignored when ZeroJankProxy is enabled.
}
@@ -3525,12 +3581,12 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@GuardedBy("ImfLock.class")
private boolean hideSoftInputLocked(IInputMethodClient client, IBinder windowToken,
@NonNull ImeTracker.Token statsToken, @InputMethodManager.HideFlags int flags,
- ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {
- final int uid = Binder.getCallingUid();
- final int callingUserId = UserHandle.getUserId(uid);
- final int userId = resolveImeUserIdLocked(callingUserId);
+ ResultReceiver resultReceiver, @SoftInputShowHideReason int reason,
+ int uid, @UserIdInt int userId) {
+ final var userData = getUserData(userId);
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
if (!canInteractWithImeLocked(uid, client, "hideSoftInput", statsToken, userId)) {
- if (mVisibilityStateComputer.isInputShown()) {
+ if (visibilityStateComputer.isInputShown()) {
ImeTracker.forLogging().onFailed(
statsToken, ImeTracker.PHASE_SERVER_CLIENT_FOCUSED);
} else {
@@ -3539,7 +3595,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
return false;
}
- final var userData = getUserData(userId);
final long ident = Binder.clearCallingIdentity();
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.hideSoftInput");
@@ -3548,7 +3603,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
if (userData.mImeBindingState != null
&& userData.mImeBindingState.mFocusedWindowClient != null
&& userData.mImeBindingState.mFocusedWindowClient.mClient != null) {
- boolean wasVisible = mVisibilityStateComputer.isInputShown();
+ boolean wasVisible = visibilityStateComputer.isInputShown();
// TODO add windowToken to interface
userData.mImeBindingState.mFocusedWindowClient.mClient
.setImeVisibility(false, statsToken);
@@ -3596,7 +3651,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@SoftInputShowHideReason int reason, @UserIdInt int userId) {
final var userData = getUserData(userId);
final var bindingController = userData.mBindingController;
- if (!mVisibilityStateComputer.canHideIme(statsToken, flags)) {
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
+ if (!visibilityStateComputer.canHideIme(statsToken, flags)) {
return false;
}
@@ -3610,10 +3666,10 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
// TODO(b/246309664): Clean up IMMS#mImeWindowVis
IInputMethodInvoker curMethod = bindingController.getCurMethod();
final boolean shouldHideSoftInput = curMethod != null
- && (mVisibilityStateComputer.isInputShown()
+ && (visibilityStateComputer.isInputShown()
|| (bindingController.getImeWindowVis() & InputMethodService.IME_ACTIVE) != 0);
- mVisibilityStateComputer.requestImeVisibility(windowToken, false);
+ visibilityStateComputer.requestImeVisibility(windowToken, false);
if (shouldHideSoftInput) {
// The IME will report its visible state again after the following message finally
// delivered to the IME process as an IPC. Hence the inconsistency between
@@ -3626,7 +3682,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
ImeTracker.forLogging().onCancelled(statsToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE);
}
bindingController.setCurrentMethodNotVisible();
- mVisibilityStateComputer.clearImeShowFlags();
+ visibilityStateComputer.clearImeShowFlags();
// Cancel existing statsToken for show IME as we got a hide request.
ImeTracker.forLogging().onCancelled(userData.mCurStatsToken,
ImeTracker.PHASE_SERVER_WAIT_IME);
@@ -3759,10 +3815,11 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
// mShowForced flag when the next client's targetSdkVersion is T or higher.
final boolean shouldClearFlag =
mImePlatformCompatUtils.shouldClearShowForcedFlag(cs.mUid);
- final boolean showForced = mVisibilityStateComputer.mShowForced;
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
+ final boolean showForced = visibilityStateComputer.mShowForced;
if (userData.mImeBindingState.mFocusedWindow != windowToken
&& showForced && shouldClearFlag) {
- mVisibilityStateComputer.mShowForced = false;
+ visibilityStateComputer.mShowForced = false;
}
// Verify if caller is a background user.
@@ -3854,7 +3911,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
final ImeTargetWindowState windowState = new ImeTargetWindowState(
softInputMode, windowFlags, !sameWindowFocused, isTextEditor,
startInputByWinGainedFocus, toolType);
- mVisibilityStateComputer.setWindowState(windowToken, windowState);
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
+ visibilityStateComputer.setWindowState(windowToken, windowState);
if (sameWindowFocused && isTextEditor) {
if (DEBUG) {
@@ -3885,7 +3943,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
boolean didStart = false;
InputBindResult res = null;
- final ImeVisibilityResult imeVisRes = mVisibilityStateComputer.computeState(windowState,
+ final ImeVisibilityResult imeVisRes = visibilityStateComputer.computeState(windowState,
isSoftInputModeStateVisibleAllowed(unverifiedTargetSdkVersion, startInputFlags));
if (imeVisRes != null) {
boolean isShow = false;
@@ -4356,7 +4414,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
final var additionalSubtypeMap = AdditionalSubtypeMapRepository.get(userId);
- final boolean isCurrentUser = (mCurrentUserId == userId);
final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
final var newAdditionalSubtypeMap = settings.getNewAdditionalSubtypeMap(
imiId, toBeAdded, additionalSubtypeMap, mPackageManagerInternal, callingUid);
@@ -4370,10 +4427,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
mUserManagerInternal.isUserUnlockingOrUnlocked(userId));
final var newSettings = InputMethodSettings.create(methodMap, userId);
InputMethodSettingsRepository.put(userId, newSettings);
- if (isCurrentUser) {
- postInputMethodSettingUpdatedLocked(false /* resetDefaultEnabledIme */,
- userId);
- }
+ postInputMethodSettingUpdatedLocked(false /* resetDefaultEnabledIme */, userId);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -4401,17 +4455,14 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
final long ident = Binder.clearCallingIdentity();
try {
synchronized (ImfLock.class) {
- final boolean currentUser = (mCurrentUserId == userId);
final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
if (!settings.setEnabledInputMethodSubtypes(imeId, subtypeHashCodes)) {
return;
}
- if (currentUser) {
- // To avoid unnecessary "updateInputMethodsFromSettingsLocked" from happening.
- final var userData = getUserData(userId);
- userData.mLastEnabledInputMethodsStr = settings.getEnabledInputMethodsStr();
- updateInputMethodsFromSettingsLocked(false /* enabledChanged */, userId);
- }
+ // To avoid unnecessary "updateInputMethodsFromSettingsLocked" from happening.
+ final var userData = getUserData(userId);
+ userData.mLastEnabledInputMethodsStr = settings.getEnabledInputMethodsStr();
+ updateInputMethodsFromSettingsLocked(false /* enabledChanged */, userId);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -4716,20 +4767,21 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
final int userId = mCurrentUserId;
final var userData = getUserData(userId);
final var bindingController = userData.mBindingController;
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
final long token = proto.start(fieldId);
proto.write(CUR_METHOD_ID, bindingController.getSelectedMethodId());
proto.write(CUR_SEQ, bindingController.getSequenceNumber());
proto.write(CUR_CLIENT, Objects.toString(userData.mCurClient));
userData.mImeBindingState.dumpDebug(proto, mWindowManagerInternal);
proto.write(LAST_IME_TARGET_WINDOW_NAME, mWindowManagerInternal.getWindowName(
- mVisibilityStateComputer.getLastImeTargetWindow()));
+ visibilityStateComputer.getLastImeTargetWindow()));
proto.write(CUR_FOCUSED_WINDOW_SOFT_INPUT_MODE, InputMethodDebug.softInputModeToString(
userData.mImeBindingState.mFocusedWindowSoftInputMode));
if (userData.mCurEditorInfo != null) {
userData.mCurEditorInfo.dumpDebug(proto, CUR_ATTRIBUTE);
}
proto.write(CUR_ID, bindingController.getCurId());
- mVisibilityStateComputer.dumpDebug(proto, fieldId);
+ visibilityStateComputer.dumpDebug(proto, fieldId);
proto.write(IN_FULLSCREEN_MODE, userData.mInFullscreenMode);
proto.write(CUR_TOKEN, Objects.toString(bindingController.getCurToken()));
proto.write(CUR_TOKEN_DISPLAY_ID, bindingController.getCurTokenDisplayId());
@@ -4784,7 +4836,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
- final IBinder requestToken = mVisibilityStateComputer.getWindowTokenFrom(
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
+ final IBinder requestToken = visibilityStateComputer.getWindowTokenFrom(
windowToken, userId);
mVisibilityApplier.applyImeVisibility(requestToken, statsToken,
setVisible ? STATE_SHOW_IME : STATE_HIDE_IME,
@@ -4849,9 +4902,10 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
void onShowHideSoftInputRequested(boolean show, IBinder requestImeToken,
@SoftInputShowHideReason int reason, @Nullable ImeTracker.Token statsToken,
@UserIdInt int userId) {
- final IBinder requestToken = mVisibilityStateComputer.getWindowTokenFrom(requestImeToken,
- userId);
final var userData = getUserData(userId);
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
+ final IBinder requestToken = visibilityStateComputer.getWindowTokenFrom(requestImeToken,
+ userId);
final var bindingController = userData.mBindingController;
final WindowManagerInternal.ImeTargetInfo info =
mWindowManagerInternal.onToggleImeRequested(
@@ -4896,7 +4950,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
.setImeVisibility(false, statsToken);
}
} else {
- hideCurrentInputLocked(mVisibilityStateComputer.getLastImeTargetWindow(),
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
+ hideCurrentInputLocked(visibilityStateComputer.getLastImeTargetWindow(),
statsToken, flags, null /* resultReceiver */, reason, userId);
}
} finally {
@@ -4935,7 +4990,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
.setImeVisibility(true, statsToken);
}
} else {
- showCurrentInputLocked(mVisibilityStateComputer.getLastImeTargetWindow(),
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
+ showCurrentInputLocked(visibilityStateComputer.getLastImeTargetWindow(),
statsToken, flags, MotionEvent.TOOL_TYPE_UNKNOWN,
null /* resultReceiver */, reason, userId);
}
@@ -4956,8 +5012,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@GuardedBy("ImfLock.class")
void onApplyImeVisibilityFromComputerLocked(IBinder windowToken,
- @NonNull ImeTracker.Token statsToken, @NonNull ImeVisibilityResult result) {
- final int userId = resolveImeUserIdFromWindowLocked(windowToken);
+ @NonNull ImeTracker.Token statsToken, @NonNull ImeVisibilityResult result,
+ @UserIdInt int userId) {
mVisibilityApplier.applyImeVisibility(windowToken, statsToken, result.getState(),
result.getReason(), userId);
}
@@ -5023,8 +5079,11 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
// This is undocumented so far, but IMM#showInputMethodPicker() has been
// implemented so that auxiliary subtypes will be excluded when the soft
// keyboard is invisible.
- case InputMethodManager.SHOW_IM_PICKER_MODE_AUTO ->
- showAuxSubtypes = mVisibilityStateComputer.isInputShown();
+ case InputMethodManager.SHOW_IM_PICKER_MODE_AUTO -> {
+ final var userData = getUserData(userId);
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
+ showAuxSubtypes = visibilityStateComputer.isInputShown();
+ }
case InputMethodManager.SHOW_IM_PICKER_MODE_INCLUDE_AUXILIARY_SUBTYPES ->
showAuxSubtypes = true;
case InputMethodManager.SHOW_IM_PICKER_MODE_EXCLUDE_AUXILIARY_SUBTYPES ->
@@ -5272,7 +5331,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
bindingController.getCurMethodUid())) {
// Handle IME visibility when interactive changed before finishing the input to
// ensure we preserve the last state as possible.
- final ImeVisibilityResult imeVisRes = mVisibilityStateComputer.onInteractiveChanged(
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
+ final ImeVisibilityResult imeVisRes = visibilityStateComputer.onInteractiveChanged(
userData.mImeBindingState.mFocusedWindow, interactive);
if (imeVisRes != null) {
// Pass in a null statsToken as the IME snapshot is not tracked by ImeTracker.
@@ -5927,7 +5987,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
// Hide the IME method menu only when the IME surface parent is changed by the
// input target changed, in case seeing the dialog dismiss flickering during
// the next focused window starting the input connection.
- if (mVisibilityStateComputer.getLastImeTargetWindow()
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
+ if (visibilityStateComputer.getLastImeTargetWindow()
!= userData.mImeBindingState.mFocusedWindow) {
if (mNewInputMethodSwitcherMenuEnabled) {
final var bindingController = getInputMethodBindingController(userId);
@@ -6299,7 +6360,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
method = bindingController.getCurMethod();
p.println(" mCurMethod=" + method);
p.println(" mEnabledSession=" + userData.mEnabledSession);
- mVisibilityStateComputer.dump(pw, " ");
+ final var visibilityStateComputer = userData.mVisibilityStateComputer;
+ visibilityStateComputer.dump(pw, " ");
p.println(" mInFullscreenMode=" + userData.mInFullscreenMode);
p.println(" mSystemReady=" + mSystemReady + " mInteractive=" + mIsInteractive);
p.println(" mConcurrentMultiUserModeEnabled=" + mConcurrentMultiUserModeEnabled);
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodMenuControllerNew.java b/services/core/java/com/android/server/inputmethod/InputMethodMenuControllerNew.java
index 35fae188a1dd..b72a34ddae5b 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodMenuControllerNew.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodMenuControllerNew.java
@@ -135,8 +135,8 @@ final class InputMethodMenuControllerNew {
final RecyclerView recyclerView = contentView
.requireViewById(com.android.internal.R.id.list);
recyclerView.setAdapter(new Adapter(items, selectedIndex, inflater, onClickListener));
- // Scroll to the currently selected IME.
- recyclerView.scrollToPosition(selectedIndex);
+ // Scroll to the currently selected IME. This must run after the recycler view is laid out.
+ recyclerView.post(() -> recyclerView.scrollToPosition(selectedIndex));
// Indicate that the list can be scrolled.
recyclerView.setScrollIndicators(
hasLanguageSettingsButton ? View.SCROLL_INDICATOR_BOTTOM : 0);
diff --git a/services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java b/services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java
index 476888ebf26d..3beec0909b21 100644
--- a/services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java
+++ b/services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java
@@ -20,10 +20,7 @@ import android.annotation.AnyThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
-import android.app.ActivityManagerInternal;
import android.content.ContentResolver;
-import android.content.Context;
-import android.content.pm.UserInfo;
import android.provider.Settings;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -321,30 +318,13 @@ final class SecureSettingsWrapper {
}
/**
- * Called when {@link InputMethodManagerService} is starting.
+ * Called when the system is starting.
*
- * @param context the {@link Context} to be used.
+ * @param contentResolver the {@link ContentResolver} to be used
*/
@AnyThread
- static void onStart(@NonNull Context context) {
- sContentResolver = context.getContentResolver();
-
- final int userId = LocalServices.getService(ActivityManagerInternal.class)
- .getCurrentUserId();
- final UserManagerInternal userManagerInternal =
- LocalServices.getService(UserManagerInternal.class);
- putOrGet(userId, createImpl(userManagerInternal, userId));
-
- userManagerInternal.addUserLifecycleListener(
- new UserManagerInternal.UserLifecycleListener() {
- @Override
- public void onUserRemoved(UserInfo user) {
- synchronized (sMutationLock) {
- sUserMap = sUserMap.cloneWithRemoveOrSelf(user.id);
- }
- }
- }
- );
+ static void setContentResolver(@NonNull ContentResolver contentResolver) {
+ sContentResolver = contentResolver;
}
/**
@@ -394,6 +374,18 @@ final class SecureSettingsWrapper {
}
/**
+ * Called when a user is being removed.
+ *
+ * @param userId the ID of the user whose storage is being removed
+ */
+ @AnyThread
+ static void onUserRemoved(@UserIdInt int userId) {
+ synchronized (sMutationLock) {
+ sUserMap = sUserMap.cloneWithRemoveOrSelf(userId);
+ }
+ }
+
+ /**
* Put the given string {@code value} to {@code key}.
*
* @param key a secure settings key.
diff --git a/services/core/java/com/android/server/inputmethod/UserData.java b/services/core/java/com/android/server/inputmethod/UserData.java
index 4fb55e191906..28394c6a6272 100644
--- a/services/core/java/com/android/server/inputmethod/UserData.java
+++ b/services/core/java/com/android/server/inputmethod/UserData.java
@@ -66,6 +66,9 @@ final class UserData {
final HardwareKeyboardShortcutController mHardwareKeyboardShortcutController =
new HardwareKeyboardShortcutController();
+ @NonNull
+ final ImeVisibilityStateComputer mVisibilityStateComputer;
+
/**
* Have we called mCurMethod.bindInput()?
*/
@@ -155,9 +158,11 @@ final class UserData {
* Intended to be instantiated only from this file.
*/
UserData(@UserIdInt int userId,
- @NonNull InputMethodBindingController bindingController) {
+ @NonNull InputMethodBindingController bindingController,
+ @NonNull ImeVisibilityStateComputer stateComputer) {
mUserId = userId;
mBindingController = bindingController;
+ mVisibilityStateComputer = stateComputer;
}
@Override
diff --git a/services/core/java/com/android/server/inputmethod/UserDataRepository.java b/services/core/java/com/android/server/inputmethod/UserDataRepository.java
index e3524b1f05e6..39f580c50624 100644
--- a/services/core/java/com/android/server/inputmethod/UserDataRepository.java
+++ b/services/core/java/com/android/server/inputmethod/UserDataRepository.java
@@ -30,7 +30,10 @@ final class UserDataRepository {
@NonNull
private volatile ImmutableSparseArray<UserData> mUserData = ImmutableSparseArray.empty();
+ @NonNull
private final IntFunction<InputMethodBindingController> mBindingControllerFactory;
+ @NonNull
+ private final IntFunction<ImeVisibilityStateComputer> mVisibilityStateComputerFactory;
@AnyThread
@NonNull
@@ -42,7 +45,8 @@ final class UserDataRepository {
}
// Note that the below line can be called concurrently. Here we assume that
// instantiating UserData for the same user multiple times would have no side effect.
- final var newUserData = new UserData(userId, mBindingControllerFactory.apply(userId));
+ final var newUserData = new UserData(userId, mBindingControllerFactory.apply(userId),
+ mVisibilityStateComputerFactory.apply(userId));
synchronized (mMutationLock) {
mUserData = mUserData.cloneWithPutOrSelf(userId, newUserData);
return newUserData;
@@ -54,9 +58,10 @@ final class UserDataRepository {
mUserData.forEach(consumer);
}
- UserDataRepository(
- @NonNull IntFunction<InputMethodBindingController> bindingControllerFactory) {
+ UserDataRepository(@NonNull IntFunction<InputMethodBindingController> bindingControllerFactory,
+ @NonNull IntFunction<ImeVisibilityStateComputer> visibilityStateComputerFactory) {
mBindingControllerFactory = bindingControllerFactory;
+ mVisibilityStateComputerFactory = visibilityStateComputerFactory;
}
@AnyThread
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java
index cd69ebaba766..2a0b1afde27b 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java
@@ -717,9 +717,13 @@ import java.util.concurrent.atomic.AtomicInteger;
}
mReliableMessageHostEndpointIdActiveSet.remove(transaction.getHostEndpointId());
- Log.d(TAG, "Successfully completed reliable message transaction with "
- + "message sequence number: " + transaction.getMessageSequenceNumber()
- + " and result: " + result);
+ Log.d(
+ TAG,
+ "Successfully completed reliable message transaction with "
+ + "message sequence number = "
+ + transaction.getMessageSequenceNumber()
+ + " and result = "
+ + result);
}
/**
@@ -732,15 +736,20 @@ import java.util.concurrent.atomic.AtomicInteger;
int numCompletedStartCalls = transaction.getNumCompletedStartCalls();
@ContextHubTransaction.Result int result = transaction.onTransact();
if (result == ContextHubTransaction.RESULT_SUCCESS) {
- Log.d(TAG, "Successfully "
- + (numCompletedStartCalls == 0 ? "started" : "retried")
- + " reliable message transaction with message sequence number: "
- + transaction.getMessageSequenceNumber());
+ Log.d(
+ TAG,
+ "Successfully "
+ + (numCompletedStartCalls == 0 ? "started" : "retried")
+ + " reliable message transaction with message sequence number = "
+ + transaction.getMessageSequenceNumber());
} else {
- Log.w(TAG, "Could not start reliable message transaction with "
- + "message sequence number: "
- + transaction.getMessageSequenceNumber()
- + ", result: " + result);
+ Log.w(
+ TAG,
+ "Could not start reliable message transaction with "
+ + "message sequence number = "
+ + transaction.getMessageSequenceNumber()
+ + ", result = "
+ + result);
}
transaction.setNextRetryTime(now + RELIABLE_MESSAGE_RETRY_WAIT_TIME.toNanos());
diff --git a/services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java b/services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java
index 5df0de83b567..df45a6ec985c 100644
--- a/services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java
+++ b/services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java
@@ -77,7 +77,7 @@ public class SystemEmergencyHelper extends EmergencyHelper {
mIsInEmergencyCall = mTelephonyManager.isEmergencyNumber(
intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER));
dispatchEmergencyStateChanged();
- } catch (IllegalStateException e) {
+ } catch (IllegalStateException | UnsupportedOperationException e) {
Log.w(TAG, "Failed to call TelephonyManager.isEmergencyNumber().", e);
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationAttentionHelper.java b/services/core/java/com/android/server/notification/NotificationAttentionHelper.java
index 5a9cf0326244..bd551fb2ab1b 100644
--- a/services/core/java/com/android/server/notification/NotificationAttentionHelper.java
+++ b/services/core/java/com/android/server/notification/NotificationAttentionHelper.java
@@ -230,9 +230,17 @@ public final class NotificationAttentionHelper {
mFlagResolver.getIntValue(NotificationFlags.NOTIF_VOLUME1),
mFlagResolver.getIntValue(NotificationFlags.NOTIF_VOLUME2),
mFlagResolver.getIntValue(NotificationFlags.NOTIF_COOLDOWN_COUNTER_RESET),
- record -> mPackageManager.checkPermission(
+ record -> {
+ final String category = record.getNotification().category;
+ if (Notification.CATEGORY_ALARM.equals(category)
+ || Notification.CATEGORY_CAR_EMERGENCY.equals(category)
+ || Notification.CATEGORY_CAR_WARNING.equals(category)) {
+ return true;
+ }
+ return mPackageManager.checkPermission(
permission.RECEIVE_EMERGENCY_BROADCAST,
- record.getSbn().getPackageName()) == PERMISSION_GRANTED);
+ record.getSbn().getPackageName()) == PERMISSION_GRANTED;
+ });
return new StrategyAvalanche(
mFlagResolver.getIntValue(NotificationFlags.NOTIF_COOLDOWN_T1),
@@ -248,9 +256,17 @@ public final class NotificationAttentionHelper {
mFlagResolver.getIntValue(NotificationFlags.NOTIF_VOLUME1),
mFlagResolver.getIntValue(NotificationFlags.NOTIF_VOLUME2),
mFlagResolver.getIntValue(NotificationFlags.NOTIF_COOLDOWN_COUNTER_RESET),
- record -> mPackageManager.checkPermission(
+ record -> {
+ final String category = record.getNotification().category;
+ if (Notification.CATEGORY_ALARM.equals(category)
+ || Notification.CATEGORY_CAR_EMERGENCY.equals(category)
+ || Notification.CATEGORY_CAR_WARNING.equals(category)) {
+ return true;
+ }
+ return mPackageManager.checkPermission(
permission.RECEIVE_EMERGENCY_BROADCAST,
- record.getSbn().getPackageName()) == PERMISSION_GRANTED);
+ record.getSbn().getPackageName()) == PERMISSION_GRANTED;
+ });
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index f615ca1da2e2..7156795ba771 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -693,13 +693,18 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
params.appLabel = TextUtils.trimToSize(params.appLabel,
PackageItemInfo.MAX_SAFE_LABEL_LENGTH);
- // Validate installer package name.
+ // Validate requested installer package name.
if (params.installerPackageName != null && !isValidPackageName(
params.installerPackageName)) {
params.installerPackageName = null;
}
- var requestedInstallerPackageName =
+ // Validate installer package name.
+ if (installerPackageName != null && !isValidPackageName(installerPackageName)) {
+ installerPackageName = null;
+ }
+
+ String requestedInstallerPackageName =
params.installerPackageName != null ? params.installerPackageName
: installerPackageName;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index c95be17b0430..21d6c6457e75 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2725,11 +2725,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override
void onLongPress(long eventTime) {
- // Long-press should be triggered only if app doesn't handle it.
- mDeferredKeyActionExecutor.queueKeyAction(
- KeyEvent.KEYCODE_STEM_PRIMARY,
- eventTime,
- () -> stemPrimaryLongPress(eventTime));
+ if (mLongPressOnStemPrimaryBehavior == LONG_PRESS_PRIMARY_LAUNCH_VOICE_ASSISTANT) {
+ // Long-press to assistant gesture is not overridable by apps.
+ stemPrimaryLongPress(eventTime);
+ } else {
+ // Other long-press actions should be triggered only if app doesn't handle it.
+ mDeferredKeyActionExecutor.queueKeyAction(
+ KeyEvent.KEYCODE_STEM_PRIMARY,
+ eventTime,
+ () -> stemPrimaryLongPress(eventTime));
+ }
}
@Override
diff --git a/services/core/java/com/android/server/power/stats/AggregatedPowerStats.java b/services/core/java/com/android/server/power/stats/AggregatedPowerStats.java
index e27f3b20b314..7496d2d0689d 100644
--- a/services/core/java/com/android/server/power/stats/AggregatedPowerStats.java
+++ b/services/core/java/com/android/server/power/stats/AggregatedPowerStats.java
@@ -27,6 +27,7 @@ import android.text.format.DateFormat;
import android.util.IndentingPrintWriter;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.util.TimeUtils;
import com.android.internal.os.PowerStats;
@@ -73,14 +74,21 @@ class AggregatedPowerStats {
private long mDurationMs;
AggregatedPowerStats(@NonNull AggregatedPowerStatsConfig aggregatedPowerStatsConfig) {
+ this(aggregatedPowerStatsConfig, new SparseBooleanArray());
+ }
+
+ AggregatedPowerStats(@NonNull AggregatedPowerStatsConfig aggregatedPowerStatsConfig,
+ @NonNull SparseBooleanArray enabledComponents) {
mConfig = aggregatedPowerStatsConfig;
List<PowerComponent> configs =
aggregatedPowerStatsConfig.getPowerComponentsAggregatedStatsConfigs();
mPowerComponentStats = new SparseArray<>(configs.size());
for (int i = 0; i < configs.size(); i++) {
PowerComponent powerComponent = configs.get(i);
- mPowerComponentStats.put(powerComponent.getPowerComponentId(),
- new PowerComponentAggregatedPowerStats(this, powerComponent));
+ if (enabledComponents.get(powerComponent.getPowerComponentId(), true)) {
+ mPowerComponentStats.put(powerComponent.getPowerComponentId(),
+ new PowerComponentAggregatedPowerStats(this, powerComponent));
+ }
}
mGenericPowerComponent = createGenericPowerComponent();
mPowerComponentStats.put(BatteryConsumer.POWER_COMPONENT_ANY, mGenericPowerComponent);
diff --git a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
index b308f3840383..d51cfeab2da9 100644
--- a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
+++ b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
@@ -428,5 +428,6 @@ public class BatteryUsageStatsProvider {
*/
public void setPowerStatsExporterEnabled(int powerComponentId, boolean enabled) {
mPowerStatsExporterEnabled.put(powerComponentId, enabled);
+ mPowerStatsExporter.setPowerComponentEnabled(powerComponentId, enabled);
}
}
diff --git a/services/core/java/com/android/server/power/stats/PowerStatsAggregator.java b/services/core/java/com/android/server/power/stats/PowerStatsAggregator.java
index 86f515cc3b4e..081e560bd74a 100644
--- a/services/core/java/com/android/server/power/stats/PowerStatsAggregator.java
+++ b/services/core/java/com/android/server/power/stats/PowerStatsAggregator.java
@@ -16,7 +16,9 @@
package com.android.server.power.stats;
import android.annotation.NonNull;
+import android.os.BatteryConsumer;
import android.os.BatteryStats;
+import android.util.SparseBooleanArray;
import com.android.internal.os.BatteryStatsHistory;
import com.android.internal.os.BatteryStatsHistoryIterator;
@@ -32,6 +34,8 @@ public class PowerStatsAggregator {
private static final long UNINITIALIZED = -1;
private final AggregatedPowerStatsConfig mAggregatedPowerStatsConfig;
private final BatteryStatsHistory mHistory;
+ private final SparseBooleanArray mEnabledComponents =
+ new SparseBooleanArray(BatteryConsumer.POWER_COMPONENT_COUNT + 10);
private AggregatedPowerStats mStats;
private int mCurrentBatteryState = AggregatedPowerStatsConfig.POWER_STATE_BATTERY;
private int mCurrentScreenState = AggregatedPowerStatsConfig.SCREEN_STATE_OTHER;
@@ -42,8 +46,13 @@ public class PowerStatsAggregator {
mHistory = history;
}
- AggregatedPowerStatsConfig getConfig() {
- return mAggregatedPowerStatsConfig;
+ void setPowerComponentEnabled(int powerComponentId, boolean enabled) {
+ synchronized (this) {
+ if (mStats != null) {
+ mStats = null;
+ }
+ mEnabledComponents.put(powerComponentId, enabled);
+ }
}
/**
@@ -62,7 +71,7 @@ public class PowerStatsAggregator {
Consumer<AggregatedPowerStats> consumer) {
synchronized (this) {
if (mStats == null) {
- mStats = new AggregatedPowerStats(mAggregatedPowerStatsConfig);
+ mStats = new AggregatedPowerStats(mAggregatedPowerStatsConfig, mEnabledComponents);
}
mStats.start(startTimeMs);
diff --git a/services/core/java/com/android/server/power/stats/PowerStatsExporter.java b/services/core/java/com/android/server/power/stats/PowerStatsExporter.java
index bd75faa4d5bb..281faf139a60 100644
--- a/services/core/java/com/android/server/power/stats/PowerStatsExporter.java
+++ b/services/core/java/com/android/server/power/stats/PowerStatsExporter.java
@@ -376,4 +376,8 @@ public class PowerStatsExporter {
}
return true;
}
+
+ void setPowerComponentEnabled(int powerComponentId, boolean enabled) {
+ mPowerStatsAggregator.setPowerComponentEnabled(powerComponentId, enabled);
+ }
}
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index c21f783003fa..331a594863e7 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -1301,7 +1301,7 @@ public class StatsPullAtomService extends SystemService {
final NetworkStats stats = getUidNetworkStatsSnapshotForTemplateLocked(
new NetworkTemplate.Builder(MATCH_PROXY).build(), /*includeTags=*/false);
if (stats != null) {
- ret.add(new NetworkStatsExt(sliceNetworkStatsByUidTagAndMetered(stats),
+ ret.add(new NetworkStatsExt(sliceNetworkStatsByUidAndFgbg(stats),
new int[]{TRANSPORT_BLUETOOTH},
/*slicedByFgbg=*/true, /*slicedByTag=*/false,
/*slicedByMetered=*/false, TelephonyManager.NETWORK_TYPE_UNKNOWN,
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperCropper.java b/services/core/java/com/android/server/wallpaper/WallpaperCropper.java
index 5d01bc33bb82..d5bea4adaf8c 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperCropper.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperCropper.java
@@ -601,8 +601,8 @@ public class WallpaperCropper {
.getDefaultDisplaySizes().get(orientation);
if (displayForThisOrientation == null) continue;
float sampleSizeForThisOrientation = Math.max(1f, Math.min(
- (float) crop.width() / displayForThisOrientation.x,
- (float) crop.height() / displayForThisOrientation.y));
+ crop.width() / displayForThisOrientation.x,
+ crop.height() / displayForThisOrientation.y));
sampleSize = Math.min(sampleSize, sampleSizeForThisOrientation);
}
// If the total crop has more width or height than either the max texture size
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index 4085ec90c95e..fb2bf39c0b7b 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -1612,7 +1612,8 @@ class ActivityMetricsLogger {
int positionToLog = APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__NOT_LETTERBOXED_POSITION;
if (isAppCompateStateChangedToLetterboxed(state)) {
- positionToLog = activity.mLetterboxUiController.getLetterboxPositionForLogging();
+ positionToLog = activity.mAppCompatController.getAppCompatReachabilityOverrides()
+ .getLetterboxPositionForLogging();
}
FrameworkStatsLog.write(FrameworkStatsLog.APP_COMPAT_STATE_CHANGED,
packageUid, state, positionToLog);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index c8aa815db749..7210098d8daf 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1988,8 +1988,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// Don't move below setOrientation(info.screenOrientation) since it triggers
// getOverrideOrientation that requires having mLetterboxUiController
// initialised.
- mLetterboxUiController = new LetterboxUiController(mWmService, this);
mAppCompatController = new AppCompatController(mWmService, this);
+ mLetterboxUiController = new LetterboxUiController(mWmService, this);
mResolveConfigHint = new TaskFragment.ConfigOverrideHint();
if (mWmService.mFlags.mInsetsDecoupledConfiguration) {
// When the stable configuration is the default behavior, override for the legacy apps
@@ -8633,8 +8633,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
/**
* Adjusts position of resolved bounds if they don't fill the parent using gravity
* requested in the config or via an ADB command. For more context see {@link
- * LetterboxUiController#getHorizontalPositionMultiplier(Configuration)} and
- * {@link LetterboxUiController#getVerticalPositionMultiplier(Configuration)}
+ * AppCompatReachabilityOverrides#getHorizontalPositionMultiplier(Configuration)} and
+ * {@link AppCompatReachabilityOverrides#getVerticalPositionMultiplier(Configuration)}
* <p>
* Note that this is the final step that can change the resolved bounds. After this method
* is called, the position of the bounds will be moved to app space as sandboxing if the
@@ -8663,11 +8663,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
} else {
navBarInsets = Insets.NONE;
}
+ final AppCompatReachabilityOverrides reachabilityOverrides =
+ mAppCompatController.getAppCompatReachabilityOverrides();
// Horizontal position
int offsetX = 0;
if (parentBounds.width() != screenResolvedBoundsWidth) {
if (screenResolvedBoundsWidth <= parentAppBoundsWidth) {
- float positionMultiplier = mLetterboxUiController.getHorizontalPositionMultiplier(
+ float positionMultiplier = reachabilityOverrides.getHorizontalPositionMultiplier(
newParentConfiguration);
// If in immersive mode, always align to right and overlap right insets (task bar)
// as they are transient and hidden. This removes awkward right spacing.
@@ -8688,7 +8690,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
int offsetY = 0;
if (parentBoundsHeight != screenResolvedBoundsHeight) {
if (screenResolvedBoundsHeight <= parentAppBoundsHeight) {
- float positionMultiplier = mLetterboxUiController.getVerticalPositionMultiplier(
+ float positionMultiplier = reachabilityOverrides.getVerticalPositionMultiplier(
newParentConfiguration);
// If in immersive mode, always align to bottom and overlap bottom insets (nav bar,
// task bar) as they are transient and hidden. This removes awkward bottom spacing.
diff --git a/services/core/java/com/android/server/wm/ActivitySnapshotController.java b/services/core/java/com/android/server/wm/ActivitySnapshotController.java
index aa63393b898b..24ed1bbe0eb1 100644
--- a/services/core/java/com/android/server/wm/ActivitySnapshotController.java
+++ b/services/core/java/com/android/server/wm/ActivitySnapshotController.java
@@ -23,7 +23,6 @@ import android.annotation.Nullable;
import android.app.ActivityManager;
import android.graphics.Rect;
import android.os.Environment;
-import android.os.SystemProperties;
import android.os.Trace;
import android.util.ArraySet;
import android.util.IntArray;
@@ -33,7 +32,6 @@ import android.window.TaskSnapshot;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wm.BaseAppSnapshotPersister.PersistInfoProvider;
-import com.android.window.flags.Flags;
import java.io.File;
import java.io.PrintWriter;
@@ -109,7 +107,6 @@ class ActivitySnapshotController extends AbsAppSnapshotController<ActivityRecord
!service.mContext
.getResources()
.getBoolean(com.android.internal.R.bool.config_disableTaskSnapshots)
- && isSnapshotEnabled()
&& !ActivityManager.isLowRamDeviceStatic(); // Don't support Android Go
setSnapshotEnabled(snapshotEnabled);
}
@@ -121,12 +118,6 @@ class ActivitySnapshotController extends AbsAppSnapshotController<ActivityRecord
return Math.max(Math.min(config, 1f), 0.1f);
}
- // TODO remove when enabled
- static boolean isSnapshotEnabled() {
- return SystemProperties.getInt("persist.wm.debug.activity_screenshot", 0) != 0
- || Flags.activitySnapshotByDefault();
- }
-
static PersistInfoProvider createPersistInfoProvider(
WindowManagerService service, BaseAppSnapshotPersister.DirectoryResolver resolver) {
// Don't persist reduced file, instead we only persist the "HighRes" bitmap which has
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index cc195ac6eae4..2f6e7deb5535 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -28,6 +28,8 @@ import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
import static android.app.ActivityManager.START_SUCCESS;
import static android.app.ActivityManager.START_TASK_TO_FRONT;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
+import static android.app.PendingIntent.FLAG_ONE_SHOT;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
@@ -146,6 +148,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.text.DateFormat;
import java.util.Date;
+import java.util.function.Supplier;
/**
* Controller for interpreting how and then launching an activity.
@@ -2079,9 +2082,23 @@ class ActivityStarter {
? targetTask.getWindowingMode() : displayContent.getWindowingMode();
final int launchingFromDisplayId =
mSourceRecord != null ? mSourceRecord.getDisplayId() : DEFAULT_DISPLAY;
+ final boolean isResultExpected = r.resultTo != null;
+ Supplier<IntentSender> intentSender = null;
+ if (android.companion.virtualdevice.flags.Flags.activityControlApi()) {
+ intentSender = () -> {
+ IIntentSender target = mService.getIntentSenderLocked(
+ ActivityManager.INTENT_SENDER_ACTIVITY, mRequest.callingPackage,
+ mRequest.callingFeatureId, mCallingUid, r.mUserId,
+ /* token= */ null, /* resultCode= */ null, /* requestCode= */ 0,
+ new Intent[]{ mIntent }, new String[]{ r.resolvedType },
+ FLAG_CANCEL_CURRENT | FLAG_ONE_SHOT,
+ mOptions == null ? null : mOptions.toBundle());
+ return new IntentSender(target);
+ };
+ }
if (!displayContent.mDwpcHelper
.canActivityBeLaunched(r.info, r.intent, targetWindowingMode,
- launchingFromDisplayId, newTask)) {
+ launchingFromDisplayId, newTask, isResultExpected, intentSender)) {
Slog.w(TAG, "Abort to launch " + r.info.getComponentName()
+ " on display area " + mPreferredTaskDisplayArea);
return START_ABORTED;
diff --git a/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java b/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java
index 25cb134a7c52..d2f3d1db16a7 100644
--- a/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java
+++ b/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java
@@ -50,8 +50,6 @@ import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wm.utils.OptPropFactory;
-import java.util.function.Function;
-
/**
* Encapsulates app compat configurations and overrides related to aspect ratio.
*/
@@ -76,20 +74,20 @@ class AppCompatAspectRatioOverrides {
@NonNull
private final OptPropFactory.OptProp mAllowOrientationOverrideOptProp;
@NonNull
- private final Function<Boolean, Boolean> mIsDisplayFullScreenAndInPostureProvider;
+ private final AppCompatDeviceStateQuery mAppCompatDeviceStateQuery;
@NonNull
- private final Function<Configuration, Float> mGetHorizontalPositionMultiplierProvider;
+ private final AppCompatReachabilityOverrides mAppCompatReachabilityOverrides;
AppCompatAspectRatioOverrides(@NonNull ActivityRecord activityRecord,
@NonNull AppCompatConfiguration appCompatConfiguration,
@NonNull OptPropFactory optPropBuilder,
- @NonNull Function<Boolean, Boolean> isDisplayFullScreenAndInPostureProvider,
- @NonNull Function<Configuration, Float> getHorizontalPositionMultiplierProvider) {
+ @NonNull AppCompatDeviceStateQuery appCompatDeviceStateQuery,
+ @NonNull AppCompatReachabilityOverrides appCompatReachabilityOverrides) {
mActivityRecord = activityRecord;
mAppCompatConfiguration = appCompatConfiguration;
+ mAppCompatDeviceStateQuery = appCompatDeviceStateQuery;
mUserAspectRatioState = new UserAspectRatioState();
- mIsDisplayFullScreenAndInPostureProvider = isDisplayFullScreenAndInPostureProvider;
- mGetHorizontalPositionMultiplierProvider = getHorizontalPositionMultiplierProvider;
+ mAppCompatReachabilityOverrides = appCompatReachabilityOverrides;
mAllowMinAspectRatioOverrideOptProp = optPropBuilder.create(
PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE);
mAllowUserAspectRatioOverrideOptProp = optPropBuilder.create(
@@ -245,12 +243,13 @@ class AppCompatAspectRatioOverrides {
}
private boolean shouldUseSplitScreenAspectRatio(@NonNull Configuration parentConfiguration) {
- final boolean isBookMode = mIsDisplayFullScreenAndInPostureProvider
- .apply(/* isTabletop */false);
- final boolean isNotCenteredHorizontally = mGetHorizontalPositionMultiplierProvider.apply(
- parentConfiguration) != LETTERBOX_POSITION_MULTIPLIER_CENTER;
- final boolean isTabletopMode = mIsDisplayFullScreenAndInPostureProvider
- .apply(/* isTabletop */ true);
+ final boolean isBookMode = mAppCompatDeviceStateQuery
+ .isDisplayFullScreenAndInPosture(/* isTabletop */false);
+ final boolean isNotCenteredHorizontally =
+ mAppCompatReachabilityOverrides.getHorizontalPositionMultiplier(parentConfiguration)
+ != LETTERBOX_POSITION_MULTIPLIER_CENTER;
+ final boolean isTabletopMode = mAppCompatDeviceStateQuery
+ .isDisplayFullScreenAndInPosture(/* isTabletop */ true);
final boolean isLandscape = isFixedOrientationLandscape(
mActivityRecord.getOverrideOrientation());
final AppCompatCameraOverrides cameraOverrides =
diff --git a/services/core/java/com/android/server/wm/AppCompatController.java b/services/core/java/com/android/server/wm/AppCompatController.java
index 54223b609449..d38edfc39a8a 100644
--- a/services/core/java/com/android/server/wm/AppCompatController.java
+++ b/services/core/java/com/android/server/wm/AppCompatController.java
@@ -35,7 +35,11 @@ class AppCompatController {
@NonNull
private final AppCompatAspectRatioPolicy mAppCompatAspectRatioPolicy;
@NonNull
+ private final AppCompatReachabilityPolicy mAppCompatReachabilityPolicy;
+ @NonNull
private final AppCompatOverrides mAppCompatOverrides;
+ @NonNull
+ private final AppCompatDeviceStateQuery mAppCompatDeviceStateQuery;
AppCompatController(@NonNull WindowManagerService wmService,
@NonNull ActivityRecord activityRecord) {
@@ -43,13 +47,16 @@ class AppCompatController {
final PackageManager packageManager = wmService.mContext.getPackageManager();
final OptPropFactory optPropBuilder = new OptPropFactory(packageManager,
activityRecord.packageName);
+ mAppCompatDeviceStateQuery = new AppCompatDeviceStateQuery(activityRecord);
mTransparentPolicy = new TransparentPolicy(activityRecord,
wmService.mAppCompatConfiguration);
mAppCompatOverrides = new AppCompatOverrides(activityRecord,
- wmService.mAppCompatConfiguration, optPropBuilder);
+ wmService.mAppCompatConfiguration, optPropBuilder, mAppCompatDeviceStateQuery);
mOrientationPolicy = new AppCompatOrientationPolicy(activityRecord, mAppCompatOverrides);
mAppCompatAspectRatioPolicy = new AppCompatAspectRatioPolicy(activityRecord,
mTransparentPolicy, mAppCompatOverrides);
+ mAppCompatReachabilityPolicy = new AppCompatReachabilityPolicy(mActivityRecord,
+ wmService.mAppCompatConfiguration);
}
@NonNull
@@ -101,7 +108,23 @@ class AppCompatController {
}
@NonNull
+ AppCompatReachabilityPolicy getAppCompatReachabilityPolicy() {
+ return mAppCompatReachabilityPolicy;
+ }
+
+ @NonNull
AppCompatFocusOverrides getAppCompatFocusOverrides() {
return mAppCompatOverrides.getAppCompatFocusOverrides();
}
+
+ @NonNull
+ AppCompatReachabilityOverrides getAppCompatReachabilityOverrides() {
+ return mAppCompatOverrides.getAppCompatReachabilityOverrides();
+ }
+
+ @NonNull
+ AppCompatDeviceStateQuery getAppCompatDeviceStateQuery() {
+ return mAppCompatDeviceStateQuery;
+ }
+
}
diff --git a/services/core/java/com/android/server/wm/AppCompatDeviceStateQuery.java b/services/core/java/com/android/server/wm/AppCompatDeviceStateQuery.java
new file mode 100644
index 000000000000..3abea24c530a
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AppCompatDeviceStateQuery.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+
+import android.annotation.NonNull;
+
+/**
+ * Provides information about the current state of the display in relation of
+ * fold/unfold and other positions.
+ */
+class AppCompatDeviceStateQuery {
+
+ @NonNull
+ final ActivityRecord mActivityRecord;
+
+ AppCompatDeviceStateQuery(@NonNull ActivityRecord activityRecord) {
+ mActivityRecord = activityRecord;
+ }
+
+ /**
+ * Check if we are in the given pose and in fullscreen mode.
+ *
+ * Note that we check the task rather than the parent as with ActivityEmbedding the parent
+ * might be a TaskFragment, and its windowing mode is always MULTI_WINDOW, even if the task is
+ * actually fullscreen. If display is still in transition e.g. unfolding, don't return true
+ * for HALF_FOLDED state or app will flicker.
+ */
+ boolean isDisplayFullScreenAndInPosture(boolean isTabletop) {
+ final Task task = mActivityRecord.getTask();
+ final DisplayContent dc = mActivityRecord.mDisplayContent;
+ return dc != null && task != null && !dc.inTransition()
+ && dc.getDisplayRotation().isDeviceInPosture(
+ DeviceStateController.DeviceState.HALF_FOLDED, isTabletop)
+ && task.getWindowingMode() == WINDOWING_MODE_FULLSCREEN;
+ }
+
+ /**
+ * Note that we check the task rather than the parent as with ActivityEmbedding the parent might
+ * be a TaskFragment, and its windowing mode is always MULTI_WINDOW, even if the task is
+ * actually fullscreen.
+ */
+ boolean isDisplayFullScreenAndSeparatingHinge() {
+ final Task task = mActivityRecord.getTask();
+ return mActivityRecord.mDisplayContent != null && task != null
+ && mActivityRecord.mDisplayContent.getDisplayRotation().isDisplaySeparatingHinge()
+ && task.getWindowingMode() == WINDOWING_MODE_FULLSCREEN;
+ }
+}
diff --git a/services/core/java/com/android/server/wm/AppCompatOverrides.java b/services/core/java/com/android/server/wm/AppCompatOverrides.java
index 445001178d26..80bbee3dd78d 100644
--- a/services/core/java/com/android/server/wm/AppCompatOverrides.java
+++ b/services/core/java/com/android/server/wm/AppCompatOverrides.java
@@ -35,19 +35,22 @@ public class AppCompatOverrides {
private final AppCompatFocusOverrides mAppCompatFocusOverrides;
@NonNull
private final AppCompatResizeOverrides mAppCompatResizeOverrides;
+ @NonNull
+ private final AppCompatReachabilityOverrides mAppCompatReachabilityOverrides;
AppCompatOverrides(@NonNull ActivityRecord activityRecord,
@NonNull AppCompatConfiguration appCompatConfiguration,
- @NonNull OptPropFactory optPropBuilder) {
+ @NonNull OptPropFactory optPropBuilder,
+ @NonNull AppCompatDeviceStateQuery appCompatDeviceStateQuery) {
mAppCompatCameraOverrides = new AppCompatCameraOverrides(activityRecord,
appCompatConfiguration, optPropBuilder);
mAppCompatOrientationOverrides = new AppCompatOrientationOverrides(activityRecord,
appCompatConfiguration, optPropBuilder, mAppCompatCameraOverrides);
- // TODO(b/341903757) Remove BooleanSuppliers after fixing dependency with reachability.
+ mAppCompatReachabilityOverrides = new AppCompatReachabilityOverrides(activityRecord,
+ appCompatConfiguration, appCompatDeviceStateQuery);
mAppCompatAspectRatioOverrides = new AppCompatAspectRatioOverrides(activityRecord,
- appCompatConfiguration, optPropBuilder,
- activityRecord.mLetterboxUiController::isDisplayFullScreenAndInPosture,
- activityRecord.mLetterboxUiController::getHorizontalPositionMultiplier);
+ appCompatConfiguration, optPropBuilder, appCompatDeviceStateQuery,
+ mAppCompatReachabilityOverrides);
mAppCompatFocusOverrides = new AppCompatFocusOverrides(activityRecord,
appCompatConfiguration, optPropBuilder);
mAppCompatResizeOverrides = new AppCompatResizeOverrides(activityRecord, optPropBuilder);
@@ -77,4 +80,9 @@ public class AppCompatOverrides {
AppCompatResizeOverrides getAppCompatResizeOverrides() {
return mAppCompatResizeOverrides;
}
+
+ @NonNull
+ AppCompatReachabilityOverrides getAppCompatReachabilityOverrides() {
+ return mAppCompatReachabilityOverrides;
+ }
}
diff --git a/services/core/java/com/android/server/wm/AppCompatReachabilityOverrides.java b/services/core/java/com/android/server/wm/AppCompatReachabilityOverrides.java
new file mode 100644
index 000000000000..b9bdc325cf98
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AppCompatReachabilityOverrides.java
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+
+import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__BOTTOM;
+import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__CENTER;
+import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__LEFT;
+import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__RIGHT;
+import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__TOP;
+import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__UNKNOWN_POSITION;
+import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER;
+import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT;
+import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT;
+import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM;
+import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER;
+import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP;
+
+import android.annotation.NonNull;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.window.flags.Flags;
+
+/**
+ * Encapsulate overrides and configurations about app compat reachability.
+ */
+class AppCompatReachabilityOverrides {
+
+ @NonNull
+ private final ActivityRecord mActivityRecord;
+ @NonNull
+ private final AppCompatConfiguration mAppCompatConfiguration;
+ @NonNull
+ private final AppCompatDeviceStateQuery mAppCompatDeviceStateQuery;
+ @NonNull
+ private final ReachabilityState mReachabilityState;
+
+ AppCompatReachabilityOverrides(@NonNull ActivityRecord activityRecord,
+ @NonNull AppCompatConfiguration appCompatConfiguration,
+ @NonNull AppCompatDeviceStateQuery appCompatDeviceStateQuery) {
+ mActivityRecord = activityRecord;
+ mAppCompatConfiguration = appCompatConfiguration;
+ mAppCompatDeviceStateQuery = appCompatDeviceStateQuery;
+ mReachabilityState = new ReachabilityState();
+ }
+
+ boolean isFromDoubleTap() {
+ return mReachabilityState.isFromDoubleTap();
+ }
+
+ boolean isDoubleTapEvent() {
+ return mReachabilityState.mIsDoubleTapEvent;
+ }
+
+ void setDoubleTapEvent() {
+ mReachabilityState.mIsDoubleTapEvent = true;
+ }
+
+ /**
+ * Provides the multiplier to use when calculating the position of a letterboxed app after
+ * an horizontal reachability event (double tap). The method takes the current state of the
+ * device (e.g. device in book mode) into account.
+ * </p>
+ * @param parentConfiguration The parent {@link Configuration}.
+ * @return The value to use for calculating the letterbox horizontal position.
+ */
+ float getHorizontalPositionMultiplier(@NonNull Configuration parentConfiguration) {
+ // Don't check resolved configuration because it may not be updated yet during
+ // configuration change.
+ boolean bookModeEnabled = isFullScreenAndBookModeEnabled();
+ return isHorizontalReachabilityEnabled(parentConfiguration)
+ // Using the last global dynamic position to avoid "jumps" when moving
+ // between apps or activities.
+ ? mAppCompatConfiguration.getHorizontalMultiplierForReachability(bookModeEnabled)
+ : mAppCompatConfiguration.getLetterboxHorizontalPositionMultiplier(bookModeEnabled);
+ }
+
+ /**
+ * Provides the multiplier to use when calculating the position of a letterboxed app after
+ * a vertical reachability event (double tap). The method takes the current state of the
+ * device (e.g. device posture) into account.
+ * </p>
+ * @param parentConfiguration The parent {@link Configuration}.
+ * @return The value to use for calculating the letterbox horizontal position.
+ */
+ float getVerticalPositionMultiplier(@NonNull Configuration parentConfiguration) {
+ // Don't check resolved configuration because it may not be updated yet during
+ // configuration change.
+ boolean tabletopMode = mAppCompatDeviceStateQuery
+ .isDisplayFullScreenAndInPosture(/* isTabletop */ true);
+ return isVerticalReachabilityEnabled(parentConfiguration)
+ // Using the last global dynamic position to avoid "jumps" when moving
+ // between apps or activities.
+ ? mAppCompatConfiguration.getVerticalMultiplierForReachability(tabletopMode)
+ : mAppCompatConfiguration.getLetterboxVerticalPositionMultiplier(tabletopMode);
+ }
+
+ @VisibleForTesting
+ boolean isHorizontalReachabilityEnabled() {
+ return isHorizontalReachabilityEnabled(mActivityRecord.getParent().getConfiguration());
+ }
+
+ @VisibleForTesting
+ boolean isVerticalReachabilityEnabled() {
+ return isVerticalReachabilityEnabled(mActivityRecord.getParent().getConfiguration());
+ }
+
+ boolean isLetterboxDoubleTapEducationEnabled() {
+ return isHorizontalReachabilityEnabled() || isVerticalReachabilityEnabled();
+ }
+
+ @AppCompatConfiguration.LetterboxVerticalReachabilityPosition
+ int getLetterboxPositionForVerticalReachability() {
+ final boolean isInFullScreenTabletopMode =
+ mAppCompatDeviceStateQuery.isDisplayFullScreenAndSeparatingHinge();
+ return mAppCompatConfiguration.getLetterboxPositionForVerticalReachability(
+ isInFullScreenTabletopMode);
+ }
+
+ @AppCompatConfiguration.LetterboxHorizontalReachabilityPosition
+ int getLetterboxPositionForHorizontalReachability() {
+ final boolean isInFullScreenBookMode = isFullScreenAndBookModeEnabled();
+ return mAppCompatConfiguration.getLetterboxPositionForHorizontalReachability(
+ isInFullScreenBookMode);
+ }
+
+ int getLetterboxPositionForLogging() {
+ int positionToLog = APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__UNKNOWN_POSITION;
+ if (isHorizontalReachabilityEnabled()) {
+ int letterboxPositionForHorizontalReachability = mAppCompatConfiguration
+ .getLetterboxPositionForHorizontalReachability(mAppCompatDeviceStateQuery
+ .isDisplayFullScreenAndInPosture(/* isTabletop */ false));
+ positionToLog = letterboxHorizontalReachabilityPositionToLetterboxPositionForLogging(
+ letterboxPositionForHorizontalReachability);
+ } else if (isVerticalReachabilityEnabled()) {
+ int letterboxPositionForVerticalReachability = mAppCompatConfiguration
+ .getLetterboxPositionForVerticalReachability(mAppCompatDeviceStateQuery
+ .isDisplayFullScreenAndInPosture(/* isTabletop */ true));
+ positionToLog = letterboxVerticalReachabilityPositionToLetterboxPositionForLogging(
+ letterboxPositionForVerticalReachability);
+ }
+ return positionToLog;
+ }
+
+ /**
+ * @return {@value true} if the vertical reachability should be allowed in case of
+ * thin letterboxing.
+ */
+ boolean allowVerticalReachabilityForThinLetterbox() {
+ if (!Flags.disableThinLetterboxingPolicy()) {
+ return true;
+ }
+ // When the flag is enabled we allow vertical reachability only if the
+ // app is not thin letterboxed vertically.
+ return !isVerticalThinLetterboxed();
+ }
+
+ /**
+ * @return {@value true} if the horizontal reachability should be enabled in case of
+ * thin letterboxing.
+ */
+ boolean allowHorizontalReachabilityForThinLetterbox() {
+ if (!Flags.disableThinLetterboxingPolicy()) {
+ return true;
+ }
+ // When the flag is enabled we allow horizontal reachability only if the
+ // app is not thin pillarboxed.
+ return !isHorizontalThinLetterboxed();
+ }
+
+ /**
+ * @return {@value true} if the resulting app is letterboxed in a way defined as thin.
+ */
+ boolean isVerticalThinLetterboxed() {
+ final int thinHeight = mAppCompatConfiguration.getThinLetterboxHeightPx();
+ if (thinHeight < 0) {
+ return false;
+ }
+ final Task task = mActivityRecord.getTask();
+ if (task == null) {
+ return false;
+ }
+ final int padding = Math.abs(
+ task.getBounds().height() - mActivityRecord.getBounds().height()) / 2;
+ return padding <= thinHeight;
+ }
+
+ /**
+ * @return {@value true} if the resulting app is pillarboxed in a way defined as thin.
+ */
+ boolean isHorizontalThinLetterboxed() {
+ final int thinWidth = mAppCompatConfiguration.getThinLetterboxWidthPx();
+ if (thinWidth < 0) {
+ return false;
+ }
+ final Task task = mActivityRecord.getTask();
+ if (task == null) {
+ return false;
+ }
+ final int padding = Math.abs(
+ task.getBounds().width() - mActivityRecord.getBounds().width()) / 2;
+ return padding <= thinWidth;
+ }
+
+ // Note that we check the task rather than the parent as with ActivityEmbedding the parent might
+ // be a TaskFragment, and its windowing mode is always MULTI_WINDOW, even if the task is
+ // actually fullscreen.
+ private boolean isDisplayFullScreenAndSeparatingHinge() {
+ Task task = mActivityRecord.getTask();
+ return mActivityRecord.mDisplayContent != null
+ && mActivityRecord.mDisplayContent.getDisplayRotation().isDisplaySeparatingHinge()
+ && task != null
+ && task.getWindowingMode() == WINDOWING_MODE_FULLSCREEN;
+ }
+
+ private int letterboxHorizontalReachabilityPositionToLetterboxPositionForLogging(
+ @AppCompatConfiguration.LetterboxHorizontalReachabilityPosition int position) {
+ switch (position) {
+ case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT:
+ return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__LEFT;
+ case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER:
+ return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__CENTER;
+ case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT:
+ return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__RIGHT;
+ default:
+ throw new AssertionError(
+ "Unexpected letterbox horizontal reachability position type: "
+ + position);
+ }
+ }
+
+ private int letterboxVerticalReachabilityPositionToLetterboxPositionForLogging(
+ @AppCompatConfiguration.LetterboxVerticalReachabilityPosition int position) {
+ switch (position) {
+ case LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP:
+ return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__TOP;
+ case LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER:
+ return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__CENTER;
+ case LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM:
+ return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__BOTTOM;
+ default:
+ throw new AssertionError(
+ "Unexpected letterbox vertical reachability position type: "
+ + position);
+ }
+ }
+
+ private boolean isFullScreenAndBookModeEnabled() {
+ return mAppCompatDeviceStateQuery.isDisplayFullScreenAndInPosture(/* isTabletop */ false)
+ && mAppCompatConfiguration.getIsAutomaticReachabilityInBookModeEnabled();
+ }
+
+ /**
+ * Whether horizontal reachability is enabled for an activity in the current configuration.
+ *
+ * <p>Conditions that needs to be met:
+ * <ul>
+ * <li>Windowing mode is fullscreen.
+ * <li>Horizontal Reachability is enabled.
+ * <li>First top opaque activity fills parent vertically, but not horizontally.
+ * </ul>
+ */
+ private boolean isHorizontalReachabilityEnabled(@NonNull Configuration parentConfiguration) {
+ if (!allowHorizontalReachabilityForThinLetterbox()) {
+ return false;
+ }
+ final Rect parentAppBoundsOverride = mActivityRecord.getParentAppBoundsOverride();
+ final Rect parentAppBounds = parentAppBoundsOverride != null
+ ? parentAppBoundsOverride : parentConfiguration.windowConfiguration.getAppBounds();
+ // Use screen resolved bounds which uses resolved bounds or size compat bounds
+ // as activity bounds can sometimes be empty
+ final Rect opaqueActivityBounds = mActivityRecord.mAppCompatController
+ .getTransparentPolicy().getFirstOpaqueActivity()
+ .map(ActivityRecord::getScreenResolvedBounds)
+ .orElse(mActivityRecord.getScreenResolvedBounds());
+ return mAppCompatConfiguration.getIsHorizontalReachabilityEnabled()
+ && parentConfiguration.windowConfiguration.getWindowingMode()
+ == WINDOWING_MODE_FULLSCREEN
+ // Check whether the activity fills the parent vertically.
+ && parentAppBounds.height() <= opaqueActivityBounds.height()
+ && parentAppBounds.width() > opaqueActivityBounds.width();
+ }
+
+ /**
+ * Whether vertical reachability is enabled for an activity in the current configuration.
+ *
+ * <p>Conditions that needs to be met:
+ * <ul>
+ * <li>Windowing mode is fullscreen.
+ * <li>Vertical Reachability is enabled.
+ * <li>First top opaque activity fills parent horizontally but not vertically.
+ * </ul>
+ */
+ private boolean isVerticalReachabilityEnabled(@NonNull Configuration parentConfiguration) {
+ if (!allowVerticalReachabilityForThinLetterbox()) {
+ return false;
+ }
+ final Rect parentAppBoundsOverride = mActivityRecord.getParentAppBoundsOverride();
+ final Rect parentAppBounds = parentAppBoundsOverride != null
+ ? parentAppBoundsOverride : parentConfiguration.windowConfiguration.getAppBounds();
+ // Use screen resolved bounds which uses resolved bounds or size compat bounds
+ // as activity bounds can sometimes be empty.
+ final Rect opaqueActivityBounds = mActivityRecord.mAppCompatController
+ .getTransparentPolicy().getFirstOpaqueActivity()
+ .map(ActivityRecord::getScreenResolvedBounds)
+ .orElse(mActivityRecord.getScreenResolvedBounds());
+ return mAppCompatConfiguration.getIsVerticalReachabilityEnabled()
+ && parentConfiguration.windowConfiguration.getWindowingMode()
+ == WINDOWING_MODE_FULLSCREEN
+ // Check whether the activity fills the parent horizontally.
+ && parentAppBounds.width() <= opaqueActivityBounds.width()
+ && parentAppBounds.height() > opaqueActivityBounds.height();
+ }
+
+ private static class ReachabilityState {
+ // If the current event is a double tap.
+ private boolean mIsDoubleTapEvent;
+
+ boolean isFromDoubleTap() {
+ final boolean isFromDoubleTap = mIsDoubleTapEvent;
+ mIsDoubleTapEvent = false;
+ return isFromDoubleTap;
+ }
+ }
+
+}
diff --git a/services/core/java/com/android/server/wm/AppCompatReachabilityPolicy.java b/services/core/java/com/android/server/wm/AppCompatReachabilityPolicy.java
new file mode 100644
index 000000000000..90bfddb2095f
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AppCompatReachabilityPolicy.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__BOTTOM_TO_CENTER;
+import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_BOTTOM;
+import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_LEFT;
+import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_RIGHT;
+import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_TOP;
+import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__LEFT_TO_CENTER;
+import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__RIGHT_TO_CENTER;
+import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__TOP_TO_CENTER;
+import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER;
+import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.graphics.Rect;
+
+import java.util.function.Supplier;
+
+/**
+ * Encapsulate logic about app compat reachability.
+ */
+class AppCompatReachabilityPolicy {
+
+ @NonNull
+ private final ActivityRecord mActivityRecord;
+ @NonNull
+ private final AppCompatConfiguration mAppCompatConfiguration;
+ @Nullable
+ private Supplier<Rect> mLetterboxInnerBoundsSupplier;
+
+ AppCompatReachabilityPolicy(@NonNull ActivityRecord activityRecord,
+ @NonNull AppCompatConfiguration appCompatConfiguration) {
+ mActivityRecord = activityRecord;
+ mAppCompatConfiguration = appCompatConfiguration;
+ }
+
+ /**
+ * To handle reachability a supplier for the current letterox inner bounds is required.
+ * <p/>
+ * @param letterboxInnerBoundsSupplier The supplier for the letterbox inner bounds.
+ */
+ void setLetterboxInnerBoundsSupplier(@Nullable Supplier<Rect> letterboxInnerBoundsSupplier) {
+ mLetterboxInnerBoundsSupplier = letterboxInnerBoundsSupplier;
+ }
+
+ /**
+ * Handles double tap events for reachability.
+ * <p/>
+ * @param x Double tap x coordinate.
+ * @param y Double tap y coordinate.
+ */
+ void handleDoubleTap(int x, int y) {
+ handleHorizontalDoubleTap(x);
+ handleVerticalDoubleTap(y);
+ }
+
+ private void handleHorizontalDoubleTap(int x) {
+ final AppCompatReachabilityOverrides reachabilityOverrides =
+ mActivityRecord.mAppCompatController.getAppCompatReachabilityOverrides();
+ if (!reachabilityOverrides.isHorizontalReachabilityEnabled()
+ || mActivityRecord.isInTransition()) {
+ return;
+ }
+ final Rect letterboxInnerFrame = getLetterboxInnerFrame();
+ if (letterboxInnerFrame.left <= x && letterboxInnerFrame.right >= x) {
+ // Only react to clicks at the sides of the letterboxed app window.
+ return;
+ }
+ final AppCompatDeviceStateQuery deviceStateQuery = mActivityRecord.mAppCompatController
+ .getAppCompatDeviceStateQuery();
+ final boolean isInFullScreenBookMode = deviceStateQuery
+ .isDisplayFullScreenAndSeparatingHinge()
+ && mAppCompatConfiguration.getIsAutomaticReachabilityInBookModeEnabled();
+ final int letterboxPositionForHorizontalReachability = mAppCompatConfiguration
+ .getLetterboxPositionForHorizontalReachability(isInFullScreenBookMode);
+ if (letterboxInnerFrame.left > x) {
+ // Moving to the next stop on the left side of the app window: right > center > left.
+ mAppCompatConfiguration.movePositionForHorizontalReachabilityToNextLeftStop(
+ isInFullScreenBookMode);
+ int letterboxPositionChangeForLog =
+ letterboxPositionForHorizontalReachability
+ == LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER
+ ? LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_LEFT
+ : LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__RIGHT_TO_CENTER;
+ logLetterboxPositionChange(letterboxPositionChangeForLog);
+ reachabilityOverrides.setDoubleTapEvent();
+ } else if (letterboxInnerFrame.right < x) {
+ // Moving to the next stop on the right side of the app window: left > center > right.
+ mAppCompatConfiguration.movePositionForHorizontalReachabilityToNextRightStop(
+ isInFullScreenBookMode);
+ final int letterboxPositionChangeForLog =
+ letterboxPositionForHorizontalReachability
+ == LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER
+ ? LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_RIGHT
+ : LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__LEFT_TO_CENTER;
+ logLetterboxPositionChange(letterboxPositionChangeForLog);
+ reachabilityOverrides.setDoubleTapEvent();
+ }
+ // TODO(197549949): Add animation for transition.
+ mActivityRecord.recomputeConfiguration();
+ }
+
+ private void handleVerticalDoubleTap(int y) {
+ final AppCompatReachabilityOverrides reachabilityOverrides =
+ mActivityRecord.mAppCompatController.getAppCompatReachabilityOverrides();
+ if (!reachabilityOverrides.isVerticalReachabilityEnabled()
+ || mActivityRecord.isInTransition()) {
+ return;
+ }
+ final Rect letterboxInnerFrame = getLetterboxInnerFrame();
+ if (letterboxInnerFrame.top <= y && letterboxInnerFrame.bottom >= y) {
+ // Only react to clicks at the top and bottom of the letterboxed app window.
+ return;
+ }
+ final AppCompatDeviceStateQuery deviceStateQuery = mActivityRecord.mAppCompatController
+ .getAppCompatDeviceStateQuery();
+ final boolean isInFullScreenTabletopMode = deviceStateQuery
+ .isDisplayFullScreenAndSeparatingHinge();
+ final int letterboxPositionForVerticalReachability = mAppCompatConfiguration
+ .getLetterboxPositionForVerticalReachability(isInFullScreenTabletopMode);
+ if (letterboxInnerFrame.top > y) {
+ // Moving to the next stop on the top side of the app window: bottom > center > top.
+ mAppCompatConfiguration.movePositionForVerticalReachabilityToNextTopStop(
+ isInFullScreenTabletopMode);
+ final int letterboxPositionChangeForLog =
+ letterboxPositionForVerticalReachability
+ == LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER
+ ? LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_TOP
+ : LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__BOTTOM_TO_CENTER;
+ logLetterboxPositionChange(letterboxPositionChangeForLog);
+ reachabilityOverrides.setDoubleTapEvent();
+ } else if (letterboxInnerFrame.bottom < y) {
+ // Moving to the next stop on the bottom side of the app window: top > center > bottom.
+ mAppCompatConfiguration.movePositionForVerticalReachabilityToNextBottomStop(
+ isInFullScreenTabletopMode);
+ final int letterboxPositionChangeForLog =
+ letterboxPositionForVerticalReachability
+ == LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER
+ ? LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_BOTTOM
+ : LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__TOP_TO_CENTER;
+ logLetterboxPositionChange(letterboxPositionChangeForLog);
+ reachabilityOverrides.setDoubleTapEvent();
+ }
+ // TODO(197549949): Add animation for transition.
+ mActivityRecord.recomputeConfiguration();
+ }
+
+ /**
+ * Logs letterbox position changes via {@link ActivityMetricsLogger#logLetterboxPositionChange}.
+ */
+ private void logLetterboxPositionChange(int letterboxPositionChangeForLog) {
+ mActivityRecord.mTaskSupervisor.getActivityMetricsLogger()
+ .logLetterboxPositionChange(mActivityRecord, letterboxPositionChangeForLog);
+ }
+
+ @NonNull
+ private Rect getLetterboxInnerFrame() {
+ return mLetterboxInnerBoundsSupplier != null ? mLetterboxInnerBoundsSupplier.get()
+ : new Rect();
+ }
+}
diff --git a/services/core/java/com/android/server/wm/AppCompatUtils.java b/services/core/java/com/android/server/wm/AppCompatUtils.java
index a4cb389f118c..0244d27f4363 100644
--- a/services/core/java/com/android/server/wm/AppCompatUtils.java
+++ b/services/core/java/com/android/server/wm/AppCompatUtils.java
@@ -63,7 +63,7 @@ class AppCompatUtils {
/**
* Returns the aspect ratio of the given {@code rect}.
*/
- static float computeAspectRatio(Rect rect) {
+ static float computeAspectRatio(@NonNull Rect rect) {
final int width = rect.width();
final int height = rect.height();
if (width == 0 || height == 0) {
@@ -89,75 +89,138 @@ class AppCompatUtils {
return activityRecord.info.isChangeEnabled(overrideChangeId);
}
+ /**
+ * Attempts to return the app bounds (bounds without insets) of the top most opaque activity. If
+ * these are not available, it defaults to the bounds of the activity which include insets. In
+ * the event the activity is in Size Compat Mode, the Size Compat bounds are returned instead.
+ */
+ @NonNull
+ static Rect getAppBounds(@NonNull ActivityRecord activityRecord) {
+ // TODO(b/268458693): Refactor configuration inheritance in case of translucent activities
+ final Rect appBounds = activityRecord.getConfiguration().windowConfiguration.getAppBounds();
+ if (appBounds == null) {
+ return activityRecord.getBounds();
+ }
+ return activityRecord.mAppCompatController.getTransparentPolicy()
+ .findOpaqueNotFinishingActivityBelow()
+ .map(AppCompatUtils::getAppBounds)
+ .orElseGet(() -> {
+ if (activityRecord.hasSizeCompatBounds()) {
+ return activityRecord.getScreenResolvedBounds();
+ }
+ return appBounds;
+ });
+ }
+
static void fillAppCompatTaskInfo(@NonNull Task task, @NonNull TaskInfo info,
@Nullable ActivityRecord top) {
final AppCompatTaskInfo appCompatTaskInfo = info.appCompatTaskInfo;
- appCompatTaskInfo.topActivityLetterboxVerticalPosition = TaskInfo.PROPERTY_VALUE_UNSET;
- appCompatTaskInfo.topActivityLetterboxHorizontalPosition = TaskInfo.PROPERTY_VALUE_UNSET;
- appCompatTaskInfo.topActivityLetterboxWidth = TaskInfo.PROPERTY_VALUE_UNSET;
- appCompatTaskInfo.topActivityLetterboxHeight = TaskInfo.PROPERTY_VALUE_UNSET;
- appCompatTaskInfo.cameraCompatTaskInfo.freeformCameraCompatMode =
- CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE;
+ clearAppCompatTaskInfo(appCompatTaskInfo);
if (top == null) {
return;
}
-
+ final AppCompatReachabilityOverrides reachabilityOverrides = top.mAppCompatController
+ .getAppCompatReachabilityOverrides();
final boolean isTopActivityResumed = top.getOrganizedTask() == task && top.isState(RESUMED);
final boolean isTopActivityVisible = top.getOrganizedTask() == task && top.isVisible();
// Whether the direct top activity is in size compat mode.
- appCompatTaskInfo.topActivityInSizeCompat = isTopActivityVisible && top.inSizeCompatMode();
- if (appCompatTaskInfo.topActivityInSizeCompat
+ appCompatTaskInfo.setTopActivityInSizeCompat(
+ isTopActivityVisible && top.inSizeCompatMode());
+ if (appCompatTaskInfo.isTopActivityInSizeCompat()
&& top.mWmService.mAppCompatConfiguration.isTranslucentLetterboxingEnabled()) {
// We hide the restart button in case of transparent activities.
- appCompatTaskInfo.topActivityInSizeCompat = top.fillsParent();
+ appCompatTaskInfo.setTopActivityInSizeCompat(top.fillsParent());
}
// Whether the direct top activity is eligible for letterbox education.
- appCompatTaskInfo.topActivityEligibleForLetterboxEducation = isTopActivityResumed
- && top.isEligibleForLetterboxEducation();
- appCompatTaskInfo.isLetterboxEducationEnabled = top.mLetterboxUiController
- .isLetterboxEducationEnabled();
-
- appCompatTaskInfo.isUserFullscreenOverrideEnabled = top.mAppCompatController
- .getAppCompatAspectRatioOverrides().shouldApplyUserFullscreenOverride();
- appCompatTaskInfo.isSystemFullscreenOverrideEnabled = top.mAppCompatController
- .getAppCompatAspectRatioOverrides().isSystemOverrideToFullscreenEnabled();
-
- appCompatTaskInfo.isFromLetterboxDoubleTap = top.mLetterboxUiController.isFromDoubleTap();
- appCompatTaskInfo.topActivityLetterboxWidth = top.getBounds().width();
- appCompatTaskInfo.topActivityLetterboxHeight = top.getBounds().height();
+ appCompatTaskInfo.setEligibleForLetterboxEducation(
+ isTopActivityResumed && top.isEligibleForLetterboxEducation());
+ appCompatTaskInfo.setLetterboxEducationEnabled(top.mLetterboxUiController
+ .isLetterboxEducationEnabled());
+
+ final AppCompatAspectRatioOverrides aspectRatioOverrides =
+ top.mAppCompatController.getAppCompatAspectRatioOverrides();
+ appCompatTaskInfo.setUserFullscreenOverrideEnabled(
+ aspectRatioOverrides.shouldApplyUserFullscreenOverride());
+ appCompatTaskInfo.setSystemFullscreenOverrideEnabled(
+ aspectRatioOverrides.isSystemOverrideToFullscreenEnabled());
+
+ appCompatTaskInfo.setIsFromLetterboxDoubleTap(reachabilityOverrides.isFromDoubleTap());
+
+ final Rect bounds = top.getBounds();
+ final Rect appBounds = getAppBounds(top);
+ appCompatTaskInfo.topActivityLetterboxWidth = bounds.width();
+ appCompatTaskInfo.topActivityLetterboxHeight = bounds.height();
+ appCompatTaskInfo.topActivityLetterboxAppWidth = appBounds.width();
+ appCompatTaskInfo.topActivityLetterboxAppHeight = appBounds.height();
// We need to consider if letterboxed or pillarboxed.
// TODO(b/336807329) Encapsulate reachability logic
- appCompatTaskInfo.isLetterboxDoubleTapEnabled = top.mLetterboxUiController
- .isLetterboxDoubleTapEducationEnabled();
- if (appCompatTaskInfo.isLetterboxDoubleTapEnabled) {
+ appCompatTaskInfo.setLetterboxDoubleTapEnabled(reachabilityOverrides
+ .isLetterboxDoubleTapEducationEnabled());
+ if (appCompatTaskInfo.isLetterboxDoubleTapEnabled()) {
if (appCompatTaskInfo.isTopActivityPillarboxed()) {
- if (top.mLetterboxUiController.allowHorizontalReachabilityForThinLetterbox()) {
+ if (reachabilityOverrides.allowHorizontalReachabilityForThinLetterbox()) {
// Pillarboxed.
appCompatTaskInfo.topActivityLetterboxHorizontalPosition =
- top.mLetterboxUiController
- .getLetterboxPositionForHorizontalReachability();
+ reachabilityOverrides.getLetterboxPositionForHorizontalReachability();
} else {
- appCompatTaskInfo.isLetterboxDoubleTapEnabled = false;
+ appCompatTaskInfo.setLetterboxDoubleTapEnabled(false);
}
} else {
- if (top.mLetterboxUiController.allowVerticalReachabilityForThinLetterbox()) {
+ if (reachabilityOverrides.allowVerticalReachabilityForThinLetterbox()) {
// Letterboxed.
appCompatTaskInfo.topActivityLetterboxVerticalPosition =
- top.mLetterboxUiController
- .getLetterboxPositionForVerticalReachability();
+ reachabilityOverrides.getLetterboxPositionForVerticalReachability();
} else {
- appCompatTaskInfo.isLetterboxDoubleTapEnabled = false;
+ appCompatTaskInfo.setLetterboxDoubleTapEnabled(false);
}
}
}
- appCompatTaskInfo.topActivityEligibleForUserAspectRatioButton =
- !info.isTopActivityTransparent && !appCompatTaskInfo.topActivityInSizeCompat
- && top.mAppCompatController.getAppCompatAspectRatioOverrides()
- .shouldEnableUserAspectRatioSettings();
- appCompatTaskInfo.topActivityBoundsLetterboxed = top.areBoundsLetterboxed();
+ final boolean eligibleForAspectRatioButton =
+ !info.isTopActivityTransparent && !appCompatTaskInfo.isTopActivityInSizeCompat()
+ && aspectRatioOverrides.shouldEnableUserAspectRatioSettings();
+ appCompatTaskInfo.setEligibleForUserAspectRatioButton(eligibleForAspectRatioButton);
+ appCompatTaskInfo.setTopActivityLetterboxed(top.areBoundsLetterboxed());
appCompatTaskInfo.cameraCompatTaskInfo.freeformCameraCompatMode = top.mAppCompatController
.getAppCompatCameraOverrides().getFreeformCameraCompatMode();
}
+
+ /**
+ * Returns a string representing the reason for letterboxing. This method assumes the activity
+ * is letterboxed.
+ * @param activityRecord The {@link ActivityRecord} for the letterboxed activity.
+ * @param mainWin The {@link WindowState} used to letterboxing.
+ */
+ @NonNull
+ static String getLetterboxReasonString(@NonNull ActivityRecord activityRecord,
+ @NonNull WindowState mainWin) {
+ if (activityRecord.inSizeCompatMode()) {
+ return "SIZE_COMPAT_MODE";
+ }
+ final AppCompatAspectRatioPolicy aspectRatioPolicy = activityRecord.mAppCompatController
+ .getAppCompatAspectRatioPolicy();
+ if (aspectRatioPolicy.isLetterboxedForFixedOrientationAndAspectRatio()) {
+ return "FIXED_ORIENTATION";
+ }
+ if (mainWin.isLetterboxedForDisplayCutout()) {
+ return "DISPLAY_CUTOUT";
+ }
+ if (aspectRatioPolicy.isLetterboxedForAspectRatioOnly()) {
+ return "ASPECT_RATIO";
+ }
+ return "UNKNOWN_REASON";
+ }
+
+ private static void clearAppCompatTaskInfo(@NonNull AppCompatTaskInfo info) {
+ info.topActivityLetterboxVerticalPosition = TaskInfo.PROPERTY_VALUE_UNSET;
+ info.topActivityLetterboxHorizontalPosition = TaskInfo.PROPERTY_VALUE_UNSET;
+ info.topActivityLetterboxWidth = TaskInfo.PROPERTY_VALUE_UNSET;
+ info.topActivityLetterboxHeight = TaskInfo.PROPERTY_VALUE_UNSET;
+ info.topActivityLetterboxAppHeight = TaskInfo.PROPERTY_VALUE_UNSET;
+ info.topActivityLetterboxAppWidth = TaskInfo.PROPERTY_VALUE_UNSET;
+ info.cameraCompatTaskInfo.freeformCameraCompatMode =
+ CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE;
+ info.clearTopActivityFlags();
+ }
}
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index 924f765ae79d..48e107931913 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -963,8 +963,7 @@ class BackNavigationController {
mWindowManagerService = wms;
final Context context = wms.mContext;
mShowWindowlessSurface = context.getResources().getBoolean(
- com.android.internal.R.bool.config_predictShowStartingSurface)
- && Flags.activitySnapshotByDefault();
+ com.android.internal.R.bool.config_predictShowStartingSurface);
}
private static final int UNKNOWN = 0;
private static final int TASK_SWITCH = 1;
diff --git a/services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java b/services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java
index 9996bbcb6597..f566df5fd147 100644
--- a/services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java
+++ b/services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java
@@ -234,12 +234,13 @@ public final class DesktopModeBoundsCalculator {
float desiredAspectRatio = 0;
if (taskInfo.isRunning) {
final AppCompatTaskInfo appCompatTaskInfo = taskInfo.appCompatTaskInfo;
- if (appCompatTaskInfo.topActivityBoundsLetterboxed) {
- desiredAspectRatio = (float) Math.max(
- appCompatTaskInfo.topActivityLetterboxWidth,
- appCompatTaskInfo.topActivityLetterboxHeight)
- / Math.min(appCompatTaskInfo.topActivityLetterboxWidth,
- appCompatTaskInfo.topActivityLetterboxHeight);
+ final int appLetterboxWidth =
+ taskInfo.appCompatTaskInfo.topActivityLetterboxAppWidth;
+ final int appLetterboxHeight =
+ taskInfo.appCompatTaskInfo.topActivityLetterboxAppHeight;
+ if (appCompatTaskInfo.isTopActivityLetterboxed()) {
+ desiredAspectRatio = (float) Math.max(appLetterboxWidth, appLetterboxHeight)
+ / Math.min(appLetterboxWidth, appLetterboxHeight);
} else {
desiredAspectRatio = Math.max(fullscreenHeight, fullscreenWidth)
/ Math.min(fullscreenHeight, fullscreenWidth);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 3a0de850771a..9c8c759765bc 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -4415,13 +4415,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mWmService.dispatchImeInputTargetVisibilityChanged(
targetWin.mClient.asBinder(), isVisibleRequested,
targetWin.mActivityRecord != null
- && targetWin.mActivityRecord.finishing);
+ && targetWin.mActivityRecord.finishing,
+ mDisplayId);
}
});
targetWin.mToken.registerWindowContainerListener(
mImeTargetTokenListenerPair.second);
mWmService.dispatchImeInputTargetVisibilityChanged(targetWin.mClient.asBinder(),
- targetWin.isVisible() /* visible */, false /* removed */);
+ targetWin.isVisible() /* visible */, false /* removed */, mDisplayId);
}
}
if (refreshImeSecureFlag(getPendingTransaction())) {
diff --git a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
index 4ec318bee726..dedf35a74e04 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
@@ -24,6 +24,7 @@ import android.app.WindowConfiguration;
import android.companion.virtualdevice.flags.Flags;
import android.content.ComponentName;
import android.content.Intent;
+import android.content.IntentSender;
import android.content.pm.ActivityInfo;
import android.os.Process;
import android.os.UserHandle;
@@ -34,6 +35,7 @@ import android.window.DisplayWindowPolicyController;
import java.io.PrintWriter;
import java.util.List;
+import java.util.function.Supplier;
class DisplayWindowPolicyControllerHelper {
private static final String TAG = "DisplayWindowPolicyControllerHelper";
@@ -98,7 +100,8 @@ class DisplayWindowPolicyControllerHelper {
*/
public boolean canActivityBeLaunched(ActivityInfo activityInfo,
Intent intent, @WindowConfiguration.WindowingMode int windowingMode,
- int launchingFromDisplayId, boolean isNewTask) {
+ int launchingFromDisplayId, boolean isNewTask, boolean isResultExpected,
+ Supplier<IntentSender> intentSender) {
if (mDisplayWindowPolicyController == null) {
// Missing controller means that this display has no categories for activity launch
// restriction.
@@ -111,7 +114,7 @@ class DisplayWindowPolicyControllerHelper {
return true;
}
return mDisplayWindowPolicyController.canActivityBeLaunched(activityInfo, intent,
- windowingMode, launchingFromDisplayId, isNewTask);
+ windowingMode, launchingFromDisplayId, isNewTask, isResultExpected, intentSender);
}
private boolean hasDisplayCategory(ActivityInfo aInfo) {
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java b/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java
index 27e6e0997c89..7135c3b8cda8 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java
@@ -44,7 +44,6 @@ import com.android.internal.util.XmlUtils;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
import com.android.server.wm.DisplayWindowSettings.SettingsProvider;
-import com.android.window.flags.Flags;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -145,9 +144,6 @@ class DisplayWindowSettingsProvider implements SettingsProvider {
* @see #DATA_DISPLAY_SETTINGS_FILE_PATH
*/
void setOverrideSettingsForUser(@UserIdInt int userId) {
- if (!Flags.perUserDisplayWindowSettings()) {
- return;
- }
final AtomicFile settingsFile = getOverrideSettingsFileForUser(userId);
setOverrideSettingsStorage(new AtomicFileStorage(settingsFile));
}
@@ -165,9 +161,6 @@ class DisplayWindowSettingsProvider implements SettingsProvider {
*/
void removeStaleDisplaySettingsLocked(@NonNull WindowManagerService wms,
@NonNull RootWindowContainer root) {
- if (!Flags.perUserDisplayWindowSettings()) {
- return;
- }
final Set<String> displayIdentifiers = new ArraySet<>();
final Consumer<DisplayInfo> addDisplayIdentifier =
displayInfo -> displayIdentifiers.add(mOverrideSettings.getIdentifier(displayInfo));
@@ -403,12 +396,9 @@ class DisplayWindowSettingsProvider implements SettingsProvider {
@NonNull
private static AtomicFile getOverrideSettingsFileForUser(@UserIdInt int userId) {
- final File directory;
- if (userId == USER_SYSTEM || !Flags.perUserDisplayWindowSettings()) {
- directory = Environment.getDataDirectory();
- } else {
- directory = Environment.getDataSystemCeDirectory(userId);
- }
+ final File directory = (userId == USER_SYSTEM)
+ ? Environment.getDataDirectory()
+ : Environment.getDataSystemCeDirectory(userId);
final File overrideSettingsFile = new File(directory, DATA_DISPLAY_SETTINGS_FILE_PATH);
return new AtomicFile(overrideSettingsFile, WM_DISPLAY_COMMIT_TAG);
}
diff --git a/services/core/java/com/android/server/wm/ImeTargetChangeListener.java b/services/core/java/com/android/server/wm/ImeTargetChangeListener.java
index 88b76aaa6992..e94f17c37051 100644
--- a/services/core/java/com/android/server/wm/ImeTargetChangeListener.java
+++ b/services/core/java/com/android/server/wm/ImeTargetChangeListener.java
@@ -37,25 +37,27 @@ public interface ImeTargetChangeListener {
* @param visible the visibility of the overlay window, {@code true} means visible
* and {@code false} otherwise.
* @param removed Whether the IME target overlay window has being removed.
+ * @param displayId display ID where the overlay window exists.
*/
default void onImeTargetOverlayVisibilityChanged(@NonNull IBinder overlayWindowToken,
@WindowManager.LayoutParams.WindowType int windowType,
- boolean visible, boolean removed) {
+ boolean visible, boolean removed, int displayId) {
}
/**
* Called when the visibility of IME input target window has changed.
*
* @param imeInputTarget the window token of the IME input target window.
- * @param visible the new window visibility made by {@param imeInputTarget}. visible is
+ * @param visible the new window visibility made by {@code imeInputTarget}. visible is
* {@code true} when switching to the new visible IME input target
* window and started input, or the same input target relayout to
* visible from invisible. In contrast, visible is {@code false} when
* closing the input target, or the same input target relayout to
* invisible from visible.
* @param removed Whether the IME input target window has being removed.
+ * @param displayId display ID where the overlay window exists.
*/
default void onImeInputTargetVisibilityChanged(@NonNull IBinder imeInputTarget, boolean visible,
- boolean removed) {
+ boolean removed, int displayId) {
}
}
diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java
index 2aa7c0c0a401..3fc5eafc8737 100644
--- a/services/core/java/com/android/server/wm/Letterbox.java
+++ b/services/core/java/com/android/server/wm/Letterbox.java
@@ -40,7 +40,6 @@ import com.android.server.UiThread;
import java.util.function.BooleanSupplier;
import java.util.function.DoubleSupplier;
-import java.util.function.IntConsumer;
import java.util.function.IntSupplier;
import java.util.function.Supplier;
@@ -76,9 +75,8 @@ public class Letterbox {
// for overlaping an app window and letterbox surfaces.
private final LetterboxSurface mFullWindowSurface = new LetterboxSurface("fullWindow");
private final LetterboxSurface[] mSurfaces = { mLeft, mTop, mRight, mBottom };
- // Reachability gestures.
- private final IntConsumer mDoubleTapCallbackX;
- private final IntConsumer mDoubleTapCallbackY;
+ @NonNull
+ private final AppCompatReachabilityPolicy mAppCompatReachabilityPolicy;
/**
* Constructs a Letterbox.
@@ -92,8 +90,7 @@ public class Letterbox {
BooleanSupplier hasWallpaperBackgroundSupplier,
IntSupplier blurRadiusSupplier,
DoubleSupplier darkScrimAlphaSupplier,
- IntConsumer doubleTapCallbackX,
- IntConsumer doubleTapCallbackY,
+ @NonNull AppCompatReachabilityPolicy appCompatReachabilityPolicy,
Supplier<SurfaceControl> parentSurface) {
mSurfaceControlFactory = surfaceControlFactory;
mTransactionFactory = transactionFactory;
@@ -102,9 +99,10 @@ public class Letterbox {
mHasWallpaperBackgroundSupplier = hasWallpaperBackgroundSupplier;
mBlurRadiusSupplier = blurRadiusSupplier;
mDarkScrimAlphaSupplier = darkScrimAlphaSupplier;
- mDoubleTapCallbackX = doubleTapCallbackX;
- mDoubleTapCallbackY = doubleTapCallbackY;
+ mAppCompatReachabilityPolicy = appCompatReachabilityPolicy;
mParentSurfaceSupplier = parentSurface;
+ // TODO Remove after Letterbox refactoring.
+ mAppCompatReachabilityPolicy.setLetterboxInnerBoundsSupplier(this::getInnerFrame);
}
/**
@@ -290,8 +288,8 @@ public class Letterbox {
// This check prevents late events to be handled in case the Letterbox has been
// already destroyed and so mOuter.isEmpty() is true.
if (!mOuter.isEmpty() && e.getAction() == MotionEvent.ACTION_UP) {
- mDoubleTapCallbackX.accept((int) e.getRawX());
- mDoubleTapCallbackY.accept((int) e.getRawY());
+ mAppCompatReachabilityPolicy.handleDoubleTap((int) e.getRawX(),
+ (int) e.getRawY());
return true;
}
return false;
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index 291eab1b2d94..38df1b0e0511 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -16,43 +16,21 @@
package com.android.server.wm;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
-import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__BOTTOM;
-import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__CENTER;
-import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__LEFT;
-import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__RIGHT;
-import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__TOP;
-import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__UNKNOWN_POSITION;
-import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__BOTTOM_TO_CENTER;
-import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_BOTTOM;
-import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_LEFT;
-import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_RIGHT;
-import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_TOP;
-import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__LEFT_TO_CENTER;
-import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__RIGHT_TO_CENTER;
-import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__TOP_TO_CENTER;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_BACKGROUND_SOLID_COLOR;
import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_BACKGROUND_WALLPAPER;
-import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER;
-import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT;
-import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT;
-import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM;
-import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER;
-import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP;
import static com.android.server.wm.AppCompatConfiguration.letterboxBackgroundTypeToString;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager.TaskDescription;
-import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
@@ -68,7 +46,6 @@ import android.view.WindowManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.statusbar.LetterboxDetails;
import com.android.server.wm.AppCompatConfiguration.LetterboxBackgroundType;
-import com.android.window.flags.Flags;
import java.io.PrintWriter;
@@ -85,6 +62,16 @@ final class LetterboxUiController {
private final ActivityRecord mActivityRecord;
+ // TODO(b/356385137): Remove these we added to make dependencies temporarily explicit.
+ @NonNull
+ private final AppCompatReachabilityOverrides mAppCompatReachabilityOverrides;
+ @NonNull
+ private final AppCompatReachabilityPolicy mAppCompatReachabilityPolicy;
+ @NonNull
+ private final TransparentPolicy mTransparentPolicy;
+ @NonNull
+ private final AppCompatOrientationOverrides mAppCompatOrientationOverrides;
+
private boolean mShowWallpaperForLetterboxBackground;
@Nullable
@@ -92,14 +79,21 @@ final class LetterboxUiController {
private boolean mLastShouldShowLetterboxUi;
- private boolean mDoubleTapEvent;
-
LetterboxUiController(WindowManagerService wmService, ActivityRecord activityRecord) {
mAppCompatConfiguration = wmService.mAppCompatConfiguration;
// Given activityRecord may not be fully constructed since LetterboxUiController
// is created in its constructor. It shouldn't be used in this constructor but it's safe
// to use it after since controller is only used in ActivityRecord.
mActivityRecord = activityRecord;
+ // TODO(b/356385137): Remove these we added to make dependencies temporarily explicit.
+ mAppCompatReachabilityOverrides = mActivityRecord.mAppCompatController
+ .getAppCompatReachabilityOverrides();
+ mAppCompatReachabilityPolicy = mActivityRecord.mAppCompatController
+ .getAppCompatReachabilityPolicy();
+ mTransparentPolicy = mActivityRecord.mAppCompatController.getTransparentPolicy();
+ mAppCompatOrientationOverrides = mActivityRecord.mAppCompatController
+ .getAppCompatOrientationOverrides();
+
}
/** Cleans up {@link Letterbox} if it exists.*/
@@ -107,6 +101,8 @@ final class LetterboxUiController {
if (mLetterbox != null) {
mLetterbox.destroy();
mLetterbox = null;
+ // TODO Remove after Letterbox refactoring.
+ mAppCompatReachabilityPolicy.setLetterboxInnerBoundsSupplier(null);
}
}
@@ -190,8 +186,7 @@ final class LetterboxUiController {
this::hasWallpaperBackgroundForLetterbox,
this::getLetterboxWallpaperBlurRadiusPx,
this::getLetterboxWallpaperDarkScrimAlpha,
- this::handleHorizontalDoubleTap,
- this::handleVerticalDoubleTap,
+ mAppCompatReachabilityPolicy,
this::getLetterboxParentSurface);
mLetterbox.attachInput(w);
}
@@ -227,11 +222,10 @@ final class LetterboxUiController {
// For this reason we use ActivityRecord#getBounds() that the translucent activity
// inherits from the first opaque activity beneath and also takes care of the scaling
// in case of activities in size compat mode.
- final Rect innerFrame = mActivityRecord.mAppCompatController
- .getTransparentPolicy().isRunning()
- ? mActivityRecord.getBounds() : w.getFrame();
+ final Rect innerFrame =
+ mTransparentPolicy.isRunning() ? mActivityRecord.getBounds() : w.getFrame();
mLetterbox.layout(spaceToFill, innerFrame, mTmpPoint);
- if (mDoubleTapEvent) {
+ if (mAppCompatReachabilityOverrides.isDoubleTapEvent()) {
// We need to notify Shell that letterbox position has changed.
mActivityRecord.getTask().dispatchTaskInfoChangedIfNeeded(true /* force */);
}
@@ -240,12 +234,6 @@ final class LetterboxUiController {
}
}
- boolean isFromDoubleTap() {
- final boolean isFromDoubleTap = mDoubleTapEvent;
- mDoubleTapEvent = false;
- return isFromDoubleTap;
- }
-
SurfaceControl getLetterboxParentSurface() {
if (mActivityRecord.isInLetterboxAnimation()) {
return mActivityRecord.getTask().getSurfaceControl();
@@ -272,310 +260,13 @@ final class LetterboxUiController {
&& mActivityRecord.fillsParent();
}
- // Check if we are in the given pose and in fullscreen mode.
- // Note that we check the task rather than the parent as with ActivityEmbedding the parent might
- // be a TaskFragment, and its windowing mode is always MULTI_WINDOW, even if the task is
- // actually fullscreen. If display is still in transition e.g. unfolding, don't return true
- // for HALF_FOLDED state or app will flicker.
- boolean isDisplayFullScreenAndInPosture(boolean isTabletop) {
- Task task = mActivityRecord.getTask();
- return mActivityRecord.mDisplayContent != null && task != null
- && mActivityRecord.mDisplayContent.getDisplayRotation().isDeviceInPosture(
- DeviceStateController.DeviceState.HALF_FOLDED, isTabletop)
- && !mActivityRecord.mDisplayContent.inTransition()
- && task.getWindowingMode() == WINDOWING_MODE_FULLSCREEN;
- }
-
- // Note that we check the task rather than the parent as with ActivityEmbedding the parent might
- // be a TaskFragment, and its windowing mode is always MULTI_WINDOW, even if the task is
- // actually fullscreen.
- private boolean isDisplayFullScreenAndSeparatingHinge() {
- Task task = mActivityRecord.getTask();
- return mActivityRecord.mDisplayContent != null
- && mActivityRecord.mDisplayContent.getDisplayRotation().isDisplaySeparatingHinge()
- && task != null
- && task.getWindowingMode() == WINDOWING_MODE_FULLSCREEN;
- }
-
-
- float getHorizontalPositionMultiplier(Configuration parentConfiguration) {
- // Don't check resolved configuration because it may not be updated yet during
- // configuration change.
- boolean bookModeEnabled = isFullScreenAndBookModeEnabled();
- return isHorizontalReachabilityEnabled(parentConfiguration)
- // Using the last global dynamic position to avoid "jumps" when moving
- // between apps or activities.
- ? mAppCompatConfiguration.getHorizontalMultiplierForReachability(bookModeEnabled)
- : mAppCompatConfiguration.getLetterboxHorizontalPositionMultiplier(bookModeEnabled);
- }
-
- private boolean isFullScreenAndBookModeEnabled() {
- return isDisplayFullScreenAndInPosture(/* isTabletop */ false)
- && mAppCompatConfiguration.getIsAutomaticReachabilityInBookModeEnabled();
- }
-
- float getVerticalPositionMultiplier(Configuration parentConfiguration) {
- // Don't check resolved configuration because it may not be updated yet during
- // configuration change.
- boolean tabletopMode = isDisplayFullScreenAndInPosture(/* isTabletop */ true);
- return isVerticalReachabilityEnabled(parentConfiguration)
- // Using the last global dynamic position to avoid "jumps" when moving
- // between apps or activities.
- ? mAppCompatConfiguration.getVerticalMultiplierForReachability(tabletopMode)
- : mAppCompatConfiguration.getLetterboxVerticalPositionMultiplier(tabletopMode);
- }
-
boolean isLetterboxEducationEnabled() {
return mAppCompatConfiguration.getIsEducationEnabled();
}
- /**
- * @return {@value true} if the resulting app is letterboxed in a way defined as thin.
- */
- boolean isVerticalThinLetterboxed() {
- final int thinHeight = mAppCompatConfiguration.getThinLetterboxHeightPx();
- if (thinHeight < 0) {
- return false;
- }
- final Task task = mActivityRecord.getTask();
- if (task == null) {
- return false;
- }
- final int padding = Math.abs(
- task.getBounds().height() - mActivityRecord.getBounds().height()) / 2;
- return padding <= thinHeight;
- }
-
- /**
- * @return {@value true} if the resulting app is pillarboxed in a way defined as thin.
- */
- boolean isHorizontalThinLetterboxed() {
- final int thinWidth = mAppCompatConfiguration.getThinLetterboxWidthPx();
- if (thinWidth < 0) {
- return false;
- }
- final Task task = mActivityRecord.getTask();
- if (task == null) {
- return false;
- }
- final int padding = Math.abs(
- task.getBounds().width() - mActivityRecord.getBounds().width()) / 2;
- return padding <= thinWidth;
- }
-
-
- /**
- * @return {@value true} if the vertical reachability should be allowed in case of
- * thin letteboxing
- */
- boolean allowVerticalReachabilityForThinLetterbox() {
- if (!Flags.disableThinLetterboxingPolicy()) {
- return true;
- }
- // When the flag is enabled we allow vertical reachability only if the
- // app is not thin letterboxed vertically.
- return !isVerticalThinLetterboxed();
- }
-
- /**
- * @return {@value true} if the vertical reachability should be enabled in case of
- * thin letteboxing
- */
- boolean allowHorizontalReachabilityForThinLetterbox() {
- if (!Flags.disableThinLetterboxingPolicy()) {
- return true;
- }
- // When the flag is enabled we allow horizontal reachability only if the
- // app is not thin pillarboxed.
- return !isHorizontalThinLetterboxed();
- }
-
- boolean shouldOverrideMinAspectRatio() {
- return mActivityRecord.mAppCompatController.getAppCompatAspectRatioOverrides()
- .shouldOverrideMinAspectRatio();
- }
-
- @AppCompatConfiguration.LetterboxVerticalReachabilityPosition
- int getLetterboxPositionForVerticalReachability() {
- final boolean isInFullScreenTabletopMode = isDisplayFullScreenAndSeparatingHinge();
- return mAppCompatConfiguration.getLetterboxPositionForVerticalReachability(
- isInFullScreenTabletopMode);
- }
-
- @AppCompatConfiguration.LetterboxHorizontalReachabilityPosition
- int getLetterboxPositionForHorizontalReachability() {
- final boolean isInFullScreenBookMode = isFullScreenAndBookModeEnabled();
- return mAppCompatConfiguration.getLetterboxPositionForHorizontalReachability(
- isInFullScreenBookMode);
- }
-
- @VisibleForTesting
- void handleHorizontalDoubleTap(int x) {
- if (!isHorizontalReachabilityEnabled() || mActivityRecord.isInTransition()) {
- return;
- }
-
- if (mLetterbox.getInnerFrame().left <= x && mLetterbox.getInnerFrame().right >= x) {
- // Only react to clicks at the sides of the letterboxed app window.
- return;
- }
-
- boolean isInFullScreenBookMode = isDisplayFullScreenAndSeparatingHinge()
- && mAppCompatConfiguration.getIsAutomaticReachabilityInBookModeEnabled();
- int letterboxPositionForHorizontalReachability = mAppCompatConfiguration
- .getLetterboxPositionForHorizontalReachability(isInFullScreenBookMode);
- if (mLetterbox.getInnerFrame().left > x) {
- // Moving to the next stop on the left side of the app window: right > center > left.
- mAppCompatConfiguration.movePositionForHorizontalReachabilityToNextLeftStop(
- isInFullScreenBookMode);
- int changeToLog =
- letterboxPositionForHorizontalReachability
- == LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER
- ? LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_LEFT
- : LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__RIGHT_TO_CENTER;
- logLetterboxPositionChange(changeToLog);
- mDoubleTapEvent = true;
- } else if (mLetterbox.getInnerFrame().right < x) {
- // Moving to the next stop on the right side of the app window: left > center > right.
- mAppCompatConfiguration.movePositionForHorizontalReachabilityToNextRightStop(
- isInFullScreenBookMode);
- int changeToLog =
- letterboxPositionForHorizontalReachability
- == LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER
- ? LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_RIGHT
- : LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__LEFT_TO_CENTER;
- logLetterboxPositionChange(changeToLog);
- mDoubleTapEvent = true;
- }
- // TODO(197549949): Add animation for transition.
- mActivityRecord.recomputeConfiguration();
- }
-
- @VisibleForTesting
- void handleVerticalDoubleTap(int y) {
- if (!isVerticalReachabilityEnabled() || mActivityRecord.isInTransition()) {
- return;
- }
-
- if (mLetterbox.getInnerFrame().top <= y && mLetterbox.getInnerFrame().bottom >= y) {
- // Only react to clicks at the top and bottom of the letterboxed app window.
- return;
- }
- boolean isInFullScreenTabletopMode = isDisplayFullScreenAndSeparatingHinge();
- int letterboxPositionForVerticalReachability = mAppCompatConfiguration
- .getLetterboxPositionForVerticalReachability(isInFullScreenTabletopMode);
- if (mLetterbox.getInnerFrame().top > y) {
- // Moving to the next stop on the top side of the app window: bottom > center > top.
- mAppCompatConfiguration.movePositionForVerticalReachabilityToNextTopStop(
- isInFullScreenTabletopMode);
- int changeToLog =
- letterboxPositionForVerticalReachability
- == LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER
- ? LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_TOP
- : LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__BOTTOM_TO_CENTER;
- logLetterboxPositionChange(changeToLog);
- mDoubleTapEvent = true;
- } else if (mLetterbox.getInnerFrame().bottom < y) {
- // Moving to the next stop on the bottom side of the app window: top > center > bottom.
- mAppCompatConfiguration.movePositionForVerticalReachabilityToNextBottomStop(
- isInFullScreenTabletopMode);
- int changeToLog =
- letterboxPositionForVerticalReachability
- == LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER
- ? LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_BOTTOM
- : LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__TOP_TO_CENTER;
- logLetterboxPositionChange(changeToLog);
- mDoubleTapEvent = true;
- }
- // TODO(197549949): Add animation for transition.
- mActivityRecord.recomputeConfiguration();
- }
-
- /**
- * Whether horizontal reachability is enabled for an activity in the current configuration.
- *
- * <p>Conditions that needs to be met:
- * <ul>
- * <li>Windowing mode is fullscreen.
- * <li>Horizontal Reachability is enabled.
- * <li>First top opaque activity fills parent vertically, but not horizontally.
- * </ul>
- */
- private boolean isHorizontalReachabilityEnabled(Configuration parentConfiguration) {
- if (!allowHorizontalReachabilityForThinLetterbox()) {
- return false;
- }
- final Rect parentAppBoundsOverride = mActivityRecord.getParentAppBoundsOverride();
- final Rect parentAppBounds = parentAppBoundsOverride != null
- ? parentAppBoundsOverride : parentConfiguration.windowConfiguration.getAppBounds();
- // Use screen resolved bounds which uses resolved bounds or size compat bounds
- // as activity bounds can sometimes be empty
- final Rect opaqueActivityBounds = mActivityRecord.mAppCompatController
- .getTransparentPolicy().getFirstOpaqueActivity()
- .map(ActivityRecord::getScreenResolvedBounds)
- .orElse(mActivityRecord.getScreenResolvedBounds());
- return mAppCompatConfiguration.getIsHorizontalReachabilityEnabled()
- && parentConfiguration.windowConfiguration.getWindowingMode()
- == WINDOWING_MODE_FULLSCREEN
- // Check whether the activity fills the parent vertically.
- && parentAppBounds.height() <= opaqueActivityBounds.height()
- && parentAppBounds.width() > opaqueActivityBounds.width();
- }
-
- @VisibleForTesting
- boolean isHorizontalReachabilityEnabled() {
- return isHorizontalReachabilityEnabled(mActivityRecord.getParent().getConfiguration());
- }
-
- boolean isLetterboxDoubleTapEducationEnabled() {
- return isHorizontalReachabilityEnabled() || isVerticalReachabilityEnabled();
- }
-
- // TODO(b/346264992): Remove after AppCompatController refactoring
- private AppCompatOverrides getAppCompatOverrides() {
- return mActivityRecord.mAppCompatController.getAppCompatOverrides();
- }
-
- /**
- * Whether vertical reachability is enabled for an activity in the current configuration.
- *
- * <p>Conditions that needs to be met:
- * <ul>
- * <li>Windowing mode is fullscreen.
- * <li>Vertical Reachability is enabled.
- * <li>First top opaque activity fills parent horizontally but not vertically.
- * </ul>
- */
- private boolean isVerticalReachabilityEnabled(Configuration parentConfiguration) {
- if (!allowVerticalReachabilityForThinLetterbox()) {
- return false;
- }
- final Rect parentAppBoundsOverride = mActivityRecord.getParentAppBoundsOverride();
- final Rect parentAppBounds = parentAppBoundsOverride != null
- ? parentAppBoundsOverride : parentConfiguration.windowConfiguration.getAppBounds();
- // Use screen resolved bounds which uses resolved bounds or size compat bounds
- // as activity bounds can sometimes be empty.
- final Rect opaqueActivityBounds = mActivityRecord.mAppCompatController
- .getTransparentPolicy().getFirstOpaqueActivity()
- .map(ActivityRecord::getScreenResolvedBounds)
- .orElse(mActivityRecord.getScreenResolvedBounds());
- return mAppCompatConfiguration.getIsVerticalReachabilityEnabled()
- && parentConfiguration.windowConfiguration.getWindowingMode()
- == WINDOWING_MODE_FULLSCREEN
- // Check whether the activity fills the parent horizontally.
- && parentAppBounds.width() <= opaqueActivityBounds.width()
- && parentAppBounds.height() > opaqueActivityBounds.height();
- }
-
- @VisibleForTesting
- boolean isVerticalReachabilityEnabled() {
- return isVerticalReachabilityEnabled(mActivityRecord.getParent().getConfiguration());
- }
-
@VisibleForTesting
boolean shouldShowLetterboxUi(WindowState mainWindow) {
- if (getAppCompatOverrides().getAppCompatOrientationOverrides()
- .getIsRelaunchingAfterRequestedOrientationChanged()) {
+ if (mAppCompatOrientationOverrides.getIsRelaunchingAfterRequestedOrientationChanged()) {
return mLastShouldShowLetterboxUi;
}
@@ -664,8 +355,7 @@ final class LetterboxUiController {
// corners because we assume the specific layout would. This is the case when the layout
// of the translucent activity uses only a part of all the bounds because of the use of
// LayoutParams.WRAP_CONTENT.
- if (mActivityRecord.mAppCompatController.getTransparentPolicy().isRunning()
- && (cropBounds.width() != mainWindow.mRequestedWidth
+ if (mTransparentPolicy.isRunning() && (cropBounds.width() != mainWindow.mRequestedWidth
|| cropBounds.height() != mainWindow.mRequestedHeight)) {
return null;
}
@@ -808,7 +498,8 @@ final class LetterboxUiController {
return;
}
- pw.println(prefix + " letterboxReason=" + getLetterboxReasonString(mainWin));
+ pw.println(prefix + " letterboxReason="
+ + AppCompatUtils.getLetterboxReasonString(mActivityRecord, mainWin));
pw.println(prefix + " activityAspectRatio="
+ AppCompatUtils.computeAspectRatio(mActivityRecord.getBounds()));
@@ -818,8 +509,10 @@ final class LetterboxUiController {
if (!shouldShowLetterboxUi) {
return;
}
- pw.println(prefix + " isVerticalThinLetterboxed=" + isVerticalThinLetterboxed());
- pw.println(prefix + " isHorizontalThinLetterboxed=" + isHorizontalThinLetterboxed());
+ pw.println(prefix + " isVerticalThinLetterboxed="
+ + mAppCompatReachabilityOverrides.isVerticalThinLetterboxed());
+ pw.println(prefix + " isHorizontalThinLetterboxed="
+ + mAppCompatReachabilityOverrides.isHorizontalThinLetterboxed());
pw.println(prefix + " letterboxBackgroundColor=" + Integer.toHexString(
getLetterboxBackgroundColor().toArgb()));
pw.println(prefix + " letterboxBackgroundType="
@@ -836,14 +529,18 @@ final class LetterboxUiController {
pw.println(prefix + " letterboxBackgroundWallpaperBlurRadius="
+ getLetterboxWallpaperBlurRadiusPx());
}
-
+ final AppCompatReachabilityOverrides reachabilityOverrides = mActivityRecord
+ .mAppCompatController.getAppCompatReachabilityOverrides();
pw.println(prefix + " isHorizontalReachabilityEnabled="
- + isHorizontalReachabilityEnabled());
- pw.println(prefix + " isVerticalReachabilityEnabled=" + isVerticalReachabilityEnabled());
+ + reachabilityOverrides.isHorizontalReachabilityEnabled());
+ pw.println(prefix + " isVerticalReachabilityEnabled="
+ + reachabilityOverrides.isVerticalReachabilityEnabled());
pw.println(prefix + " letterboxHorizontalPositionMultiplier="
- + getHorizontalPositionMultiplier(mActivityRecord.getParent().getConfiguration()));
+ + mAppCompatReachabilityOverrides.getHorizontalPositionMultiplier(mActivityRecord
+ .getParent().getConfiguration()));
pw.println(prefix + " letterboxVerticalPositionMultiplier="
- + getVerticalPositionMultiplier(mActivityRecord.getParent().getConfiguration()));
+ + mAppCompatReachabilityOverrides.getVerticalPositionMultiplier(mActivityRecord
+ .getParent().getConfiguration()));
pw.println(prefix + " letterboxPositionForHorizontalReachability="
+ AppCompatConfiguration.letterboxHorizontalReachabilityPositionToString(
mAppCompatConfiguration.getLetterboxPositionForHorizontalReachability(false)));
@@ -861,86 +558,6 @@ final class LetterboxUiController {
.getIsDisplayAspectRatioEnabledForFixedOrientationLetterbox());
}
- /**
- * Returns a string representing the reason for letterboxing. This method assumes the activity
- * is letterboxed.
- */
- private String getLetterboxReasonString(WindowState mainWin) {
- if (mActivityRecord.inSizeCompatMode()) {
- return "SIZE_COMPAT_MODE";
- }
- if (mActivityRecord.mAppCompatController.getAppCompatAspectRatioPolicy()
- .isLetterboxedForFixedOrientationAndAspectRatio()) {
- return "FIXED_ORIENTATION";
- }
- if (mainWin.isLetterboxedForDisplayCutout()) {
- return "DISPLAY_CUTOUT";
- }
- if (mActivityRecord.mAppCompatController.getAppCompatAspectRatioPolicy()
- .isLetterboxedForAspectRatioOnly()) {
- return "ASPECT_RATIO";
- }
- return "UNKNOWN_REASON";
- }
-
- private int letterboxHorizontalReachabilityPositionToLetterboxPosition(
- @AppCompatConfiguration.LetterboxHorizontalReachabilityPosition int position) {
- switch (position) {
- case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT:
- return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__LEFT;
- case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER:
- return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__CENTER;
- case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT:
- return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__RIGHT;
- default:
- throw new AssertionError(
- "Unexpected letterbox horizontal reachability position type: "
- + position);
- }
- }
-
- private int letterboxVerticalReachabilityPositionToLetterboxPosition(
- @AppCompatConfiguration.LetterboxVerticalReachabilityPosition int position) {
- switch (position) {
- case LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP:
- return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__TOP;
- case LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER:
- return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__CENTER;
- case LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM:
- return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__BOTTOM;
- default:
- throw new AssertionError(
- "Unexpected letterbox vertical reachability position type: "
- + position);
- }
- }
-
- int getLetterboxPositionForLogging() {
- int positionToLog = APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__UNKNOWN_POSITION;
- if (isHorizontalReachabilityEnabled()) {
- int letterboxPositionForHorizontalReachability = mAppCompatConfiguration
- .getLetterboxPositionForHorizontalReachability(
- isDisplayFullScreenAndInPosture(/* isTabletop */ false));
- positionToLog = letterboxHorizontalReachabilityPositionToLetterboxPosition(
- letterboxPositionForHorizontalReachability);
- } else if (isVerticalReachabilityEnabled()) {
- int letterboxPositionForVerticalReachability = mAppCompatConfiguration
- .getLetterboxPositionForVerticalReachability(
- isDisplayFullScreenAndInPosture(/* isTabletop */ true));
- positionToLog = letterboxVerticalReachabilityPositionToLetterboxPosition(
- letterboxPositionForVerticalReachability);
- }
- return positionToLog;
- }
-
- /**
- * Logs letterbox position changes via {@link ActivityMetricsLogger#logLetterboxPositionChange}.
- */
- private void logLetterboxPositionChange(int letterboxPositionChange) {
- mActivityRecord.mTaskSupervisor.getActivityMetricsLogger()
- .logLetterboxPositionChange(mActivityRecord, letterboxPositionChange);
- }
-
@Nullable
LetterboxDetails getLetterboxDetails() {
final WindowState w = mActivityRecord.findMainWindow();
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 7ada4c7f9c09..d3df5fdcc447 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -3389,7 +3389,6 @@ class Task extends TaskFragment {
info.isTopActivityTransparent = top != null && !top.fillsParent();
info.isTopActivityStyleFloating = top != null && top.isStyleFloating();
info.lastNonFullscreenBounds = topTask.mLastNonFullscreenBounds;
-
AppCompatUtils.fillAppCompatTaskInfo(this, info, top);
}
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 26526707267b..6ea1f3ab6469 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -1064,13 +1064,17 @@ class WallpaperController {
/**
* Mirrors the visible wallpaper if it's available.
+ * <p>
+ * We mirror at the WallpaperWindowToken level because scale and translation is applied at
+ * the WindowState level and mirroring the WindowState's SurfaceControl will remove any local
+ * scale and translation.
*
* @return A SurfaceControl for the parent of the mirrored wallpaper.
*/
SurfaceControl mirrorWallpaperSurface() {
final WindowState wallpaperWindowState = getTopVisibleWallpaper();
return wallpaperWindowState != null
- ? SurfaceControl.mirrorSurface(wallpaperWindowState.getSurfaceControl())
+ ? SurfaceControl.mirrorSurface(wallpaperWindowState.mToken.getSurfaceControl())
: null;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d73d509863ab..cf92f1bbb9cf 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1897,7 +1897,8 @@ public class WindowManagerService extends IWindowManager.Stub
displayContent.computeImeTarget(true /* updateImeTarget */);
if (win.isImeOverlayLayeringTarget()) {
dispatchImeTargetOverlayVisibilityChanged(client.asBinder(), win.mAttrs.type,
- win.isVisibleRequestedOrAdding(), false /* removed */);
+ win.isVisibleRequestedOrAdding(), false /* removed */,
+ displayContent.getDisplayId());
}
}
@@ -2661,13 +2662,13 @@ public class WindowManagerService extends IWindowManager.Stub
final boolean winVisibleChanged = win.isVisible() != wasVisible;
if (win.isImeOverlayLayeringTarget() && winVisibleChanged) {
dispatchImeTargetOverlayVisibilityChanged(client.asBinder(), win.mAttrs.type,
- win.isVisible(), false /* removed */);
+ win.isVisible(), false /* removed */, win.getDisplayId());
}
// Notify listeners about IME input target window visibility change.
final boolean isImeInputTarget = win.getDisplayContent().getImeInputTarget() == win;
if (isImeInputTarget && winVisibleChanged) {
dispatchImeInputTargetVisibilityChanged(win.mClient.asBinder(),
- win.isVisible() /* visible */, false /* removed */);
+ win.isVisible() /* visible */, false /* removed */, win.getDisplayId());
}
if (outRelayoutResult != null) {
@@ -3515,27 +3516,29 @@ public class WindowManagerService extends IWindowManager.Stub
void dispatchImeTargetOverlayVisibilityChanged(@NonNull IBinder token,
@WindowManager.LayoutParams.WindowType int windowType, boolean visible,
- boolean removed) {
+ boolean removed, int displayId) {
if (mImeTargetChangeListener != null) {
if (DEBUG_INPUT_METHOD) {
Slog.d(TAG, "onImeTargetOverlayVisibilityChanged, win=" + mWindowMap.get(token)
+ ", type=" + ViewDebug.intToString(WindowManager.LayoutParams.class,
- "type", windowType) + "visible=" + visible + ", removed=" + removed);
+ "type", windowType) + "visible=" + visible + ", removed=" + removed
+ + ", displayId=" + displayId);
}
mH.post(() -> mImeTargetChangeListener.onImeTargetOverlayVisibilityChanged(token,
- windowType, visible, removed));
+ windowType, visible, removed, displayId));
}
}
void dispatchImeInputTargetVisibilityChanged(@NonNull IBinder token, boolean visible,
- boolean removed) {
+ boolean removed, int displayId) {
if (mImeTargetChangeListener != null) {
if (DEBUG_INPUT_METHOD) {
Slog.d(TAG, "onImeInputTargetVisibilityChanged, win=" + mWindowMap.get(token)
- + "visible=" + visible + ", removed=" + removed);
+ + "visible=" + visible + ", removed=" + removed
+ + ", displayId" + displayId);
}
mH.post(() -> mImeTargetChangeListener.onImeInputTargetVisibilityChanged(token,
- visible, removed));
+ visible, removed, displayId));
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 51d5bc099bd6..092a7515a8f8 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -284,30 +284,28 @@ public class WindowManagerShellCommand extends ShellCommand {
private int runDisplayDensity(PrintWriter pw) throws RemoteException {
String densityStr = getNextArg();
- String option = getNextOption();
String arg = getNextArg();
int density;
int displayId = Display.DEFAULT_DISPLAY;
- if ("-d".equals(option) && arg != null) {
+ if ("-d".equals(densityStr) && arg != null) {
try {
displayId = Integer.parseInt(arg);
} catch (NumberFormatException e) {
getErrPrintWriter().println("Error: bad number " + e);
}
- } else if ("-u".equals(option) && arg != null) {
+ densityStr = getNextArg();
+ } else if ("-u".equals(densityStr) && arg != null) {
displayId = mInterface.getDisplayIdByUniqueId(arg);
if (displayId == Display.INVALID_DISPLAY) {
getErrPrintWriter().println("Error: the uniqueId is invalid ");
return -1;
}
+ densityStr = getNextArg();
}
if (densityStr == null) {
printInitialDisplayDensity(pw, displayId);
return 0;
- } else if ("-d".equals(densityStr)) {
- printInitialDisplayDensity(pw, displayId);
- return 0;
} else if ("reset".equals(densityStr)) {
density = -1;
} else {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 153d41be4fee..e6467522a410 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2359,11 +2359,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
super.removeImmediately();
+ final DisplayContent dc = getDisplayContent();
if (isImeOverlayLayeringTarget()) {
mWmService.dispatchImeTargetOverlayVisibilityChanged(mClient.asBinder(), mAttrs.type,
- false /* visible */, true /* removed */);
+ false /* visible */, true /* removed */, dc.getDisplayId());
}
- final DisplayContent dc = getDisplayContent();
if (isImeLayeringTarget()) {
// Remove the attached IME screenshot surface.
dc.removeImeSurfaceByTarget(this);
@@ -2374,7 +2374,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
if (dc.getImeInputTarget() == this && !inRelaunchingActivity()) {
mWmService.dispatchImeInputTargetVisibilityChanged(mClient.asBinder(),
- false /* visible */, true /* removed */);
+ false /* visible */, true /* removed */, dc.getDisplayId());
dc.updateImeInputAndControlTarget(null);
}
@@ -4415,6 +4415,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
for (int i = mChildren.size() - 1; i >= 0; i--) {
committed |= mChildren.get(i).commitFinishDrawing(t);
}
+ // In case commitFinishDrawingLocked starts a window level animation, make sure the surface
+ // operation (reparent to leash) is synced with the visibility by transition.
+ if (getAnimationLeash() != null) {
+ t.merge(getSyncTransaction());
+ }
return committed;
}
@@ -5028,7 +5033,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
new WindowAnimationSpec(anim, position, false /* canSkipFirstFrame */,
0 /* windowCornerRadius */),
mWmService.mSurfaceAnimationRunner);
- startAnimation(getPendingTransaction(), adapter);
+ final Transaction t = mActivityRecord != null
+ ? getSyncTransaction() : getPendingTransaction();
+ startAnimation(t, adapter);
commitPendingTransaction();
}
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 9fa1a53237cc..f1e94deb8a45 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -79,6 +79,7 @@ cc_library_static {
"com_android_server_wm_TaskFpsCallbackController.cpp",
"onload.cpp",
":lib_cachedAppOptimizer_native",
+ ":lib_freezer_native",
":lib_gameManagerService_native",
":lib_oomConnection_native",
":lib_anrTimer_native",
@@ -241,6 +242,13 @@ filegroup {
}
filegroup {
+ name: "lib_freezer_native",
+ srcs: [
+ "com_android_server_am_Freezer.cpp",
+ ],
+}
+
+filegroup {
name: "lib_gameManagerService_native",
srcs: [
"com_android_server_app_GameManagerService.cpp",
diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
index 95e7b198c1bb..a91fd082e589 100644
--- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
+++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
@@ -24,7 +24,6 @@
#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
#include <android_runtime/AndroidRuntime.h>
-#include <binder/IPCThreadState.h>
#include <cutils/compiler.h>
#include <dirent.h>
#include <jni.h>
@@ -34,7 +33,6 @@
#include <meminfo/procmeminfo.h>
#include <meminfo/sysmeminfo.h>
#include <nativehelper/JNIHelp.h>
-#include <processgroup/processgroup.h>
#include <stddef.h>
#include <stdio.h>
#include <sys/mman.h>
@@ -63,10 +61,6 @@ static const size_t kPageMask = ~(kPageSize - 1);
using VmaToAdviseFunc = std::function<int(const Vma&)>;
using android::base::unique_fd;
-#define SYNC_RECEIVED_WHILE_FROZEN (1)
-#define ASYNC_RECEIVED_WHILE_FROZEN (2)
-#define TXNS_PENDING_WHILE_FROZEN (4)
-
#define MAX_RW_COUNT (INT_MAX & kPageMask)
// Defines the maximum amount of VMAs we can send per process_madvise syscall.
@@ -527,58 +521,6 @@ static void com_android_server_am_CachedAppOptimizer_compactProcess(JNIEnv*, job
compactProcessOrFallback(pid, compactionFlags);
}
-static jint com_android_server_am_CachedAppOptimizer_freezeBinder(JNIEnv* env, jobject clazz,
- jint pid, jboolean freeze,
- jint timeout_ms) {
- jint retVal = IPCThreadState::freeze(pid, freeze, timeout_ms);
- if (retVal != 0 && retVal != -EAGAIN) {
- jniThrowException(env, "java/lang/RuntimeException", "Unable to freeze/unfreeze binder");
- }
-
- return retVal;
-}
-
-static jint com_android_server_am_CachedAppOptimizer_getBinderFreezeInfo(JNIEnv *env,
- jobject clazz, jint pid) {
- uint32_t syncReceived = 0, asyncReceived = 0;
-
- int error = IPCThreadState::getProcessFreezeInfo(pid, &syncReceived, &asyncReceived);
-
- if (error < 0) {
- jniThrowException(env, "java/lang/RuntimeException", strerror(error));
- }
-
- jint retVal = 0;
-
- // bit 0 of sync_recv goes to bit 0 of retVal
- retVal |= syncReceived & SYNC_RECEIVED_WHILE_FROZEN;
- // bit 0 of async_recv goes to bit 1 of retVal
- retVal |= (asyncReceived << 1) & ASYNC_RECEIVED_WHILE_FROZEN;
- // bit 1 of sync_recv goes to bit 2 of retVal
- retVal |= (syncReceived << 1) & TXNS_PENDING_WHILE_FROZEN;
-
- return retVal;
-}
-
-static jstring com_android_server_am_CachedAppOptimizer_getFreezerCheckPath(JNIEnv* env,
- jobject clazz) {
- std::string path;
-
- if (!getAttributePathForTask("FreezerState", getpid(), &path)) {
- path = "";
- }
-
- return env->NewStringUTF(path.c_str());
-}
-
-static jboolean com_android_server_am_CachedAppOptimizer_isFreezerProfileValid(JNIEnv* env) {
- uid_t uid = getuid();
- pid_t pid = getpid();
-
- return isProfileValidForProcess("Frozen", uid, pid) &&
- isProfileValidForProcess("Unfrozen", uid, pid);
-}
-
static const JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"cancelCompaction", "()V",
@@ -592,13 +534,7 @@ static const JNINativeMethod sMethods[] = {
(void*)com_android_server_am_CachedAppOptimizer_getMemoryFreedCompaction},
{"compactSystem", "()V", (void*)com_android_server_am_CachedAppOptimizer_compactSystem},
{"compactProcess", "(II)V", (void*)com_android_server_am_CachedAppOptimizer_compactProcess},
- {"freezeBinder", "(IZI)I", (void*)com_android_server_am_CachedAppOptimizer_freezeBinder},
- {"getBinderFreezeInfo", "(I)I",
- (void*)com_android_server_am_CachedAppOptimizer_getBinderFreezeInfo},
- {"getFreezerCheckPath", "()Ljava/lang/String;",
- (void*)com_android_server_am_CachedAppOptimizer_getFreezerCheckPath},
- {"isFreezerProfileValid", "()Z",
- (void*)com_android_server_am_CachedAppOptimizer_isFreezerProfileValid}};
+};
int register_android_server_am_CachedAppOptimizer(JNIEnv* env)
{
diff --git a/services/core/jni/com_android_server_am_Freezer.cpp b/services/core/jni/com_android_server_am_Freezer.cpp
new file mode 100644
index 000000000000..81487281dee7
--- /dev/null
+++ b/services/core/jni/com_android_server_am_Freezer.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+#define LOG_TAG "Freezer"
+//#define LOG_NDEBUG 0
+#define ATRACE_TAG ATRACE_TAG_ACTIVITY_MANAGER
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+#include <binder/IPCThreadState.h>
+#include <nativehelper/JNIHelp.h>
+#include <processgroup/processgroup.h>
+
+namespace android {
+namespace {
+
+// Binder status bit flags.
+static const int SYNC_RECEIVED_WHILE_FROZEN = 1;
+static const int ASYNC_RECEIVED_WHILE_FROZEN = 2;
+static const int TXNS_PENDING_WHILE_FROZEN = 4;
+
+jint freezeBinder(JNIEnv* env, jobject, jint pid, jboolean freeze, jint timeout_ms) {
+ jint retVal = IPCThreadState::freeze(pid, freeze, timeout_ms);
+ if (retVal != 0 && retVal != -EAGAIN) {
+ jniThrowException(env, "java/lang/RuntimeException", "Unable to freeze/unfreeze binder");
+ }
+
+ return retVal;
+}
+
+jint getBinderFreezeInfo(JNIEnv *env, jobject, jint pid) {
+ uint32_t syncReceived = 0, asyncReceived = 0;
+
+ int error = IPCThreadState::getProcessFreezeInfo(pid, &syncReceived, &asyncReceived);
+
+ if (error < 0) {
+ jniThrowException(env, "java/lang/RuntimeException", strerror(error));
+ }
+
+ jint retVal = 0;
+
+ // bit 0 of sync_recv goes to bit 0 of retVal
+ retVal |= syncReceived & SYNC_RECEIVED_WHILE_FROZEN;
+ // bit 0 of async_recv goes to bit 1 of retVal
+ retVal |= (asyncReceived << 1) & ASYNC_RECEIVED_WHILE_FROZEN;
+ // bit 1 of sync_recv goes to bit 2 of retVal
+ retVal |= (syncReceived << 1) & TXNS_PENDING_WHILE_FROZEN;
+
+ return retVal;
+}
+
+bool isFreezerSupported(JNIEnv *env, jclass) {
+ std::string path;
+ if (!getAttributePathForTask("FreezerState", getpid(), &path)) {
+ ALOGI("No attribute for FreezerState");
+ return false;
+ }
+ base::unique_fd fid(open(path.c_str(), O_RDONLY));
+ if (fid < 0) {
+ ALOGI("Cannot open freezer path \"%s\": %s", path.c_str(), strerror(errno));
+ return false;
+ }
+
+ char state;
+ if (::read(fid, &state, 1) != 1) {
+ ALOGI("Failed to read freezer state: %s", strerror(errno));
+ return false;
+ }
+ if (state != '1' && state != '0') {
+ ALOGE("Unexpected value in cgroup.freeze: %d", state);
+ return false;
+ }
+
+ uid_t uid = getuid();
+ pid_t pid = getpid();
+
+ uint32_t syncReceived = 0, asyncReceived = 0;
+ int error = IPCThreadState::getProcessFreezeInfo(pid, &syncReceived, &asyncReceived);
+ if (error < 0) {
+ ALOGE("Unable to read freezer info: %s", strerror(errno));
+ return false;
+ }
+
+ if (!isProfileValidForProcess("Frozen", uid, pid)
+ || !isProfileValidForProcess("Unfrozen", uid, pid)) {
+ ALOGE("Missing freezer profiles");
+ return false;
+ }
+
+ return true;
+}
+
+static const JNINativeMethod sMethods[] = {
+ {"nativeIsFreezerSupported", "()Z", (void*) isFreezerSupported },
+ {"nativeFreezeBinder", "(IZI)I", (void*) freezeBinder },
+ {"nativeGetBinderFreezeInfo", "(I)I", (void*) getBinderFreezeInfo },
+};
+
+} // end of anonymous namespace
+
+int register_android_server_am_Freezer(JNIEnv* env)
+{
+ char const *className = "com/android/server/am/Freezer";
+ return jniRegisterNativeMethods(env, className, sMethods, NELEM(sMethods));
+}
+
+} // end of namespace android
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 314ff9d3c808..3c55d18245d7 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -54,6 +54,7 @@ int register_android_server_SyntheticPasswordManager(JNIEnv* env);
int register_android_hardware_display_DisplayViewport(JNIEnv* env);
int register_android_server_am_OomConnection(JNIEnv* env);
int register_android_server_am_CachedAppOptimizer(JNIEnv* env);
+int register_android_server_am_Freezer(JNIEnv* env);
int register_android_server_am_LowMemDetector(JNIEnv* env);
int register_android_server_utils_AnrTimer(JNIEnv *env);
int register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl(JNIEnv* env);
@@ -118,6 +119,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
register_android_hardware_display_DisplayViewport(env);
register_android_server_am_OomConnection(env);
register_android_server_am_CachedAppOptimizer(env);
+ register_android_server_am_Freezer(env);
register_android_server_am_LowMemDetector(env);
register_android_server_utils_AnrTimer(env);
register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl(env);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java b/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java
index c582a462db81..dd0493032c56 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java
@@ -663,7 +663,7 @@ class SecurityLogMonitor implements Runnable {
}
}
if (DEBUG) {
- Slogf.d(TAG, "Adding audit %d events to % already present in the buffer",
+ Slogf.d(TAG, "Adding audit %d events to %d already present in the buffer",
events.size(), mAuditLogEventBuffer.size());
}
mAuditLogEventBuffer.addAll(events);
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java
index dd3b33e0d12a..8ce2422563a3 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java
@@ -23,7 +23,6 @@ import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
import static android.view.WindowManager.DISPLAY_IME_POLICY_HIDE;
import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.internal.inputmethod.SoftInputShowHideReason.HIDE_WHEN_INPUT_TARGET_INVISIBLE;
@@ -41,6 +40,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.notNull;
+import android.annotation.UserIdInt;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
@@ -50,7 +50,6 @@ import android.view.inputmethod.InputMethodManager;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.internal.annotations.GuardedBy;
-import com.android.server.wm.ImeTargetChangeListener;
import com.android.server.wm.WindowManagerInternal;
import org.junit.Before;
@@ -68,7 +67,6 @@ import org.mockito.ArgumentCaptor;
@RunWith(AndroidJUnit4.class)
public class ImeVisibilityStateComputerTest extends InputMethodManagerServiceTestBase {
private ImeVisibilityStateComputer mComputer;
- private ImeTargetChangeListener mListener;
private int mImeDisplayPolicy = DISPLAY_IME_POLICY_LOCAL;
@Before
@@ -84,12 +82,14 @@ public class ImeVisibilityStateComputerTest extends InputMethodManagerServiceTes
public ImeDisplayValidator getImeValidator() {
return displayId -> mImeDisplayPolicy;
}
+
+ @UserIdInt
+ @Override
+ public int getUserId() {
+ return mUserId;
+ }
};
- ArgumentCaptor<ImeTargetChangeListener> captor = ArgumentCaptor.forClass(
- ImeTargetChangeListener.class);
- verify(mMockWindowManagerInternal).setInputMethodTargetChangeListener(captor.capture());
mComputer = new ImeVisibilityStateComputer(mInputMethodManagerService, injector);
- mListener = captor.getValue();
}
@Test
@@ -298,28 +298,32 @@ public class ImeVisibilityStateComputerTest extends InputMethodManagerServiceTes
@Test
public void testOnApplyImeVisibilityFromComputer() {
synchronized (ImfLock.class) {
- final IBinder testImeTargetOverlay = new Binder();
final IBinder testImeInputTarget = new Binder();
// Simulate a test IME input target was visible.
- mListener.onImeInputTargetVisibilityChanged(testImeInputTarget, true, false);
+ mComputer.onImeInputTargetVisibilityChanged(testImeInputTarget,
+ true /* visibleAndNotRemoved */);
// Simulate a test IME layering target overlay fully occluded the IME input target.
- mListener.onImeTargetOverlayVisibilityChanged(testImeTargetOverlay,
- TYPE_APPLICATION_OVERLAY, true, false);
- mListener.onImeInputTargetVisibilityChanged(testImeInputTarget, false, false);
+ mComputer.setHasVisibleImeLayeringOverlay(true /* visibleAndNotRemoved */);
+ mComputer.onImeInputTargetVisibilityChanged(testImeInputTarget,
+ false /* visibleAndNotRemoved */);
final ArgumentCaptor<IBinder> targetCaptor = ArgumentCaptor.forClass(IBinder.class);
final ArgumentCaptor<ImeVisibilityResult> resultCaptor = ArgumentCaptor.forClass(
ImeVisibilityResult.class);
+ final ArgumentCaptor<Integer> userIdCaptor = ArgumentCaptor.forClass(Integer.class);
verify(mInputMethodManagerService).onApplyImeVisibilityFromComputerLocked(
- targetCaptor.capture(), notNull() /* statsToken */, resultCaptor.capture());
+ targetCaptor.capture(), notNull() /* statsToken */, resultCaptor.capture(),
+ userIdCaptor.capture());
final IBinder imeInputTarget = targetCaptor.getValue();
final ImeVisibilityResult result = resultCaptor.getValue();
+ final int userId = userIdCaptor.getValue();
// Verify the computer will callback hiding IME state to IMMS.
assertThat(imeInputTarget).isEqualTo(testImeInputTarget);
assertThat(result.getState()).isEqualTo(STATE_HIDE_IME_EXPLICIT);
assertThat(result.getReason()).isEqualTo(HIDE_WHEN_INPUT_TARGET_INVISIBLE);
+ assertThat(userId).isEqualTo(mUserId);
}
}
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java
index d59f28b4cad2..b984624b3e9b 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java
@@ -19,6 +19,11 @@ package com.android.server.inputmethod;
import static com.google.common.truth.Truth.assertThat;
import android.platform.test.ravenwood.RavenwoodRule;
+import android.view.WindowManager;
+
+import androidx.annotation.NonNull;
+
+import com.android.server.wm.WindowManagerInternal;
import org.junit.After;
import org.junit.Before;
@@ -43,20 +48,43 @@ public final class UserDataRepositoryTest {
@Mock
private InputMethodManagerService mMockInputMethodManagerService;
+ @Mock
+ private WindowManagerInternal mMockWindowManagerInternal;
+
+ @NonNull
private IntFunction<InputMethodBindingController> mBindingControllerFactory;
+ @NonNull
+ private IntFunction<ImeVisibilityStateComputer> mVisibilityStateComputerFactory;
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
SecureSettingsWrapper.startTestMode();
- mBindingControllerFactory = new IntFunction<InputMethodBindingController>() {
-
- @Override
- public InputMethodBindingController apply(int userId) {
- return new InputMethodBindingController(userId, mMockInputMethodManagerService);
- }
- };
+ mBindingControllerFactory = userId ->
+ new InputMethodBindingController(userId, mMockInputMethodManagerService);
+
+ mVisibilityStateComputerFactory = userId -> new ImeVisibilityStateComputer(
+ mMockInputMethodManagerService,
+ new ImeVisibilityStateComputer.Injector() {
+ @NonNull
+ @Override
+ public WindowManagerInternal getWmService() {
+ return mMockWindowManagerInternal;
+ }
+
+ @NonNull
+ @Override
+ public InputMethodManagerService.ImeDisplayValidator getImeValidator() {
+ return displayId -> WindowManager.DISPLAY_IME_POLICY_LOCAL;
+ }
+
+ @Override
+ public int getUserId() {
+ return userId;
+ }
+ });
}
@After
@@ -69,7 +97,8 @@ public final class UserDataRepositoryTest {
public void testUserDataRepository_removesUserInfoOnUserRemovedEvent() {
// Create UserDataRepository
final var repository = new UserDataRepository(
- userId -> new InputMethodBindingController(userId, mMockInputMethodManagerService));
+ userId -> new InputMethodBindingController(userId, mMockInputMethodManagerService),
+ mVisibilityStateComputerFactory);
// Add one UserData ...
final var userData = repository.getOrCreate(ANY_USER_ID);
@@ -85,7 +114,8 @@ public final class UserDataRepositoryTest {
@Test
public void testGetOrCreate() {
- final var repository = new UserDataRepository(mBindingControllerFactory);
+ final var repository = new UserDataRepository(mBindingControllerFactory,
+ mVisibilityStateComputerFactory);
final var userData = repository.getOrCreate(ANY_USER_ID);
assertThat(userData.mUserId).isEqualTo(ANY_USER_ID);
@@ -96,6 +126,7 @@ public final class UserDataRepositoryTest {
// Assert UserDataRepository called the InputMethodBindingController creator function.
assertThat(allUserData.get(0).mBindingController.getUserId()).isEqualTo(ANY_USER_ID);
+ assertThat(allUserData.get(0).mVisibilityStateComputer.getUserId()).isEqualTo(ANY_USER_ID);
}
private List<UserData> collectUserData(UserDataRepository repository) {
diff --git a/services/tests/mockingservicestests/jni/Android.bp b/services/tests/mockingservicestests/jni/Android.bp
index 1eb9888489cb..00543a8a9871 100644
--- a/services/tests/mockingservicestests/jni/Android.bp
+++ b/services/tests/mockingservicestests/jni/Android.bp
@@ -21,6 +21,7 @@ cc_library_shared {
srcs: [
":lib_cachedAppOptimizer_native",
+ ":lib_freezer_native",
":lib_gameManagerService_native",
":lib_oomConnection_native",
"onload.cpp",
diff --git a/services/tests/mockingservicestests/jni/onload.cpp b/services/tests/mockingservicestests/jni/onload.cpp
index fb910513adda..cb246d15fce8 100644
--- a/services/tests/mockingservicestests/jni/onload.cpp
+++ b/services/tests/mockingservicestests/jni/onload.cpp
@@ -25,6 +25,7 @@
namespace android {
int register_android_server_am_CachedAppOptimizer(JNIEnv* env);
+int register_android_server_am_Freezer(JNIEnv* env);
int register_android_server_app_GameManagerService(JNIEnv* env);
int register_android_server_am_OomConnection(JNIEnv* env);
};
@@ -42,8 +43,8 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
}
ALOG_ASSERT(env, "Could not retrieve the env!");
register_android_server_am_CachedAppOptimizer(env);
+ register_android_server_am_Freezer(env);
register_android_server_app_GameManagerService(env);
register_android_server_am_OomConnection(env);
return JNI_VERSION_1_4;
}
-
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index cb15d6f84403..b980ca05b609 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -132,6 +132,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.PermissionChecker;
import android.content.pm.PackageManagerInternal;
+import android.content.pm.UserInfo;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.Bundle;
@@ -149,6 +150,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.os.UserManager;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
@@ -176,6 +178,7 @@ import com.android.server.DeviceIdleInternal;
import com.android.server.LocalServices;
import com.android.server.SystemClockTime.TimeConfidence;
import com.android.server.SystemService;
+import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.permission.PermissionManagerService;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.pm.pkg.AndroidPackage;
@@ -250,6 +253,8 @@ public final class AlarmManagerServiceTest {
@Mock
private ActivityManagerInternal mActivityManagerInternal;
@Mock
+ private UserManagerInternal mUserManagerInternal;
+ @Mock
private ActivityManager mActivityManager;
@Mock
private PackageManagerInternal mPackageManagerInternal;
@@ -447,6 +452,8 @@ public final class AlarmManagerServiceTest {
() -> LocalServices.getService(PermissionManagerServiceInternal.class));
doReturn(mActivityManagerInternal).when(
() -> LocalServices.getService(ActivityManagerInternal.class));
+ doReturn(mUserManagerInternal).when(
+ () -> LocalServices.getService(UserManagerInternal.class));
doReturn(mPackageManagerInternal).when(
() -> LocalServices.getService(PackageManagerInternal.class));
doReturn(mAppStateTracker).when(() -> LocalServices.getService(AppStateTracker.class));
@@ -1252,6 +1259,26 @@ public final class AlarmManagerServiceTest {
}
@Test
+ public void wakeupShouldBeScheduledForFullUsers_skipsGuestSystemAndProfiles() {
+ final int systemUserId = 0;
+ final int fullUserId = 10;
+ final int privateProfileId = 12;
+ final int guestUserId = 13;
+ when(mUserManagerInternal.getUserInfo(fullUserId)).thenReturn(new UserInfo(fullUserId,
+ "TestUser2", UserInfo.FLAG_FULL));
+ when(mUserManagerInternal.getUserInfo(privateProfileId)).thenReturn(new UserInfo(
+ privateProfileId, "TestUser3", UserInfo.FLAG_PROFILE));
+ when(mUserManagerInternal.getUserInfo(guestUserId)).thenReturn(new UserInfo(
+ guestUserId, "TestUserGuest", null, 0, UserManager.USER_TYPE_FULL_GUEST));
+ when(mUserManagerInternal.getUserInfo(systemUserId)).thenReturn(new UserInfo(
+ systemUserId, "TestUserSystem", null, 0, UserManager.USER_TYPE_FULL_SYSTEM));
+ assertTrue(mService.shouldAddWakeupForUser(fullUserId));
+ assertFalse(mService.shouldAddWakeupForUser(systemUserId));
+ assertFalse(mService.shouldAddWakeupForUser(privateProfileId));
+ assertFalse(mService.shouldAddWakeupForUser(guestUserId));
+ }
+
+ @Test
public void sendsTimeTickOnInteractive() {
final ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class);
// Stubbing so the handler doesn't actually run the runnable.
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/UserWakeupStoreTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/UserWakeupStoreTest.java
index 5bd919f28e6a..72883e269a65 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/UserWakeupStoreTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/UserWakeupStoreTest.java
@@ -23,7 +23,6 @@ import static com.android.server.alarm.UserWakeupStore.USER_START_TIME_DEVIATION
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import static org.testng.AssertJUnit.assertFalse;
import android.os.Environment;
import android.os.FileUtils;
@@ -52,7 +51,6 @@ public class UserWakeupStoreTest {
private static final int USER_ID_1 = 10;
private static final int USER_ID_2 = 11;
private static final int USER_ID_3 = 12;
- private static final int USER_ID_SYSTEM = 0;
private static final long TEST_TIMESTAMP = 150_000;
private static final File TEST_SYSTEM_DIR = new File(InstrumentationRegistry
.getInstrumentation().getContext().getDataDir(), "alarmsTestDir");
@@ -112,14 +110,6 @@ public class UserWakeupStoreTest {
}
@Test
- public void testAddWakeupForSystemUser_shouldDoNothing() {
- mUserWakeupStore.addUserWakeup(USER_ID_SYSTEM, TEST_TIMESTAMP - 19_000);
- assertEquals(0, mUserWakeupStore.getUserIdsToWakeup(TEST_TIMESTAMP).length);
- final File file = new File(ROOT_DIR , "usersWithAlarmClocks.xml");
- assertFalse(file.exists());
- }
-
- @Test
public void testAddMultipleWakeupsForUser_ensureOnlyLastWakeupRemains() {
final long finalAlarmTime = TEST_TIMESTAMP - 13_000;
mUserWakeupStore.addUserWakeup(USER_ID_1, TEST_TIMESTAMP - 29_000);
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java b/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java
index 03439e552a06..d203de537b81 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java
@@ -21,10 +21,21 @@ import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
import static com.android.server.am.ActivityManagerService.Injector;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import android.app.ActivityManagerInternal;
+import android.app.ActivityManagerInternal.FrozenProcessListener;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -33,12 +44,14 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.MessageQueue;
import android.os.Process;
+import android.os.SystemClock;
import android.platform.test.annotations.Presubmit;
import android.provider.DeviceConfig;
import android.text.TextUtils;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.internal.annotations.GuardedBy;
import com.android.modules.utils.testing.ExtendedMockitoRule;
import com.android.modules.utils.testing.TestableDeviceConfig;
import com.android.server.LocalServices;
@@ -55,9 +68,11 @@ import org.mockito.Mock;
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
/**
@@ -79,12 +94,17 @@ public final class CachedAppOptimizerTest {
private CountDownLatch mCountDown;
private ActivityManagerService mAms;
private Context mContext;
+ private TestFreezer mFreezer;
+ private CountDownLatch mFreezeCounter;
private TestInjector mInjector;
private TestProcessDependencies mProcessDependencies;
@Mock
private PackageManagerInternal mPackageManagerInt;
+ // Control whether the freezer mock reports that freezing is enabled or not.
+ private boolean mUseFreezer;
+
@Rule
public final ApplicationExitInfoTest.ServiceThreadRule
mServiceThreadRule = new ApplicationExitInfoTest.ServiceThreadRule();
@@ -103,9 +123,12 @@ public final class CachedAppOptimizerTest {
true /* allowIo */);
mThread.start();
mContext = InstrumentationRegistry.getInstrumentation().getContext();
+
+ mUseFreezer = false;
+ mFreezer = new TestFreezer();
+
mInjector = new TestInjector(mContext);
- mAms = new ActivityManagerService(
- new TestInjector(mContext), mServiceThreadRule.getThread());
+ mAms = new ActivityManagerService(mInjector, mServiceThreadRule.getThread());
doReturn(new ComponentName("", "")).when(mPackageManagerInt).getSystemUiServiceComponent();
mProcessDependencies = new TestProcessDependencies();
mCachedAppOptimizerUnderTest = new CachedAppOptimizer(mAms,
@@ -126,6 +149,7 @@ public final class CachedAppOptimizerTest {
mHandlerThread.quit();
mThread.quit();
mCountDown = null;
+ mFreezeCounter = null;
}
private ProcessRecord makeProcessRecord(int pid, int uid, int packageUid, String processName,
@@ -179,7 +203,7 @@ public final class CachedAppOptimizerTest {
assertThat(mCachedAppOptimizerUnderTest.mProcStateThrottle)
.containsExactlyElementsIn(expected);
- Assume.assumeTrue(mCachedAppOptimizerUnderTest.isFreezerSupported());
+ Assume.assumeTrue(mAms.isAppFreezerSupported());
assertThat(mCachedAppOptimizerUnderTest.useFreezer()).isEqualTo(
CachedAppOptimizer.DEFAULT_USE_FREEZER);
}
@@ -265,8 +289,8 @@ public final class CachedAppOptimizerTest {
CachedAppOptimizer.DEFAULT_COMPACT_FULL_RSS_THROTTLE_KB + 1);
assertThat(mCachedAppOptimizerUnderTest.mProcStateThrottle).containsExactly(1, 2, 3);
- Assume.assumeTrue(CachedAppOptimizer.isFreezerSupported());
- if (CachedAppOptimizer.isFreezerSupported()) {
+ Assume.assumeTrue(mAms.isAppFreezerSupported());
+ if (mAms.isAppFreezerSupported()) {
if (CachedAppOptimizer.DEFAULT_USE_FREEZER) {
assertThat(mCachedAppOptimizerUnderTest.useFreezer()).isFalse();
} else {
@@ -300,7 +324,7 @@ public final class CachedAppOptimizerTest {
@Test
public void useFreeze_doesNotListenToDeviceConfigChanges() throws InterruptedException {
- Assume.assumeTrue(CachedAppOptimizer.isFreezerSupported());
+ Assume.assumeTrue(mAms.isAppFreezerSupported());
assertThat(mCachedAppOptimizerUnderTest.useFreezer()).isFalse();
@@ -353,7 +377,7 @@ public final class CachedAppOptimizerTest {
@Test
public void useFreeze_listensToDeviceConfigChangesBadValues() throws InterruptedException {
- Assume.assumeTrue(CachedAppOptimizer.isFreezerSupported());
+ Assume.assumeTrue(mAms.isAppFreezerSupported());
assertThat(mCachedAppOptimizerUnderTest.useFreezer()).isFalse();
// When we push an invalid flag value...
@@ -982,6 +1006,87 @@ public final class CachedAppOptimizerTest {
}
}
+ @Test
+ public void testFreezerDelegator() throws Exception {
+ mUseFreezer = true;
+ mProcessDependencies.setRss(new long[] {
+ 0 /*total_rss*/,
+ 0 /*file*/,
+ 0 /*anon*/,
+ 0 /*swap*/,
+ 0 /*shmem*/
+ });
+
+ // Force the system to use the freezer
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT,
+ CachedAppOptimizer.KEY_USE_FREEZER, "true", false);
+ mCachedAppOptimizerUnderTest.init();
+ initActivityManagerService();
+
+ assertTrue(mAms.isAppFreezerSupported());
+ assertThat(mCachedAppOptimizerUnderTest.useFreezer()).isTrue();
+
+ int pid = 10000;
+ int uid = 2;
+ int pkgUid = 3;
+ ProcessRecord app = makeProcessRecord(pid, uid, pkgUid, "p1", "app1");
+
+ mFreezeCounter = new CountDownLatch(1);
+ mCachedAppOptimizerUnderTest.forceFreezeForTest(app, true);
+ assertTrue(mFreezeCounter.await(5, TimeUnit.SECONDS));
+
+ mFreezeCounter = new CountDownLatch(1);
+ mCachedAppOptimizerUnderTest.forceFreezeForTest(app, false);
+ assertTrue(mFreezeCounter.await(5, TimeUnit.SECONDS));
+ }
+
+ @Test
+ public void testFrozenNotifier() throws Exception {
+ mUseFreezer = true;
+ mProcessDependencies.setRss(new long[] {
+ 0 /*total_rss*/,
+ 0 /*file*/,
+ 0 /*anon*/,
+ 0 /*swap*/,
+ 0 /*shmem*/
+ });
+
+ // Force the system to use the freezer
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT,
+ CachedAppOptimizer.KEY_USE_FREEZER, "true", false);
+ mCachedAppOptimizerUnderTest.init();
+ initActivityManagerService();
+
+ assertTrue(mAms.isAppFreezerSupported());
+ assertThat(mCachedAppOptimizerUnderTest.useFreezer()).isTrue();
+
+ int pid = 10000;
+ int uid = 2;
+ int pkgUid = 3;
+ ProcessRecord app = makeProcessRecord(pid, uid, pkgUid, "p1", "app1");
+ assertNotNull(app.mOptRecord);
+
+ FrozenProcessListener listener = new FrozenProcessListener() {
+ @Override
+ public void onProcessFrozen(int pid) {
+ mFreezeCounter.countDown();
+ }
+ @Override
+ public void onProcessUnfrozen(int pid) {
+ mFreezeCounter.countDown();
+ }
+ };
+ mCachedAppOptimizerUnderTest.addFrozenProcessListener(app, directExecutor(), listener);
+
+ mFreezeCounter = new CountDownLatch(2);
+ mCachedAppOptimizerUnderTest.forceFreezeForTest(app, true);
+ assertTrue(mFreezeCounter.await(5, TimeUnit.SECONDS));
+
+ mFreezeCounter = new CountDownLatch(2);
+ mCachedAppOptimizerUnderTest.forceFreezeForTest(app, false);
+ assertTrue(mFreezeCounter.await(5, TimeUnit.SECONDS));
+ }
+
private void setFlag(String key, String value, boolean defaultValue) throws Exception {
mCountDown = new CountDownLatch(1);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, key, value, defaultValue);
@@ -1042,6 +1147,11 @@ public final class CachedAppOptimizerTest {
public Handler getUiHandler(ActivityManagerService service) {
return mHandler;
}
+
+ @Override
+ public Freezer getFreezer() {
+ return mFreezer;
+ }
}
// Test implementation for ProcessDependencies.
@@ -1069,4 +1179,27 @@ public final class CachedAppOptimizerTest {
mRssAfterCompaction = newValues;
}
}
+
+ // Intercept Freezer calls.
+ private class TestFreezer extends Freezer {
+ @Override
+ public void setProcessFrozen(int pid, int uid, boolean frozen) {
+ mFreezeCounter.countDown();
+ }
+
+ @Override
+ public int freezeBinder(int pid, boolean freeze, int timeoutMs) {
+ return 0;
+ }
+
+ @Override
+ public int getBinderFreezeInfo(int pid) {
+ return 0;
+ }
+
+ @Override
+ public boolean isFreezerSupported() {
+ return mUseFreezer;
+ }
+ }
}
diff --git a/services/tests/servicestests/jni/Android.bp b/services/tests/servicestests/jni/Android.bp
index c30e4eb666b4..0a3103722796 100644
--- a/services/tests/servicestests/jni/Android.bp
+++ b/services/tests/servicestests/jni/Android.bp
@@ -21,6 +21,7 @@ cc_library_shared {
srcs: [
":lib_cachedAppOptimizer_native",
+ ":lib_freezer_native",
":lib_gameManagerService_native",
":lib_oomConnection_native",
":lib_anrTimer_native",
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
index 7b71f85a42b0..1426d5d20419 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
@@ -48,6 +48,7 @@ import android.animation.ValueAnimator;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
+import android.content.res.Resources;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.Region;
@@ -67,6 +68,7 @@ import android.widget.Scroller;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.R;
import com.android.internal.util.ConcurrentUtils;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.server.LocalServices;
@@ -118,6 +120,7 @@ public class FullScreenMagnificationControllerTest {
final FullScreenMagnificationController.ControllerContext mMockControllerCtx =
mock(FullScreenMagnificationController.ControllerContext.class);
final Context mMockContext = mock(Context.class);
+ final Resources mMockResources = mock(Resources.class);
final AccessibilityTraceManager mMockTraceManager = mock(AccessibilityTraceManager.class);
final WindowManagerInternal mMockWindowManager = mock(WindowManagerInternal.class);
private final MagnificationAnimationCallback mAnimationCallback = mock(
@@ -162,6 +165,7 @@ public class FullScreenMagnificationControllerTest {
mResolver = new MockContentResolver();
mResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
when(mMockContext.getContentResolver()).thenReturn(mResolver);
+ when(mMockContext.getResources()).thenReturn(mMockResources);
mOriginalMagnificationPersistedScale = Settings.Secure.getFloatForUser(mResolver,
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 2.0f,
CURRENT_USER_ID);
@@ -928,7 +932,8 @@ public class FullScreenMagnificationControllerTest {
/* displayId= */ i,
/* isMagnifierActivated= */ true,
/* isAlwaysOnEnabled= */ false,
- /* expectedActivated= */ false);
+ /* expectedActivated= */ false,
+ /* expectedMagnified= */ false);
resetMockWindowManager();
}
}
@@ -940,7 +945,24 @@ public class FullScreenMagnificationControllerTest {
/* displayId= */ i,
/* isMagnifierActivated= */ true,
/* isAlwaysOnEnabled= */ true,
- /* expectedActivated= */ true);
+ /* expectedActivated= */ true,
+ /* expectedMagnified= */ false);
+ resetMockWindowManager();
+ }
+ }
+
+ @Test
+ public void testUserContextChange_magnifierActivatedAndKeepMagnifiedEnabled_stayActivated() {
+ when(mMockResources.getBoolean(
+ R.bool.config_magnification_keep_zoom_level_when_context_changed))
+ .thenReturn(true);
+ for (int i = 0; i < DISPLAY_COUNT; i++) {
+ contextChange_expectedValues(
+ /* displayId= */ i,
+ /* isMagnifierActivated= */ true,
+ /* isAlwaysOnEnabled= */ true,
+ /* expectedActivated= */ true,
+ /* expectedMagnified= */ true);
resetMockWindowManager();
}
}
@@ -952,7 +974,8 @@ public class FullScreenMagnificationControllerTest {
/* displayId= */ i,
/* isMagnifierActivated= */ false,
/* isAlwaysOnEnabled= */ false,
- /* expectedActivated= */ false);
+ /* expectedActivated= */ false,
+ /* expectedMagnified= */ false);
resetMockWindowManager();
}
}
@@ -964,14 +987,15 @@ public class FullScreenMagnificationControllerTest {
/* displayId= */ i,
/* isMagnifierActivated= */ false,
/* isAlwaysOnEnabled= */ true,
- /* expectedActivated= */ false);
+ /* expectedActivated= */ false,
+ /* expectedMagnified= */ false);
resetMockWindowManager();
}
}
private void contextChange_expectedValues(
int displayId, boolean isMagnifierActivated, boolean isAlwaysOnEnabled,
- boolean expectedActivated) {
+ boolean expectedActivated, boolean expectedMagnified) {
mFullScreenMagnificationController.setAlwaysOnMagnificationEnabled(isAlwaysOnEnabled);
register(displayId);
MagnificationCallbacks callbacks = getMagnificationCallbacks(displayId);
@@ -982,7 +1006,7 @@ public class FullScreenMagnificationControllerTest {
callbacks.onUserContextChanged();
mMessageCapturingHandler.sendAllMessages();
checkActivatedAndMagnifying(
- /* activated= */ expectedActivated, /* magnifying= */ false, displayId);
+ /* activated= */ expectedActivated, expectedMagnified, displayId);
if (expectedActivated) {
verify(mMockThumbnail, times(2)).setThumbnailBounds(
@@ -1526,8 +1550,8 @@ public class FullScreenMagnificationControllerTest {
private void checkActivatedAndMagnifying(boolean activated, boolean magnifying, int displayId) {
final boolean isActivated = mFullScreenMagnificationController.isActivated(displayId);
final boolean isMagnifying = mFullScreenMagnificationController.getScale(displayId) > 1.0f;
- assertTrue(isActivated == activated);
- assertTrue(isMagnifying == magnifying);
+ assertEquals(isActivated, activated);
+ assertEquals(isMagnifying, magnifying);
}
private MagnificationCallbacks getMagnificationCallbacks(int displayId) {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
index 60bcecc2f885..957ee06b6e27 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
@@ -17,6 +17,7 @@
package com.android.server.accessibility.magnification;
import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_HOVER_MOVE;
import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_POINTER_DOWN;
import static android.view.MotionEvent.ACTION_POINTER_INDEX_SHIFT;
@@ -27,6 +28,8 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat
import static com.android.server.testutils.TestUtils.strictMock;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -300,7 +303,8 @@ public class FullScreenMagnificationGestureHandlerTest {
mMockFullScreenMagnificationVibrationHelper,
mMockMagnificationLogger,
ViewConfiguration.get(mContext),
- mMockOneFingerPanningSettingsProvider);
+ mMockOneFingerPanningSettingsProvider,
+ new MouseEventHandler(mFullScreenMagnificationController));
// OverscrollHandler is only supported on watches.
// @See config_enable_a11y_fullscreen_magnification_overscroll_handler
if (isWatch()) {
@@ -1398,6 +1402,302 @@ public class FullScreenMagnificationGestureHandlerTest {
mFullScreenMagnificationController.reset(DISPLAY_0, /* animate= */ false);
}
+ @Test
+ @RequiresFlagsDisabled(Flags.FLAG_ENABLE_MAGNIFICATION_FOLLOWS_MOUSE)
+ public void testMouseMoveEventsDoNotMoveMagnifierViewport() {
+ runMoveEventsDoNotMoveMagnifierViewport(InputDevice.SOURCE_MOUSE);
+ }
+
+ @Test
+ public void testStylusMoveEventsDoNotMoveMagnifierViewport() {
+ runMoveEventsDoNotMoveMagnifierViewport(InputDevice.SOURCE_STYLUS);
+ }
+
+ @Test
+ @RequiresFlagsDisabled(Flags.FLAG_ENABLE_MAGNIFICATION_FOLLOWS_MOUSE)
+ public void testMouseHoverMoveEventsDoNotMoveMagnifierViewport() {
+ runHoverMoveEventsDoNotMoveMagnifierViewport(InputDevice.SOURCE_MOUSE);
+ }
+
+ @Test
+ @RequiresFlagsDisabled(Flags.FLAG_ENABLE_MAGNIFICATION_FOLLOWS_MOUSE)
+ public void testStylusHoverMoveEventsDoNotMoveMagnifierViewport() {
+ runHoverMoveEventsDoNotMoveMagnifierViewport(InputDevice.SOURCE_STYLUS);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_FOLLOWS_MOUSE)
+ public void testMouseHoverMoveEventsMoveMagnifierViewport() {
+ runHoverMovesViewportTest(InputDevice.SOURCE_MOUSE);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_FOLLOWS_MOUSE)
+ public void testStylusHoverMoveEventsMoveMagnifierViewport() {
+ runHoverMovesViewportTest(InputDevice.SOURCE_STYLUS);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_FOLLOWS_MOUSE)
+ public void testMouseDownEventsDoNotMoveMagnifierViewport() {
+ runDownDoesNotMoveViewportTest(InputDevice.SOURCE_MOUSE);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_FOLLOWS_MOUSE)
+ public void testStylusDownEventsDoNotMoveMagnifierViewport() {
+ runDownDoesNotMoveViewportTest(InputDevice.SOURCE_STYLUS);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_FOLLOWS_MOUSE)
+ public void testMouseUpEventsDoNotMoveMagnifierViewport() {
+ runUpDoesNotMoveViewportTest(InputDevice.SOURCE_MOUSE);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_FOLLOWS_MOUSE)
+ public void testStylusUpEventsDoNotMoveMagnifierViewport() {
+ runUpDoesNotMoveViewportTest(InputDevice.SOURCE_STYLUS);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_FOLLOWS_MOUSE)
+ public void testMouseMoveEventsMoveMagnifierViewport() {
+ final EventCaptor eventCaptor = new EventCaptor();
+ mMgh.setNext(eventCaptor);
+
+ float centerX =
+ (INITIAL_MAGNIFICATION_BOUNDS.left + INITIAL_MAGNIFICATION_BOUNDS.width()) / 2.0f;
+ float centerY =
+ (INITIAL_MAGNIFICATION_BOUNDS.top + INITIAL_MAGNIFICATION_BOUNDS.height()) / 2.0f;
+ float scale = 6.2f; // value is unimportant but unique among tests to increase coverage.
+ mFullScreenMagnificationController.setScaleAndCenter(
+ DISPLAY_0, centerX, centerY, scale, /* animate= */ false, 1);
+ MotionEvent event = mouseEvent(centerX, centerY, ACTION_HOVER_MOVE);
+ send(event, InputDevice.SOURCE_MOUSE);
+ fastForward(20);
+ event = mouseEvent(centerX, centerY, ACTION_DOWN);
+ send(event, InputDevice.SOURCE_MOUSE);
+ fastForward(20);
+
+ // Mouse drag event does impact magnifier viewport.
+ event = mouseEvent(centerX + 30, centerY + 60, ACTION_MOVE);
+ send(event, InputDevice.SOURCE_MOUSE);
+ fastForward(20);
+
+ assertThat(mFullScreenMagnificationController.getCenterX(DISPLAY_0))
+ .isEqualTo(centerX + 30);
+ assertThat(mFullScreenMagnificationController.getCenterY(DISPLAY_0))
+ .isEqualTo(centerY + 60);
+
+ // The mouse events were not consumed by magnifier.
+ assertThat(eventCaptor.mEvents.size()).isEqualTo(3);
+ assertThat(eventCaptor.mEvents.get(0).getSource()).isEqualTo(InputDevice.SOURCE_MOUSE);
+ assertThat(eventCaptor.mEvents.get(1).getSource()).isEqualTo(InputDevice.SOURCE_MOUSE);
+ assertThat(eventCaptor.mEvents.get(2).getSource()).isEqualTo(InputDevice.SOURCE_MOUSE);
+
+ final List<Integer> expectedActions = new ArrayList();
+ expectedActions.add(Integer.valueOf(ACTION_HOVER_MOVE));
+ expectedActions.add(Integer.valueOf(ACTION_DOWN));
+ expectedActions.add(Integer.valueOf(ACTION_MOVE));
+ assertActionsInOrder(eventCaptor.mEvents, expectedActions);
+ }
+
+ private void runHoverMovesViewportTest(int source) {
+ final EventCaptor eventCaptor = new EventCaptor();
+ mMgh.setNext(eventCaptor);
+
+ float centerX =
+ (INITIAL_MAGNIFICATION_BOUNDS.left + INITIAL_MAGNIFICATION_BOUNDS.width()) / 2.0f;
+ float centerY =
+ (INITIAL_MAGNIFICATION_BOUNDS.top + INITIAL_MAGNIFICATION_BOUNDS.height()) / 2.0f;
+ float scale = 4.0f; // value is unimportant but unique among tests to increase coverage.
+ mFullScreenMagnificationController.setScaleAndCenter(
+ DISPLAY_0, centerX, centerY, scale, /* animate= */ false, 1);
+
+ // HOVER_MOVE should change magnifier viewport.
+ MotionEvent event = motionEvent(centerX + 20, centerY, ACTION_HOVER_MOVE);
+ send(event, source);
+ fastForward(20);
+
+ assertThat(mFullScreenMagnificationController.getCenterX(DISPLAY_0))
+ .isEqualTo(centerX + 20);
+ assertThat(mFullScreenMagnificationController.getCenterY(DISPLAY_0)).isEqualTo(centerY);
+
+ // Make sure mouse events are sent onward and not blocked after moving the viewport.
+ assertThat(eventCaptor.mEvents.size()).isEqualTo(1);
+ assertThat(eventCaptor.mEvents.get(0).getSource()).isEqualTo(source);
+
+ // Send another hover.
+ event = motionEvent(centerX + 20, centerY + 40, ACTION_HOVER_MOVE);
+ send(event, source);
+ fastForward(20);
+
+ assertThat(mFullScreenMagnificationController.getCenterX(DISPLAY_0))
+ .isEqualTo(centerX + 20);
+ assertThat(mFullScreenMagnificationController.getCenterY(DISPLAY_0))
+ .isEqualTo(centerY + 40);
+
+ assertThat(eventCaptor.mEvents.size()).isEqualTo(2);
+ assertThat(eventCaptor.mEvents.get(1).getSource()).isEqualTo(source);
+
+ final List<Integer> expectedActions = new ArrayList();
+ expectedActions.add(Integer.valueOf(ACTION_HOVER_MOVE));
+ expectedActions.add(Integer.valueOf(ACTION_HOVER_MOVE));
+ assertActionsInOrder(eventCaptor.mEvents, expectedActions);
+ }
+
+ private void runDownDoesNotMoveViewportTest(int source) {
+ final EventCaptor eventCaptor = new EventCaptor();
+ mMgh.setNext(eventCaptor);
+
+ float centerX =
+ (INITIAL_MAGNIFICATION_BOUNDS.left + INITIAL_MAGNIFICATION_BOUNDS.width()) / 2.0f;
+ float centerY =
+ (INITIAL_MAGNIFICATION_BOUNDS.top + INITIAL_MAGNIFICATION_BOUNDS.height()) / 2.0f;
+ float scale = 5.3f; // value is unimportant but unique among tests to increase coverage.
+ mFullScreenMagnificationController.setScaleAndCenter(
+ DISPLAY_0, centerX, centerY, scale, /* animate= */ false, 1);
+ MotionEvent event = motionEvent(centerX, centerY, ACTION_HOVER_MOVE);
+ send(event, source);
+ fastForward(20);
+
+ // Down event doesn't impact magnifier viewport.
+ event = motionEvent(centerX + 20, centerY + 40, ACTION_DOWN);
+ send(event, source);
+ fastForward(20);
+
+ assertThat(mFullScreenMagnificationController.getCenterX(DISPLAY_0)).isEqualTo(centerX);
+ assertThat(mFullScreenMagnificationController.getCenterY(DISPLAY_0)).isEqualTo(centerY);
+
+ // The events were not consumed by magnifier.
+ assertThat(eventCaptor.mEvents.size()).isEqualTo(2);
+ assertThat(eventCaptor.mEvents.get(0).getSource()).isEqualTo(source);
+ assertThat(eventCaptor.mEvents.get(1).getSource()).isEqualTo(source);
+
+ final List<Integer> expectedActions = new ArrayList();
+ expectedActions.add(Integer.valueOf(ACTION_HOVER_MOVE));
+ expectedActions.add(Integer.valueOf(ACTION_DOWN));
+ assertActionsInOrder(eventCaptor.mEvents, expectedActions);
+ }
+
+ private void runUpDoesNotMoveViewportTest(int source) {
+ final EventCaptor eventCaptor = new EventCaptor();
+ mMgh.setNext(eventCaptor);
+
+ float centerX =
+ (INITIAL_MAGNIFICATION_BOUNDS.left + INITIAL_MAGNIFICATION_BOUNDS.width()) / 2.0f;
+ float centerY =
+ (INITIAL_MAGNIFICATION_BOUNDS.top + INITIAL_MAGNIFICATION_BOUNDS.height()) / 2.0f;
+ float scale = 2.7f; // value is unimportant but unique among tests to increase coverage.
+ mFullScreenMagnificationController.setScaleAndCenter(
+ DISPLAY_0, centerX, centerY, scale, /* animate= */ false, 1);
+ MotionEvent event = motionEvent(centerX, centerY, ACTION_HOVER_MOVE);
+ send(event, source);
+ fastForward(20);
+ event = motionEvent(centerX, centerY, ACTION_DOWN);
+ send(event, source);
+ fastForward(20);
+
+ // Up event should not move the viewport.
+ event = motionEvent(centerX + 30, centerY + 60, ACTION_UP);
+ send(event, source);
+ fastForward(20);
+
+ // The events were not consumed by magnifier.
+ assertThat(eventCaptor.mEvents.size()).isEqualTo(3);
+ assertThat(eventCaptor.mEvents.get(0).getSource()).isEqualTo(source);
+ assertThat(eventCaptor.mEvents.get(1).getSource()).isEqualTo(source);
+ assertThat(eventCaptor.mEvents.get(2).getSource()).isEqualTo(source);
+
+ final List<Integer> expectedActions = new ArrayList();
+ expectedActions.add(Integer.valueOf(ACTION_HOVER_MOVE));
+ expectedActions.add(Integer.valueOf(ACTION_DOWN));
+ expectedActions.add(Integer.valueOf(ACTION_UP));
+ assertActionsInOrder(eventCaptor.mEvents, expectedActions);
+ }
+
+ private void runMoveEventsDoNotMoveMagnifierViewport(int source) {
+ final EventCaptor eventCaptor = new EventCaptor();
+ mMgh.setNext(eventCaptor);
+
+ float centerX =
+ (INITIAL_MAGNIFICATION_BOUNDS.left + INITIAL_MAGNIFICATION_BOUNDS.width()) / 2.0f;
+ float centerY =
+ (INITIAL_MAGNIFICATION_BOUNDS.top + INITIAL_MAGNIFICATION_BOUNDS.height()) / 2.0f;
+ float scale = 3.8f; // value is unimportant but unique among tests to increase coverage.
+ mFullScreenMagnificationController.setScaleAndCenter(
+ DISPLAY_0, centerX, centerY, scale, /* animate= */ false, 1);
+ centerX = mFullScreenMagnificationController.getCenterX(DISPLAY_0);
+ centerY = mFullScreenMagnificationController.getCenterY(DISPLAY_0);
+
+ MotionEvent event = motionEvent(centerX, centerY, ACTION_DOWN);
+ send(event, source);
+ fastForward(20);
+
+ // Drag event doesn't impact magnifier viewport.
+ event = stylusEvent(centerX + 18, centerY + 42, ACTION_MOVE);
+ send(event, source);
+ fastForward(20);
+
+ assertThat(mFullScreenMagnificationController.getCenterX(DISPLAY_0)).isEqualTo(centerX);
+ assertThat(mFullScreenMagnificationController.getCenterY(DISPLAY_0)).isEqualTo(centerY);
+
+ // The events were not consumed by magnifier.
+ assertThat(eventCaptor.mEvents.size()).isEqualTo(2);
+ assertThat(eventCaptor.mEvents.get(0).getSource()).isEqualTo(source);
+ assertThat(eventCaptor.mEvents.get(1).getSource()).isEqualTo(source);
+
+ final List<Integer> expectedActions = new ArrayList();
+ expectedActions.add(Integer.valueOf(ACTION_DOWN));
+ expectedActions.add(Integer.valueOf(ACTION_MOVE));
+ assertActionsInOrder(eventCaptor.mEvents, expectedActions);
+ }
+
+ private void runHoverMoveEventsDoNotMoveMagnifierViewport(int source) {
+ final EventCaptor eventCaptor = new EventCaptor();
+ mMgh.setNext(eventCaptor);
+
+ float centerX =
+ (INITIAL_MAGNIFICATION_BOUNDS.left + INITIAL_MAGNIFICATION_BOUNDS.width()) / 2.0f;
+ float centerY =
+ (INITIAL_MAGNIFICATION_BOUNDS.top + INITIAL_MAGNIFICATION_BOUNDS.height()) / 2.0f;
+ float scale = 4.0f; // value is unimportant but unique among tests to increase coverage.
+ mFullScreenMagnificationController.setScaleAndCenter(
+ DISPLAY_0, centerX, centerY, scale, /* animate= */ false, 1);
+ centerX = mFullScreenMagnificationController.getCenterX(DISPLAY_0);
+ centerY = mFullScreenMagnificationController.getCenterY(DISPLAY_0);
+
+ // HOVER_MOVE should not change magnifier viewport.
+ MotionEvent event = motionEvent(centerX + 20, centerY, ACTION_HOVER_MOVE);
+ send(event, source);
+ fastForward(20);
+
+ assertThat(mFullScreenMagnificationController.getCenterX(DISPLAY_0)).isEqualTo(centerX);
+ assertThat(mFullScreenMagnificationController.getCenterY(DISPLAY_0)).isEqualTo(centerY);
+
+ // Make sure events are sent onward and not blocked after moving the viewport.
+ assertThat(eventCaptor.mEvents.size()).isEqualTo(1);
+ assertThat(eventCaptor.mEvents.get(0).getSource()).isEqualTo(source);
+
+ // Send another hover.
+ event = motionEvent(centerX + 20, centerY + 40, ACTION_HOVER_MOVE);
+ send(event, source);
+ fastForward(20);
+
+ assertThat(mFullScreenMagnificationController.getCenterX(DISPLAY_0)).isEqualTo(centerX);
+ assertThat(mFullScreenMagnificationController.getCenterY(DISPLAY_0)).isEqualTo(centerY);
+
+ assertThat(eventCaptor.mEvents.size()).isEqualTo(2);
+ assertThat(eventCaptor.mEvents.get(1).getSource()).isEqualTo(source);
+
+ final List<Integer> expectedActions = new ArrayList();
+ expectedActions.add(Integer.valueOf(ACTION_HOVER_MOVE));
+ expectedActions.add(Integer.valueOf(ACTION_HOVER_MOVE));
+ assertActionsInOrder(eventCaptor.mEvents, expectedActions);
+ }
+
private void enableOneFingerPanning(boolean enable) {
mMockOneFingerPanningEnabled = enable;
when(mMockOneFingerPanningSettingsProvider.isOneFingerPanningEnabled()).thenReturn(enable);
@@ -1795,8 +2095,14 @@ public class FullScreenMagnificationGestureHandlerTest {
mMgh.notifyShortcutTriggered();
}
+ /** Sends the MotionEvent from a Touchscreen source */
private void send(MotionEvent event) {
- event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+ send(event, InputDevice.SOURCE_TOUCHSCREEN);
+ }
+
+ /** Sends the MotionEvent from the given source type. */
+ private void send(MotionEvent event, int source) {
+ event.setSource(source);
try {
mMgh.onMotionEvent(event, event, /* policyFlags */ 0);
} catch (Throwable t) {
@@ -1810,9 +2116,30 @@ public class FullScreenMagnificationGestureHandlerTest {
return ev;
}
+ private static MotionEvent fromMouse(MotionEvent ev) {
+ ev.setSource(InputDevice.SOURCE_MOUSE);
+ return ev;
+ }
+
+ private static MotionEvent fromStylus(MotionEvent ev) {
+ ev.setSource(InputDevice.SOURCE_STYLUS);
+ return ev;
+ }
+
+ private MotionEvent motionEvent(float x, float y, int action) {
+ return MotionEvent.obtain(mLastDownTime, mClock.now(), action, x, y, 0);
+ }
+
+ private MotionEvent mouseEvent(float x, float y, int action) {
+ return fromMouse(motionEvent(x, y, action));
+ }
+
+ private MotionEvent stylusEvent(float x, float y, int action) {
+ return fromStylus(motionEvent(x, y, action));
+ }
+
private MotionEvent moveEvent(float x, float y) {
- return fromTouchscreen(
- MotionEvent.obtain(mLastDownTime, mClock.now(), ACTION_MOVE, x, y, 0));
+ return fromTouchscreen(motionEvent(x, y, ACTION_MOVE));
}
private MotionEvent downEvent() {
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java
index e078238f6385..9317d06ec968 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java
@@ -42,9 +42,11 @@ import android.content.AttributionSource;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentSender;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.net.Uri;
+import android.os.Binder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
@@ -518,19 +520,6 @@ public class GenericWindowPolicyControllerTest {
}
@Test
- public void canActivityBeLaunched_permissionComponent_isBlocked() {
- GenericWindowPolicyController gwpc = createGwpcWithPermissionComponent(BLOCKED_COMPONENT);
- gwpc.setDisplayId(DISPLAY_ID, /* isMirrorDisplay= */ false);
-
- ActivityInfo activityInfo = getActivityInfo(
- BLOCKED_PACKAGE_NAME,
- BLOCKED_PACKAGE_NAME,
- /* displayOnRemoteDevices */ true,
- /* targetDisplayCategory */ null);
- assertActivityIsBlocked(gwpc, activityInfo);
- }
-
- @Test
public void registerRunningAppsChangedListener_onRunningAppsChanged_listenersNotified() {
ArraySet<Integer> uids = new ArraySet<>(Arrays.asList(TEST_UID));
GenericWindowPolicyController gwpc = createGwpc();
@@ -605,13 +594,15 @@ public class GenericWindowPolicyControllerTest {
// register interceptor and intercept intent
when(mIntentListenerCallback.shouldInterceptIntent(any(Intent.class))).thenReturn(true);
assertThat(gwpc.canActivityBeLaunched(activityInfo, intent,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, /*isNewTask=*/false))
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, /* isNewTask= */false,
+ /* isResultExpected = */ false, /* intentSender= */ null))
.isFalse();
// unregister interceptor and launch activity
when(mIntentListenerCallback.shouldInterceptIntent(any(Intent.class))).thenReturn(false);
assertThat(gwpc.canActivityBeLaunched(activityInfo, intent,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, /*isNewTask=*/false))
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, /* isNewTask= */false,
+ /* isResultExpected = */ false, /* intentSender= */ null))
.isTrue();
}
@@ -630,13 +621,36 @@ public class GenericWindowPolicyControllerTest {
// register interceptor with different filter
when(mIntentListenerCallback.shouldInterceptIntent(any(Intent.class))).thenReturn(false);
assertThat(gwpc.canActivityBeLaunched(activityInfo, intent,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, /*isNewTask=*/false))
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, /* isNewTask= */false,
+ /* isResultExpected = */ false, /* intentSender= */ null))
.isTrue();
verify(mIntentListenerCallback, timeout(TIMEOUT_MILLIS))
.shouldInterceptIntent(any(Intent.class));
}
@Test
+ public void canActivityBeLaunched_resultExpected_noIntentSenderInCallback() {
+ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("testing"));
+
+ GenericWindowPolicyController gwpc = createGwpc();
+ gwpc.setDisplayId(DISPLAY_ID, /* isMirrorDisplay= */ false);
+ ActivityInfo activityInfo = getActivityInfo(
+ NONBLOCKED_APP_PACKAGE_NAME,
+ NONBLOCKED_APP_PACKAGE_NAME,
+ /* displayOnRemoteDevices */ false,
+ /* targetDisplayCategory */ null);
+
+ IntentSender intentSender = new IntentSender(new Binder());
+ assertThat(gwpc.canActivityBeLaunched(activityInfo, intent,
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, /* isNewTask= */false,
+ /* isResultExpected = */ true, /* intentSender= */ () -> intentSender))
+ .isFalse();
+
+ verify(mActivityBlockedCallback, timeout(TIMEOUT_MILLIS))
+ .onActivityBlocked(DISPLAY_ID, activityInfo, /* intentSender= */ null);
+ }
+
+ @Test
public void onTopActivitychanged_null_noCallback() {
GenericWindowPolicyController gwpc = createGwpc();
gwpc.setDisplayId(DISPLAY_ID, /* isMirrorDisplay= */ false);
@@ -672,7 +686,8 @@ public class GenericWindowPolicyControllerTest {
verify(mSecureWindowCallback, after(TIMEOUT_MILLIS).never())
.onSecureWindowShown(DISPLAY_ID, activityInfo.applicationInfo.uid);
- verify(mActivityBlockedCallback, never()).onActivityBlocked(DISPLAY_ID, activityInfo);
+ verify(mActivityBlockedCallback, never())
+ .onActivityBlocked(eq(DISPLAY_ID), eq(activityInfo), any());
}
@Test
@@ -691,7 +706,7 @@ public class GenericWindowPolicyControllerTest {
verify(mSecureWindowCallback, timeout(TIMEOUT_MILLIS)).onSecureWindowShown(DISPLAY_ID,
activityInfo.applicationInfo.uid);
verify(mActivityBlockedCallback, after(TIMEOUT_MILLIS).never())
- .onActivityBlocked(DISPLAY_ID, activityInfo);
+ .onActivityBlocked(eq(DISPLAY_ID), eq(activityInfo), any());
}
@Test
@@ -710,7 +725,8 @@ public class GenericWindowPolicyControllerTest {
verify(mSecureWindowCallback, after(TIMEOUT_MILLIS).never())
.onSecureWindowShown(DISPLAY_ID, activityInfo.applicationInfo.uid);
- verify(mActivityBlockedCallback, never()).onActivityBlocked(DISPLAY_ID, activityInfo);
+ verify(mActivityBlockedCallback, never())
+ .onActivityBlocked(eq(DISPLAY_ID), eq(activityInfo), any());
}
@Test
@@ -740,7 +756,6 @@ public class GenericWindowPolicyControllerTest {
/* activityPolicyExemptions= */ new ArraySet<>(),
/* crossTaskNavigationAllowedByDefault= */ true,
/* crossTaskNavigationExemptions= */ new ArraySet<>(),
- /* permissionDialogComponent= */ null,
/* activityListener= */ mActivityListener,
/* activityBlockedCallback= */ mActivityBlockedCallback,
/* secureWindowCallback= */ mSecureWindowCallback,
@@ -760,7 +775,6 @@ public class GenericWindowPolicyControllerTest {
/* activityPolicyExemptions= */ new ArraySet<>(),
/* crossTaskNavigationAllowedByDefault= */ true,
/* crossTaskNavigationExemptions= */ new ArraySet<>(),
- /* permissionDialogComponent= */ null,
/* activityListener= */ mActivityListener,
/* activityBlockedCallback= */ mActivityBlockedCallback,
/* secureWindowCallback= */ mSecureWindowCallback,
@@ -781,7 +795,6 @@ public class GenericWindowPolicyControllerTest {
/* activityPolicyExemptions= */ new ArraySet<>(),
/* crossTaskNavigationAllowedByDefault= */ true,
/* crossTaskNavigationExemptions= */ new ArraySet<>(),
- /* permissionDialogComponent= */ null,
/* activityListener= */ mActivityListener,
/* activityBlockedCallback= */ mActivityBlockedCallback,
/* secureWindowCallback= */ null,
@@ -802,7 +815,6 @@ public class GenericWindowPolicyControllerTest {
/* activityPolicyExemptions= */ Collections.singleton(blockedComponent),
/* crossTaskNavigationAllowedByDefault= */ true,
/* crossTaskNavigationExemptions= */ new ArraySet<>(),
- /* permissionDialogComponent= */ null,
/* activityListener= */ mActivityListener,
/* activityBlockedCallback= */ mActivityBlockedCallback,
/* secureWindowCallback= */ null,
@@ -823,7 +835,6 @@ public class GenericWindowPolicyControllerTest {
/* activityPolicyExemptions= */ Collections.singleton(allowedComponent),
/* crossTaskNavigationAllowedByDefault= */ true,
/* crossTaskNavigationExemptions= */ new ArraySet<>(),
- /* permissionDialogComponent= */ null,
/* activityListener= */ mActivityListener,
/* activityBlockedCallback= */ mActivityBlockedCallback,
/* secureWindowCallback= */ null,
@@ -844,7 +855,6 @@ public class GenericWindowPolicyControllerTest {
/* activityPolicyExemptions= */ new ArraySet<>(),
/* crossTaskNavigationAllowedByDefault= */ true,
/* crossTaskNavigationExemptions= */ new ArraySet<>(),
- /* permissionDialogComponent= */ null,
/* activityListener= */ mActivityListener,
/* activityBlockedCallback= */ mActivityBlockedCallback,
/* secureWindowCallback= */ null,
@@ -865,7 +875,6 @@ public class GenericWindowPolicyControllerTest {
/* activityPolicyExemptions= */ new ArraySet<>(),
/* crossTaskNavigationAllowedByDefault= */ true,
/* crossTaskNavigationExemptions= */ Collections.singleton(blockedComponent),
- /* permissionDialogComponent= */ null,
/* activityListener= */ mActivityListener,
/* activityBlockedCallback= */ mActivityBlockedCallback,
/* secureWindowCallback= */ null,
@@ -886,29 +895,6 @@ public class GenericWindowPolicyControllerTest {
/* activityPolicyExemptions= */ new ArraySet<>(),
/* crossTaskNavigationAllowedByDefault= */ false,
/* crossTaskNavigationExemptions= */ Collections.singleton(allowedComponent),
- /* permissionDialogComponent= */ null,
- /* activityListener= */ mActivityListener,
- /* activityBlockedCallback= */ mActivityBlockedCallback,
- /* secureWindowCallback= */ null,
- /* intentListenerCallback= */ mIntentListenerCallback,
- /* displayCategories= */ new ArraySet<>(),
- /* showTasksInHostDeviceRecents= */ true,
- /* customHomeComponent= */ null);
- }
-
- private GenericWindowPolicyController createGwpcWithPermissionComponent(
- ComponentName permissionComponent) {
- //TODO instert the component
- return new GenericWindowPolicyController(
- 0,
- 0,
- AttributionSource.myAttributionSource(),
- /* allowedUsers= */ new ArraySet<>(getCurrentUserId()),
- /* activityLaunchAllowedByDefault= */ true,
- /* activityPolicyExemptions= */ new ArraySet<>(),
- /* crossTaskNavigationAllowedByDefault= */ false,
- /* crossTaskNavigationExemptions= */ new ArraySet<>(),
- /* permissionDialogComponent= */ permissionComponent,
/* activityListener= */ mActivityListener,
/* activityBlockedCallback= */ mActivityBlockedCallback,
/* secureWindowCallback= */ null,
@@ -954,11 +940,12 @@ public class GenericWindowPolicyControllerTest {
private void assertActivityCanBeLaunched(GenericWindowPolicyController gwpc, int fromDisplay,
boolean isNewTask, int windowingMode, ActivityInfo activityInfo) {
+ IntentSender intentSender = new IntentSender(new Binder());
assertThat(gwpc.canActivityBeLaunched(activityInfo, null, windowingMode, fromDisplay,
- isNewTask)).isTrue();
+ isNewTask, /* isResultExpected= */ false, () -> intentSender)).isTrue();
verify(mActivityBlockedCallback, after(TIMEOUT_MILLIS).never())
- .onActivityBlocked(fromDisplay, activityInfo);
+ .onActivityBlocked(fromDisplay, activityInfo, intentSender);
verify(mIntentListenerCallback, never()).shouldInterceptIntent(any(Intent.class));
}
@@ -970,23 +957,26 @@ public class GenericWindowPolicyControllerTest {
private void assertActivityIsBlocked(GenericWindowPolicyController gwpc, int fromDisplay,
boolean isNewTask, int windowingMode, ActivityInfo activityInfo) {
+ IntentSender intentSender = new IntentSender(new Binder());
assertThat(gwpc.canActivityBeLaunched(activityInfo, null, windowingMode, fromDisplay,
- isNewTask)).isFalse();
+ isNewTask, /* isResultExpected= */ false, () -> intentSender)).isFalse();
verify(mActivityBlockedCallback, timeout(TIMEOUT_MILLIS))
- .onActivityBlocked(fromDisplay, activityInfo);
+ .onActivityBlocked(fromDisplay, activityInfo, intentSender);
verify(mIntentListenerCallback, after(TIMEOUT_MILLIS).never())
.shouldInterceptIntent(any(Intent.class));
}
private void assertNoActivityLaunched(GenericWindowPolicyController gwpc, int fromDisplay,
ActivityInfo activityInfo) {
+ IntentSender intentSender = new IntentSender(new Binder());
assertThat(gwpc.canActivityBeLaunched(activityInfo, null,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, true))
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, /* isNewTask= */false,
+ /* isResultExpected= */ false, () -> intentSender))
.isFalse();
verify(mActivityBlockedCallback, after(TIMEOUT_MILLIS).never())
- .onActivityBlocked(fromDisplay, activityInfo);
+ .onActivityBlocked(eq(fromDisplay), eq(activityInfo), any());
verify(mIntentListenerCallback, never()).shouldInterceptIntent(any(Intent.class));
}
}
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
index da8961df38a8..c2882124e6e3 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
@@ -314,7 +314,8 @@ public class VirtualDeviceManagerServiceTest {
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
activityInfo, mAssociationInfo.getDisplayName());
gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false);
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false,
+ /* isResultExpected = */ false, /* intentSender= */ null);
return blockedAppIntent;
}
@@ -1522,7 +1523,8 @@ public class VirtualDeviceManagerServiceTest {
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
activityInfo, mAssociationInfo.getDisplayName());
gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false);
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false,
+ /* isResultExpected = */ false, /* intentSender= */ null);
verify(mContext, never()).startActivityAsUser(argThat(intent ->
intent.filterEquals(blockedAppIntent)), any(), any());
@@ -1543,15 +1545,15 @@ public class VirtualDeviceManagerServiceTest {
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
activityInfo, mAssociationInfo.getDisplayName());
gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false);
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false,
+ /* isResultExpected = */ false, /* intentSender= */ null);
verify(mContext).startActivityAsUser(argThat(intent ->
intent.filterEquals(blockedAppIntent)), any(), any());
}
@Test
- public void openPermissionControllerOnVirtualDisplay_displayOnRemoteDevices_startsWhenFlagIsEnabled() {
- mSetFlagsRule.enableFlags(Flags.FLAG_STREAM_PERMISSIONS);
+ public void openPermissionControllerOnVirtualDisplay_displayOnRemoteDevices_starts() {
addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1);
GenericWindowPolicyController gwpc = mDeviceImpl.getDisplayWindowPolicyControllerForTest(
DISPLAY_ID_1);
@@ -1565,15 +1567,15 @@ public class VirtualDeviceManagerServiceTest {
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
activityInfo, mAssociationInfo.getDisplayName());
gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false);
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false,
+ /* isResultExpected = */ false, /* intentSender= */ null);
verify(mContext, never()).startActivityAsUser(argThat(intent ->
intent.filterEquals(blockedAppIntent)), any(), any());
}
@Test
- public void openPermissionControllerOnVirtualDisplay_dontDisplayOnRemoteDevices_startsWhenFlagIsEnabled() {
- mSetFlagsRule.enableFlags(Flags.FLAG_STREAM_PERMISSIONS);
+ public void openPermissionControllerOnVirtualDisplay_dontDisplayOnRemoteDevices_starts() {
addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1);
GenericWindowPolicyController gwpc = mDeviceImpl.getDisplayWindowPolicyControllerForTest(
DISPLAY_ID_1);
@@ -1587,7 +1589,8 @@ public class VirtualDeviceManagerServiceTest {
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
activityInfo, mAssociationInfo.getDisplayName());
gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false);
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false,
+ /* isResultExpected = */ false, /* intentSender= */ null);
verify(mContext).startActivityAsUser(argThat(intent ->
intent.filterEquals(blockedAppIntent)), any(), any());
@@ -1608,7 +1611,8 @@ public class VirtualDeviceManagerServiceTest {
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
activityInfo, mAssociationInfo.getDisplayName());
gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false);
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false,
+ /* isResultExpected = */ false, /* intentSender= */ null);
verify(mContext).startActivityAsUser(argThat(intent ->
intent.filterEquals(blockedAppIntent)), any(), any());
@@ -1629,7 +1633,8 @@ public class VirtualDeviceManagerServiceTest {
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
activityInfo, mAssociationInfo.getDisplayName());
gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false);
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false,
+ /* isResultExpected = */ false, /* intentSender= */ null);
verify(mContext).startActivityAsUser(argThat(intent ->
intent.filterEquals(blockedAppIntent)), any(), any());
@@ -1650,7 +1655,8 @@ public class VirtualDeviceManagerServiceTest {
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
activityInfo, mAssociationInfo.getDisplayName());
gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false);
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false,
+ /* isResultExpected = */ false, /* intentSender= */ null);
verify(mContext).startActivityAsUser(argThat(intent ->
intent.filterEquals(blockedAppIntent)), any(), any());
@@ -1671,7 +1677,8 @@ public class VirtualDeviceManagerServiceTest {
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
activityInfo, mAssociationInfo.getDisplayName());
gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false);
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false,
+ /* isResultExpected = */ false, /* intentSender= */ null);
verify(mContext).startActivityAsUser(argThat(intent ->
intent.filterEquals(blockedAppIntent)), any(), any());
@@ -1693,7 +1700,8 @@ public class VirtualDeviceManagerServiceTest {
/* displayOnRemoteDevices */ true,
/* targetDisplayCategory */ null);
assertThat(gwpc.canActivityBeLaunched(activityInfo, null,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/ false))
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false,
+ /* isResultExpected = */ false, /* intentSender= */ null))
.isFalse();
// Verify that BlockedAppStreamingActivity also doesn't launch for mirror displays.
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
@@ -1718,7 +1726,8 @@ public class VirtualDeviceManagerServiceTest {
/* displayOnRemoteDevices */ true,
/* targetDisplayCategory */ null);
assertThat(gwpc.canActivityBeLaunched(activityInfo, null,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/ false))
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false,
+ /* isResultExpected = */ false, /* intentSender= */ null))
.isTrue();
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
activityInfo, mAssociationInfo.getDisplayName());
@@ -1755,35 +1764,7 @@ public class VirtualDeviceManagerServiceTest {
}
@Test
- public void canActivityBeLaunched_permissionDialog_flagDisabled_isBlocked() {
- mSetFlagsRule.disableFlags(Flags.FLAG_STREAM_PERMISSIONS);
- VirtualDeviceParams params = new VirtualDeviceParams.Builder().build();
- mDeviceImpl.close();
- mDeviceImpl = createVirtualDevice(VIRTUAL_DEVICE_ID_1, DEVICE_OWNER_UID_1, params);
- doNothing().when(mContext).startActivityAsUser(any(), any(), any());
-
- addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1);
- GenericWindowPolicyController gwpc = mDeviceImpl.getDisplayWindowPolicyControllerForTest(
- DISPLAY_ID_1);
- ComponentName permissionComponent = getPermissionDialogComponent();
- ActivityInfo activityInfo = getActivityInfo(
- permissionComponent.getPackageName(),
- permissionComponent.getClassName(),
- /* displayOnRemoteDevices */ true,
- /* targetDisplayCategory */ null);
- assertThat(gwpc.canActivityBeLaunched(activityInfo, null,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false))
- .isFalse();
-
- Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
- activityInfo, mAssociationInfo.getDisplayName());
- verify(mContext).startActivityAsUser(argThat(intent ->
- intent.filterEquals(blockedAppIntent)), any(), any());
- }
-
- @Test
- public void canActivityBeLaunched_permissionDialog_flagEnabled_isStreamed() {
- mSetFlagsRule.enableFlags(Flags.FLAG_STREAM_PERMISSIONS);
+ public void canActivityBeLaunched_permissionDialog_isStreamed() {
VirtualDeviceParams params = new VirtualDeviceParams.Builder().build();
mDeviceImpl.close();
mDeviceImpl = createVirtualDevice(VIRTUAL_DEVICE_ID_1, DEVICE_OWNER_UID_1, params);
@@ -1798,7 +1779,8 @@ public class VirtualDeviceManagerServiceTest {
/* displayOnRemoteDevices */ true,
/* targetDisplayCategory */ null);
assertThat(gwpc.canActivityBeLaunched(activityInfo, null,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false))
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false,
+ /* isResultExpected = */ false, /* intentSender= */ null))
.isTrue();
}
@@ -1814,7 +1796,8 @@ public class VirtualDeviceManagerServiceTest {
/* displayOnRemoteDevices */ true,
/* targetDisplayCategory */ null);
assertThat(gwpc.canActivityBeLaunched(activityInfo, intent,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false))
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false,
+ /* isResultExpected = */ false, /* intentSender= */ null))
.isTrue();
}
@@ -1845,7 +1828,8 @@ public class VirtualDeviceManagerServiceTest {
// register interceptor and intercept intent
mDeviceImpl.registerIntentInterceptor(interceptor, intentFilter);
assertThat(gwpc.canActivityBeLaunched(activityInfo, intent,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false))
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false,
+ /* isResultExpected = */ false, /* intentSender= */ null))
.isFalse();
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(interceptor).onIntentIntercepted(intentCaptor.capture());
@@ -1857,7 +1841,8 @@ public class VirtualDeviceManagerServiceTest {
// unregister interceptor and launch activity
mDeviceImpl.unregisterIntentInterceptor(interceptor);
assertThat(gwpc.canActivityBeLaunched(activityInfo, intent,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false))
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false,
+ /* isResultExpected = */ false, /* intentSender= */ null))
.isTrue();
}
@@ -1888,7 +1873,8 @@ public class VirtualDeviceManagerServiceTest {
mDeviceImpl.registerIntentInterceptor(interceptor, intentFilter);
assertThat(gwpc.canActivityBeLaunched(activityInfo, intent,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false))
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false,
+ /* isResultExpected = */ false, /* intentSender= */ null))
.isTrue();
}
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
index b946a43ea038..c3db3965bd77 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
@@ -85,7 +85,6 @@ public class VirtualAudioControllerTest {
/* activityPolicyExemptions= */ new ArraySet<>(),
/* crossTaskNavigationAllowedByDefault= */ true,
/* crossTaskNavigationExemptions= */ new ArraySet<>(),
- /* permissionDialogComponent */ null,
/* activityListener= */ null,
/* activityBlockedCallback= */ null,
/* secureWindowCallback= */ null,
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java
index e06d939a34f7..de70280ee0a9 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java
@@ -2454,6 +2454,50 @@ public class NotificationAttentionHelperTest extends UiServiceTestCase {
}
@Test
+ public void testBeepVolume_politeNotif_Avalanche_exemptCategories() throws Exception {
+ mSetFlagsRule.enableFlags(Flags.FLAG_POLITE_NOTIFICATIONS);
+ mSetFlagsRule.enableFlags(Flags.FLAG_CROSS_APP_POLITE_NOTIFICATIONS);
+ mSetFlagsRule.enableFlags(Flags.FLAG_POLITE_NOTIFICATIONS_ATTN_UPDATE);
+ TestableFlagResolver flagResolver = new TestableFlagResolver();
+ flagResolver.setFlagOverride(NotificationFlags.NOTIF_VOLUME1, 50);
+ flagResolver.setFlagOverride(NotificationFlags.NOTIF_VOLUME2, 0);
+ initAttentionHelper(flagResolver);
+
+ // Trigger avalanche trigger intent
+ final Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+ intent.putExtra("state", false);
+ mAvalancheBroadcastReceiver.onReceive(getContext(), intent);
+
+ // CATEGORY_ALARM is exempted
+ NotificationRecord r = getBeepyNotification();
+ r.getNotification().category = Notification.CATEGORY_ALARM;
+ // Should beep at 100% volume
+ mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+ verifyBeepVolume(1.0f);
+ assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+
+ // CATEGORY_CAR_EMERGENCY is exempted
+ Mockito.reset(mRingtonePlayer);
+ NotificationRecord r2 = getBeepyNotification();
+ r2.getNotification().category = Notification.CATEGORY_CAR_EMERGENCY;
+ // Should beep at 100% volume
+ mAttentionHelper.buzzBeepBlinkLocked(r2, DEFAULT_SIGNALS);
+ verifyBeepVolume(1.0f);
+ assertNotEquals(-1, r2.getLastAudiblyAlertedMs());
+
+ // CATEGORY_CAR_WARNING is exempted
+ Mockito.reset(mRingtonePlayer);
+ NotificationRecord r3 = getBeepyNotification();
+ r3.getNotification().category = Notification.CATEGORY_CAR_WARNING;
+ // Should beep at 100% volume
+ mAttentionHelper.buzzBeepBlinkLocked(r3, DEFAULT_SIGNALS);
+ verifyBeepVolume(1.0f);
+ assertNotEquals(-1, r3.getLastAudiblyAlertedMs());
+
+ verify(mAccessibilityService, times(3)).sendAccessibilityEvent(any(), anyInt());
+ }
+
+ @Test
public void testBeepVolume_politeNotif_exemptEmergency() throws Exception {
mSetFlagsRule.enableFlags(Flags.FLAG_POLITE_NOTIFICATIONS);
mSetFlagsRule.disableFlags(Flags.FLAG_CROSS_APP_POLITE_NOTIFICATIONS);
@@ -2492,6 +2536,73 @@ public class NotificationAttentionHelperTest extends UiServiceTestCase {
}
@Test
+ public void testBeepVolume_politeNotif_exemptCategories() throws Exception {
+ mSetFlagsRule.enableFlags(Flags.FLAG_POLITE_NOTIFICATIONS);
+ mSetFlagsRule.disableFlags(Flags.FLAG_CROSS_APP_POLITE_NOTIFICATIONS);
+ mSetFlagsRule.enableFlags(Flags.FLAG_POLITE_NOTIFICATIONS_ATTN_UPDATE);
+ TestableFlagResolver flagResolver = new TestableFlagResolver();
+ flagResolver.setFlagOverride(NotificationFlags.NOTIF_VOLUME1, 50);
+ flagResolver.setFlagOverride(NotificationFlags.NOTIF_VOLUME2, 0);
+ // NOTIFICATION_COOLDOWN_ALL setting is enabled
+ Settings.System.putInt(getContext().getContentResolver(),
+ Settings.System.NOTIFICATION_COOLDOWN_ALL, 1);
+ initAttentionHelper(flagResolver);
+
+ // CATEGORY_ALARM is exempted
+ NotificationRecord r = getBeepyNotification();
+ r.getNotification().category = Notification.CATEGORY_ALARM;
+ mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+ Mockito.reset(mRingtonePlayer);
+
+ // update should beep at 100% volume
+ mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+ assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+ verifyBeepVolume(1.0f);
+
+ // 2nd update should beep at 100% volume
+ Mockito.reset(mRingtonePlayer);
+ mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+ assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+ verifyBeepVolume(1.0f);
+
+ // CATEGORY_CAR_WARNING is exempted
+ r = getBeepyNotification();
+ r.getNotification().category = Notification.CATEGORY_CAR_WARNING;
+ mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+ Mockito.reset(mRingtonePlayer);
+
+ // update should beep at 100% volume
+ mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+ assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+ verifyBeepVolume(1.0f);
+
+ // 2nd update should beep at 100% volume
+ Mockito.reset(mRingtonePlayer);
+ mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+ assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+ verifyBeepVolume(1.0f);
+
+ // CATEGORY_CAR_EMERGENCY is exempted
+ r = getBeepyNotification();
+ r.getNotification().category = Notification.CATEGORY_CAR_EMERGENCY;
+ mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+ Mockito.reset(mRingtonePlayer);
+
+ // update should beep at 100% volume
+ mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+ assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+ verifyBeepVolume(1.0f);
+
+ // 2nd update should beep at 100% volume
+ Mockito.reset(mRingtonePlayer);
+ mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+ assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+ verifyBeepVolume(1.0f);
+
+ verify(mAccessibilityService, times(9)).sendAccessibilityEvent(any(), anyInt());
+ }
+
+ @Test
public void testBeepVolume_politeNotif_applyPerApp() throws Exception {
mSetFlagsRule.enableFlags(Flags.FLAG_POLITE_NOTIFICATIONS);
mSetFlagsRule.disableFlags(Flags.FLAG_CROSS_APP_POLITE_NOTIFICATIONS);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
index f7340abcaeca..3c3c2f34490a 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
@@ -19,12 +19,18 @@ package com.android.server.notification;
import static android.app.AutomaticZenRule.TYPE_BEDTIME;
import static android.app.Flags.FLAG_MODES_UI;
import static android.app.Flags.modesUi;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
+import static android.app.NotificationManager.Policy.suppressedEffectsToString;
import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
import static android.provider.Settings.Global.ZEN_MODE_OFF;
import static android.service.notification.Condition.SOURCE_UNKNOWN;
import static android.service.notification.Condition.SOURCE_USER_ACTION;
import static android.service.notification.Condition.STATE_FALSE;
import static android.service.notification.Condition.STATE_TRUE;
+import static android.service.notification.NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_ON;
import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_IMPORTANT;
import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_NONE;
import static android.service.notification.ZenPolicy.PEOPLE_TYPE_ANYONE;
@@ -219,8 +225,8 @@ public class ZenModeConfigTest extends UiServiceTestCase {
priorityCategories |= Policy.PRIORITY_CATEGORY_REMINDERS;
priorityCategories |= Policy.PRIORITY_CATEGORY_EVENTS;
priorityCategories |= Policy.PRIORITY_CATEGORY_CONVERSATIONS;
- suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_LIGHTS;
- suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_AMBIENT;
+ suppressedVisualEffects |= SUPPRESSED_EFFECT_LIGHTS;
+ suppressedVisualEffects |= SUPPRESSED_EFFECT_AMBIENT;
Policy expectedPolicy = new Policy(priorityCategories, priorityCallSenders,
priorityMessageSenders, suppressedVisualEffects, 0, priorityConversationsSenders);
@@ -256,8 +262,8 @@ public class ZenModeConfigTest extends UiServiceTestCase {
priorityCategories |= Policy.PRIORITY_CATEGORY_REMINDERS;
priorityCategories |= Policy.PRIORITY_CATEGORY_EVENTS;
priorityCategories |= Policy.PRIORITY_CATEGORY_CONVERSATIONS;
- suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_LIGHTS;
- suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_AMBIENT;
+ suppressedVisualEffects |= SUPPRESSED_EFFECT_LIGHTS;
+ suppressedVisualEffects |= SUPPRESSED_EFFECT_AMBIENT;
Policy expectedPolicy = new Policy(priorityCategories, priorityCallSenders,
priorityMessageSenders, suppressedVisualEffects,
@@ -309,8 +315,8 @@ public class ZenModeConfigTest extends UiServiceTestCase {
config.setAllowMessagesFrom(Policy.PRIORITY_SENDERS_STARRED);
config.setAllowConversationsFrom(CONVERSATION_SENDERS_NONE);
config.setSuppressedVisualEffects(config.getSuppressedVisualEffects()
- | Policy.SUPPRESSED_EFFECT_BADGE | Policy.SUPPRESSED_EFFECT_LIGHTS
- | Policy.SUPPRESSED_EFFECT_AMBIENT);
+ | Policy.SUPPRESSED_EFFECT_BADGE | SUPPRESSED_EFFECT_LIGHTS
+ | SUPPRESSED_EFFECT_AMBIENT);
}
ZenPolicy actual = config.getZenPolicy();
@@ -357,8 +363,8 @@ public class ZenModeConfigTest extends UiServiceTestCase {
config.setAllowConversationsFrom(CONVERSATION_SENDERS_NONE);
config.setAllowPriorityChannels(false);
config.setSuppressedVisualEffects(config.getSuppressedVisualEffects()
- | Policy.SUPPRESSED_EFFECT_BADGE | Policy.SUPPRESSED_EFFECT_LIGHTS
- | Policy.SUPPRESSED_EFFECT_AMBIENT);
+ | Policy.SUPPRESSED_EFFECT_BADGE | SUPPRESSED_EFFECT_LIGHTS
+ | SUPPRESSED_EFFECT_AMBIENT);
}
ZenPolicy actual = config.getZenPolicy();
@@ -1063,6 +1069,43 @@ public class ZenModeConfigTest extends UiServiceTestCase {
.isEqualTo("name");
}
+ @Test
+ public void toNotificationPolicy_withNewSuppressedEffects_returnsSuppressedEffects() {
+ ZenModeConfig config = getCustomConfig();
+ // From LegacyNotificationManagerTest.testSetNotificationPolicy_preP_setNewFields
+ // When a pre-P app sets SUPPRESSED_EFFECT_NOTIFICATION_LIST, it's converted by NMS into:
+ Policy policy = new Policy(0, 0, 0,
+ SUPPRESSED_EFFECT_FULL_SCREEN_INTENT | SUPPRESSED_EFFECT_LIGHTS
+ | SUPPRESSED_EFFECT_PEEK | SUPPRESSED_EFFECT_AMBIENT);
+
+ config.applyNotificationPolicy(policy);
+ Policy result = config.toNotificationPolicy();
+
+ assertThat(suppressedEffectsOf(result)).isEqualTo(suppressedEffectsOf(policy));
+ }
+
+ @Test
+ public void toNotificationPolicy_withOldAndNewSuppressedEffects_returnsSuppressedEffects() {
+ ZenModeConfig config = getCustomConfig();
+ // From LegacyNotificationManagerTest.testSetNotificationPolicy_preP_setOldNewFields.
+ // When a pre-P app sets SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_STATUS_BAR, it's
+ // converted by NMS into:
+ Policy policy = new Policy(0, 0, 0,
+ SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
+ | SUPPRESSED_EFFECT_LIGHTS | SUPPRESSED_EFFECT_PEEK
+ | SUPPRESSED_EFFECT_AMBIENT);
+
+ config.applyNotificationPolicy(policy);
+ Policy result = config.toNotificationPolicy();
+
+ assertThat(suppressedEffectsOf(result)).isEqualTo(suppressedEffectsOf(policy));
+ }
+
+ private static String suppressedEffectsOf(Policy policy) {
+ return suppressedEffectsToString(policy.suppressedVisualEffects) + "("
+ + policy.suppressedVisualEffects + ")";
+ }
+
private ZenModeConfig getMutedRingerConfig() {
ZenModeConfig config = new ZenModeConfig();
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java
index 57587f7dc38a..9af00218dda4 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java
@@ -61,6 +61,7 @@ import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@@ -80,19 +81,6 @@ public class ZenModeDiffTest extends UiServiceTestCase {
? Set.of("version", "manualRule", "automaticRules", "deletedRules")
: Set.of("version", "manualRule", "automaticRules");
- // Differences for flagged fields are only generated if the flag is enabled.
- // "Metadata" fields (userModifiedFields, deletionInstant, disabledOrigin) are not compared.
- private static final Set<String> ZEN_RULE_EXEMPT_FIELDS =
- android.app.Flags.modesApi()
- ? Set.of("userModifiedFields", "zenPolicyUserModifiedFields",
- "zenDeviceEffectsUserModifiedFields", "deletionInstant",
- "disabledOrigin")
- : Set.of(RuleDiff.FIELD_TYPE, RuleDiff.FIELD_TRIGGER_DESCRIPTION,
- RuleDiff.FIELD_ICON_RES, RuleDiff.FIELD_ALLOW_MANUAL,
- RuleDiff.FIELD_ZEN_DEVICE_EFFECTS, "userModifiedFields",
- "zenPolicyUserModifiedFields", "zenDeviceEffectsUserModifiedFields",
- "deletionInstant", "disabledOrigin");
-
// allowPriorityChannels is flagged by android.app.modes_api
public static final Set<String> ZEN_MODE_CONFIG_FLAGGED_FIELDS =
Set.of("allowPriorityChannels");
@@ -102,8 +90,7 @@ public class ZenModeDiffTest extends UiServiceTestCase {
@Parameters(name = "{0}")
public static List<FlagsParameterization> getParams() {
- return FlagsParameterization.allCombinationsOf(
- FLAG_MODES_UI);
+ return FlagsParameterization.progressionOf(FLAG_MODES_API, FLAG_MODES_UI);
}
public ZenModeDiffTest(FlagsParameterization flags) {
@@ -140,7 +127,7 @@ public class ZenModeDiffTest extends UiServiceTestCase {
ArrayMap<String, Object> expectedFrom = new ArrayMap<>();
ArrayMap<String, Object> expectedTo = new ArrayMap<>();
List<Field> fieldsForDiff = getFieldsForDiffCheck(
- ZenModeConfig.ZenRule.class, ZEN_RULE_EXEMPT_FIELDS);
+ ZenModeConfig.ZenRule.class, getZenRuleExemptFields());
generateFieldDiffs(r1, r2, fieldsForDiff, expectedFrom, expectedTo);
ZenModeDiff.RuleDiff d = new ZenModeDiff.RuleDiff(r1, r2);
@@ -158,6 +145,25 @@ public class ZenModeDiffTest extends UiServiceTestCase {
}
}
+ private static Set<String> getZenRuleExemptFields() {
+ // "Metadata" fields are never compared.
+ Set<String> exemptFields = new LinkedHashSet<>(
+ Set.of("userModifiedFields", "zenPolicyUserModifiedFields",
+ "zenDeviceEffectsUserModifiedFields", "deletionInstant", "disabledOrigin"));
+ // Flagged fields are only compared if their flag is on.
+ if (!Flags.modesApi()) {
+ exemptFields.addAll(
+ Set.of(RuleDiff.FIELD_TYPE, RuleDiff.FIELD_TRIGGER_DESCRIPTION,
+ RuleDiff.FIELD_ICON_RES, RuleDiff.FIELD_ALLOW_MANUAL,
+ RuleDiff.FIELD_ZEN_DEVICE_EFFECTS,
+ RuleDiff.FIELD_LEGACY_SUPPRESSED_EFFECTS));
+ }
+ if (!(Flags.modesApi() && Flags.modesUi())) {
+ exemptFields.add(RuleDiff.FIELD_LEGACY_SUPPRESSED_EFFECTS);
+ }
+ return exemptFields;
+ }
+
@Test
public void testConfigDiff_addRemoveSame() {
// Default config, will test add, remove, and no change
diff --git a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutManagerTests.java b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutManagerTests.java
index 50041d023e64..d147325921bf 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutManagerTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutManagerTests.java
@@ -35,6 +35,7 @@ import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.os.Handler;
@@ -89,9 +90,12 @@ public class ModifierShortcutManagerTests {
testActivityInfo.applicationInfo = new ApplicationInfo();
testActivityInfo.packageName =
testActivityInfo.applicationInfo.packageName = "com.test";
+ ResolveInfo testResolveInfo = new ResolveInfo();
+ testResolveInfo.activityInfo = testActivityInfo;
doReturn(testActivityInfo).when(mPackageManager).getActivityInfo(
eq(new ComponentName("com.test", "com.test.BookmarkTest")), anyInt());
+ doReturn(testResolveInfo).when(mPackageManager).resolveActivity(anyObject(), anyInt());
doThrow(new PackageManager.NameNotFoundException("com.test3")).when(mPackageManager)
.getActivityInfo(eq(new ComponentName("com.test3", "com.test.BookmarkTest")),
anyInt());
diff --git a/services/tests/wmtests/src/com/android/server/policy/StemKeyGestureTests.java b/services/tests/wmtests/src/com/android/server/policy/StemKeyGestureTests.java
index 2e850252765b..9b92ff45952b 100644
--- a/services/tests/wmtests/src/com/android/server/policy/StemKeyGestureTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/StemKeyGestureTests.java
@@ -36,6 +36,7 @@ import android.os.RemoteException;
import android.provider.Settings;
import android.view.Display;
+import org.junit.Before;
import org.junit.Test;
/**
@@ -48,6 +49,13 @@ public class StemKeyGestureTests extends ShortcutKeyTestBase {
private static final String TEST_TARGET_ACTIVITY = "com.android.server.policy/.TestActivity";
+ @Before
+ public void setup() {
+ super.setup();
+ overrideResource(com.android.internal.R.integer.config_longPressOnStemPrimaryBehavior,
+ LONG_PRESS_PRIMARY_LAUNCH_VOICE_ASSISTANT);
+ }
+
/**
* Stem single key should not launch behavior during set up.
*/
@@ -186,6 +194,26 @@ public class StemKeyGestureTests extends ShortcutKeyTestBase {
}
@Test
+ public void stemLongKey_appHasOverridePermission_consumedByApp_triggerStatusBarToStartAssist() {
+ overrideBehavior(
+ STEM_PRIMARY_BUTTON_LONG_PRESS,
+ LONG_PRESS_PRIMARY_LAUNCH_VOICE_ASSISTANT);
+ setUpPhoneWindowManager(/* supportSettingsUpdate= */ true);
+ mPhoneWindowManager.overrideShouldEarlyShortPressOnStemPrimary(false);
+ mPhoneWindowManager.setupAssistForLaunch();
+ mPhoneWindowManager.overrideSearchManager(null);
+ mPhoneWindowManager.overrideStatusBarManagerInternal();
+ mPhoneWindowManager.overrideIsUserSetupComplete(true);
+ mPhoneWindowManager.overrideFocusedWindowButtonOverridePermission(true);
+
+ setDispatchedKeyHandler(keyEvent -> true);
+
+ sendKey(KEYCODE_STEM_PRIMARY, /* longPress= */ true);
+
+ mPhoneWindowManager.assertStatusBarStartAssist();
+ }
+
+ @Test
public void stemDoubleKey_EarlyShortPress_AllAppsThenSwitchToMostRecent()
throws RemoteException {
overrideBehavior(STEM_PRIMARY_BUTTON_SHORT_PRESS, SHORT_PRESS_PRIMARY_LAUNCH_ALL_APPS);
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
index 220248cdb2c1..f8cf97e71274 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
@@ -178,6 +178,10 @@ class AppCompatActivityRobot {
doReturn(enabled).when(mActivityStack.top()).shouldCreateCompatDisplayInsets();
}
+ void setTopActivityInSizeCompatMode(boolean inScm) {
+ doReturn(inScm).when(mActivityStack.top()).inSizeCompatMode();
+ }
+
void setShouldApplyUserFullscreenOverride(boolean enabled) {
doReturn(enabled).when(mActivityStack.top().mAppCompatController
.getAppCompatAspectRatioOverrides()).shouldApplyUserFullscreenOverride();
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatUtilsTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatUtilsTest.java
new file mode 100644
index 000000000000..9e242eeeb58e
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatUtilsTest.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static org.mockito.Mockito.when;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.annotation.NonNull;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+
+import java.util.function.Consumer;
+
+/**
+ * Test class for {@link AppCompatUtils}.
+ * <p>
+ * Build/Install/Run:
+ * atest WmTests:AppCompatUtilsTest
+ */
+@Presubmit
+@RunWith(WindowTestRunner.class)
+public class AppCompatUtilsTest extends WindowTestsBase {
+
+ @Test
+ public void getLetterboxReasonString_inSizeCompatMode() {
+ runTestScenario((robot) -> {
+ robot.activity().setTopActivityInSizeCompatMode(/* inScm */ true);
+
+ robot.checkTopActivityLetterboxReason(/* expected */ "SIZE_COMPAT_MODE");
+ });
+ }
+
+ @Test
+ public void getLetterboxReasonString_fixedOrientation() {
+ runTestScenario((robot) -> {
+ robot.activity().checkTopActivityInSizeCompatMode(/* inScm */ false);
+ robot.setIsLetterboxedForFixedOrientationAndAspectRatio(
+ /* forFixedOrientationAndAspectRatio */ true);
+
+ robot.checkTopActivityLetterboxReason(/* expected */ "FIXED_ORIENTATION");
+ });
+ }
+
+ @Test
+ public void getLetterboxReasonString_isLetterboxedForDisplayCutout() {
+ runTestScenario((robot) -> {
+ robot.activity().checkTopActivityInSizeCompatMode(/* inScm */ false);
+ robot.setIsLetterboxedForFixedOrientationAndAspectRatio(
+ /* forFixedOrientationAndAspectRatio */ false);
+ robot.setIsLetterboxedForDisplayCutout(/* displayCutout */ true);
+
+ robot.checkTopActivityLetterboxReason(/* expected */ "DISPLAY_CUTOUT");
+ });
+ }
+
+ @Test
+ public void getLetterboxReasonString_aspectRatio() {
+ runTestScenario((robot) -> {
+ robot.activity().checkTopActivityInSizeCompatMode(/* inScm */ false);
+ robot.setIsLetterboxedForFixedOrientationAndAspectRatio(
+ /* forFixedOrientationAndAspectRatio */ false);
+ robot.setIsLetterboxedForDisplayCutout(/* displayCutout */ false);
+ robot.setIsLetterboxedForAspectRatioOnly(/* forAspectRatio */ true);
+
+ robot.checkTopActivityLetterboxReason(/* expected */ "ASPECT_RATIO");
+ });
+ }
+
+ @Test
+ public void getLetterboxReasonString_unknownReason() {
+ runTestScenario((robot) -> {
+ robot.activity().checkTopActivityInSizeCompatMode(/* inScm */ false);
+ robot.setIsLetterboxedForFixedOrientationAndAspectRatio(
+ /* forFixedOrientationAndAspectRatio */ false);
+ robot.setIsLetterboxedForDisplayCutout(/* displayCutout */ false);
+ robot.setIsLetterboxedForAspectRatioOnly(/* forAspectRatio */ false);
+
+ robot.checkTopActivityLetterboxReason(/* expected */ "UNKNOWN_REASON");
+ });
+ }
+
+
+ /**
+ * Runs a test scenario providing a Robot.
+ */
+ void runTestScenario(@NonNull Consumer<AppCompatUtilsRobotTest> consumer) {
+ final AppCompatUtilsRobotTest robot = new AppCompatUtilsRobotTest(mWm, mAtm, mSupervisor);
+ consumer.accept(robot);
+ }
+
+ private static class AppCompatUtilsRobotTest extends AppCompatRobotBase {
+
+ private final WindowState mWindowState;
+
+ AppCompatUtilsRobotTest(@NonNull WindowManagerService wm,
+ @NonNull ActivityTaskManagerService atm,
+ @NonNull ActivityTaskSupervisor supervisor) {
+ super(wm, atm, supervisor);
+ activity().createActivityWithComponent();
+ mWindowState = Mockito.mock(WindowState.class);
+ }
+
+ void setIsLetterboxedForFixedOrientationAndAspectRatio(
+ boolean forFixedOrientationAndAspectRatio) {
+ when(activity().top().mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForFixedOrientationAndAspectRatio())
+ .thenReturn(forFixedOrientationAndAspectRatio);
+ }
+
+ void setIsLetterboxedForAspectRatioOnly(boolean forAspectRatio) {
+ when(activity().top().mAppCompatController.getAppCompatAspectRatioPolicy()
+ .isLetterboxedForAspectRatioOnly()).thenReturn(forAspectRatio);
+ }
+
+ void setIsLetterboxedForDisplayCutout(boolean displayCutout) {
+ when(mWindowState.isLetterboxedForDisplayCutout()).thenReturn(displayCutout);
+ }
+
+ void checkTopActivityLetterboxReason(@NonNull String expected) {
+ Assert.assertEquals(expected,
+ AppCompatUtils.getLetterboxReasonString(activity().top(), mWindowState));
+ }
+
+ }
+
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
index bb5887d12f4b..58f8eb220218 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
@@ -33,6 +33,7 @@ import static org.mockito.Mockito.mock;
import android.app.WindowConfiguration;
import android.content.ComponentName;
import android.content.Intent;
+import android.content.IntentSender;
import android.content.pm.ActivityInfo;
import android.os.Process;
import android.util.ArraySet;
@@ -40,12 +41,14 @@ import android.view.Display;
import android.window.DisplayWindowPolicyController;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Set;
+import java.util.function.Supplier;
/**
* Tests for the {@link DisplayWindowPolicyController} class.
@@ -224,7 +227,7 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase {
assertEquals(result, START_ABORTED);
}
- private class TestDisplayWindowPolicyController extends DisplayWindowPolicyController {
+ private static class TestDisplayWindowPolicyController extends DisplayWindowPolicyController {
public ComponentName DISALLOWED_ACTIVITY =
new ComponentName("fake.package", "DisallowedActivity");
@@ -236,7 +239,8 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase {
@Override
public boolean canActivityBeLaunched(@NonNull ActivityInfo activity, Intent intent,
@WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId,
- boolean isNewTask) {
+ boolean isNewTask, boolean isResultExpected,
+ @Nullable Supplier<IntentSender> intentSender) {
return canContainActivity(activity, windowingMode, launchingFromDisplayId, isNewTask);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
index 2e0d4d46ec05..2f2b4732f1eb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
@@ -31,7 +31,6 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.testng.Assert.assertFalse;
@@ -357,8 +356,6 @@ public class DisplayWindowSettingsProviderTests extends WindowTestsBase {
@Test
public void testRemovesStaleDisplaySettings_defaultDisplay_removesStaleDisplaySettings() {
- assumeTrue(com.android.window.flags.Flags.perUserDisplayWindowSettings());
-
// Write density setting for second display then remove it.
final DisplayWindowSettingsProvider provider = new DisplayWindowSettingsProvider(
mDefaultVendorSettingsStorage, mOverrideSettingsStorage);
@@ -387,8 +384,6 @@ public class DisplayWindowSettingsProviderTests extends WindowTestsBase {
@Test
public void testRemovesStaleDisplaySettings_displayNotInLayout_keepsDisplaySettings() {
- assumeTrue(com.android.window.flags.Flags.perUserDisplayWindowSettings());
-
// Write density setting for primary display.
final DisplayWindowSettingsProvider provider = new DisplayWindowSettingsProvider(
mDefaultVendorSettingsStorage, mOverrideSettingsStorage);
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
index fbc4c7b6bd34..ffaa2d820203 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
@@ -66,7 +66,7 @@ public class LetterboxTest {
mLetterbox = new Letterbox(mSurfaces, StubTransaction::new,
() -> mAreCornersRounded, () -> Color.valueOf(mColor),
() -> mHasWallpaperBackground, () -> mBlurRadius, () -> mDarkScrimAlpha,
- /* doubleTapCallbackX= */ x -> {}, /* doubleTapCallbackY= */ y -> {},
+ mock(AppCompatReachabilityPolicy.class),
() -> mParentSurface);
mTransaction = spy(StubTransaction.class);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
index 61a6f316244c..33df5d896f7f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
@@ -300,7 +300,9 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
// Vertical thin letterbox disabled
doReturn(-1).when(mActivity.mWmService.mAppCompatConfiguration)
.getThinLetterboxHeightPx();
- assertFalse(mController.isVerticalThinLetterboxed());
+ final AppCompatReachabilityOverrides reachabilityOverrides = mActivity.mAppCompatController
+ .getAppCompatReachabilityOverrides();
+ assertFalse(reachabilityOverrides.isVerticalThinLetterboxed());
// Define a Task 100x100
final Task task = mock(Task.class);
doReturn(new Rect(0, 0, 100, 100)).when(task).getBounds();
@@ -309,21 +311,21 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
// Vertical thin letterbox disabled without Task
doReturn(null).when(mActivity).getTask();
- assertFalse(mController.isVerticalThinLetterboxed());
+ assertFalse(reachabilityOverrides.isVerticalThinLetterboxed());
// Assign a Task for the Activity
doReturn(task).when(mActivity).getTask();
// (task.width() - act.width()) / 2 = 5 < 10
doReturn(new Rect(5, 5, 95, 95)).when(mActivity).getBounds();
- assertTrue(mController.isVerticalThinLetterboxed());
+ assertTrue(reachabilityOverrides.isVerticalThinLetterboxed());
// (task.width() - act.width()) / 2 = 10 = 10
doReturn(new Rect(10, 10, 90, 90)).when(mActivity).getBounds();
- assertTrue(mController.isVerticalThinLetterboxed());
+ assertTrue(reachabilityOverrides.isVerticalThinLetterboxed());
// (task.width() - act.width()) / 2 = 11 > 10
doReturn(new Rect(11, 11, 89, 89)).when(mActivity).getBounds();
- assertFalse(mController.isVerticalThinLetterboxed());
+ assertFalse(reachabilityOverrides.isVerticalThinLetterboxed());
}
@Test
@@ -331,7 +333,9 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
// Horizontal thin letterbox disabled
doReturn(-1).when(mActivity.mWmService.mAppCompatConfiguration)
.getThinLetterboxWidthPx();
- assertFalse(mController.isHorizontalThinLetterboxed());
+ final AppCompatReachabilityOverrides reachabilityOverrides = mActivity.mAppCompatController
+ .getAppCompatReachabilityOverrides();
+ assertFalse(reachabilityOverrides.isHorizontalThinLetterboxed());
// Define a Task 100x100
final Task task = mock(Task.class);
doReturn(new Rect(0, 0, 100, 100)).when(task).getBounds();
@@ -340,51 +344,55 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
// Vertical thin letterbox disabled without Task
doReturn(null).when(mActivity).getTask();
- assertFalse(mController.isHorizontalThinLetterboxed());
+ assertFalse(reachabilityOverrides.isHorizontalThinLetterboxed());
// Assign a Task for the Activity
doReturn(task).when(mActivity).getTask();
// (task.height() - act.height()) / 2 = 5 < 10
doReturn(new Rect(5, 5, 95, 95)).when(mActivity).getBounds();
- assertTrue(mController.isHorizontalThinLetterboxed());
+ assertTrue(reachabilityOverrides.isHorizontalThinLetterboxed());
// (task.height() - act.height()) / 2 = 10 = 10
doReturn(new Rect(10, 10, 90, 90)).when(mActivity).getBounds();
- assertTrue(mController.isHorizontalThinLetterboxed());
+ assertTrue(reachabilityOverrides.isHorizontalThinLetterboxed());
// (task.height() - act.height()) / 2 = 11 > 10
doReturn(new Rect(11, 11, 89, 89)).when(mActivity).getBounds();
- assertFalse(mController.isHorizontalThinLetterboxed());
+ assertFalse(reachabilityOverrides.isHorizontalThinLetterboxed());
}
@Test
@EnableFlags(Flags.FLAG_DISABLE_THIN_LETTERBOXING_POLICY)
public void testAllowReachabilityForThinLetterboxWithFlagEnabled() {
- spyOn(mController);
- doReturn(true).when(mController).isVerticalThinLetterboxed();
- assertFalse(mController.allowVerticalReachabilityForThinLetterbox());
- doReturn(true).when(mController).isHorizontalThinLetterboxed();
- assertFalse(mController.allowHorizontalReachabilityForThinLetterbox());
-
- doReturn(false).when(mController).isVerticalThinLetterboxed();
- assertTrue(mController.allowVerticalReachabilityForThinLetterbox());
- doReturn(false).when(mController).isHorizontalThinLetterboxed();
- assertTrue(mController.allowHorizontalReachabilityForThinLetterbox());
+ final AppCompatReachabilityOverrides reachabilityOverrides =
+ mActivity.mAppCompatController.getAppCompatReachabilityOverrides();
+ spyOn(reachabilityOverrides);
+ doReturn(true).when(reachabilityOverrides).isVerticalThinLetterboxed();
+ assertFalse(reachabilityOverrides.allowVerticalReachabilityForThinLetterbox());
+ doReturn(true).when(reachabilityOverrides).isHorizontalThinLetterboxed();
+ assertFalse(reachabilityOverrides.allowHorizontalReachabilityForThinLetterbox());
+
+ doReturn(false).when(reachabilityOverrides).isVerticalThinLetterboxed();
+ assertTrue(reachabilityOverrides.allowVerticalReachabilityForThinLetterbox());
+ doReturn(false).when(reachabilityOverrides).isHorizontalThinLetterboxed();
+ assertTrue(reachabilityOverrides.allowHorizontalReachabilityForThinLetterbox());
}
@Test
@DisableFlags(Flags.FLAG_DISABLE_THIN_LETTERBOXING_POLICY)
public void testAllowReachabilityForThinLetterboxWithFlagDisabled() {
- spyOn(mController);
- doReturn(true).when(mController).isVerticalThinLetterboxed();
- assertTrue(mController.allowVerticalReachabilityForThinLetterbox());
- doReturn(true).when(mController).isHorizontalThinLetterboxed();
- assertTrue(mController.allowHorizontalReachabilityForThinLetterbox());
-
- doReturn(false).when(mController).isVerticalThinLetterboxed();
- assertTrue(mController.allowVerticalReachabilityForThinLetterbox());
- doReturn(false).when(mController).isHorizontalThinLetterboxed();
- assertTrue(mController.allowHorizontalReachabilityForThinLetterbox());
+ final AppCompatReachabilityOverrides reachabilityOverrides =
+ mActivity.mAppCompatController.getAppCompatReachabilityOverrides();
+ spyOn(reachabilityOverrides);
+ doReturn(true).when(reachabilityOverrides).isVerticalThinLetterboxed();
+ assertTrue(reachabilityOverrides.allowVerticalReachabilityForThinLetterbox());
+ doReturn(true).when(reachabilityOverrides).isHorizontalThinLetterboxed();
+ assertTrue(reachabilityOverrides.allowHorizontalReachabilityForThinLetterbox());
+
+ doReturn(false).when(reachabilityOverrides).isVerticalThinLetterboxed();
+ assertTrue(reachabilityOverrides.allowVerticalReachabilityForThinLetterbox());
+ doReturn(false).when(reachabilityOverrides).isHorizontalThinLetterboxed();
+ assertTrue(reachabilityOverrides.allowHorizontalReachabilityForThinLetterbox());
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index ed93a8c6ecff..aa997ac42c66 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -281,7 +281,8 @@ public class SizeCompatTests extends WindowTestsBase {
if (horizontalReachability) {
final Consumer<Integer> doubleClick =
(Integer x) -> {
- mActivity.mLetterboxUiController.handleHorizontalDoubleTap(x);
+ mActivity.mAppCompatController.getAppCompatReachabilityPolicy()
+ .handleDoubleTap(x, displayHeight / 2);
mActivity.mRootWindowContainer.performSurfacePlacement();
};
@@ -310,7 +311,8 @@ public class SizeCompatTests extends WindowTestsBase {
} else {
final Consumer<Integer> doubleClick =
(Integer y) -> {
- mActivity.mLetterboxUiController.handleVerticalDoubleTap(y);
+ mActivity.mAppCompatController.getAppCompatReachabilityPolicy()
+ .handleDoubleTap(displayWidth / 2, y);
mActivity.mRootWindowContainer.performSurfacePlacement();
};
@@ -373,7 +375,8 @@ public class SizeCompatTests extends WindowTestsBase {
final Consumer<Integer> doubleClick =
(Integer y) -> {
- activity.mLetterboxUiController.handleVerticalDoubleTap(y);
+ activity.mAppCompatController.getAppCompatReachabilityPolicy()
+ .handleDoubleTap(dw / 2, y);
activity.mRootWindowContainer.performSurfacePlacement();
};
@@ -886,7 +889,7 @@ public class SizeCompatTests extends WindowTestsBase {
verify(mTask).onSizeCompatActivityChanged();
ActivityManager.RunningTaskInfo taskInfo = mTask.getTaskInfo();
- assertTrue(taskInfo.appCompatTaskInfo.topActivityInSizeCompat);
+ assertTrue(taskInfo.appCompatTaskInfo.isTopActivityInSizeCompat());
// Make the activity resizable again by restarting it
clearInvocations(mTask);
@@ -901,7 +904,7 @@ public class SizeCompatTests extends WindowTestsBase {
verify(mTask).onSizeCompatActivityChanged();
taskInfo = mTask.getTaskInfo();
- assertFalse(taskInfo.appCompatTaskInfo.topActivityInSizeCompat);
+ assertFalse(taskInfo.appCompatTaskInfo.isTopActivityInSizeCompat());
}
@Test
@@ -919,7 +922,7 @@ public class SizeCompatTests extends WindowTestsBase {
verify(mTask).onSizeCompatActivityChanged();
ActivityManager.RunningTaskInfo taskInfo = mTask.getTaskInfo();
- assertTrue(taskInfo.appCompatTaskInfo.topActivityInSizeCompat);
+ assertTrue(taskInfo.appCompatTaskInfo.isTopActivityInSizeCompat());
// Create another Task to hold another size compat activity.
clearInvocations(mTask);
@@ -939,7 +942,7 @@ public class SizeCompatTests extends WindowTestsBase {
verify(mTask, never()).onSizeCompatActivityChanged();
taskInfo = secondTask.getTaskInfo();
- assertTrue(taskInfo.appCompatTaskInfo.topActivityInSizeCompat);
+ assertTrue(taskInfo.appCompatTaskInfo.isTopActivityInSizeCompat());
}
@Test
@@ -3431,9 +3434,10 @@ public class SizeCompatTests extends WindowTestsBase {
mActivity.getWindowConfiguration().setBounds(null);
setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ false);
-
- assertFalse(mActivity.mLetterboxUiController.isVerticalReachabilityEnabled());
- assertFalse(mActivity.mLetterboxUiController.isHorizontalReachabilityEnabled());
+ final AppCompatReachabilityOverrides reachabilityOverrides =
+ mActivity.mAppCompatController.getAppCompatReachabilityOverrides();
+ assertFalse(reachabilityOverrides.isVerticalReachabilityEnabled());
+ assertFalse(reachabilityOverrides.isHorizontalReachabilityEnabled());
}
@Test
@@ -3456,7 +3460,8 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(WINDOWING_MODE_MULTI_WINDOW, mActivity.getWindowingMode());
// Horizontal reachability is disabled because the app is in split screen.
- assertFalse(mActivity.mLetterboxUiController.isHorizontalReachabilityEnabled());
+ assertFalse(mActivity.mAppCompatController.getAppCompatReachabilityOverrides()
+ .isHorizontalReachabilityEnabled());
}
@Test
@@ -3479,7 +3484,8 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(WINDOWING_MODE_MULTI_WINDOW, mActivity.getWindowingMode());
// Vertical reachability is disabled because the app is in split screen.
- assertFalse(mActivity.mLetterboxUiController.isVerticalReachabilityEnabled());
+ assertFalse(mActivity.mAppCompatController.getAppCompatReachabilityOverrides()
+ .isVerticalReachabilityEnabled());
}
@Test
@@ -3501,7 +3507,8 @@ public class SizeCompatTests extends WindowTestsBase {
// Vertical reachability is disabled because the app does not match parent width
assertNotEquals(mActivity.getScreenResolvedBounds().width(),
mActivity.mDisplayContent.getBounds().width());
- assertFalse(mActivity.mLetterboxUiController.isVerticalReachabilityEnabled());
+ assertFalse(mActivity.mAppCompatController.getAppCompatReachabilityOverrides()
+ .isVerticalReachabilityEnabled());
}
@Test
@@ -3518,7 +3525,8 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(new Rect(0, 0, 0, 0), mActivity.getBounds());
// Vertical reachability is still enabled as resolved bounds is not empty
- assertTrue(mActivity.mLetterboxUiController.isVerticalReachabilityEnabled());
+ assertTrue(mActivity.mAppCompatController.getAppCompatReachabilityOverrides()
+ .isVerticalReachabilityEnabled());
}
@Test
@@ -3535,7 +3543,8 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(new Rect(0, 0, 0, 0), mActivity.getBounds());
// Horizontal reachability is still enabled as resolved bounds is not empty
- assertTrue(mActivity.mLetterboxUiController.isHorizontalReachabilityEnabled());
+ assertTrue(mActivity.mAppCompatController.getAppCompatReachabilityOverrides()
+ .isHorizontalReachabilityEnabled());
}
@Test
@@ -3549,7 +3558,8 @@ public class SizeCompatTests extends WindowTestsBase {
prepareMinAspectRatio(mActivity, OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE,
SCREEN_ORIENTATION_PORTRAIT);
- assertTrue(mActivity.mLetterboxUiController.isHorizontalReachabilityEnabled());
+ assertTrue(mActivity.mAppCompatController.getAppCompatReachabilityOverrides()
+ .isHorizontalReachabilityEnabled());
}
@Test
@@ -3563,7 +3573,8 @@ public class SizeCompatTests extends WindowTestsBase {
prepareMinAspectRatio(mActivity, OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE,
SCREEN_ORIENTATION_LANDSCAPE);
- assertTrue(mActivity.mLetterboxUiController.isVerticalReachabilityEnabled());
+ assertTrue(mActivity.mAppCompatController.getAppCompatReachabilityOverrides()
+ .isVerticalReachabilityEnabled());
}
@Test
@@ -3585,7 +3596,8 @@ public class SizeCompatTests extends WindowTestsBase {
// Horizontal reachability is disabled because the app does not match parent height
assertNotEquals(mActivity.getScreenResolvedBounds().height(),
mActivity.mDisplayContent.getBounds().height());
- assertFalse(mActivity.mLetterboxUiController.isHorizontalReachabilityEnabled());
+ assertFalse(mActivity.mAppCompatController.getAppCompatReachabilityOverrides()
+ .isHorizontalReachabilityEnabled());
}
@Test
@@ -3607,7 +3619,8 @@ public class SizeCompatTests extends WindowTestsBase {
// Horizontal reachability is enabled because the app matches parent height
assertEquals(mActivity.getScreenResolvedBounds().height(),
mActivity.mDisplayContent.getBounds().height());
- assertTrue(mActivity.mLetterboxUiController.isHorizontalReachabilityEnabled());
+ assertTrue(mActivity.mAppCompatController.getAppCompatReachabilityOverrides()
+ .isHorizontalReachabilityEnabled());
}
@Test
@@ -3629,7 +3642,8 @@ public class SizeCompatTests extends WindowTestsBase {
// Vertical reachability is enabled because the app matches parent width
assertEquals(mActivity.getScreenResolvedBounds().width(),
mActivity.mDisplayContent.getBounds().width());
- assertTrue(mActivity.mLetterboxUiController.isVerticalReachabilityEnabled());
+ assertTrue(mActivity.mAppCompatController.getAppCompatReachabilityOverrides()
+ .isVerticalReachabilityEnabled());
}
@Test
@@ -4306,15 +4320,17 @@ public class SizeCompatTests extends WindowTestsBase {
resizeDisplay(mTask.mDisplayContent, 1400, 2800);
// Make sure app doesn't jump to top (default tabletop position) when unfolding.
- assertEquals(1.0f, mActivity.mLetterboxUiController.getVerticalPositionMultiplier(
- mActivity.getParent().getConfiguration()), 0);
+ assertEquals(1.0f, mActivity.mAppCompatController
+ .getAppCompatReachabilityOverrides().getVerticalPositionMultiplier(mActivity
+ .getParent().getConfiguration()), 0);
// Simulate display fully open after unfolding.
setFoldablePosture(false /* isHalfFolded */, false /* isTabletop */);
doReturn(false).when(mActivity.mDisplayContent).inTransition();
- assertEquals(1.0f, mActivity.mLetterboxUiController.getVerticalPositionMultiplier(
- mActivity.getParent().getConfiguration()), 0);
+ assertEquals(1.0f, mActivity.mAppCompatController
+ .getAppCompatReachabilityOverrides().getVerticalPositionMultiplier(mActivity
+ .getParent().getConfiguration()), 0);
}
@Test
@@ -4728,7 +4744,7 @@ public class SizeCompatTests extends WindowTestsBase {
assertTrue(mActivity.inSizeCompatMode());
assertEquals(mActivity.getState(), PAUSED);
assertTrue(mActivity.isVisible());
- assertTrue(mTask.getTaskInfo().appCompatTaskInfo.topActivityInSizeCompat);
+ assertTrue(mTask.getTaskInfo().appCompatTaskInfo.isTopActivityInSizeCompat());
}
/**
@@ -4809,10 +4825,12 @@ public class SizeCompatTests extends WindowTestsBase {
}
private void setUpAllowThinLetterboxed(boolean thinLetterboxAllowed) {
- spyOn(mActivity.mLetterboxUiController);
- doReturn(thinLetterboxAllowed).when(mActivity.mLetterboxUiController)
+ final AppCompatReachabilityOverrides reachabilityOverrides =
+ mActivity.mAppCompatController.getAppCompatReachabilityOverrides();
+ spyOn(reachabilityOverrides);
+ doReturn(thinLetterboxAllowed).when(reachabilityOverrides)
.allowVerticalReachabilityForThinLetterbox();
- doReturn(thinLetterboxAllowed).when(mActivity.mLetterboxUiController)
+ doReturn(thinLetterboxAllowed).when(reachabilityOverrides)
.allowHorizontalReachabilityForThinLetterbox();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index a232ff0dfcb6..0a592f2ae92a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -635,27 +635,27 @@ public class TaskTests extends WindowTestsBase {
// The button should be eligible to be displayed
assertTrue(task.getTaskInfo()
- .appCompatTaskInfo.topActivityEligibleForUserAspectRatioButton);
+ .appCompatTaskInfo.eligibleForUserAspectRatioButton());
// When shouldApplyUserMinAspectRatioOverride is disable the button is not enabled
doReturn(false).when(
root.mAppCompatController.getAppCompatAspectRatioOverrides())
.shouldEnableUserAspectRatioSettings();
assertFalse(task.getTaskInfo()
- .appCompatTaskInfo.topActivityEligibleForUserAspectRatioButton);
+ .appCompatTaskInfo.eligibleForUserAspectRatioButton());
doReturn(true).when(root.mAppCompatController
.getAppCompatAspectRatioOverrides()).shouldEnableUserAspectRatioSettings();
// When in size compat mode the button is not enabled
doReturn(true).when(root).inSizeCompatMode();
assertFalse(task.getTaskInfo()
- .appCompatTaskInfo.topActivityEligibleForUserAspectRatioButton);
+ .appCompatTaskInfo.eligibleForUserAspectRatioButton());
doReturn(false).when(root).inSizeCompatMode();
// When the top activity is transparent, the button is not enabled
doReturn(false).when(root).fillsParent();
assertFalse(task.getTaskInfo()
- .appCompatTaskInfo.topActivityEligibleForUserAspectRatioButton);
+ .appCompatTaskInfo.eligibleForUserAspectRatioButton());
doReturn(true).when(root).fillsParent();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index fb81a52bce85..2b611b754edd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -1708,7 +1708,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
verify(organizer).onTaskInfoChanged(infoCaptor.capture());
RunningTaskInfo info = infoCaptor.getValue();
assertEquals(rootTask.mTaskId, info.taskId);
- assertTrue(info.appCompatTaskInfo.topActivityInSizeCompat);
+ assertTrue(info.appCompatTaskInfo.isTopActivityInSizeCompat());
// Ensure task info show top activity that is not visible as not in size compat.
clearInvocations(organizer);
@@ -1718,7 +1718,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
verify(organizer).onTaskInfoChanged(infoCaptor.capture());
info = infoCaptor.getValue();
assertEquals(rootTask.mTaskId, info.taskId);
- assertFalse(info.appCompatTaskInfo.topActivityInSizeCompat);
+ assertFalse(info.appCompatTaskInfo.isTopActivityInSizeCompat());
// Ensure task info show non size compat top activity as not in size compat.
clearInvocations(organizer);
@@ -1729,7 +1729,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
verify(organizer).onTaskInfoChanged(infoCaptor.capture());
info = infoCaptor.getValue();
assertEquals(rootTask.mTaskId, info.taskId);
- assertFalse(info.appCompatTaskInfo.topActivityInSizeCompat);
+ assertFalse(info.appCompatTaskInfo.isTopActivityInSizeCompat());
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index b46189c1704a..11df331ff398 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -1351,6 +1351,7 @@ public class WindowStateTests extends WindowTestsBase {
assertThat(listener.mImeTargetToken).isEqualTo(imeTarget.mClient.asBinder());
assertThat(listener.mIsRemoved).isFalse();
assertThat(listener.mIsVisibleForImeInputTarget).isTrue();
+ assertThat(listener.mDisplayId).isEqualTo(mDisplayContent.getDisplayId());
imeTarget.mActivityRecord.setVisibleRequested(false);
waitHandlerIdle(mWm.mH);
@@ -1358,11 +1359,13 @@ public class WindowStateTests extends WindowTestsBase {
assertThat(listener.mImeTargetToken).isEqualTo(imeTarget.mClient.asBinder());
assertThat(listener.mIsRemoved).isFalse();
assertThat(listener.mIsVisibleForImeInputTarget).isFalse();
+ assertThat(listener.mDisplayId).isEqualTo(mDisplayContent.getDisplayId());
imeTarget.removeImmediately();
assertThat(listener.mImeTargetToken).isEqualTo(imeTarget.mClient.asBinder());
assertThat(listener.mIsRemoved).isTrue();
assertThat(listener.mIsVisibleForImeInputTarget).isFalse();
+ assertThat(listener.mDisplayId).isEqualTo(mDisplayContent.getDisplayId());
}
@SetupWindows(addWindows = {W_INPUT_METHOD})
@@ -1402,6 +1405,7 @@ public class WindowStateTests extends WindowTestsBase {
assertThat(listener.mImeTargetToken).isEqualTo(client.asBinder());
assertThat(listener.mIsRemoved).isFalse();
assertThat(listener.mIsVisibleForImeTargetOverlay).isTrue();
+ assertThat(listener.mDisplayId).isEqualTo(mDisplayContent.getDisplayId());
// Scenario 2: test relayoutWindow to let the Ime layering target overlay window invisible.
mWm.relayoutWindow(session, client, params, 100, 200, View.GONE, 0, 0, 0,
@@ -1412,6 +1416,7 @@ public class WindowStateTests extends WindowTestsBase {
assertThat(listener.mImeTargetToken).isEqualTo(client.asBinder());
assertThat(listener.mIsRemoved).isFalse();
assertThat(listener.mIsVisibleForImeTargetOverlay).isFalse();
+ assertThat(listener.mDisplayId).isEqualTo(mDisplayContent.getDisplayId());
// Scenario 3: test removeWindow to remove the Ime layering target overlay window.
mWm.removeClientToken(session, client.asBinder());
@@ -1420,6 +1425,7 @@ public class WindowStateTests extends WindowTestsBase {
assertThat(listener.mImeTargetToken).isEqualTo(client.asBinder());
assertThat(listener.mIsRemoved).isTrue();
assertThat(listener.mIsVisibleForImeTargetOverlay).isFalse();
+ assertThat(listener.mDisplayId).isEqualTo(mDisplayContent.getDisplayId());
}
@Test
@@ -1468,22 +1474,25 @@ public class WindowStateTests extends WindowTestsBase {
private boolean mIsRemoved;
private boolean mIsVisibleForImeTargetOverlay;
private boolean mIsVisibleForImeInputTarget;
+ private int mDisplayId;
@Override
public void onImeTargetOverlayVisibilityChanged(IBinder overlayWindowToken,
@WindowManager.LayoutParams.WindowType int windowType, boolean visible,
- boolean removed) {
+ boolean removed, int displayId) {
mImeTargetToken = overlayWindowToken;
mIsVisibleForImeTargetOverlay = visible;
mIsRemoved = removed;
+ mDisplayId = displayId;
}
@Override
public void onImeInputTargetVisibilityChanged(IBinder imeInputTarget,
- boolean visibleRequested, boolean removed) {
+ boolean visibleRequested, boolean removed, int displayId) {
mImeTargetToken = imeInputTarget;
mIsVisibleForImeInputTarget = visibleRequested;
mIsRemoved = removed;
+ mDisplayId = displayId;
}
}
}
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 14044135eca7..6c1e1a428fb8 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -80,9 +80,9 @@ import android.os.storage.StorageVolume;
import android.provider.Settings;
import android.service.usb.UsbDeviceManagerProto;
import android.service.usb.UsbHandlerProto;
+import android.text.TextUtils;
import android.util.Pair;
import android.util.Slog;
-import android.text.TextUtils;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
@@ -880,7 +880,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
}
}
- private void notifyAccessoryModeExit(int operationId) {
+ protected void notifyAccessoryModeExit(int operationId) {
// make sure accessory mode is off
// and restore default functions
Slog.d(TAG, "exited USB accessory mode");
@@ -2313,8 +2313,13 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser
*/
operationId = sUsbOperationCount.incrementAndGet();
if (msg.arg1 != 1) {
- // Set this since default function may be selected from Developer options
- setEnabledFunctions(mScreenUnlockedFunctions, false, operationId);
+ if (mCurrentFunctions == UsbManager.FUNCTION_ACCESSORY) {
+ notifyAccessoryModeExit(operationId);
+ } else {
+ // Set this since default function may be selected from Developer
+ // options
+ setEnabledFunctions(mScreenUnlockedFunctions, false, operationId);
+ }
}
break;
case MSG_GADGET_HAL_REGISTERED:
diff --git a/telecomm/java/android/telecom/CallerInfoAsyncQuery.java b/telecomm/java/android/telecom/CallerInfoAsyncQuery.java
index 93cd291aeea0..a03d7e25d4c5 100644
--- a/telecomm/java/android/telecom/CallerInfoAsyncQuery.java
+++ b/telecomm/java/android/telecom/CallerInfoAsyncQuery.java
@@ -483,18 +483,28 @@ public class CallerInfoAsyncQuery {
// check to see if these are recognized numbers, and use shortcuts if we can.
TelephonyManager tm = context.getSystemService(TelephonyManager.class);
+
boolean isEmergencyNumber = false;
try {
isEmergencyNumber = tm.isEmergencyNumber(number);
- } catch (IllegalStateException ise) {
+ } catch (IllegalStateException | UnsupportedOperationException ise) {
// Ignore the exception that Telephony is not up. Use PhoneNumberUtils API now.
// Ideally the PhoneNumberUtils API needs to be removed once the
// telphony service not up issue can be fixed (b/187412989)
+ // UnsupportedOperationException: telephony.calling may not be supported on this device
isEmergencyNumber = PhoneNumberUtils.isLocalEmergencyNumber(context, number);
}
+
+ boolean isVoicemailNumber;
+ try {
+ isVoicemailNumber = PhoneNumberUtils.isVoiceMailNumber(context, subId, number);
+ } catch (UnsupportedOperationException ex) {
+ isVoicemailNumber = false;
+ }
+
if (isEmergencyNumber) {
cw.event = EVENT_EMERGENCY_NUMBER;
- } else if (PhoneNumberUtils.isVoiceMailNumber(context, subId, number)) {
+ } else if (isVoicemailNumber) {
cw.event = EVENT_VOICEMAIL_NUMBER;
} else {
cw.event = EVENT_NEW_QUERY;
diff --git a/telephony/common/com/android/internal/telephony/SmsApplication.java b/telephony/common/com/android/internal/telephony/SmsApplication.java
index 94d4d2260d5c..9b83719402a0 100644
--- a/telephony/common/com/android/internal/telephony/SmsApplication.java
+++ b/telephony/common/com/android/internal/telephony/SmsApplication.java
@@ -528,7 +528,7 @@ public final class SmsApplication {
// current SMS app will already be the preferred activity - but checking whether or
// not this is true is just as expensive as reconfiguring the preferred activity so
// we just reconfigure every time.
- defaultSmsAppChanged(context);
+ grantPermissionsToSystemApps(context);
}
}
if (DEBUG_MULTIUSER) {
@@ -542,9 +542,9 @@ public final class SmsApplication {
}
/**
- * Grants various permissions and appops on sms app change
+ * Grants various permissions and appops, e.g. on sms app change
*/
- private static void defaultSmsAppChanged(Context context) {
+ public static void grantPermissionsToSystemApps(Context context) {
PackageManager packageManager = context.getPackageManager();
AppOpsManager appOps = context.getSystemService(AppOpsManager.class);
@@ -680,7 +680,7 @@ public final class SmsApplication {
return;
}
- defaultSmsAppChanged(context);
+ grantPermissionsToSystemApps(context);
}
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index c6959ae6345a..b9a001d1f2b6 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -9604,9 +9604,8 @@ public class CarrierConfigManager {
* Defines the rules for data setup retry.
*
* The syntax of the retry rule:
- * 1. Retry based on {@link NetworkCapabilities}. Note that only APN-type network capabilities
- * are supported. If the capabilities are not specified, then the retry rule only applies
- * to the current failed APN used in setup data call request.
+ * 1. Retry based on {@link NetworkCapabilities}. If the capabilities are not specified, then
+ * the retry rule only applies to the current failed APN used in setup data call request.
* "capabilities=[netCaps1|netCaps2|...], [retry_interval=n1|n2|n3|n4...], [maximum_retries=n]"
*
* 2. Retry based on {@link DataFailCause}
diff --git a/tools/protologtool/src/com/android/protolog/tool/ViewerConfigProtoBuilder.kt b/tools/protologtool/src/com/android/protolog/tool/ViewerConfigProtoBuilder.kt
index cf0876a1f072..0115339a68b7 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ViewerConfigProtoBuilder.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ViewerConfigProtoBuilder.kt
@@ -55,6 +55,7 @@ class ViewerConfigProtoBuilder : ProtoLogTool.ProtologViewerConfigBuilder {
.setLevel(
ProtoLogLevel.forNumber(log.logLevel.ordinal + 1))
.setGroupId(groupId)
+ .setLocation(log.position)
)
}
diff --git a/wifi/java/src/android/net/wifi/WifiBlobStore.java b/wifi/java/src/android/net/wifi/WifiBlobStore.java
index 8737c7e91454..57d997bc2267 100644
--- a/wifi/java/src/android/net/wifi/WifiBlobStore.java
+++ b/wifi/java/src/android/net/wifi/WifiBlobStore.java
@@ -16,8 +16,11 @@
package android.net.wifi;
+import android.os.Build;
import android.os.ServiceManager;
+import android.os.SystemProperties;
import android.security.legacykeystore.ILegacyKeystore;
+import android.util.Log;
import com.android.internal.net.ConnectivityBlobStore;
@@ -26,13 +29,44 @@ import com.android.internal.net.ConnectivityBlobStore;
* @hide
*/
public class WifiBlobStore extends ConnectivityBlobStore {
+ private static final String TAG = "WifiBlobStore";
private static final String DB_NAME = "WifiBlobStore.db";
private static final String LEGACY_KEYSTORE_SERVICE_NAME = "android.security.legacykeystore";
+ private static final boolean sIsVendorApiLevelGreaterThanT = isVendorApiLevelGreaterThanT();
private static WifiBlobStore sInstance;
private WifiBlobStore() {
super(DB_NAME);
}
+ private static boolean isVendorApiLevelGreaterThanT() {
+ int androidT = Build.VERSION_CODES.TIRAMISU; // redefine to avoid errorprone build issue
+ String[] vendorApiLevelProps = {
+ "ro.board.api_level", "ro.board.first_api_level", "ro.vndk.version"};
+ for (String propertyName : vendorApiLevelProps) {
+ int apiLevel = SystemProperties.getInt(propertyName, -1);
+ if (apiLevel != -1) {
+ Log.i(TAG, "Retrieved API level property, value=" + apiLevel);
+ return apiLevel > androidT;
+ }
+ }
+ // If none of the properties are defined, we are using the current API level (> V)
+ Log.i(TAG, "No API level properties are defined");
+ return true;
+ }
+
+ /**
+ * Check whether supplicant can access values stored in WifiBlobstore.
+ *
+ * NonStandardCertCallback was added in Android U, allowing supplicant to access the
+ * WifiKeystore APIs, which access WifiBlobstore. Previously, supplicant used
+ * WifiKeystoreHalConnector to access values stored in Legacy Keystore.
+ *
+ * @hide
+ */
+ public static boolean supplicantCanAccessBlobstore() {
+ return sIsVendorApiLevelGreaterThanT;
+ }
+
/** Returns an instance of WifiBlobStore. */
public static WifiBlobStore getInstance() {
if (sInstance == null) {